ceml 0.7.13 → 0.8.0
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/Makefile +1 -1
- data/VERSION +1 -1
- data/ceml.gemspec +62 -50
- data/guide/guide.html +69 -14
- data/guide/guide.md +74 -15
- data/guide/guide.pdf +0 -0
- data/lib/ceml/driver.rb +0 -181
- data/lib/ceml/lang/basic_instruction.rb +49 -0
- data/lib/ceml/{casting_statement.rb → lang/casting_statement.rb} +19 -9
- data/lib/ceml/{instruction_statements.rb → lang/instruction_statements.rb} +5 -16
- data/lib/ceml/{script.rb → lang/script.rb} +53 -43
- data/lib/ceml/lang/tt/casting.rb +432 -0
- data/lib/ceml/lang/tt/casting.treetop +29 -0
- data/lib/ceml/lang/tt/instructions.rb +1130 -0
- data/lib/ceml/lang/tt/instructions.treetop +86 -0
- data/lib/ceml/lang/tt/lexer.rb +1804 -0
- data/lib/ceml/{tt → lang/tt}/lexer.treetop +70 -7
- data/lib/ceml/lang/tt/scripts.rb +647 -0
- data/lib/ceml/{tt → lang/tt}/scripts.treetop +2 -2
- data/lib/ceml/lang.rb +10 -0
- data/lib/ceml/models/audition.rb +65 -0
- data/lib/ceml/models/bundle.rb +64 -0
- data/lib/ceml/models/cast.rb +108 -0
- data/lib/ceml/models/castable.rb +81 -0
- data/lib/ceml/{incident.rb → models/incident.rb} +63 -15
- data/lib/ceml/models/incident_model.rb +100 -0
- data/lib/ceml/models/incident_role_slot.rb +16 -0
- data/lib/ceml/models/player.rb +80 -0
- data/lib/ceml/models/queue.rb +12 -0
- data/lib/ceml/models/waiting_room.rb +40 -0
- data/lib/ceml/models.rb +16 -0
- data/lib/ceml/processor.rb +162 -0
- data/lib/ceml.rb +7 -14
- data/test/askchain.ceml +6 -0
- data/test/compliment.ceml +4 -0
- data/test/dialogues/accept.ceml +24 -0
- data/test/dialogues/basic_seed.ceml +26 -0
- data/test/dialogues/jordan.ceml +121 -0
- data/test/helper.rb +44 -39
- data/test/jane.ceml +48 -0
- data/test/{test_casting.rb → lang/test_casting.rb} +5 -0
- data/test/lang/test_instructions.rb +42 -0
- data/test/{test_scripts.rb → lang/test_scripts.rb} +3 -2
- data/test/sync.ceml +6 -0
- data/test/test_castable.rb +20 -0
- data/test/test_dialogues.rb +58 -0
- data/test/test_incident.rb +64 -127
- metadata +54 -30
- data/.gitignore +0 -23
- data/lib/ceml/confluence.rb +0 -63
- data/lib/ceml/role.rb +0 -61
- data/lib/ceml/tt/casting.treetop +0 -65
- data/lib/ceml/tt/instructions.treetop +0 -91
- data/test/test_instructions.rb +0 -27
- data/test/test_release.rb +0 -78
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'ceml'
|
2
|
+
require 'test/helper'
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
class TestCemlTests < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
CEML::Queue.new.calls.clear
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_cemltests
|
12
|
+
Dir["test/dialogues/*.ceml"].each do |f|
|
13
|
+
name = File.basename(f, '.ceml')
|
14
|
+
test = File.new(f).read
|
15
|
+
scripts, test = test.split("\n---\n")
|
16
|
+
|
17
|
+
puts "Running cemltest #{name}..."
|
18
|
+
|
19
|
+
s = CEML.parse(:scripts, scripts).map(&:castable)
|
20
|
+
bundle_id = s.hash.to_s
|
21
|
+
CEML::Processor.set_bundle(bundle_id, s)
|
22
|
+
CEML::Processor.reset_bundle(bundle_id)
|
23
|
+
pl = Set.new
|
24
|
+
play do
|
25
|
+
test.each_line do |line|
|
26
|
+
puts ">>>> #{line}"
|
27
|
+
case line.strip
|
28
|
+
when /^(\w+) *< *(.*)$/
|
29
|
+
if $2.empty?
|
30
|
+
silent $1
|
31
|
+
else
|
32
|
+
told $1, /#{$2}/
|
33
|
+
end
|
34
|
+
when /^(\w+) *> *(.*)$/
|
35
|
+
player_id, msg = $1, $2
|
36
|
+
player = {:id => player_id, :received => msg }
|
37
|
+
if !pl.include?(player_id)
|
38
|
+
player[:tags] = ['new']
|
39
|
+
pl << player_id
|
40
|
+
end
|
41
|
+
player[:recognized] = :yes if msg == 'y' || msg =~ /^yes/i
|
42
|
+
player[:recognized] = :abort if msg == 'abort'
|
43
|
+
player[:recognized] = :done if msg =~ /^done/i || msg == 'd'
|
44
|
+
CEML::Processor.ping(bundle_id, player)
|
45
|
+
CEML::Processor.run
|
46
|
+
when /^\((\d+)\s*(\w+)\)$/
|
47
|
+
CEML.incr_clock CEML.dur($1.to_i, $2)
|
48
|
+
CEML::Processor.run_latest
|
49
|
+
CEML::Processor.run
|
50
|
+
when /^#/
|
51
|
+
else "Skipping line #{line}..."
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
data/test/test_incident.rb
CHANGED
@@ -1,93 +1,29 @@
|
|
1
1
|
require 'ceml'
|
2
2
|
require 'test/helper'
|
3
3
|
|
4
|
-
SYNC_SCRIPT = <<XXX
|
5
|
-
await 1 alpha and 1 beta
|
6
|
-
ask alpha re color: What color?
|
7
|
-
ask beta re color: What color?
|
8
|
-
sync both
|
9
|
-
tell alpha: Hi there
|
10
|
-
tell beta: Goodbye
|
11
|
-
XXX
|
12
|
-
|
13
|
-
COMPLIMENT_SCRIPT = <<XXX
|
14
|
-
"Overwhelm a specific person with compliments"
|
15
|
-
gather 5-20 players within 4 blocks
|
16
|
-
ask organizer re target: Describe their appearance and location
|
17
|
-
tell agents: Look for |somebody.target| and compliment them briefly, then move on.
|
18
|
-
XXX
|
19
|
-
|
20
|
-
JANE_SCRIPT = <<XXX
|
21
|
-
|
22
|
-
await 1 new signup
|
23
|
-
record signup first_name
|
24
|
-
ask signup re shoeless:
|
25
|
-
Hello |his.first_name|. You are Level Zero. Lowly level zero.
|
26
|
-
To advance to Level 1, please remove a shoe. Keep it off,
|
27
|
-
and text back "shoeless".
|
28
|
-
tell signup:
|
29
|
-
O ho! Well done |his.first_name|. Now the other players
|
30
|
-
know you're in the game, too. But you're still a sad Level 1.
|
31
|
-
ask signup re game:
|
32
|
-
To advance to Level 2, answer this question. What was your
|
33
|
-
favorite game when you were 10 years old? Tell me now.
|
34
|
-
tell signup:
|
35
|
-
Ah yes. |his.game| WAS an amazing game. You should try to play
|
36
|
-
it again--sometime this week, perhaps?
|
37
|
-
In the meantime you are but a mere Level 2. Let's see if we can do
|
38
|
-
something about that. (You still have your shoe off, right?)
|
39
|
-
ask signup re friend:
|
40
|
-
While you're texting... Pick someone in your address book you
|
41
|
-
haven't talked to in a while. Send them an SMS
|
42
|
-
just to say hello. Then tell me their first name.
|
43
|
-
tell signup:
|
44
|
-
That was awfully nice of you to message |his.friend|
|
45
|
-
Welcome to the amazing Level 3. You'll like it here. Stay awhile.
|
46
|
-
tell signup:
|
47
|
-
Just kidding. Level 4 is way better than this. To get to
|
48
|
-
Level 4, wait for an appropriate moment in Jane's talk
|
49
|
-
and shout an encouraging "Amen!" Yes. Out loud.
|
50
|
-
ask signup re amen:
|
51
|
-
If you're not the spiritual type, a forceful "YEAH!" will do.
|
52
|
-
When you've accomplished your mission, text me "amen".
|
53
|
-
tell signup:
|
54
|
-
Wow. I didn't think you had it in you. No one has ever gotten to
|
55
|
-
Level 4 before. This is VERY exciting.
|
56
|
-
tell signup:
|
57
|
-
If you get to Level 5, I'll give you a secret password. Tell it to
|
58
|
-
Jane, and you'll get some very fancy loot.
|
59
|
-
ask signup re ovation:
|
60
|
-
All you have to do is wait until the end of Jane's talk--and try to
|
61
|
-
spark a standing ovation. Good luck! Text ovation afterward for your
|
62
|
-
password.
|
63
|
-
tell signup:
|
64
|
-
You did it! You are Level 5. You are AMAZING. The conquering hero of
|
65
|
-
the entire audience! Now I can give you your password.
|
66
|
-
tell signup:
|
67
|
-
Ask Jane to sign a copy of her book to Mr. Gamey McGameful. Of course,
|
68
|
-
this will only work if she saw you standing in that ovation. You were
|
69
|
-
standing, right?
|
70
|
-
XXX
|
71
|
-
|
72
4
|
class TestIncident < Test::Unit::TestCase
|
73
5
|
|
6
|
+
def setup
|
7
|
+
CEML::Queue.new.calls.clear
|
8
|
+
end
|
9
|
+
|
74
10
|
def test_sync
|
75
|
-
s = scriptfam
|
11
|
+
s = scriptfam SCRIPTS['sync']
|
76
12
|
play do
|
77
|
-
ping s, :id => 'alpha'
|
78
|
-
ping s, :id => 'beta'
|
13
|
+
ping s, :id => 'alpha', :tags => ['new']
|
14
|
+
ping s, :id => 'beta', :tags => ['new']
|
79
15
|
asked 'alpha', /olor/
|
80
16
|
asked 'beta', /olor/
|
81
17
|
says 'alpha', "red"
|
82
18
|
silent 'alpha'
|
83
19
|
says 'beta', "blue"
|
84
|
-
told '
|
85
|
-
told '
|
20
|
+
told 'beta', /Hi/
|
21
|
+
told 'alpha', /Goodbye/
|
86
22
|
end
|
87
23
|
end
|
88
24
|
|
89
25
|
def test_jane
|
90
|
-
s = scriptfam
|
26
|
+
s = scriptfam SCRIPTS['jane']
|
91
27
|
play do
|
92
28
|
ping s, :id => 'fred', :tags => ['new'], :received => 'freddy'
|
93
29
|
asked 'fred', /Hello freddy. You are Level Zero./
|
@@ -128,42 +64,40 @@ class TestIncident < Test::Unit::TestCase
|
|
128
64
|
s = scriptfam "await 2 new signups\ntell signups: thanks"
|
129
65
|
play do
|
130
66
|
ping s, :id => 'fred', :tags => ['new']
|
131
|
-
silent 'fred'
|
132
|
-
ping s, :id => 'wilma', :tags => ['old']
|
133
|
-
silent 'fred'
|
134
|
-
ping s, :id => 'betty', :tags => ['new']
|
67
|
+
# silent 'fred'
|
68
|
+
# ping s, :id => 'wilma', :tags => ['old']
|
69
|
+
# silent 'fred'
|
70
|
+
# ping s, :id => 'betty', :tags => ['new']
|
135
71
|
told 'fred', /thanks/
|
136
72
|
end
|
137
73
|
end
|
138
74
|
|
139
75
|
|
140
|
-
def test_inside_timewindow
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
end
|
150
|
-
|
151
|
-
def test_outside_timewindow
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
end
|
76
|
+
# def test_inside_timewindow
|
77
|
+
# s = scriptfam "await 2 new signups over 10s\ntell signups: thanks"
|
78
|
+
# play do
|
79
|
+
# ping s, :id => 'fred', :tags => ['new']
|
80
|
+
# silent 'fred'
|
81
|
+
# CEML.incr_clock 5
|
82
|
+
# ping s, :id => 'betty', :tags => ['new']
|
83
|
+
# told 'fred', /thanks/
|
84
|
+
# end
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
# def test_outside_timewindow
|
88
|
+
# s = scriptfam "await 2 new signups over 10s\ntell signups: thanks"
|
89
|
+
# play do
|
90
|
+
# ping s, :id => 'fred', :tags => ['new']
|
91
|
+
# silent 'fred'
|
92
|
+
# CEML.incr_clock 15
|
93
|
+
# ping s, :id => 'betty', :tags => ['new']
|
94
|
+
# silent 'fred'
|
95
|
+
# end
|
96
|
+
# end
|
161
97
|
|
162
98
|
def test_interpolation
|
163
99
|
s = "\"Soccer in the park\"\ngather 2 players within 1mi\nask players re color: which color?\ntell players: its |someone.color|\n"
|
164
100
|
s = CEML.parse(:script, s)
|
165
|
-
instrs = s.instructions_for(s.roles)
|
166
|
-
assert !instrs.empty?
|
167
101
|
play s do
|
168
102
|
player :bill, :players
|
169
103
|
player :fred, :players
|
@@ -176,23 +110,36 @@ class TestIncident < Test::Unit::TestCase
|
|
176
110
|
end
|
177
111
|
end
|
178
112
|
|
113
|
+
def test_abort
|
114
|
+
s = "\"Soccer in the park\"\ngather 2 players within 1mi\nask players re color: which color?\ntell players: its |someone.color|\n"
|
115
|
+
s = CEML.parse(:script, s)
|
116
|
+
play s do
|
117
|
+
player :bill, :players
|
118
|
+
player :fred, :players
|
119
|
+
asked :bill, /color\?/i
|
120
|
+
asked :fred, /color\?/i
|
121
|
+
says :bill, 'abort'
|
122
|
+
told :bill, /aborted/i
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
179
126
|
def test_await
|
180
|
-
s = scriptfam "await a,b,c\ntell a: foo\ntell b: bar\ntell c: baz"
|
127
|
+
s = scriptfam "await new a, new b, new c\ntell a: foo\ntell b: bar\ntell c: baz"
|
181
128
|
play do
|
182
|
-
ping s, :id => 'fred'
|
129
|
+
ping s, :id => 'fred', :tags => ['new']
|
183
130
|
silent 'fred'
|
184
|
-
ping s, :id => 'wilma'
|
131
|
+
ping s, :id => 'wilma', :tags => ['new']
|
185
132
|
silent 'fred'
|
186
133
|
silent 'wilma'
|
187
|
-
ping s, :id => 'betty'
|
134
|
+
ping s, :id => 'betty', :tags => ['new']
|
188
135
|
told 'fred', /foo/
|
189
136
|
told 'betty', /baz/
|
190
137
|
end
|
191
138
|
end
|
192
139
|
|
193
140
|
def test_incident
|
194
|
-
play
|
195
|
-
player :joe, :organizer
|
141
|
+
play SCRIPTS['compliment'] do
|
142
|
+
player :joe, :organizer
|
196
143
|
player :bill, :agent
|
197
144
|
|
198
145
|
asked :joe, /^Describe/
|
@@ -202,27 +149,17 @@ class TestIncident < Test::Unit::TestCase
|
|
202
149
|
end
|
203
150
|
end
|
204
151
|
|
205
|
-
ASKCHAIN_SCRIPT = <<XXX
|
206
|
-
"Meet your neighbor"
|
207
|
-
gather 2 players within 1 block
|
208
|
-
ask players re color: what's your favorite color?
|
209
|
-
ask players re observation: find someone near you with the color |somebody.color|. what are they wearing?
|
210
|
-
ask players re rightmatch: are you wearing |somebody.observation|?
|
211
|
-
ask players re task: take your new partner and see if you can find something beautiful in the park.
|
212
|
-
XXX
|
213
|
-
|
214
|
-
|
215
152
|
def test_askchain
|
216
|
-
play
|
217
|
-
player :
|
218
|
-
player :
|
219
|
-
|
220
|
-
asked :
|
221
|
-
asked :
|
222
|
-
says :
|
223
|
-
says :
|
224
|
-
asked :
|
225
|
-
asked :
|
153
|
+
play SCRIPTS['askchain'] do
|
154
|
+
player :joey, :players
|
155
|
+
player :billy, :players
|
156
|
+
|
157
|
+
asked :joey, /favorite color/
|
158
|
+
asked :billy, /favorite color/
|
159
|
+
says :joey, "red"
|
160
|
+
says :billy, "green"
|
161
|
+
asked :joey, /with the color green/
|
162
|
+
asked :billy, /with the color red/
|
226
163
|
end
|
227
164
|
end
|
228
165
|
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ceml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 63
|
5
|
+
prerelease:
|
5
6
|
segments:
|
6
7
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
8
|
+
- 8
|
9
|
+
- 0
|
10
|
+
version: 0.8.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Joe Edelman
|
@@ -14,16 +15,18 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2011-
|
18
|
+
date: 2011-05-27 00:00:00 -07:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: treetop
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
24
26
|
requirements:
|
25
27
|
- - ">="
|
26
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
27
30
|
segments:
|
28
31
|
- 0
|
29
32
|
version: "0"
|
@@ -40,7 +43,6 @@ extra_rdoc_files:
|
|
40
43
|
- README.markdown
|
41
44
|
files:
|
42
45
|
- .document
|
43
|
-
- .gitignore
|
44
46
|
- LICENSE
|
45
47
|
- Makefile
|
46
48
|
- README.markdown
|
@@ -56,58 +58,80 @@ files:
|
|
56
58
|
- guide/guide.md
|
57
59
|
- guide/guide.pdf
|
58
60
|
- lib/ceml.rb
|
59
|
-
- lib/ceml/casting_statement.rb
|
60
|
-
- lib/ceml/confluence.rb
|
61
61
|
- lib/ceml/driver.rb
|
62
|
-
- lib/ceml/
|
63
|
-
- lib/ceml/
|
64
|
-
- lib/ceml/
|
65
|
-
- lib/ceml/
|
66
|
-
- lib/ceml/
|
67
|
-
- lib/ceml/tt/
|
68
|
-
- lib/ceml/tt/
|
69
|
-
- lib/ceml/tt/
|
62
|
+
- lib/ceml/lang.rb
|
63
|
+
- lib/ceml/lang/basic_instruction.rb
|
64
|
+
- lib/ceml/lang/casting_statement.rb
|
65
|
+
- lib/ceml/lang/instruction_statements.rb
|
66
|
+
- lib/ceml/lang/script.rb
|
67
|
+
- lib/ceml/lang/tt/casting.rb
|
68
|
+
- lib/ceml/lang/tt/casting.treetop
|
69
|
+
- lib/ceml/lang/tt/instructions.rb
|
70
|
+
- lib/ceml/lang/tt/instructions.treetop
|
71
|
+
- lib/ceml/lang/tt/lexer.rb
|
72
|
+
- lib/ceml/lang/tt/lexer.treetop
|
73
|
+
- lib/ceml/lang/tt/scripts.rb
|
74
|
+
- lib/ceml/lang/tt/scripts.treetop
|
75
|
+
- lib/ceml/models.rb
|
76
|
+
- lib/ceml/models/audition.rb
|
77
|
+
- lib/ceml/models/bundle.rb
|
78
|
+
- lib/ceml/models/cast.rb
|
79
|
+
- lib/ceml/models/castable.rb
|
80
|
+
- lib/ceml/models/incident.rb
|
81
|
+
- lib/ceml/models/incident_model.rb
|
82
|
+
- lib/ceml/models/incident_role_slot.rb
|
83
|
+
- lib/ceml/models/player.rb
|
84
|
+
- lib/ceml/models/queue.rb
|
85
|
+
- lib/ceml/models/waiting_room.rb
|
86
|
+
- lib/ceml/processor.rb
|
87
|
+
- test/askchain.ceml
|
88
|
+
- test/compliment.ceml
|
89
|
+
- test/dialogues/accept.ceml
|
90
|
+
- test/dialogues/basic_seed.ceml
|
91
|
+
- test/dialogues/jordan.ceml
|
70
92
|
- test/helper.rb
|
71
|
-
- test/
|
93
|
+
- test/jane.ceml
|
94
|
+
- test/lang/test_casting.rb
|
95
|
+
- test/lang/test_instructions.rb
|
96
|
+
- test/lang/test_scripts.rb
|
97
|
+
- test/sync.ceml
|
98
|
+
- test/test_castable.rb
|
99
|
+
- test/test_dialogues.rb
|
72
100
|
- test/test_incident.rb
|
73
|
-
- test/test_instructions.rb
|
74
|
-
- test/test_release.rb
|
75
|
-
- test/test_scripts.rb
|
76
101
|
- try
|
77
102
|
has_rdoc: true
|
78
103
|
homepage: http://github.com/citizenlogistics/ceml
|
79
104
|
licenses: []
|
80
105
|
|
81
106
|
post_install_message:
|
82
|
-
rdoc_options:
|
83
|
-
|
107
|
+
rdoc_options: []
|
108
|
+
|
84
109
|
require_paths:
|
85
110
|
- lib
|
86
111
|
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
+
none: false
|
87
113
|
requirements:
|
88
114
|
- - ">="
|
89
115
|
- !ruby/object:Gem::Version
|
116
|
+
hash: 3
|
90
117
|
segments:
|
91
118
|
- 0
|
92
119
|
version: "0"
|
93
120
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
94
122
|
requirements:
|
95
123
|
- - ">="
|
96
124
|
- !ruby/object:Gem::Version
|
125
|
+
hash: 3
|
97
126
|
segments:
|
98
127
|
- 0
|
99
128
|
version: "0"
|
100
129
|
requirements: []
|
101
130
|
|
102
131
|
rubyforge_project:
|
103
|
-
rubygems_version: 1.
|
132
|
+
rubygems_version: 1.6.2
|
104
133
|
signing_key:
|
105
134
|
specification_version: 3
|
106
135
|
summary: a language for coordinating real world events
|
107
|
-
test_files:
|
108
|
-
|
109
|
-
- test/test_casting.rb
|
110
|
-
- test/test_incident.rb
|
111
|
-
- test/test_instructions.rb
|
112
|
-
- test/test_release.rb
|
113
|
-
- test/test_scripts.rb
|
136
|
+
test_files: []
|
137
|
+
|
data/.gitignore
DELETED
data/lib/ceml/confluence.rb
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
require 'geokit'
|
2
|
-
require 'forwardable'
|
3
|
-
|
4
|
-
module CEML
|
5
|
-
class Confluence
|
6
|
-
attr_accessor :hash, :created, :roles_to_cast, :incident_id, :star
|
7
|
-
alias_method :launched?, :incident_id
|
8
|
-
|
9
|
-
def initialize roles_to_cast, candidate = nil
|
10
|
-
@hash = {}
|
11
|
-
@created = true
|
12
|
-
@roles_to_cast = roles_to_cast
|
13
|
-
push candidate if candidate
|
14
|
-
end
|
15
|
-
|
16
|
-
def rm *candidates
|
17
|
-
@roles_to_cast.each{ |role| role.rm *candidates }
|
18
|
-
end
|
19
|
-
|
20
|
-
def best_role_for candidate
|
21
|
-
# puts "confluence finding best role #{object_id} #{candidate[:id]} #{star}"
|
22
|
-
winner = @roles_to_cast.max_by{ |role| role.affinity(candidate, star) }
|
23
|
-
winner unless winner.affinity(candidate, star)[0] == -1
|
24
|
-
end
|
25
|
-
|
26
|
-
def stage_with_candidate candidate
|
27
|
-
return :uninterested if cast_with?(candidate)
|
28
|
-
best_role = best_role_for(candidate)
|
29
|
-
return :uninterested unless best_role
|
30
|
-
return :joinable if launched?
|
31
|
-
other_roles = @roles_to_cast - [best_role]
|
32
|
-
return :launchable if best_role.one_left? and other_roles.all?(&:filled?)
|
33
|
-
return :listable
|
34
|
-
end
|
35
|
-
|
36
|
-
def push candidate
|
37
|
-
best_role = best_role_for(candidate)
|
38
|
-
candidate[:roles] = best_role.name.to_sym
|
39
|
-
best_role.casted << candidate
|
40
|
-
@star ||= candidate
|
41
|
-
end
|
42
|
-
|
43
|
-
def full?
|
44
|
-
@roles_to_cast.all?{ |role| role.allowed == 0 }
|
45
|
-
end
|
46
|
-
|
47
|
-
def over?
|
48
|
-
@roles_to_cast.any?{ |r| r.over?(star) }
|
49
|
-
end
|
50
|
-
|
51
|
-
def cast_with?(candidate)
|
52
|
-
@roles_to_cast.any?{ |r| r.casted.any?{ |guy| guy[:id] == candidate[:id] } }
|
53
|
-
end
|
54
|
-
|
55
|
-
def live_with?(candidate)
|
56
|
-
launched? and cast_with?(candidate)
|
57
|
-
end
|
58
|
-
|
59
|
-
def cast
|
60
|
-
@roles_to_cast.map{ |r| r.casted }.flatten
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
data/lib/ceml/role.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
module CEML
|
2
|
-
|
3
|
-
class Criteria < Struct.new :plus_tags, :minus_tags, :matching, :radius, :timewindow
|
4
|
-
def complexity; plus_tags.size; end
|
5
|
-
def =~(candidate)
|
6
|
-
candidate[:tags] ||= []
|
7
|
-
(plus_tags - candidate[:tags]).empty? and (minus_tags & candidate[:tags]).empty?
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
class Role < Struct.new :name, :criteria, :range, :casted
|
12
|
-
# def <=>(b); b.criteria.complexity <=> criteria.complexity; end
|
13
|
-
def affinity candidate, star
|
14
|
-
return [-1, -1, -1 ] unless fits?(candidate, star)
|
15
|
-
[ criteria.complexity, -needed, -allowed ]
|
16
|
-
end
|
17
|
-
|
18
|
-
def comparable_object
|
19
|
-
[name, criteria, range]
|
20
|
-
end
|
21
|
-
|
22
|
-
def ==(other); comparable_object == other.comparable_object; end
|
23
|
-
def hash; comparable_object.hash; end
|
24
|
-
|
25
|
-
def filled?; needed == 0; end
|
26
|
-
def one_left?; needed == 1; end
|
27
|
-
|
28
|
-
def rm(*ids); casted.delete_if{ |guy| ids.include? guy[:id] }; end
|
29
|
-
def needed; [range.min - casted.size, 0].max; end
|
30
|
-
def allowed; [range.max - casted.size, 0].max; end
|
31
|
-
|
32
|
-
def over?(star)
|
33
|
-
return unless criteria.timewindow and star
|
34
|
-
CEML.clock - star[:ts] > criteria.timewindow
|
35
|
-
end
|
36
|
-
|
37
|
-
def fits?(candidate, star = nil)
|
38
|
-
return false unless criteria =~ candidate
|
39
|
-
return false if casted.size >= range.max
|
40
|
-
return false if casted.any?{ |guy| guy[:id] == candidate[:id] }
|
41
|
-
return true unless star
|
42
|
-
c = criteria
|
43
|
-
if c.matching
|
44
|
-
return unless c.matching.all? do |g|
|
45
|
-
candidate[:matchables][g] && star[:matchables][g] &&
|
46
|
-
candidate[:matchables][g].downcase.strip == star[:matchables][g].downcase.strip
|
47
|
-
end
|
48
|
-
end
|
49
|
-
if c.radius
|
50
|
-
c_ll = Geokit::LatLng(candidate[:lat], candidate[:lng])
|
51
|
-
s_ll = Geokit::LatLng(star[:lat], star[:lng])
|
52
|
-
return unless c_ll.distance_to(s_ll, :meters) <= c.radius
|
53
|
-
end
|
54
|
-
if c.timewindow
|
55
|
-
# puts "checking timewindow #{c.timewindow} #{candidate[:ts] - star[:ts]}"
|
56
|
-
return unless candidate[:ts] - star[:ts] <= c.timewindow
|
57
|
-
end
|
58
|
-
return true
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
data/lib/ceml/tt/casting.treetop
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
module CEML
|
2
|
-
grammar Casting
|
3
|
-
include Lexer
|
4
|
-
|
5
|
-
rule casting_statement
|
6
|
-
('gather' / 'await' / 'nab') ws roles modifiers:modifier_phrase* <CastingStatement>
|
7
|
-
end
|
8
|
-
|
9
|
-
rule modifier_phrase
|
10
|
-
over_phrase / within_phrase / with_matching_phrase
|
11
|
-
end
|
12
|
-
|
13
|
-
rule over_phrase
|
14
|
-
ws 'over' ws duration
|
15
|
-
end
|
16
|
-
|
17
|
-
rule within_phrase
|
18
|
-
ws 'within' ws distance
|
19
|
-
end
|
20
|
-
|
21
|
-
rule with_matching_phrase
|
22
|
-
ws 'with' ws 'matching' ws thing:id
|
23
|
-
end
|
24
|
-
|
25
|
-
rule roles
|
26
|
-
role more:(and role)* {
|
27
|
-
def list
|
28
|
-
[role] + more.elements.map{ |e| e.role }
|
29
|
-
end
|
30
|
-
|
31
|
-
def names; list.map{ |r| r.name.to_sym }; end
|
32
|
-
def [](x); list.detect{ |r| r.name.to_sym == x }; end
|
33
|
-
def min; list.map(&:min).inject(0, &:+); end
|
34
|
-
def max; list.map(&:max).inject(0, &:+); end
|
35
|
-
}
|
36
|
-
end
|
37
|
-
|
38
|
-
rule qualifier
|
39
|
-
id
|
40
|
-
end
|
41
|
-
|
42
|
-
rule rolename
|
43
|
-
id
|
44
|
-
end
|
45
|
-
|
46
|
-
rule role
|
47
|
-
(rolename &and / range ws qualifier ws rolename / range ws rolename / qualifier ws rolename / rolename) {
|
48
|
-
def name; if respond_to? :rolename then rolename.text_value else text_value end; end
|
49
|
-
def min
|
50
|
-
return range.value.min if respond_to? :range
|
51
|
-
name =~ /s$/ ? 2 : 1
|
52
|
-
end
|
53
|
-
def max
|
54
|
-
return range.value.max if respond_to? :range
|
55
|
-
name =~ /s$/ ? 10000 : 1
|
56
|
-
end
|
57
|
-
def qualifiers
|
58
|
-
return [qualifier.text_value] if respond_to? :qualifier
|
59
|
-
return []
|
60
|
-
end
|
61
|
-
}
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|
65
|
-
end
|