chione 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 414e1caef54ca7d5f41452376a2309e343bb52812f567012504628b5ec2347ff
4
- data.tar.gz: ca11c73c74c4e45c1373e54f224603f059b8eb0338e40b4a8e5cc676dc56c98f
2
+ SHA1:
3
+ metadata.gz: e97a13cf34e52ecdafa6435e9f8a6a055b0491d8
4
+ data.tar.gz: c166e2cf474f7eadd82c8974ce30cdab06961e2e
5
5
  SHA512:
6
- metadata.gz: 1a21bcb7a924fdeff7f3d1fd4effe157a642baf7ddbc56303cb966b83ad182e41c5b7ab9d9d000dfa7fc963ad36fd1cdab560bdcad2ae2da87a57789a0a8abf5
7
- data.tar.gz: 2ba9b26c5f7cbf5be5dd1d6b85857215861a4827e2454c67fd6d529154346921582568f1d47248d34bba8aef6af63bce2d860e2e8569009bc79e6afd6e77acf8
6
+ metadata.gz: f3d4d5d410fe1a8b41dd56f5ed5888d2e9a553c55a279857fb1759ce9e9b40c3e4b763aabaed899e04375b539b6143f1f526637d3db81e955a6f0d185c3b5644
7
+ data.tar.gz: de83ffeaefad492c73ca249f3af9ebfbb8d0371ec955a39c0f35938131be8fe95f4c140e3789404d88b147afb522ddcac1dcc19289c8c8ec404c5e71dcfdaa2e
Binary file
data.tar.gz.sig CHANGED
Binary file
data/ChangeLog CHANGED
@@ -1,8 +1,170 @@
1
+ 2017-05-26 Michael Granger <ged@FaerieMUD.org>
2
+
3
+ * Rakefile, chione.gemspec:
4
+ Update gemspec
5
+ [068af8eec0e0] [github/master, tip]
6
+
7
+ 2017-05-25 Michael Granger <ged@FaerieMUD.org>
8
+
9
+ * .hgignore, .ruby-version, Rakefile, chione.gemspec:
10
+ Update to latest Ruby.
11
+ [4dbb8e19b86c]
12
+
13
+ * .gems, lib/chione/world.rb, spec/chione/world_spec.rb:
14
+ Refactor the World for better subclassing
15
+
16
+ - Extract a method for creating blank Entities to facilitate
17
+ overriding which Entity class is used.
18
+ - Defer event processing until the event loop so events which are
19
+ published at startup aren't missed.
20
+ [a71b51f9f017]
21
+
22
+ * lib/chione/system.rb, spec/chione/system_spec.rb:
23
+ Allow shorthand required component list for system aspects
24
+ [4464660e20d0]
25
+
26
+ 2017-05-24 Michael Granger <ged@FaerieMUD.org>
27
+
28
+ * History.md, lib/chione.rb:
29
+ Bump the minor version.
30
+ [96d2395340ca]
31
+
32
+ * .gems, Rakefile, chione.gemspec, lib/chione/assemblage.rb,
33
+ lib/chione/component.rb, lib/chione/manager.rb,
34
+ lib/chione/system.rb, spec/chione/world_spec.rb:
35
+ Make Assemblage, Component, Manager and System all pluggable.
36
+ [7ef6fce14d50]
37
+
38
+ * lib/chione/system.rb, spec/chione/system_spec.rb:
39
+ Don't assume the process model of Systems
40
+ [b11a20a6e865]
41
+
42
+ 2017-05-22 Michael Granger <ged@FaerieMUD.org>
43
+
44
+ * .hgtags:
45
+ Added tag v0.1.0 for changeset 60f8ee90a031
46
+ [ba57ae8fc87c]
47
+
48
+ * .hgsigs:
49
+ Added signature for changeset d9f6a6089e01
50
+ [60f8ee90a031] [v0.1.0]
51
+
52
+ * History.md, lib/chione.rb:
53
+ Bump the minor version, update history.
54
+ [d9f6a6089e01]
55
+
56
+ * lib/chione/behaviors.rb, lib/chione/world.rb,
57
+ spec/chione/world_spec.rb:
58
+ Refactor a bit of the World start/stop logic
59
+
60
+ This makes it easier to override in implementations which have their
61
+ own process models.
62
+
63
+ This also stringifies the Manager or System in `manager/added` and
64
+ `system/added` events.
65
+ [3075fc1b71f7]
66
+
67
+ * lib/chione/component.rb, spec/chione/component_spec.rb:
68
+ Allow a component's default to be generated by a callable
69
+ [c72f6364c89a]
70
+
71
+ 2017-01-04 Michael Granger <ged@FaerieMUD.org>
72
+
73
+ * .hgtags:
74
+ Added tag v0.0.3 for changeset 80fff8665d92
75
+ [dd6453480c59]
76
+
77
+ * .hgsigs:
78
+ Added signature for changeset 7fac98a60c47
79
+ [80fff8665d92] [v0.0.3]
80
+
81
+ * History.md, lib/chione.rb:
82
+ Bump the patch version, update history.
83
+ [7fac98a60c47]
84
+
85
+ * .gems, .ruby-gemset, .ruby-version, .rvmrc, History.md,
86
+ History.rdoc, Manifest.txt, README.md, README.rdoc, Rakefile,
87
+ certs/ged.pem, chione.gemspec, lib/chione/component.rb,
88
+ lib/chione/world.rb:
89
+ Add a bunch of little updates
90
+
91
+ - Add a proper #inspect to Component
92
+ - Fix misnamed attr in World, update to latest Configurability syntax
93
+ - Update to version-manager-agnostic environment files
94
+ - Convert README and History to Markdown
95
+ - Update dependencies
96
+ - Update gem-signing cert
97
+ [e5a0f12057bb]
98
+
1
99
  2015-07-13 Michael Granger <ged@FaerieMUD.org>
