ceml 0.7.3 → 0.7.4
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/ceml.gemspec +3 -1
- data/lib/ceml/driver.rb +35 -7
- data/lib/ceml/incident.rb +26 -3
- data/lib/ceml/tt/casting.treetop +5 -1
- data/lib/ceml/tt/instructions.treetop +29 -12
- data/lib/ceml/tt/lexer.treetop +1 -1
- data/test/helper.rb +5 -1
- data/test/test_release.rb +106 -0
- metadata +4 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.4
|
data/ceml.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ceml}
|
8
|
-
s.version = "0.7.
|
8
|
+
s.version = "0.7.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Joe Edelman"]
|
@@ -49,6 +49,7 @@ Gem::Specification.new do |s|
|
|
49
49
|
"test/test_casting.rb",
|
50
50
|
"test/test_incident.rb",
|
51
51
|
"test/test_instructions.rb",
|
52
|
+
"test/test_release.rb",
|
52
53
|
"test/test_scripts.rb",
|
53
54
|
"try"
|
54
55
|
]
|
@@ -62,6 +63,7 @@ Gem::Specification.new do |s|
|
|
62
63
|
"test/test_casting.rb",
|
63
64
|
"test/test_incident.rb",
|
64
65
|
"test/test_instructions.rb",
|
66
|
+
"test/test_release.rb",
|
65
67
|
"test/test_scripts.rb"
|
66
68
|
]
|
67
69
|
|
data/lib/ceml/driver.rb
CHANGED
@@ -39,16 +39,23 @@ module CEML
|
|
39
39
|
SCRIPTS[script_collection_id] << script
|
40
40
|
end
|
41
41
|
|
42
|
-
def ping_all script_collection_id, candidate
|
43
|
-
|
42
|
+
def ping_all script_collection_id, candidate, release = false
|
43
|
+
candidate[:script_collection_id] = script_collection_id
|
44
|
+
SCRIPTS[script_collection_id].each{ |s| ping script_collection_id, s.roles_to_cast, candidate, release }
|
44
45
|
end
|
45
46
|
|
47
|
+
def released_from_all script_collection_id, candidate
|
48
|
+
SCRIPTS[script_collection_id].each{ |s| release script_collection_id, s.roles_to_cast, candidate }
|
49
|
+
end
|
50
|
+
|
51
|
+
|
46
52
|
def launch script_collection_id, roleset, *cast
|
47
53
|
script = SCRIPTS[script_collection_id].select{ |s| s.roles_to_cast == roleset }.sort_by{ rand }.first
|
48
54
|
unless script
|
49
55
|
rolesets = SCRIPTS[script_collection_id].map(&:roles_to_cast)
|
50
56
|
raise "matching roleset not found: #{roleset.inspect} in #{rolesets.inspect}"
|
51
57
|
end
|
58
|
+
log "launching #{script.bytecode.inspect} with cast #{cast.inspect}"
|
52
59
|
push nil, script.bytecode, *cast
|
53
60
|
end
|
54
61
|
|
@@ -58,8 +65,7 @@ module CEML
|
|
58
65
|
yield LOCATIONS["#{script_collection_id}:#{roleset.hash}"]
|
59
66
|
end
|
60
67
|
|
61
|
-
|
62
|
-
def ping script_collection_id, roleset, candidate
|
68
|
+
def ping script_collection_id, roleset, candidate, involvement = :sticky
|
63
69
|
return unless roleset.any?{ |r| r.fits? candidate }
|
64
70
|
candidate[:ts] = CEML.clock
|
65
71
|
already_launched_with = nil
|
@@ -68,14 +74,15 @@ module CEML
|
|
68
74
|
live_with = confluences.select{ |c| c.live_with?(candidate) }
|
69
75
|
if not live_with.empty?
|
70
76
|
already_launched_with = live_with.first.incident_id
|
71
|
-
|
77
|
+
live_with.each{ |c| c.rm candidate } if involvement != :sticky
|
78
|
+
break if involvement != :released
|
72
79
|
end
|
73
80
|
|
74
81
|
locs = confluences.group_by{ |l| l.stage_with_candidate(candidate) }
|
75
82
|
if locs[:joinable]
|
76
83
|
log "joining..."
|
77
84
|
first = locs[:joinable].shift
|
78
|
-
first.push candidate
|
85
|
+
first.push candidate unless first.incident_id == already_launched_with
|
79
86
|
push first.incident_id, nil, candidate # JOIN THEM
|
80
87
|
|
81
88
|
elsif locs[:launchable]
|
@@ -105,7 +112,8 @@ module CEML
|
|
105
112
|
confluences.delete_if(&:over?)
|
106
113
|
end
|
107
114
|
|
108
|
-
if already_launched_with
|
115
|
+
if already_launched_with and involvement == :sticky
|
116
|
+
puts "PUSHING INSTEAD"
|
109
117
|
push already_launched_with, nil, candidate
|
110
118
|
end
|
111
119
|
end
|
@@ -152,5 +160,25 @@ module CEML
|
|
152
160
|
JUST_SAID[data[:player][:id]] = what
|
153
161
|
puts "Said #{what.inspect}"
|
154
162
|
end
|
163
|
+
|
164
|
+
# def player_start(data, what)
|
165
|
+
# puts "STARTED #{data[:player].inspect}"
|
166
|
+
# end
|
167
|
+
|
168
|
+
def player_released(data, tag)
|
169
|
+
p = data[:player].dup
|
170
|
+
p[:tags] -= ['new']
|
171
|
+
if tag =~ /^(\w+)=/
|
172
|
+
p[:tags].delete_if{ |t| t =~ /^#{$1}=/ }
|
173
|
+
end
|
174
|
+
p[:tags] += [tag]
|
175
|
+
p.delete :pc
|
176
|
+
p.delete :roles
|
177
|
+
data[:player][:released] = true
|
178
|
+
# data[:players].delete_if{ |pl| pl[:id] == p[:id] }
|
179
|
+
puts "released: #{p.inspect} with #{tag}"
|
180
|
+
# puts "remaining players: #{data[:players].inspect}"
|
181
|
+
ping_all p[:script_collection_id], p, true
|
182
|
+
end
|
155
183
|
end
|
156
184
|
end
|
data/lib/ceml/incident.rb
CHANGED
@@ -28,8 +28,12 @@ module CEML
|
|
28
28
|
def run(players, &blk)
|
29
29
|
@players = players
|
30
30
|
@callback = blk
|
31
|
-
|
32
|
-
|
31
|
+
puts "playing with #{@players.map{|p|p[:id]}}"
|
32
|
+
:loop while @players.any? do |thing|
|
33
|
+
@this = thing
|
34
|
+
next if thing[:released]
|
35
|
+
puts "trying #{@this[:id]}"
|
36
|
+
puts "not yet released"
|
33
37
|
next unless instr = seq[pc]
|
34
38
|
instr = instr.dup
|
35
39
|
if rolematch(instr.shift)
|
@@ -37,6 +41,7 @@ module CEML
|
|
37
41
|
next unless send(*instr)
|
38
42
|
cb(*instr)
|
39
43
|
end
|
44
|
+
# next if @this[:released]
|
40
45
|
this[:pc]+=1
|
41
46
|
end
|
42
47
|
@callback = @players = nil
|
@@ -116,7 +121,8 @@ module CEML
|
|
116
121
|
|
117
122
|
def answered_q q
|
118
123
|
got or return false
|
119
|
-
qs_answers[q[:key]] = got
|
124
|
+
this[:last_answer] = qs_answers[q[:key]] = got
|
125
|
+
this[:last_answer_recognized] = recognized
|
120
126
|
handled!
|
121
127
|
true
|
122
128
|
end
|
@@ -152,6 +158,23 @@ module CEML
|
|
152
158
|
end
|
153
159
|
end
|
154
160
|
|
161
|
+
def last_answer_match?(value)
|
162
|
+
case value
|
163
|
+
when :yes; this[:last_answer_recognized] == :yes
|
164
|
+
when :no; this[:last_answer_recognized] == :no
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def expectation(type, value)
|
169
|
+
if type == :if then last_answer_match?(value) else !last_answer_match?(value) end
|
170
|
+
end
|
171
|
+
|
172
|
+
def release x
|
173
|
+
return true if x[:cond] and not expectation(*x[:cond])
|
174
|
+
cb :released, x[:tag]
|
175
|
+
false
|
176
|
+
end
|
177
|
+
|
155
178
|
def null_assign
|
156
179
|
say :proceed
|
157
180
|
true
|
data/lib/ceml/tt/casting.treetop
CHANGED
@@ -7,7 +7,7 @@ grammar Casting
|
|
7
7
|
end
|
8
8
|
|
9
9
|
rule modifier_phrase
|
10
|
-
over_phrase / within_phrase
|
10
|
+
over_phrase / within_phrase / with_matching_phrase
|
11
11
|
end
|
12
12
|
|
13
13
|
rule over_phrase
|
@@ -18,6 +18,10 @@ grammar Casting
|
|
18
18
|
ws 'within' ws distance
|
19
19
|
end
|
20
20
|
|
21
|
+
rule with_matching_phrase
|
22
|
+
ws 'with' ws 'matching' ws thing:id
|
23
|
+
end
|
24
|
+
|
21
25
|
rule roles
|
22
26
|
role more:(and role)* {
|
23
27
|
def list
|
@@ -3,7 +3,7 @@ grammar Instructions
|
|
3
3
|
include Lexer
|
4
4
|
|
5
5
|
rule basic_statement
|
6
|
-
(ask_stmt / tell_stmt / assign_stmt / record_stmt / set_stmt / sync_stmt) {
|
6
|
+
(ask_stmt / tell_stmt / assign_stmt / record_stmt / set_stmt / sync_stmt / release_stmt) {
|
7
7
|
|
8
8
|
def delay
|
9
9
|
if parent.respond_to? :later and not parent.later.empty?
|
@@ -12,27 +12,31 @@ grammar Instructions
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def role; id.text_value.to_sym; end
|
15
|
-
def text; super.text_value; end
|
15
|
+
def text; defined?(super) && super.text_value; end
|
16
16
|
def var
|
17
|
-
return varname.text_value if cmd == :record or cmd == :set
|
18
|
-
(!
|
17
|
+
return varname.text_value if cmd == :record or cmd == :set or cmd == :release
|
18
|
+
(!respond_to?(:about) || about.empty?) ? nil : about.varname.text_value;
|
19
19
|
end
|
20
20
|
def key; var || text; end
|
21
21
|
def cmd; text_value.split.first.to_sym; end
|
22
|
+
def cond
|
23
|
+
(!respond_to?(:condition) || condition.empty?) ? nil : condition.value
|
24
|
+
end
|
22
25
|
|
23
26
|
def bytecode
|
24
27
|
code = []
|
25
28
|
code.concat [[[role], :start_delay, delay],
|
26
29
|
[[role], :complete_delay]] if delay
|
27
30
|
code.concat case cmd
|
28
|
-
when :record;
|
29
|
-
when :set;
|
30
|
-
when :ask;
|
31
|
-
|
32
|
-
when :tell;
|
33
|
-
when :assign;
|
34
|
-
|
35
|
-
when :
|
31
|
+
when :record; [[[role], :answered_q, {:key => key}]]
|
32
|
+
when :set; [[[role], :set, {:key => key, :value => text}]]
|
33
|
+
when :ask; [[[role], :ask_q, {:text => text}],
|
34
|
+
[[role], :answered_q, {:key => key}]]
|
35
|
+
when :tell; [[[role], :send_msg, {:text => text}]]
|
36
|
+
when :assign; [[[role], :assign, {:text => text}],
|
37
|
+
[[role], :complete_assign, {:text => text}]]
|
38
|
+
when :release; [[[role], :release, {:tag => key, :cond => cond}]]
|
39
|
+
when :sync; [[[role], :sync]]
|
36
40
|
end
|
37
41
|
code
|
38
42
|
end
|
@@ -70,5 +74,18 @@ grammar Instructions
|
|
70
74
|
rule sync_stmt
|
71
75
|
'sync' ws id
|
72
76
|
end
|
77
|
+
|
78
|
+
rule release_stmt
|
79
|
+
'release' ws id ws 'as' ws varname:id condition:condition?
|
80
|
+
end
|
81
|
+
|
82
|
+
rule condition
|
83
|
+
ws type:('if' / 'else') ws thing:id {
|
84
|
+
def value
|
85
|
+
[type.text_value.to_sym, thing.text_value.to_sym]
|
86
|
+
end
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
73
90
|
end
|
74
91
|
end
|
data/lib/ceml/tt/lexer.treetop
CHANGED
data/test/helper.rb
CHANGED
@@ -33,7 +33,11 @@ class Test::Unit::TestCase
|
|
33
33
|
iid = CEML::Driver::INCIDENTS.keys.find do |iid|
|
34
34
|
CEML::Driver::PLAYERS[iid].find{ |p| p[:id] == id }
|
35
35
|
end
|
36
|
-
|
36
|
+
if str == 'y'
|
37
|
+
DRIVER.post iid, :id => id, :received => str, :recognized => :yes
|
38
|
+
else
|
39
|
+
DRIVER.post iid, :id => id, :received => str
|
40
|
+
end
|
37
41
|
end
|
38
42
|
|
39
43
|
def player id, *roles
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'ceml'
|
2
|
+
require 'test/helper'
|
3
|
+
|
4
|
+
class TestRelease < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_release_syntax
|
7
|
+
s = CEML.parse(:script, "release all as booger")
|
8
|
+
assert l=s.bytecode.find{ |line| line[1] == :release }
|
9
|
+
assert_equal 'booger', l[2][:tag]
|
10
|
+
|
11
|
+
s = CEML.parse(:script, "release all as booger if yes")
|
12
|
+
puts s.bytecode.inspect
|
13
|
+
assert l=s.bytecode.find{ |line| line[1] == :release }
|
14
|
+
assert_equal 'booger', l[2][:tag]
|
15
|
+
assert_equal :if, l[2][:cond][0]
|
16
|
+
assert_equal :yes, l[2][:cond][1]
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_release_and_catch
|
20
|
+
s1 = "await 1 new signup\nrelease signup as confused"
|
21
|
+
s2 = "await 1 confused booger\ntell booger: you're okay dude"
|
22
|
+
f = scriptfam s1, s2
|
23
|
+
play do
|
24
|
+
ping f, :id => 'sam', :tags => ['new']
|
25
|
+
told 'sam', /okay dude/
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_conditional_release_and_catch
|
30
|
+
s1 = "await 1 new signup\nask signup re coffee: want some?\nrelease signup as confused if yes"
|
31
|
+
s2 = "await 1 confused booger\ntell booger: you're okay dude"
|
32
|
+
f = scriptfam s1, s2
|
33
|
+
play do
|
34
|
+
ping f, :id => 'sam', :tags => ['new']
|
35
|
+
asked 'sam', /want/
|
36
|
+
says 'sam', 'y'
|
37
|
+
told 'sam', /okay dude/
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
SAM_IAN_SIGNUP_SCRIPTS = <<XXXX
|
43
|
+
await 1 new signup
|
44
|
+
ask signup re first_name:
|
45
|
+
Thanks for signing up for Infatuated!
|
46
|
+
What's your first name?
|
47
|
+
ask signup re couple:
|
48
|
+
Do you have an Infatuated Match Card you want to use?
|
49
|
+
(These are available at the Infatuated table on the first floor.)
|
50
|
+
release signup as stage=couple if yes
|
51
|
+
ask signup re tags:
|
52
|
+
Who are you and who are you looking for tonight? (text back one: w4w, w4m, m4m, or m4w)
|
53
|
+
|
54
|
+
await stage=couple player
|
55
|
+
ask player re code:
|
56
|
+
Type in your Infatuated Match Card code now.
|
57
|
+
release player as stage=coded
|
58
|
+
|
59
|
+
await 1 stage=coded alpha and 1 stage=coded beta with matching code
|
60
|
+
release alpha as alpha
|
61
|
+
release beta as beta
|
62
|
+
|
63
|
+
await 1 w4w alpha and 1 w4w beta
|
64
|
+
release alpha as alpha
|
65
|
+
release beta as beta
|
66
|
+
|
67
|
+
await 1 w4m alpha and 1 m4w beta
|
68
|
+
release alpha as alpha
|
69
|
+
release beta as beta
|
70
|
+
|
71
|
+
await 1 m4m alpha and 1 m4m beta
|
72
|
+
release alpha as alpha
|
73
|
+
release beta as beta
|
74
|
+
|
75
|
+
await 1 m4w alpha and 1 w4m beta
|
76
|
+
release alpha as alpha
|
77
|
+
release beta as beta
|
78
|
+
|
79
|
+
await 1 alpha alpha, 1 beta beta over 5 minutes
|
80
|
+
tell both: Your date has started, |her.first_name|, |buddy.first_name|
|
81
|
+
XXXX
|
82
|
+
|
83
|
+
|
84
|
+
def test_couple
|
85
|
+
f = scriptfam *CEML.parse(:scripts, SAM_IAN_SIGNUP_SCRIPTS)
|
86
|
+
play do
|
87
|
+
ping f, :id => 'Sara', :tags => ['new']
|
88
|
+
ping f, :id => 'Jon', :tags => ['new']
|
89
|
+
asked 'Sara', /Thanks/
|
90
|
+
says 'Sara', 'Sara'
|
91
|
+
asked 'Sara', /Match Card/
|
92
|
+
says 'Sara', 'y'
|
93
|
+
asked 'Jon', /Thanks/
|
94
|
+
says 'Jon', 'Jon'
|
95
|
+
asked 'Jon', /Match Card/
|
96
|
+
says 'Jon', 'y'
|
97
|
+
asked 'Sara', /code now/
|
98
|
+
says 'Sara', 'xyzzy'
|
99
|
+
asked 'Jon', /code now/
|
100
|
+
says 'Jon', 'xyZZy '
|
101
|
+
told 'Sara', /started, Sara, Jon/
|
102
|
+
told 'Jon', /started, Jon, Sara/
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 7
|
8
|
-
-
|
9
|
-
version: 0.7.
|
8
|
+
- 4
|
9
|
+
version: 0.7.4
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Joe Edelman
|
@@ -71,6 +71,7 @@ files:
|
|
71
71
|
- test/test_casting.rb
|
72
72
|
- test/test_incident.rb
|
73
73
|
- test/test_instructions.rb
|
74
|
+
- test/test_release.rb
|
74
75
|
- test/test_scripts.rb
|
75
76
|
- try
|
76
77
|
has_rdoc: true
|
@@ -108,4 +109,5 @@ test_files:
|
|
108
109
|
- test/test_casting.rb
|
109
110
|
- test/test_incident.rb
|
110
111
|
- test/test_instructions.rb
|
112
|
+
- test/test_release.rb
|
111
113
|
- test/test_scripts.rb
|