ceml 0.6.4 → 0.7.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/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