2
100
 
101
+ * lib/chione/assemblage.rb, lib/chione/mixins.rb, lib/chione/world.rb:
102
+ Fix some documentation typos.
103
+ [9a01e0471b50]
104
+
105
+ * .hgtags:
106
+ Added tag v0.0.2 for changeset ee5d26409b8d
107
+ [bd7605922424]
108
+
109
+ * .hgsigs:
110
+ Added signature for changeset 1a4caa248cf7
111
+ [ee5d26409b8d] [v0.0.2]
112
+
113
+ * History.rdoc, lib/chione.rb:
114
+ Bump the patch version, update history.
115
+ [1a4caa248cf7]
116
+
117
+ * README.rdoc, Rakefile, chione.gemspec:
118
+ Fix a couple of build problems.
119
+ [31319f6c6df1]
120
+
121
+ * .hgtags:
122
+ Added tag v0.0.1 for changeset 79260690f4a7
123
+ [0c3b149df34c]
124
+
125
+ * .hgsigs:
126
+ Added signature for changeset 2cf024eb42d5
127
+ [79260690f4a7] [v0.0.1]
128
+
129
+ * History.md, History.rdoc, Manifest.txt, README.md, README.rdoc,
130
+ Rakefile, chione.gemspec:
131
+ Switch README and History back to RDoc
132
+
133
+ Markdown is still a little funky under Hoe.
134
+ [2cf024eb42d5]
135
+
136
+ * cert/ged.pem, certs/ged.pem:
137
+ Fix the name of the certs directory
138
+ [ed11a49519fc]
139
+
140
+ * Manifest.txt, lib/chione/system.rb, lib/chione/world.rb,
141
+ spec/chione/mixins_spec.rb, spec/chione/world_spec.rb:
142
+ Catch specs up to current code, fix a few little issues.
143
+
144
+ - Make World use class-level config instead of instance-level
145
+ - Add World#has_entity?
146
+ [1f44064f9807]
147
+
148
+ * README.md:
149
+ Reformat README for Hoe; add Gitter.im badge.
150
+
151
+ Closes ged/chione#1.
152
+ [8b96713eb85f]
153
+
154
+ * lib/chione/entity.rb, spec/chione/entity_spec.rb:
155
+ Change Entity#get_component to take a list, ala `one_of` Aspects.
156
+
157
+ COMPAT: This also removes the heretofore unused/untested
158
+ `raise_if_missing` setting.
159
+ [d071accf5605]
160
+
161
+ * Manifest.txt:
162
+ Add missing behaviors file to the Manifest
163
+ [c874155aa149]
164
+
3
165
  * lib/chione/behaviors.rb:
4
166
  Add a shared-behaviors collection
5
- [5ac263b85052] [github/master, tip]
167
+ [5ac263b85052]
6
168
 
