ceml 0.6.4 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.4
1
+ 0.7.0
data/ceml.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ceml}
8
- s.version = "0.6.4"
8
+ s.version = "0.7.0"
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"]
12
- s.date = %q{2011-02-11}
12
+ s.date = %q{2011-02-12}
13
13
  s.description = %q{a language for coordinating real world events}
14
14
  s.email = %q{joe@citizenlogistics.com}
15
15
  s.extra_rdoc_files = [
@@ -1,13 +1,4 @@
1
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
2
  module CastingStatement
12
3
  extend Forwardable
13
4
  def_delegators :roles, :names, :[], :min
@@ -3,14 +3,13 @@ require 'forwardable'
3
3
 
4
4
  module CEML
5
5
  class Confluence
6
- attr_accessor :script, :hash, :created, :dirty, :roles_to_cast, :incident_id, :star
6
+ attr_accessor :hash, :created, :roles_to_cast, :incident_id, :star
7
7
  alias_method :launched?, :incident_id
8
8
 
9
- def initialize script, candidate = nil
10
- @script = script
9
+ def initialize roles_to_cast, candidate = nil
11
10
  @hash = {}
12
11
  @created = true
13
- @roles_to_cast = script.roles_to_cast
12
+ @roles_to_cast = roles_to_cast
14
13
  push candidate if candidate
15
14
  end
16
15
 
@@ -38,7 +37,6 @@ module CEML
38
37
  candidate[:roles] = best_role.name.to_sym
39
38
  best_role.casted << candidate
40
39
  @star ||= candidate
41
- @dirty = true
42
40
  end
43
41
 
44
42
  def full?
data/lib/ceml/driver.rb CHANGED
@@ -14,60 +14,89 @@ module CEML
14
14
  def with_incident(id, script = nil, metadata = {})
15
15
  id ||= rand(36**10).to_s(36)
16
16
  PLAYERS[id] ||= []
17
- INCIDENTS[id] ||= CEML::Incident.new script, id if script
17
+ INCIDENTS[id] ||= CEML::Incident.new to_bytecode(script), id if script
18
18
  raise "no incident #{id}" unless INCIDENTS[id]
19
19
  yield INCIDENTS[id], PLAYERS[id], metadata if block_given?
20
20
  id
21
21
  end
22
22
  alias_method :start, :with_incident
23
23
 
24
+ def to_bytecode bytecode_or_script
25
+ case bytecode_or_script
26
+ when String; return CEML.parse(:script, bytecode_or_script).bytecode
27
+ when CEML::Script; return bytecode_or_script.bytecode
28
+ when Array; return bytecode_or_script
29
+ else return nil
30
+ end
31
+ end
32
+
24
33
  def log(s)
25
34
  # puts s
26
35
  end
27
36
 
37
+ SCRIPTS = Hash.new{ |h,k| h[k] = [] }
38
+ def add_script script_collection_id, script
39
+ SCRIPTS[script_collection_id] << script
40
+ end
41
+
42
+ def ping_all script_collection_id, candidate
43
+ SCRIPTS[script_collection_id].each{ |s| ping script_collection_id, s.roles_to_cast, candidate }
44
+ end
45
+
46
+ def launch script_collection_id, roleset, *cast
47
+ script = SCRIPTS[script_collection_id].select{ |s| s.roles_to_cast == roleset }.sort_by{ rand }.first
48
+ unless script
49
+ rolesets = SCRIPTS[script_collection_id].map(&:roles_to_cast)
50
+ raise "matching roleset not found: #{roleset.inspect} in #{rolesets.inspect}"
51
+ end
52
+ push nil, script.bytecode, *cast
53
+ end
54
+
55
+
28
56
  LOCATIONS = Hash.new{ |h,k| h[k] = [] }
29
- def ping script, candidate
30
- return unless script.fits? candidate
57
+ def with_confluences script_collection_id, roleset
58
+ yield LOCATIONS["#{script_collection_id}:#{roleset.hash}"]
59
+ end
60
+
61
+
62
+ def ping script_collection_id, roleset, candidate
63
+ return unless roleset.any?{ |r| r.fits? candidate }
31
64
  candidate[:ts] = CEML.clock
32
- script_id = script.text_value
33
-
34
- locs = LOCATIONS[script_id].group_by{ |l| l.stage_with_candidate(candidate) }
35
- if locs[:joinable]
36
- log "joining..."
37
- first = locs[:joinable].shift
38
- first.push candidate
39
- push first.incident_id, nil, candidate
40
-
41
- elsif locs[:launchable]
42
- log "launching..."
43
- first = locs[:launchable].shift
44
- first.push candidate
45
- cast = first.cast
46
- push nil, script, *cast
47
- (locs[:launchable] + (locs[:listable]||[])).each{ |l| l.rm *cast }
48
-
49
- elsif locs[:listable]
50
- log "listing..."
51
- locs[:listable].each{ |l| l.push candidate }
52
-
53
- else
54
- c = Confluence.new(script)
55
- case c.stage_with_candidate(candidate)
56
- when :launchable
57
- log "start-launching..."
58
- c.push candidate
59
- push nil, script, candidate
60
- when :listable
65
+
66
+ with_confluences script_collection_id, roleset do |confluences|
67
+ locs = confluences.group_by{ |l| l.stage_with_candidate(candidate) }
68
+ if locs[:joinable]
69
+ log "joining..."
70
+ first = locs[:joinable].shift
71
+ first.push candidate
72
+ push first.incident_id, nil, candidate # JOIN THEM
73
+
74
+ elsif locs[:launchable]
75
+ log "launching..."
76
+ first = locs[:launchable].shift
77
+ first.push candidate
78
+ cast = first.cast
79
+ first.incident_id = launch script_collection_id, roleset, *cast
80
+ (locs[:launchable] + (locs[:listable]||[])).each{ |l| l.rm *cast }
81
+
82
+ elsif locs[:listable]
83
+ log "listing..."
84
+ locs[:listable].each{ |l| l.push candidate }
85
+
86
+ else
87
+ c = Confluence.new(roleset)
61
88
  log "start-listing..."
62
- c.push candidate
63
- LOCATIONS[script_id] << c
64
- else raise "what?"
89
+ if c.stage_with_candidate(candidate) == :launchable
90
+ log "start-launching..."
91
+ c.push candidate
92
+ c.incident_id = launch script_collection_id, roleset, candidate
93
+ else
94
+ c.push candidate
95
+ end
96
+ confluences << c
65
97
  end
66
-
98
+ confluences.delete_if(&:full?)
67
99
  end
68
-
69
- LOCATIONS[script_id].delete_if(&:full?)
70
- # save the changed ones and clear dirty flag
71
100
  end
72
101
 
73
102
  def push incident_id, script, *updated_players
data/lib/ceml/incident.rb CHANGED
@@ -2,24 +2,20 @@ require 'set'
2
2
 
3
3
  module CEML
4
4
  class Incident
5
- attr_reader :script, :id, :this
5
+ attr_reader :seq, :id, :this
6
+ def initialize(seq, id); @id = id; @seq = seq; end
7
+
6
8
  def roles; this[:roles] ||= Set.new; end
7
9
  def got; this[:received]; end
8
10
  def recognized; this[:recognized]; end
9
11
  def pc; this[:pc] ||= 0; end
10
12
  def qs_answers; this[:qs_answers] ||= Hash.new; end
11
- def seq; @seq ||= script.bytecode; end
12
13
 
13
14
  def handled!
14
15
  this.delete :received
15
16
  this.delete :recognized
16
17
  end
17
18
 
18
- def initialize(script, id)
19
- @id = id
20
- @script = Script === script ? script : CEML.parse(:script, script)
21
- end
22
-
23
19
  def cb *stuff
24
20
  @callback.call this, *stuff if @callback
25
21
  end
@@ -61,9 +57,9 @@ module CEML
61
57
 
62
58
  def expand(role, var)
63
59
  case role
64
- when 'his', 'her', 'their'; return qs_answers[var]
60
+ when 'his', 'her', 'their', 'my', 'its'; return qs_answers[var]
65
61
  when 'world', 'game', 'exercise', 'group'; return (cb :world, var)
66
- when 'somebody', 'someone', 'buddy'; role = nil
62
+ when 'somebody', 'someone', 'buddy', 'teammate'; role = nil
67
63
  end
68
64
  role = role.to_sym if role
69
65
  @players.each do |p|
@@ -146,8 +142,8 @@ module CEML
146
142
  got or return false
147
143
  if recognized == :done
148
144
  cb :did_complete
149
- say :ok
150
145
  handled!
146
+ say :ok if pc == seq.size - 2
151
147
  true
152
148
  else
153
149
  cb :did_report
data/lib/ceml/role.rb CHANGED
@@ -1,4 +1,13 @@
1
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
+
2
11
  class Role < Struct.new :name, :criteria, :range, :casted
3
12
  # def <=>(b); b.criteria.complexity <=> criteria.complexity; end
4
13
  def affinity candidate, star
@@ -6,6 +15,13 @@ module CEML
6
15
  [ criteria.complexity, -needed, -allowed ]
7
16
  end
8
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
+
9
25
  def filled?; needed == 0; end
10
26
  def one_left?; needed == 1; end
11
27
 
data/lib/ceml/script.rb CHANGED
@@ -6,10 +6,6 @@ module CEML
6
6
  # = casting =
7
7
  # ===========
8
8
 
9
- def fits? candidate
10
- roles_to_cast.any?{ |r| r.fits? candidate }
11
- end
12
-
13
9
  def roles_to_cast
14
10
  return [] unless cast.type == :await
15
11
  return cast.roles_to_cast(self)
@@ -114,8 +110,11 @@ module CEML
114
110
 
115
111
  def bytecode
116
112
  code = [[[:all], :start]]
117
- return [[[:all], :null_assign], [[:all], :complete_assign]] if !instructions and title
118
- instructions.list.each{ |inst| code.concat inst.bytecode } if instructions
113
+ if !instructions and title
114
+ code.concat [[[:all], :null_assign], [[:all], :complete_assign]]
115
+ elsif instructions
116
+ instructions.list.each{ |inst| code.concat inst.bytecode } if instructions
117
+ end
119
118
  code << [[:all], :finish]
120
119
  code
121
120
  end
data/test/helper.rb CHANGED
@@ -16,8 +16,17 @@ class Test::Unit::TestCase
16
16
  CEML::Driver::INCIDENTS.clear
17
17
  end
18
18
 
19
+ def scriptfam *scripts
20
+ fam_id = gen_code
21
+ scripts.each do |script|
22
+ script = CEML.parse(:script, script) if String === script
23
+ DRIVER.add_script fam_id, script
24
+ end
25
+ fam_id
26
+ end
27
+
19
28
  def ping s, candidate
20
- DRIVER.ping s, candidate
29
+ DRIVER.ping_all s, candidate
21
30
  end
22
31
 
23
32
  def says id, str
@@ -72,7 +72,7 @@ XXX
72
72
  class TestIncident < Test::Unit::TestCase
73
73
 
74
74
  def test_sync
75
- s = CEML.parse(:script, SYNC_SCRIPT)
75
+ s = scriptfam SYNC_SCRIPT
76
76
  play do
77
77
  ping s, :id => 'alpha'
78
78
  ping s, :id => 'beta'
@@ -87,7 +87,7 @@ class TestIncident < Test::Unit::TestCase
87
87
  end
88
88
 
89
89
  def test_jane
90
- s = CEML.parse(:script, JANE_SCRIPT)
90
+ s = scriptfam JANE_SCRIPT
91
91
  play do
92
92
  ping s, :id => 'fred', :tags => ['new'], :received => 'freddy'
93
93
  asked 'fred', /Hello freddy. You are Level Zero./
@@ -117,7 +117,7 @@ class TestIncident < Test::Unit::TestCase
117
117
  end
118
118
 
119
119
  def test_signup_1
120
- s = CEML.parse(:script, "await 1 new signup\ntell signup: thanks")
120
+ s = scriptfam "await 1 new signup\ntell signup: thanks"
121
121
  play do
122
122
  ping s, :id => 'fred', :tags => ['new']
123
123
  told 'fred', /thanks/
@@ -125,7 +125,7 @@ class TestIncident < Test::Unit::TestCase
125
125
  end
126
126
 
127
127
  def test_signup_2
128
- s = CEML.parse(:script, "await 2 new signups\ntell signups: thanks")
128
+ s = scriptfam "await 2 new signups\ntell signups: thanks"
129
129
  play do
130
130
  ping s, :id => 'fred', :tags => ['new']
131
131
  silent 'fred'
@@ -138,7 +138,7 @@ class TestIncident < Test::Unit::TestCase
138
138
 
139
139
 
140
140
  def test_inside_timewindow
141
- s = CEML.parse(:script, "await 2 new signups over 10s\ntell signups: thanks")
141
+ s = scriptfam "await 2 new signups over 10s\ntell signups: thanks"
142
142
  play do
143
143
  ping s, :id => 'fred', :tags => ['new']
144
144
  silent 'fred'
@@ -149,7 +149,7 @@ class TestIncident < Test::Unit::TestCase
149
149
  end
150
150
 
151
151
  def test_outside_timewindow
152
- s = CEML.parse(:script, "await 2 new signups over 10s\ntell signups: thanks")
152
+ s = scriptfam "await 2 new signups over 10s\ntell signups: thanks"
153
153
  play do
154
154
  ping s, :id => 'fred', :tags => ['new']
155
155
  silent 'fred'
@@ -177,7 +177,7 @@ class TestIncident < Test::Unit::TestCase
177
177
  end
178
178
 
179
179
  def test_await
180
- s = CEML.parse(:script, "await a,b,c\ntell a: foo\ntell b: bar\ntell c: baz")
180
+ s = scriptfam "await a,b,c\ntell a: foo\ntell b: bar\ntell c: baz"
181
181
  play do
182
182
  ping s, :id => 'fred'
183
183
  silent 'fred'
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 6
8
- - 4
9
- version: 0.6.4
7
+ - 7
8
+ - 0
9
+ version: 0.7.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Joe Edelman
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-02-11 00:00:00 -08:00
17
+ date: 2011-02-12 00:00:00 -08:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency