james 0.0.3-universal-darwin-10 → 0.0.4-universal-darwin-10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/aux/james/cli.rb CHANGED
@@ -4,18 +4,26 @@ module James
4
4
 
5
5
  class CLI
6
6
 
7
- def execute *dialogues
8
- all_dialogues = Dir["**/*_dialog{,ue}.rb"]
9
- all_dialogues.select! { |dialogue| dialogues.any? { |given| dialogue =~ %r{#{given}_dialog(ue)?.rb$} } } unless dialogues.empty?
7
+ def execute *given_dialogues
8
+ dialogues = find_dialogues
9
+ dialogues.select! { |dialogue| given_dialogues.any? { |given| dialogue =~ %r{#{given}_dialog(ue)?.rb$} } } unless given_dialogues.empty?
10
10
 
11
- puts "James: Using #{all_dialogues.join(', ')} for our conversation, Sir."
11
+ puts "James: I haven't found anything to talk about (No *_dialog{ue,}.rb files found). Exiting." or exit!(1) if dialogues.empty?
12
12
 
13
- all_dialogues.each do |dialogue|
14
- require File.expand_path dialogue, Dir.pwd
15
- end
13
+ puts "James: Using #{dialogues.join(', ')} for our conversation, Sir."
14
+
15
+ require_all dialogues
16
16
 
17
17
  James.listen
18
18
  end
19
+ def find_dialogues
20
+ Dir["**/*_dialog{,ue}.rb"]
21
+ end
22
+ def require_all dialogues
23
+ dialogues.each do |dialogue|
24
+ require File.expand_path dialogue, Dir.pwd
25
+ end
26
+ end
19
27
 
20
28
  end
21
29
 
data/lib/james.rb CHANGED
@@ -2,6 +2,7 @@ module James; end
2
2
 
3
3
  require File.expand_path '../james/timer', __FILE__
4
4
  require File.expand_path '../james/visitor', __FILE__
5
+ require File.expand_path '../james/visitors', __FILE__
5
6
  require File.expand_path '../james/dialogues', __FILE__
6
7
 
7
8
  require File.expand_path '../james/dialogue_api', __FILE__
@@ -0,0 +1,27 @@
1
+ class CoreDialogue
2
+
3
+ include James::Dialogue
4
+
5
+ state :awake do
6
+ chainable # If James is awake, he offers more dialogues on this state, if there are any.
7
+
8
+ hear 'Leave me alone, James.' => :away,
9
+ "That's it for today, James." => :exit,
10
+ "Something else, James." => :awake
11
+ into { "Sir?" }
12
+ end
13
+
14
+ state :away do
15
+ hear 'James?' => :awake,
16
+ "That's it for today, James." => :exit
17
+ into { "Of course, Sir!" }
18
+ end
19
+
20
+ state :exit do
21
+ into do
22
+ puts "James: Exits through a side door."
23
+ Kernel.exit
24
+ end
25
+ end
26
+
27
+ end
@@ -7,6 +7,8 @@ require File.expand_path '../inputs/terminal', __FILE__
7
7
  require File.expand_path '../outputs/audio', __FILE__
8
8
  require File.expand_path '../outputs/terminal', __FILE__
9
9
 
10
+ require File.expand_path '../builtin/core_dialogue', __FILE__
11
+
10
12
  module James
11
13
 
12
14
  class Controller
@@ -14,7 +16,9 @@ module James
14
16
  attr_reader :visitor
15
17
 
16
18
  def initialize
17
- @visitor = initialize_dialogues.visitor
19
+ user_visitor = initialize_dialogues.visitor
20
+ system_visitor = Visitor.new CoreDialogue.new.state_for(:awake)
21
+ @visitor = Visitors.new system_visitor, user_visitor
18
22
  end
19
23
 
20
24
  def applicationDidFinishLaunching notification
@@ -80,29 +84,31 @@ module James
80
84
  end
81
85
  end
82
86
  def expects
83
- @visitor.expects
87
+ possibilities = @visitor.expects
88
+ puts "Possibilities:\n #{possibilities.join("\n ")}"
89
+ possibilities
84
90
  end
85
91
 
86
92
  def listen
87
93
  app = NSApplication.sharedApplication
88
94
  app.delegate = self
89
95
 
90
- # window = NSWindow.alloc.initWithContentRect([200, 300, 300, 100],
96
+ # window = NSWindow.alloc.initWithContentRect([100, 300, 300, 100],
91
97
  # styleMask:NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask,
92
98
  # backing:NSBackingStoreBuffered,
93
99
  # defer:false)
94
- # window.title = 'MacRuby: The Definitive Guide'
100
+ # window.title = 'James Debug/Info'
95
101
  # window.level = 3
96
102
  # window.delegate = app.delegate
103
+
104
+ # @button = NSButton.alloc.initWithFrame([10, 10, 400, 10])
105
+ # @button.bezelStyle = 4
106
+ # @button.title = ''
107
+ # @button.target = app.delegate
108
+ # @button.action = 'say_hello:'
97
109
  #
98
- # button = NSButton.alloc.initWithFrame([80, 10, 120, 80])
99
- # button.bezelStyle = 4
100
- # button.title = 'Hello World!'
101
- # button.target = app.delegate
102
- # button.action = 'say_hello:'
103
- #
104
- # window.contentView.addSubview(button)
105
- #
110
+ # window.contentView.addSubview(@button)
111
+
106
112
  # window.display
107
113
  # window.orderFrontRegardless
108
114
 
@@ -11,7 +11,7 @@ module James
11
11
 
12
12
  def self.included into
13
13
  into.extend ClassMethods
14
- Dialogues << into
14
+ Dialogues << into unless into == CoreDialogue # TODO Dirty as hell.
15
15
  end
16
16
 
17
17
  #
@@ -58,6 +58,15 @@ module James
58
58
  @exit_block = block
59
59
  end
60
60
 
61
+ # By default, a state is not chainable.
62
+ #
63
+ def chainable?
64
+ @chainable
65
+ end
66
+ def chainable
67
+ @chainable = true
68
+ end
69
+
61
70
  # Description of self using name and transitions.
62
71
  #
63
72
  def to_s
data/lib/james/visitor.rb CHANGED
@@ -21,13 +21,13 @@ module James
21
21
  @current = initial
22
22
 
23
23
  @initial = initial
24
- @timer = timer || Timer.new
24
+ # @timer = timer || Timer.new
25
25
  end
26
26
 
27
27
  # Escapes the current state back to the initial.
28
28
  #
29
- def escape
30
- timer.stop
29
+ def reset
30
+ # timer.stop
31
31
  self.current = initial
32
32
  end
33
33
 
@@ -53,7 +53,7 @@ module James
53
53
  end
54
54
  def hear phrase, &block
55
55
  return unless hears? phrase
56
- timer.restart
56
+ # timer.restart
57
57
  exit_text = exit &block
58
58
  transition phrase
59
59
  check &block
@@ -66,6 +66,15 @@ module James
66
66
  def expects
67
67
  current.phrases
68
68
  end
69
+ # Does the current state allow penetration into another dialogue?
70
+ #
71
+ def chainable?
72
+ current.chainable?
73
+ end
74
+
75
+ def to_s
76
+ "#{self.class.name}(#{initial}, current: #{current})"
77
+ end
69
78
 
70
79
  end
71
80
 
@@ -22,14 +22,39 @@ module James
22
22
  @visitors = visitors
23
23
  end
24
24
 
25
+ # Hear tries all visitors in order
26
+ # until one hears a phrase he knows.
27
+ #
28
+ # After that, all remaining visitors are reset.
29
+ #
25
30
  def hear phrase, &block
26
- visitors.each do |visitor|
31
+ enumerator = visitors.dup
32
+
33
+ while visitor = enumerator.shift
27
34
  visitor.hear phrase, &block and break
28
35
  end
36
+
37
+ while visitor = enumerator.shift
38
+ visitor.reset
39
+ end
29
40
  end
30
41
 
42
+ # Enter enters the first dialogue.
43
+ #
44
+ def enter
45
+ visitors.first.enter
46
+ end
47
+
48
+ # Simply returns the sum of what phrases all dialogues expect.
49
+ #
50
+ # Stops as soon as a visitor is not in a chainable state anymore.
51
+ #
31
52
  def expects
32
- visitors.inject([]) { |expects, visitor| expects + visitor.expects }
53
+ visitors.inject([]) do |expects, visitor|
54
+ total = expects + visitor.expects
55
+ break total unless visitor.chainable?
56
+ total
57
+ end
33
58
  end
34
59
 
35
60
  end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ #
3
+ require File.expand_path '../../../../aux/james/cli', __FILE__
4
+
5
+ describe James::CLI do
6
+
7
+ before(:each) do
8
+ Dir.stub! :[] => ['test_dialogue.rb', 'test_dialog.rb', 'test/test_dialogue.rb']
9
+ end
10
+
11
+ let(:cli) { James::CLI.new }
12
+
13
+ describe 'find_dialogues' do
14
+ it 'returns the right ones' do
15
+ cli.find_dialogues.should == ['test_dialogue.rb', 'test_dialog.rb', 'test/test_dialogue.rb']
16
+ end
17
+ end
18
+
19
+ end
@@ -8,6 +8,30 @@ describe James::Visitor do
8
8
  let(:timer) { stub :timer }
9
9
  let(:visitor) { described_class.new initial, timer }
10
10
 
11
+ describe 'reset' do
12
+ it 'works' do
13
+ expect { visitor.reset }.to_not raise_error
14
+ end
15
+ # it 'calls methods in order' do
16
+ # timer.should_receive(:stop).once.with
17
+ # visitor.should_receive(:current=).once.with initial
18
+ #
19
+ # visitor.reset
20
+ # end
21
+ it 'survives a functional test' do
22
+ next_state = stub :next_state
23
+ initial.stub! :next_for => next_state
24
+
25
+ visitor.current.should == initial
26
+ visitor.transition :some_phrase
27
+ visitor.current.should == next_state
28
+
29
+ visitor.reset
30
+
31
+ visitor.current.should == initial
32
+ end
33
+ end
34
+
11
35
  describe 'current' do
12
36
  it { visitor.current.should == initial }
13
37
  end
@@ -62,19 +86,10 @@ describe James::Visitor do
62
86
  end
63
87
  end
64
88
 
65
- describe 'escape' do
66
- it 'calls methods in order' do
67
- timer.should_receive(:stop).once.with
68
- visitor.should_receive(:current=).once.with initial
69
-
70
- visitor.escape
71
- end
72
- end
73
-
74
89
  describe 'hear' do
75
90
  it 'calls methods in order' do
76
91
  visitor.should_receive(:hears?).once.ordered.with(:some_phrase).and_return true
77
- timer.should_receive(:restart).once.ordered.with
92
+ # timer.should_receive(:restart).once.ordered.with
78
93
  visitor.should_receive(:exit).once.ordered.with
79
94
  visitor.should_receive(:transition).once.ordered.with :some_phrase
80
95
  # visitor.should_receive(:check).once.ordered.with
@@ -15,11 +15,14 @@ describe James::Visitors do
15
15
  second.stub! :hear => nil
16
16
  end
17
17
  it 'works' do
18
+ second.stub! :reset
19
+
18
20
  visitors.hear 'some phrase'
19
21
  end
20
22
  it 'calls the second never' do
21
23
  first.should_receive(:hear).once.and_return true
22
24
  second.should_receive(:hear).never
25
+ second.should_receive(:reset).once
23
26
 
24
27
  visitors.hear 'some phrase'
25
28
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 3
9
- version: 0.0.3
8
+ - 4
9
+ version: 0.0.4
10
10
  platform: universal-darwin-10
11
11
  authors:
12
12
  - Florian Hanke
@@ -42,7 +42,7 @@ executables:
42
42
  extensions: []
43
43
  extra_rdoc_files: []
44
44
  files:
45
- - lib/james/builtin/main_dialogue.rb
45
+ - lib/james/builtin/core_dialogue.rb
46
46
  - lib/james/controller.rb
47
47
  - lib/james/dialogue_api.rb
48
48
  - lib/james/dialogue_internals.rb
@@ -50,7 +50,6 @@ files:
50
50
  - lib/james/inputs/audio.rb
51
51
  - lib/james/inputs/base.rb
52
52
  - lib/james/inputs/terminal.rb
53
- - lib/james/main_dialogue.rb
54
53
  - lib/james/outputs/audio.rb
55
54
  - lib/james/outputs/terminal.rb
56
55
  - lib/james/state_api.rb
@@ -90,6 +89,7 @@ signing_key:
90
89
  specification_version: 3
91
90
  summary: 'James: Modular Electronic Butler.'
92
91
  test_files:
92
+ - spec/aux/james/cli_spec.rb
93
93
  - spec/integration/test_dialogue_spec.rb
94
94
  - spec/lib/james/controller_spec.rb
95
95
  - spec/lib/james/dialogue_spec.rb
@@ -1,25 +0,0 @@
1
- class Bla
2
-
3
- include James::Dialogue
4
-
5
- hear 'James?' => :awake
6
-
7
- state :awake do
8
- hear 'Leave me alone, James' => :away
9
- into { "Sir?" }
10
- end
11
-
12
- state :away do
13
- hear 'Are you there, James?' => :awake,
14
- "That's it for today, James" => :exit
15
- into { "Goodbye, Sir" }
16
- end
17
-
18
- state :exit do
19
- into do
20
- puts "James: Exits through a side door."
21
- Kernel.exit
22
- end
23
- end
24
-
25
- end
@@ -1,15 +0,0 @@
1
- module James
2
-
3
- # MainDialogue for first visitor.
4
- #
5
- module MainDialogue
6
-
7
- extend Dialogue
8
-
9
- def self.included into
10
- into.extend ClassMethods
11
- end
12
-
13
- end
14
-
15
- end