7
169
  * lib/chione/world.rb, spec/chione/world_spec.rb:
8
170
  Add support for more than one GameWorld callback per event pattern
data/History.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## v0.2.0 [2017-05-26] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ Enhancements:
4
+
5
+ - Make Assemblage, Component, Manager and System all pluggable.
6
+ - Don't assume the process model of Systems
7
+ - Extract a method for creating blank Entities to facilitate
8
+ overriding which Entity class is used.
9
+ - Defer event processing until the event loop so events which are
10
+ published at startup aren't missed.
11
+ - Allow shorthand required component list for system aspects
12
+
13
+
1
14
  ## v0.1.0 [2017-05-22] Michael Granger <ged@FaerieMUD.org>
2
15
 
3
16
  Enhancements:
data/Rakefile CHANGED
@@ -33,11 +33,13 @@ hoespec = Hoe.spec 'chione' do |spec|
33
33
 
34
34
  spec.dependency 'loggability', '~> 0.12'
35
35
  spec.dependency 'configurability', '~> 3.0'
36
+ spec.dependency 'pluggability', '~> 0.4'
36
37
  spec.dependency 'uuid', '~> 2.3'
37
38
 
38
- spec.dependency 'hoe-deveiate', '~> 0.8', :developer
39
+ spec.dependency 'hoe-deveiate', '~> 1.0', :developer
39
40
  spec.dependency 'simplecov', '~> 0.12', :developer
40
- spec.dependency 'rdoc-generator-fivefish', '~> 0.1', :developer
41
+ spec.dependency 'rdoc-generator-fivefish', '~> 0.3', :developer
42
+ spec.dependency 'rdoc', '~> 5.1', :developer
41
43
 
42
44
  spec.require_ruby_version( '>=2.3.3' )
43
45
  spec.hg_sign_tags = true if spec.respond_to?( :hg_sign_tags= )
@@ -73,9 +75,9 @@ if File.directory?( '.hg' )
73
75
 
74
76
  Rake::Task[ 'docs' ].clear
75
77
  RDoc::Task.new( 'docs' ) do |rdoc|
76
- rdoc.main = "README.rdoc"
78
+ rdoc.main = "README.md"
77
79
  rdoc.markup = 'markdown'
78
- rdoc.rdoc_files.include( "*.rdoc", "ChangeLog", "lib/**/*.rb" )
80
+ rdoc.rdoc_files.include( "*.md", "ChangeLog", "lib/**/*.rb" )
79
81
  rdoc.generator = :fivefish
80
82
  rdoc.title = 'Chione'
81
83
  rdoc.rdoc_dir = 'doc'
@@ -86,6 +88,7 @@ end
86
88
  task :gemspec => GEMSPEC
87
89
  file GEMSPEC => __FILE__
88
90
  task GEMSPEC do |task|
91
+ Rake.application.trace "Updating gemspec"
89
92
  spec = $hoespec.spec
90
93
  spec.files.delete( '.gemtest' )
91
94
  spec.signing_key = nil
@@ -13,7 +13,7 @@ module Chione
13
13
 
14
14
 
15
15
  # Gem version
16
- VERSION = '0.1.0'
16
+ VERSION = '0.2.0'
17
17
 
18
18
 
19
19
  require 'chione/mixins'
@@ -1,6 +1,7 @@
1
1
  # -*- ruby -*-
2
2
  #encoding: utf-8
3
3
 
4
+ require 'pluggability'
4
5
  require 'loggability'
5
6
 
6
7
  require 'chione' unless defined?( Chione )
@@ -8,11 +9,15 @@ require 'chione' unless defined?( Chione )
8
9
 
9
10
  # An Assemblage mixin for defining factories for common entity configurations.
10
11
  module Chione::Assemblage
11
- extend Loggability
12
+ extend Loggability,
13
+ Pluggability
12
14
 
13
15
  # Loggability API -- log to the chione logger
14
16
  log_to :chione
15
17
 
18
+ # Pluggability API -- load subclasses from the 'chione/assemblage' directory
19
+ plugin_prefixes 'chione/assemblage'
20
+
16
21
 
17
22
  ### Extension callback -- add assemblage functionality to an extended +object+.
18
23
  def self::extended( object )
@@ -2,6 +2,7 @@
2
2
  #encoding: utf-8
3
3
 
4
4
  require 'loggability'
