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 +15 -7
- data/lib/james.rb +1 -0
- data/lib/james/builtin/core_dialogue.rb +27 -0
- data/lib/james/controller.rb +18 -12
- data/lib/james/dialogue_internals.rb +1 -1
- data/lib/james/state_api.rb +9 -0
- data/lib/james/visitor.rb +13 -4
- data/lib/james/visitors.rb +27 -2
- data/spec/aux/james/cli_spec.rb +19 -0
- data/spec/lib/james/visitor_spec.rb +25 -10
- data/spec/lib/james/visitors_spec.rb +3 -0
- metadata +4 -4
- data/lib/james/builtin/main_dialogue.rb +0 -25
- data/lib/james/main_dialogue.rb +0 -15
data/aux/james/cli.rb
CHANGED
@@ -4,18 +4,26 @@ module James
|
|
4
4
|
|
5
5
|
class CLI
|
6
6
|
|
7
|
-
def execute *
|
8
|
-
|
9
|
-
|
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:
|
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
|
-
|
14
|
-
|
15
|
-
|
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
|
data/lib/james/controller.rb
CHANGED
@@ -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
|
-
|
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([
|
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 = '
|
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
|
-
#
|
99
|
-
|
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
|
|
data/lib/james/state_api.rb
CHANGED
@@ -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
|
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
|
|
data/lib/james/visitors.rb
CHANGED
@@ -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.
|
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([])
|
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
|
-
-
|
9
|
-
version: 0.0.
|
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/
|
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
|