ceml 0.7.13 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|