5
+ require 'pluggability'
5
6
 
6
7
  require 'chione' unless defined?( Chione )
7
8
  require 'chione/mixins'
@@ -10,11 +11,14 @@ require 'chione/mixins'
10
11
  # The Component (data) class
11
12
  class Chione::Component
12
13
  extend Loggability,
14
+ Pluggability,
13
15
  Chione::MethodUtilities
14
16
 
15
17
  # Loggability API -- log to the 'chione' logger
16
18
  log_to :chione
17
19
 
20
+ # Pluggability API -- load subclasses from the 'chione/component' directory
21
+ plugin_prefixes 'chione/component'
18
22
 
19
23
  ##
20
24
  # The Hash of fields implemented by the component
@@ -1,6 +1,7 @@
1
1
  # -*- ruby -*-
2
2
  #encoding: utf-8
3
3
 
4
+ require 'pluggability'
4
5
  require 'loggability'
5
6
 
6
7
  require 'chione' unless defined?( Chione )
@@ -8,11 +9,15 @@ require 'chione' unless defined?( Chione )
8
9
 
9
10
  # The Manager class
10
11
  class Chione::Manager
11
- extend Loggability
12
+ extend Loggability,
13
+ Pluggability
12
14
 
13
15
  # Loggability API -- send logs to the Chione logger
14
16
  log_to :chione
15
17
 
18
+ # Pluggability API -- load subclasses from the 'chione/manager' directory
19
+ plugin_prefixes 'chione/manager'
20
+
16
21
 
17
22
  ### Create a new Chione::Manager for the specified +world+.
18
23
  def initialize( world, * )
@@ -1,6 +1,7 @@
1
1
  # -*- ruby -*-
2
2
  #encoding: utf-8
3
3
 
4
+ require 'pluggability'
4
5
  require 'loggability'
5
6
 
6
7
  require 'chione' unless defined?( Chione )
@@ -11,18 +12,24 @@ require 'chione/aspect'
11
12
  # The System (behavior) class
12
13
  class Chione::System
13
14
  extend Loggability,
15
+ Pluggability,
14
16
  Chione::MethodUtilities
15
17
 
16
18
  # Loggability API -- send logs to the Chione logger
17
19
  log_to :chione
18
20
 
21
+ # Pluggability API -- load subclasses from the 'chione/system' directory
22
+ plugin_prefixes 'chione/system'
23
+
19
24
 
20
25
  ### Add the specified +component_types+ to the Aspect of this System as being
21
26
  ### required in any entities it processes.
22
- def self::aspect( all_of: nil, one_of: nil, none_of: nil )
27
+ def self::aspect( *required, all_of: nil, one_of: nil, none_of: nil )
23
28
  @aspect ||= Chione::Aspect.new
24
29
 
25
- @aspect = @aspect.with_all_of( all_of ) if all_of
30
+ all_of = required + Array( all_of )
31
+
32
+ @aspect = @aspect.with_all_of( all_of )
26
33
  @aspect = @aspect.with_one_of( one_of ) if one_of
27
34
  @aspect = @aspect.with_none_of( none_of ) if none_of
28
35
 
@@ -34,7 +41,6 @@ class Chione::System
34
41
  ### Create a new Chione::System for the specified +world+.
35
42
  def initialize( world, * )
36
43
  @world = world
37
- @thread = nil
38
44
  end
39
45
 
40
46
 
@@ -49,21 +55,12 @@ class Chione::System
49
55
  ### Start the system.
50
56
  def start
51
57
  self.log.info "Starting the %p" % [ self.class ]
52
- @thread = Thread.new( &self.method(:process_loop) )
53
58
  end
54
59
 
55
60
 
56
61
  ### Stop the system.
57
62
  def stop
58
- @thread.kill
59
63
  end
60
64
 
61
65
 
62
- ### The main loop of the system -- process entities that this system is
63
- ### interested in at an appropriate interval.
64
- def process_loop
65
- raise NotImplementedError, "%p does not implement required method #process_loop" %
66
- [ self.class ]
67
- end
68
-
69
66
  end # class Chione::System
@@ -45,6 +45,8 @@ class Chione::World
45
45
  @subscriptions = Hash.new do |h,k|
46
46
  h[ k ] = Set.new
47
47
  end
48
+ @defer_events = true
49
+ @deferred_events = []
48
50
 
49
51
  @main_thread = nil
50
52
  @world_threads = ThreadGroup.new
@@ -59,28 +61,45 @@ class Chione::World
59
61
  public
60
62
  ######
61
63
 
64
+ ##
62
65
  # The number of times the event loop has executed.
63
66
  attr_reader :timing_event_count
64
67
 
68
+ ##
65
69
  # The Hash of all Entities in the World, keyed by ID
66
70
  attr_reader :entities
67
71
 
72
+ ##
68
73
  # The Hash of all Systems currently in the World, keyed by class.
69
74
  attr_reader :systems
70
75
 
76
+ ##
71
77
  # The Hash of all Managers currently in the World, keyed by class.
72
78
  attr_reader :managers
73
79
 
80
+ ##
74
81
  # The ThreadGroup that contains all Threads managed by the World.
75
82
  attr_reader :world_threads
76
83
 
84
+ ##
77
85
  # The Thread object running the World's IO reactor loop
78
86
  attr_reader :main_thread
79
87
 
88
+ ##
80
89
  # The Hash of event subscription callbacks registered with the world, keyed by
81
90
  # event pattern.
82
91
  attr_reader :subscriptions
83
92
 
93
+ ##
94
+ # Whether or not to queue published events instead of sending them to
95
+ # subscribers immediately.
96
+ attr_predicate_accessor :defer_events
97
+
98
+ ##
99
+ # The queue of events that have not yet been sent to subscribers.
100
+ attr_reader :deferred_events
101
+ alias_method :deferring_events?, :defer_events?
102
+
84
103
 
85
104
  ### Start the world; returns the Thread in which the world is running.
86
105
  def start
@@ -190,7 +209,7 @@ class Chione::World
190
209
  raise ArgumentError, "callback has wrong arity" unless
191
210
  callback.arity >= 2 || callback.arity < 0
192
211
 
193
- @subscriptions[ event_name ].add( callback )
212
+ self.subscriptions[ event_name ].add( callback )
194
213
 
195
214
  return callback
196
215
  end
@@ -198,46 +217,86 @@ class Chione::World
198
217
 
199
218
  ### Unsubscribe from events that publish to the specified +callback+.
200
219
  def unsubscribe( callback )
201
- @subscriptions.values.each {|cbset| cbset.delete(callback) }
220
+ self.subscriptions.keys.each do |pattern|
221
+ cbset = self.subscriptions[ pattern ]
222
+ cbset.delete( callback )
223
+ self.subscriptions.delete( pattern ) if cbset.empty?
224
+ end
202
225
  end
203
226
 
204
227
 
205
- ### Publish an event with the specified +event_name+, calling any subscribers with
206
- ### the specified +payload+.
228
+ ### Publish an event with the specified +event_name+ and +payload+.
207
229
  def publish( event_name, *payload )
208
230
  # self.log.debug "Publishing a %p event: %p" % [ event_name, payload ]
209
- @subscriptions.each do |pattern, callbacks|
231
+ if self.defer_events?
232
+ self.deferred_events.push( [event_name, payload] )
233
+ else
234
+ self.call_subscription_callbacks( event_name, payload )
235
+ end
236
+ end
237
+
238
+
239
+ ### Send any deferred events to subscribers.
240
+ def publish_deferred_events
241
+ while event = self.deferred_events.shift
242
+ self.call_subscription_callbacks( *event )
243
+ end
244
+ end
245
+
246
+
247
+ ### Call the callbacks of any subscriptions matching the specified +event_name+ with
248
+ ### the given +payload+.
249
+ def call_subscription_callbacks( event_name, payload )
250
+ self.subscriptions.each do |pattern, callbacks|
210
251
  next unless File.fnmatch?( pattern, event_name, File::FNM_EXTGLOB|File::FNM_PATHNAME )
211
252
 
212
253
  callbacks.each do |callback|
213
- begin
214
- callback.call( event_name, payload )
215
- rescue => err
216
- self.log.error "%p while calling %p for a %p event: %s" %
217
- [ err.class, callback, event_name, err.message ]
218
- self.log.debug " %s" % [ err.backtrace.join("\n ") ]
219
- callbacks.delete( callback )
254
+ unless self.call_subscription_callback( callback, event_name, payload )
255
+ self.log.debug "Callback failed; removing it from the subscription."
256
+ self.unsubscribe( callback )
220
257
  end
221
258
  end
222
259
  end
223
260
  end
224
261
 
225
262
 
226
- ### Return a new Chione::Entity for the receiving World.
263
+ ### Call the specified +callback+ with the provided +event_name+ and +payload+, returning
264
+ ### +true+ if the callback executed without error.
265
+ def call_subscription_callback( callback, event_name, payload )
266
+ callback.call( event_name, payload )
267
+ return true
268
+ rescue => err
269
+ self.log.error "%p while calling %p for a %p event: %s" %
270
+ [ err.class, callback, event_name, err.message ]
271
+ self.log.debug " %s" % [ err.backtrace.join("\n ") ]
272
+ return false
273
+ end
274
+
275
+
276
+ ### Return a new Chione::Entity for the receiving World, using the optional
277
+ ### +assemblage+ to populate it with components if it's specified.
227
278
  def create_entity( assemblage=nil )
228
279
  entity = if assemblage
229
280
  assemblage.construct_for( self )
230
281
  else
231
- Chione::Entity.new( self )
282
+ self.create_blank_entity
232
283
  end
233
284
 
234
285
  @entities[ entity.id ] = entity
235
286
 
236
- self.publish( 'entity/created', entity )
287
+ self.publish( 'entity/created', entity.id )
237
288
  return entity
238
289
  end
239
290
 
240
291
 
292
+ ### Return a new Chione::Entity with no components for the receiving world.
293
+ ### Override this if you wish to use a class other than Chione::Entity for your
294
+ ### world.
295
+ def create_blank_entity
296
+ return Chione::Entity.new( self )
297
+ end
298
+
299
+
241
300
  ### Destroy the specified entity and remove it from any registered
242
301
  ### systems/managers.
243
302
  def destroy_entity( entity )
@@ -335,12 +394,14 @@ class Chione::World
335
394
  self.log.info "Starting timing loop."
336
395
  last_timing_event = Time.now
337
396
  interval = self.class.timing_event_interval
397
+ self.defer_events = false
338
398
  @timing_event_count = 0
339
399
 
340
400
  loop do
341
401
  previous_time, last_timing_event = last_timing_event, Time.now
342
402
 
343
403
  self.publish( 'timing', last_timing_event - previous_time, @timing_event_count )
404
+ self.publish_deferred_events
344
405
 
345
406
  @timing_event_count += 1
346
407
  remaining_time = interval - (Time.now - last_timing_event)
@@ -20,21 +20,17 @@ describe Chione::System do
20
20
  end
21
21
  end
22
22
 
23
+ let( :volition_component ) do
24
+ Class.new( Chione::Component ) do
25
+ field :verbs, default: []
26
+ end
27
+ end
28
+
23
29
 
24
30
  describe "a subclass" do
25
31
 
26
32
  let( :subclass ) do
27
- Class.new(described_class) do
28
- def initialize( * )
29
- super
30
- @processed = false
31
- end
32
- attr_reader :processed
33
-
34
- def process_loop
35
- @processed = true
36
- end
37
- end
33
+ Class.new(described_class)
38
34
  end
39
35
 
40
36
 
@@ -44,28 +40,23 @@ describe Chione::System do
44
40
 
45
41
 
46
42
  it "can declare components for its aspect" do
47
- subclass.aspect one_of: tags_component
43
+ subclass.aspect all_of: volition_component,
44
+ one_of: [ tags_component, location_component ]
48
45
 
49
46
  expect( subclass.aspect ).to_not be_empty
50
- expect( subclass.aspect.one_of ).to include( tags_component )
47
+ expect( subclass.aspect.all_of ).to include( volition_component )
48
+ expect( subclass.aspect.one_of ).to include( tags_component, location_component )
51
49
  end
52
50
 
53
51
 
54
- it "is required to implement #process_loop" do
55
- expect {
56
- Class.new( described_class ).new( :world ).process_loop
57
- }.to raise_error( NotImplementedError, /implement required method/i )
58
- end
59
-
52
+ it "can declare required components for its aspect via shorthand syntax" do
53
+ subclass.for_entities_that_have( volition_component )
60
54
 
61
- it "runs a Thread in its #process_loop when started" do
62
- system = subclass.new( :world )
63
- system_thread = system.start
64
- expect( system_thread ).to be_a( Thread )
65
- system_thread.join( 2 )
66
- expect( system.processed ).to be_truthy
55
+ expect( subclass.aspect ).to_not be_empty
56
+ expect( subclass.aspect.all_of ).to include( volition_component )
67
57
  end
68
58
 
59
+
69
60
  end
70
61
 
71
62
  end
@@ -24,22 +24,14 @@ describe Chione::World do
24
24
  @args = args
25
25
  @started = false
26
26
  @stopped = false
27
- @thread = nil
28
27
  end
29
- attr_reader :args, :started, :stopped, :thread
28
+ attr_reader :args, :started, :stopped
30
29
  def start
31
30
  @started = true
32
- super
33
31
  end
34
32
  def stop
35
- super
36
33
  @stopped = true
37
34
  end
38
- def process_loop
39
- loop do
40
- sleep 1
41
- end
42
- end
43
35
  end
44
36
  end
45
37
  let( :test_manager ) do
@@ -99,15 +91,6 @@ describe Chione::World do
99
91
  end
100
92
 
101
93
 
102
- it "joins on any Threads started by subsystems when stopping" do
103
- system = world.add_system( test_system )
104
- world.start
105
- sleep 0.1 until world.running?
106
- world.stop
107
- expect( system.thread ).to_not be_alive
108
- end
109
-
110
-
111
94
  describe "configuration" do
112
95
 
113
96
  it "is done via the Configurability API" do
@@ -127,11 +110,18 @@ describe Chione::World do
127
110
 
128
111
  describe "publish/subscribe" do
129
112
 
113
+
114
+ it "starts out with events deferred" do
115
+ expect( world ).to be_deferring_events
116
+ end
117
+
118
+
130
119
  it "allows subscription to events" do
131
120
  received = []
132
121
  world.subscribe( 'test/subscription' ) {|*args| received << args }
133
122
  expect {
134
123
  world.publish( 'test/subscription' )
124
+ world.publish_deferred_events
135
125
  }.to change { received.length }.by( 1 )
136
126
 
137
127
  expect( received ).to eq([ ['test/subscription', []] ])
@@ -144,6 +134,7 @@ describe Chione::World do
144
134
  world.subscribe( 'test/subscription' ) {|*args| received << 2 }
145
135
  expect {
146
136
  world.publish( 'test/subscription' )
137
+ world.publish_deferred_events
147
138
  }.to change { received.length }.by( 2 )
148
139
 
149
140
  expect( received ).to eq([ 1, 2 ])
@@ -155,6 +146,7 @@ describe Chione::World do
155
146
  expect {
156
147
  Loggability.with_level( :fatal ) do
157
148
  world.publish( 'test/subscription' )
149
+ world.publish_deferred_events
158
150
  end
159
151
  }.to change { world.subscriptions['test/subscription'].length }.by( -1 )
160
152
  expect( world.subscriptions['test/subscriptions'] ).to_not include( callback )
@@ -168,12 +160,20 @@ describe Chione::World do
168
160
 
169
161
  expect {
170
162
  world.publish( 'test/subscription' )
163
+ world.publish_deferred_events
171
164
  }.to_not change { received.length }
172
165
  end
173
166
 
174
167
 
175
168
  describe "with glob-style wildcard patterns" do
176
169
 
170
+ let( :world ) do
171
+ instance = super()
172
+ instance.defer_events = false
173
+ instance
174
+ end
175
+
176
+
177
177
  it "matches any one event segment with an asterisk" do
178
178
  received = []
179
179
 
@@ -229,6 +229,13 @@ describe Chione::World do
229
229
 
230
230
  describe "entities" do
231
231
 
232
+ let( :world ) do
233
+ instance = super()
234
+ instance.defer_events = false
235
+ instance
236
+ end
237
+
238
+
232
239
  it "can create entities" do
233
240
  expect( world.create_entity ).to be_a( Chione::Entity )
234
241
  end
@@ -262,7 +269,7 @@ describe Chione::World do
262
269
  world.subscribe( 'entity/created' ) {|*payload| event_payload = payload }
263
270
  entity = world.create_entity
264
271
 
265
- expect( event_payload ).to eq([ 'entity/created', [entity] ])
272
+ expect( event_payload ).to eq([ 'entity/created', [entity.id] ])
266
273
  end
267
274
 
268
275
 
@@ -289,6 +296,7 @@ describe Chione::World do
289
296
  world.subscribe( 'entity/destroyed' ) {|*payload| event_payload = payload }
290
297
  entity = world.create_entity
291
298
  world.destroy_entity( entity )
299
+ world.publish_deferred_events
292
300
 
293
301
  expect( event_payload ).to eq([ 'entity/destroyed', [entity] ])
294
302
  end
@@ -298,6 +306,13 @@ describe Chione::World do
298
306
 
299
307
  describe "components" do
300
308
 
309
+ let( :world ) do
310
+ instance = super()
311
+ instance.defer_events = false
312
+ instance
313
+ end
314
+
315
+
301
316
  let!( :entity1 ) do
302
317
  obj = world.create_entity
303
318
  obj.add_component( location_component.new )
@@ -360,6 +375,13 @@ describe Chione::World do
360
375
 
361
376
  describe "systems" do
362
377
 
378
+ let( :world ) do
379
+ instance = super()
380
+ instance.defer_events = false
381
+ instance
382
+ end
383
+
384
+
363
385
  it "can have Systems added to it" do
364
386
  system = world.add_system( test_system )
365
387
  expect( world.systems ).to include( test_system )
@@ -375,6 +397,7 @@ describe Chione::World do
375
397
 
376
398
  it "broadcasts a `system/added` event when a System is added" do
377
399
  event_payload = nil
400
+ world.defer_events = false
378
401
  world.subscribe( 'system/added' ) {|*payload| event_payload = payload }
379
402
 
380
403
  sys = world.add_system( test_system )
@@ -405,6 +428,13 @@ describe Chione::World do
405
428
 
406
429
  describe "managers" do
407
430
 
431
+ let( :world ) do
432
+ instance = super()
433
+ instance.defer_events = false
434
+ instance
435
+ end
436
+
437
+
408
438
  it "can register Managers" do
409
439
  manager = world.add_manager( test_manager )
410
440
  expect( world.managers ).to include( test_manager )
@@ -420,6 +450,7 @@ describe Chione::World do
420
450
 
421
451
  it "broadcasts a `manager/added` event when a Manager is added" do
422
452
  event_payload = nil
453
+ world.defer_events = false
423
454
  world.subscribe( 'manager/added' ) {|*payload| event_payload = payload }
424
455
 
425
456
  manager = world.add_manager( test_manager )
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chione
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Granger
@@ -35,7 +35,7 @@ cert_chain:
35
35
  w8aNA5re5+Rt/Vvjxj5AcEnZnZiz5x959NaddQocX32Z1unHw44pzRNUur1GInfW
36
36
  p4vpx2kUSFSAGjtCbDGTNV2AH8w9OU4xEmNz8c5lyoA=
37
37
  -----END CERTIFICATE-----
38
- date: 2017-05-22 00:00:00.000000000 Z
38
+ date: 2017-05-26 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: loggability
@@ -65,6 +65,20 @@ dependencies:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
67
  version: '3.0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: pluggability
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '0.4'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '0.4'
68
82
  - !ruby/object:Gem::Dependency
69
83
  name: uuid
70
84
  requirement: !ruby/object:Gem::Requirement
@@ -141,28 +155,28 @@ dependencies:
141
155
  requirements:
142
156
  - - "~>"
143
157
  - !ruby/object:Gem::Version
144
- version: '0.1'
158
+ version: '0.3'
145
159
  type: :development
146
160
  prerelease: false
147
161
  version_requirements: !ruby/object:Gem::Requirement
148
162
  requirements:
149
163
  - - "~>"
150
164
  - !ruby/object:Gem::Version
151
- version: '0.1'
165
+ version: '0.3'
152
166
  - !ruby/object:Gem::Dependency
153
167
  name: rdoc
154
168
  requirement: !ruby/object:Gem::Requirement
155
169
  requirements:
156
170
  - - "~>"
157
171
  - !ruby/object:Gem::Version
158
- version: '4.0'
172
+ version: '5.1'
159
173
  type: :development
160
174
  prerelease: false
161
175
  version_requirements: !ruby/object:Gem::Requirement
162
176
  requirements:
163
177
  - - "~>"
164
178
  - !ruby/object:Gem::Version
165
- version: '4.0'
179
+ version: '5.1'
166
180
  - !ruby/object:Gem::Dependency
167
181
  name: hoe
168
182
  requirement: !ruby/object:Gem::Requirement
metadata.gz.sig CHANGED
Binary file