chione 0.2.0 → 0.3.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
2
  SHA1:
3
- metadata.gz: e97a13cf34e52ecdafa6435e9f8a6a055b0491d8
4
- data.tar.gz: c166e2cf474f7eadd82c8974ce30cdab06961e2e
3
+ metadata.gz: 9b24299f45b2755cca922ee6762900f1afb4b2b7
4
+ data.tar.gz: e4bb1a2a39c594b2ecee9e898b358f138c9d6ce7
5
5
  SHA512:
6
- metadata.gz: f3d4d5d410fe1a8b41dd56f5ed5888d2e9a553c55a279857fb1759ce9e9b40c3e4b763aabaed899e04375b539b6143f1f526637d3db81e955a6f0d185c3b5644
7
- data.tar.gz: de83ffeaefad492c73ca249f3af9ebfbb8d0371ec955a39c0f35938131be8fe95f4c140e3789404d88b147afb522ddcac1dcc19289c8c8ec404c5e71dcfdaa2e
6
+ metadata.gz: fde13065c29d54acf5e355456f146740ed8a6f4a02084dff417944fae714e9395f566b2b717eef18ea398e4a7e9940f8f57871e1d9eb140ce60aa99bdaf45856
7
+ data.tar.gz: 19d74ac66382bd50991a149ff5082346ba6eb67cbf0a629852051f19361bde42e3b7ec1e2b3279f128dbca377e94e8057df88b8eca349bed45480f0cb5caea4f
Binary file
data.tar.gz.sig CHANGED
Binary file
data/ChangeLog CHANGED
@@ -1,8 +1,78 @@
1
+ 2017-05-31 Michael Granger <ged@FaerieMUD.org>
2
+
3
+ * .hgtags:
4
+ Added tag v0.3.0 for changeset c91f71b3d7d9
5
+ [06fdcde9eb00] [tip]
6
+
7
+ * .hgsigs:
8
+ Added signature for changeset 0d453cae95c3
9
+ [c91f71b3d7d9] [v0.3.0]
10
+
11
+ * Rakefile, chione.gemspec:
12
+ Update gemspec
13
+ [0d453cae95c3]
14
+
15
+ * History.md, Manifest.txt, lib/chione.rb:
16
+ Bump the minor version, update history.
17
+ [e102f20bc862]
18
+
19
+ * lib/chione.rb, lib/chione/archetype.rb, lib/chione/assemblage.rb,
20
+ spec/chione/archetype_spec.rb:
21
+ Add more backward-compat for Chione::Assemblage
22
+ [a2e8b35fb950] [github/master]
23
+
24
+ * .gems, Manifest.txt, Rakefile, chione.gemspec, lib/chione.rb,
25
+ lib/chione/archetype.rb, lib/chione/assemblage.rb,
26
+ lib/chione/entity.rb, lib/chione/world.rb,
27
+ spec/chione/archetype_spec.rb, spec/chione/assemblage_spec.rb,
28
+ spec/chione/entity_spec.rb, spec/chione/world_spec.rb,
29
+ spec/spec_helper.rb:
30
+ Rename Assemblage to Archetype to follow Artemis's naming.
31
+
32
+ Also add 'deprecatable' to track deprecations.
33
+ [687db9f6d955]
34
+
35
+ * lib/chione/entity.rb, lib/chione/system.rb, lib/chione/world.rb,
36
+ spec/chione/entity_spec.rb, spec/chione/system_spec.rb:
37
+ Add some flexibility to working with Components.
38
+
39
+ - Add a Chione::Component() coercion method
40
+ - Allow a component to be added to an entity by name or class
41
+ - Rename Entity#get_component to #find_component to more accurately
42
+ reflect what it does. Aliased to the old name for backward
43
+ compatibility, but the alias will likely be removed before 1.0.
44
+ - Add an #entities method to System for easy iteration by subclasses.
45
+ - Change the return value of World#entities_for to an Enumerator for
46
+ future optimizations.
47
+ [0f1b93f7118f]
48
+
49
+ * lib/chione/component.rb:
50
+ Add a missing private method to Component
51
+ [476c7503fa52]
52
+
53
+ 2017-05-30 Michael Granger <ged@FaerieMUD.org>
54
+
55
+ * lib/chione.rb, spec/chione_spec.rb:
56
+ Add a Component coercion method
57
+ [48f58a3494f1]
58
+
1
59
  2017-05-26 Michael Granger <ged@FaerieMUD.org>
2
60
 
61
+ * .hgtags:
62
+ Added tag v0.2.0 for changeset 94e6caba943c
63
+ [582fdd9c20c8]
64
+
65
+ * .hgsigs:
66
+ Added signature for changeset 89f0f18003f0
67
+ [94e6caba943c] [v0.2.0]
68
+
69
+ * History.md, Rakefile, chione.gemspec:
70
+ Re-prep for 0.2.0 release.
71
+ [89f0f18003f0]
72
+
3
73
  * Rakefile, chione.gemspec:
4
74
  Update gemspec
5
- [068af8eec0e0] [github/master, tip]
75
+ [068af8eec0e0]
6
76
 
7
77
  2017-05-25 Michael Granger <ged@FaerieMUD.org>
8
78
 
data/History.md CHANGED
@@ -1,3 +1,25 @@
1
+ ## v0.3.0 [2017-05-31] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ Changes:
4
+
5
+ - Rename Assemblage to Archetype to follow Artemis's naming.
6
+ - Rename Entity#get_component to #find_component to more accurately
7
+ reflect what it does. Aliased to the old name for backward
8
+ compatibility, but the alias will likely be removed before 1.0.
9
+
10
+ Enhancements:
11
+
12
+ - Add a Chione::Component() coercion method
13
+ - Allow a component to be added to an entity by name or class
14
+ - Add an #entities method to System for easy iteration by subclasses.
15
+ - Change the return value of World#entities_for to an Enumerator for
16
+ future optimizations.
17
+
18
+ Bugfixes:
19
+
20
+ - Add a missing private method to Component
21
+
22
+
1
23
  ## v0.2.0 [2017-05-26] Michael Granger <ged@FaerieMUD.org>
2
24
 
3
25
  Enhancements:
@@ -6,6 +6,7 @@ Manifest.txt
6
6
  README.md
7
7
  Rakefile
8
8
  lib/chione.rb
9
+ lib/chione/archetype.rb
9
10
  lib/chione/aspect.rb
10
11
  lib/chione/assemblage.rb
11
12
  lib/chione/behaviors.rb
@@ -15,8 +16,8 @@ lib/chione/manager.rb
15
16
  lib/chione/mixins.rb
16
17
  lib/chione/system.rb
17
18
  lib/chione/world.rb
19
+ spec/chione/archetype_spec.rb
18
20
  spec/chione/aspect_spec.rb
19
- spec/chione/assemblage_spec.rb
20
21
  spec/chione/component_spec.rb
21
22
  spec/chione/entity_spec.rb
22
23
  spec/chione/manager_spec.rb
data/Rakefile CHANGED
@@ -35,6 +35,7 @@ hoespec = Hoe.spec 'chione' do |spec|
35
35
  spec.dependency 'configurability', '~> 3.0'
36
36
  spec.dependency 'pluggability', '~> 0.4'
37
37
  spec.dependency 'uuid', '~> 2.3'
38
+ spec.dependency 'deprecatable', '~> 1.0'
38
39
 
39
40
  spec.dependency 'hoe-deveiate', '~> 1.0', :developer
40
41
  spec.dependency 'simplecov', '~> 0.12', :developer
@@ -84,9 +85,12 @@ if File.directory?( '.hg' )
84
85
  end
85
86
  end
86
87
 
88
+ file __FILE__
89
+ file 'lib/chione.rb'
90
+ file 'Manifest.txt'
87
91
 
88
92
  task :gemspec => GEMSPEC
89
- file GEMSPEC => __FILE__
93
+ file GEMSPEC => [ __FILE__, 'Manifest.txt', 'lib/chione.rb' ]
90
94
  task GEMSPEC do |task|
91
95
  Rake.application.trace "Updating gemspec"
92
96
  spec = $hoespec.spec
@@ -100,3 +104,4 @@ task GEMSPEC do |task|
100
104
  end
101
105
 
102
106
  CLOBBER.include( GEMSPEC.to_s )
107
+
@@ -3,23 +3,26 @@
3
3
 
4
4
  require 'uuid'
5
5
  require 'loggability'
6
+ require 'deprecatable'
7
+
8
+ Deprecatable.options.has_at_exit_report = false
6
9
 
7
10
  # An Entity/Component System inspired by Artemis
8
11
  module Chione
9
12
  extend Loggability
10
13
 
11
- # Loggability API -- set up a log host
12
- log_as :chione
14
+ # Gem version
15
+ VERSION = '0.3.0'
13
16
 
14
17
 
15
- # Gem version
16
- VERSION = '0.2.0'
18
+ # Loggability API -- set up a log host
19
+ log_as :chione
17
20
 
18
21
 
19
22
  require 'chione/mixins'
20
23
 
21
24
  autoload :Aspect, 'chione/aspect'
22
- autoload :Assemblage, 'chione/assemblage'
25
+ autoload :Archetype, 'chione/archetype'
23
26
  autoload :Component, 'chione/component'
24
27
  autoload :Entity, 'chione/entity'
25
28
  autoload :Manager, 'chione/manager'
@@ -31,6 +34,25 @@ module Chione
31
34
  class << self; attr_reader :uuid ; end
32
35
  @uuid = UUID.new
33
36
 
37
+
38
+ ### Coerce the specified +object+ into a Chione::Component and return it.
39
+ def self::Component( object )
40
+ return object if object.is_a?( Chione::Component )
41
+ return Chione::Component.create( object ) if
42
+ object.is_a?( Class ) || object.is_a?( String ) || object.is_a?( Symbol )
43
+ raise TypeError, "can't convert %p into Chione::Component" % [ object.class ]
44
+ end
45
+
46
+
47
+ ### Warn about deprecated constants.
48
+ def self::const_missing( name )
49
+ super unless name == :Assemblage
50
+ warn "Chione::Assemblage has been renamed to Chione::Archetype. " \
51
+ "This alias will be removed before 1.0\n" \
52
+ "Used at #{caller(1).first}"
53
+ return Chione::Archetype
54
+ end
55
+
34
56
  end # module Chione
35
57
 
36
58
  # vim: set nosta noet ts=4 sw=4:
@@ -0,0 +1,71 @@
1
+ # -*- ruby -*-
2
+ #encoding: utf-8
3
+
4
+ require 'pluggability'
5
+ require 'loggability'
6
+
7
+ require 'chione' unless defined?( Chione )
8
+
9
+
10
+ # An Archetype mixin for defining factories for common entity configurations.
11
+ module Chione::Archetype
12
+ extend Loggability,
13
+ Pluggability
14
+
15
+ # Loggability API -- log to the chione logger
16
+ log_to :chione
17
+
18
+ # Pluggability API -- load subclasses from the 'chione/archetype' directory
19
+ plugin_prefixes 'chione/archetype', 'chione/assemblage'
20
+
21
+
22
+ ### Extension callback -- add archetype functionality to an extended +object+.
23
+ def self::extended( object )
24
+ super
25
+ object.extend( Loggability )
26
+ object.log_to( :chione )
27
+ object.components ||= {}
28
+ end
29
+
30
+
31
+ ### Inclusion callback -- add the components from this archetype to those in
32
+ ### the specified +mod+.
33
+ def included( mod )
34
+ super
35
+ self.log.debug "Including %d components in %p" % [ self.components.length, mod ]
36
+ self.components.each do |component_type, args|
37
+ self.log.debug "Adding %p to %p from %p" % [ component_type, mod, self ]
38
+ mod.add( component_type, *args )
39
+ end
40
+ end
41
+
42
+
43
+ ##
44
+ # The Hash of component types and initialization values to add to entities
45
+ # constructed by this Archetype.
46
+ attr_accessor :components
47
+
48
+
49
+ ### Add a +component_type+ to the list used when constructing a new entity from
50
+ ### the current Archetype. The component will be instantiated using the specified
51
+ ### +init_args+.
52
+ def add( component_type, *init_args )
53
+ self.components[ component_type ] = init_args
54
+ end
55
+
56
+
57
+ ### Construct a new entity for the specified +world+ with all of the archetype's
58
+ ### components.
59
+ def construct_for( world )
60
+ entity = world.create_entity
61
+ self.components.each do |component_type, args|
62
+ component = component_type.new( *args )
63
+ entity.add_component( component )
64
+ end
65
+
66
+ return entity
67
+ end
68
+
69
+ end # module Chione::Archetype
70
+
71
+
@@ -1,69 +1,6 @@
1
1
  # -*- ruby -*-
2
2
  #encoding: utf-8
3
3
 
4
- require 'pluggability'
5
- require 'loggability'
4
+ # Replaced by chione/archetype
5
+ require 'chione/archetype'
6
6
 
7
- require 'chione' unless defined?( Chione )
8
-
9
-
10
- # An Assemblage mixin for defining factories for common entity configurations.
11
- module Chione::Assemblage
12
- extend Loggability,
13
- Pluggability
14
-
15
- # Loggability API -- log to the chione logger
16
- log_to :chione
17
-
18
- # Pluggability API -- load subclasses from the 'chione/assemblage' directory
19
- plugin_prefixes 'chione/assemblage'
20
-
21
-
22
- ### Extension callback -- add assemblage functionality to an extended +object+.
23
- def self::extended( object )
24
- super
25
- object.extend( Loggability )
26
- object.log_to( :chione )
27
- object.components ||= {}
28
- end
29
-
30
-
31
- ### Inclusion callback -- add the components from this assemblage to those in
32
- ### the specified +mod+.
33
- def included( mod )
34
- super
35
- self.log.debug "Including %d components in %p" % [ self.components.length, mod ]
36
- self.components.each do |component_type, args|
37
- self.log.debug "Adding %p to %p from %p" % [ component_type, mod, self ]
38
- mod.add( component_type, *args )
39
- end
40
- end
41
-
42
-
43
- ##
44
- # The Hash of component types and initialization values to add to entities
45
- # constructed by this Assemblage.
46
- attr_accessor :components
47
-
48
-
49
- ### Add a +component_type+ to the list used when constructing a new entity from
50
- ### the current Assemblage. The component will be instantiated using the specified
51
- ### +init_args+.
52
- def add( component_type, *init_args )
53
- self.components[ component_type ] = init_args
54
- end
55
-
56
-
57
- ### Construct a new entity for the specified +world+ with all of the assemblage's
58
- ### components.
59
- def construct_for( world )
60
- entity = world.create_entity
61
- self.components.each do |component_type, args|
62
- component = component_type.new( *args )
63
- entity.add_component( component )
64
- end
65
-
66
- return entity
67
- end
68
-
69
- end # module Chione::Assemblage
@@ -80,4 +80,12 @@ class Chione::Component
80
80
  return Marshal.load( Marshal.dump(value) )
81
81
  end
82
82
 
83
+
84
+ ### Return a slice of the specified +string+ truncated to at most +maxlen+
85
+ ### characters. Returns the unchanged +string+ if it's not longer than +maxlen+.
86
+ def truncate_string( string, maxlen )
87
+ return string unless string.length > maxlen
88
+ return string[ 0, maxlen - 3 ] + '...'
89
+ end
90
+
83
91
  end # class Chione::Component
@@ -1,6 +1,7 @@
1
1
  # -*- ruby -*-
2
2
  #encoding: utf-8
3
3
 
4
+ require 'deprecatable'
4
5
  require 'loggability'
5
6
  require 'securerandom'
6
7
 
@@ -8,7 +9,8 @@ require 'chione' unless defined?( Chione )
8
9
 
9
10
  # The Entity (identity) class
10
11
  class Chione::Entity
11
- extend Loggability
12
+ extend Loggability,
13
+ Deprecatable
12
14
 
13
15
  # Loggability API -- send logs to the Chione logger
14
16
  log_to :chione
@@ -47,6 +49,7 @@ class Chione::Entity
47
49
  ### Add the specified +component+ to the entity. It will replace any existing component
48
50
  ### of the same type.
49
51
  def add_component( component )
52
+ component = Chione::Component( component )
50
53
  self.components[ component.class ] = component
51
54
  self.world.add_component_for( self, component )
52
55
  end
@@ -54,11 +57,13 @@ class Chione::Entity
54
57
 
55
58
  ### Fetch the first Component of the specified +types+ that belongs to the entity. If the
56
59
  ### Entity doesn't have any of the specified types of Component, raises a KeyError.
57
- def get_component( *types )
60
+ def find_component( *types )
58
61
  found_type = types.find {|type| self.components[type] } or
59
62
  raise KeyError, "entity %s doesn't have any of %p" % [ self.id, types ]
60
63
  return self.components[ found_type ]
61
64
  end
65
+ alias_method :get_component, :find_component
66
+ deprecate :get_component, message: 'Use #find_component instead', removal_version: '1.0'
62
67
 
63
68
 
64
69
  ### Returns +true+ if this entity has the specified +component+.
@@ -63,4 +63,10 @@ class Chione::System
63
63
  end
64
64
 
65
65
 
66
+ ### Return an Enumerator that yields the entities which this system operators
67
+ ### over.
68
+ def entities
69
+ return self.world.entities_for( self )
70
+ end
71
+
66
72
  end # class Chione::System
@@ -274,10 +274,10 @@ class Chione::World
274
274
 
275
275
 
276
276
  ### Return a new Chione::Entity for the receiving World, using the optional
277
- ### +assemblage+ to populate it with components if it's specified.
278
- def create_entity( assemblage=nil )
279
- entity = if assemblage
280
- assemblage.construct_for( self )
277
+ ### +archetype+ to populate it with components if it's specified.
278
+ def create_entity( archetype=nil )
279
+ entity = if archetype
280
+ archetype.construct_for( self )
281
281
  else
282
282
  self.create_blank_entity
283
283
  end
@@ -323,15 +323,16 @@ class Chione::World
323
323
  ### Register the specified +component+ as having been added to the specified
324
324
  ### +entity+.
325
325
  def add_component_for( entity, component )
326
+ self.log.debug "Adding %p for %p" % [ component.class, entity ]
326
327
  @entities_by_component[ component.class ].add( entity )
327
328
  end
328
329
 
329
330
 
330
- ### Return the Entities that have a Component composition that is compatible with
331
- ### the specified +system+'s aspect.
331
+ ### Return an Enumerator of the Entities that have a Component composition that
332
+ ### is compatible with the specified +system+'s aspect.
332
333
  def entities_for( system )
333
334
  system = system.class unless system.is_a?( Class )
334
- return self.entities_with( system.aspect )
335
+ return self.entities_with( system.aspect ).to_enum
335
336
  end
336
337
 
337
338
 
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env rspec -cfd
2
+
3
+ require_relative '../spec_helper'
4
+
5
+ require 'chione/archetype'
6
+ require 'chione/component'
7
+ require 'chione/entity'
8
+ require 'chione/world'
9
+
10
+ describe Chione::Archetype do
11
+
12
+ let( :world ) { Chione::World.new }
13
+
14
+ let( :location_component ) do
15
+ Class.new( Chione::Component ) do
16
+ field :x, default: 0
17
+ field :y, default: 0
18
+ end
19
+ end
20
+
21
+ let( :tags_component ) do
22
+ Class.new( Chione::Component ) do
23
+ field :tags, default: []
24
+ end
25
+ end
26
+
27
+
28
+ it "acts as a factory for entities with pre-set components" do
29
+ archetype = Module.new
30
+ archetype.extend( described_class )
31
+ archetype.add( location_component, x: 10, y: 8 )
32
+ archetype.add( tags_component, tags: [:foo, :bar] )
33
+
34
+ entity = archetype.construct_for( world )
35
+
36
+ expect( entity ).to be_a( Chione::Entity )
37
+ expect( entity.world ).to be( world )
38
+ expect( entity.components ).to include( location_component, tags_component )
39
+ end
40
+
41
+
42
+ it "can include other archetypes" do
43
+ general_archetype = Module.new
44
+ general_archetype.extend( described_class )
45
+ general_archetype.add( location_component, x: 10, y: 8 )
46
+
47
+ specific_archetype = Module.new
48
+ specific_archetype.extend( described_class )
49
+ specific_archetype.send( :include, general_archetype )
50
+ specific_archetype.add( tags_component, tags: [:foo, :bar] )
51
+
52
+ entity = specific_archetype.construct_for( world )
53
+
54
+ expect( entity ).to be_a( Chione::Entity )
55
+ expect( entity.world ).to be( world )
56
+ expect( entity.components ).to include( location_component, tags_component )
57
+ end
58
+
59
+
60
+ it "is still loadable as an `Assemblage`" do
61
+ expect {
62
+ expect( Chione::Assemblage ).to equal( described_class )
63
+ }.to output( /has been renamed/i ).to_stderr
64
+ end
65
+
66
+
67
+ it "still looks in the chione/assemblage directory for derivatives" do
68
+ expect( described_class.plugin_prefixes ).to include( 'chione/assemblage' )
69
+ end
70
+
71
+ end
72
+
@@ -8,27 +8,47 @@ require 'chione/component'
8
8
 
9
9
  describe Chione::Entity do
10
10
 
11
+ before( :all ) do
12
+ @component_classes = Chione::Component.derivatives.dup
13
+ end
14
+ before( :each ) do
15
+ Chione::Component.derivatives.clear
16
+ end
17
+ after( :all ) do
18
+ Chione::Component.derivatives.replace( @component_classes )
19
+ end
20
+
21
+
11
22
  let( :world ) { Chione::World.new }
12
23
 
13
24
  let( :location_component ) do
14
- Class.new( Chione::Component ) do
25
+ klass = Class.new( Chione::Component ) do
26
+ def self::name; "Location"; end
15
27
  field :x, default: 0
16
28
  field :y, default: 0
17
29
  end
30
+ Chione::Component.derivatives['location'] = klass
31
+ klass
18
32
  end
19
33
 
20
34
  let( :tags_component ) do
21
- Class.new( Chione::Component ) do
35
+ klass = Class.new( Chione::Component ) do
36
+ def self::name; "Tags"; end
22
37
  field :tags, default: []
23
38
  end
39
+ Chione::Component.derivatives['tags'] = klass
40
+ klass
24
41
  end
25
42
 
26
43
  let( :bounding_box_component ) do
27
- Class.new( Chione::Component ) do
44
+ klass = Class.new( Chione::Component ) do
45
+ def self::name; "BoundingBox"; end
28
46
  field :width, default: 1
29
47
  field :height, default: 1
30
48
  field :depth, default: 1
31
49
  end
50
+ Chione::Component.derivatives['bounding_box'] = klass
51
+ klass
32
52
  end
33
53
 
34
54
 
@@ -58,8 +78,20 @@ describe Chione::Entity do
58
78
 
59
79
 
60
80
  it "can have components added to it" do
61
- entity.add_component( location_component.new )
62
- entity.add_component( tags_component.new )
81
+ entity.add_component( location_component )
82
+ entity.add_component( tags_component )
83
+
84
+ expect( entity ).to have_component( location_component )
85
+ expect( entity ).to have_component( tags_component )
86
+ end
87
+
88
+
89
+ it "can have components added to it by name" do
90
+ location_component()
91
+ tags_component()
92
+
93
+ entity.add_component( :location )
94
+ entity.add_component( :tags )
63
95
 
64
96
  expect( entity ).to have_component( location_component )
65
97
  expect( entity ).to have_component( tags_component )
@@ -67,8 +99,18 @@ describe Chione::Entity do
67
99
 
68
100
 
69
101
  it "lets components be fetched from it" do
70
- entity.add_component( location_component.new )
71
- entity.add_component( tags_component.new )
102
+ entity.add_component( location_component )
103
+ entity.add_component( tags_component )
104
+
105
+ expect(
106
+ entity.find_component( location_component )
107
+ ).to eq( entity.components[location_component] )
108
+ end
109
+
110
+
111
+ it "supports backward-compatible component-fetcher method" do
112
+ entity.add_component( location_component )
113
+ entity.add_component( tags_component )
72
114
 
73
115
  expect(
74
116
  entity.get_component( location_component )
@@ -77,29 +119,29 @@ describe Chione::Entity do
77
119
 
78
120
 
79
121
  it "lets one of a list of components be fetched from it" do
80
- entity.add_component( location_component.new )
81
- entity.add_component( tags_component.new )
122
+ entity.add_component( location_component )
123
+ entity.add_component( tags_component )
82
124
 
83
125
  expect(
84
- entity.get_component( bounding_box_component, location_component )
126
+ entity.find_component( bounding_box_component, location_component )
85
127
  ).to eq( entity.components[location_component] )
86
128
  end
87
129
 
88
130
 
89
131
  it "raises a KeyError if it doesn't have a fetched component" do
90
- entity.add_component( tags_component.new )
132
+ entity.add_component( tags_component )
91
133
 
92
134
  expect {
93
- entity.get_component( location_component )
135
+ entity.find_component( location_component )
94
136
  }.to raise_error( KeyError, /#{entity.id} doesn't have/i )
95
137
  end
96
138
 
97
139
 
98
140
  it "raises a KeyError if it doesn't have any of several fetched components" do
99
- entity.add_component( tags_component.new )
141
+ entity.add_component( tags_component )
100
142
 
101
143
  expect {
102
- entity.get_component( location_component, bounding_box_component )
144
+ entity.find_component( location_component, bounding_box_component )
103
145
  }.to raise_error( KeyError, /#{entity.id} doesn't have any of/i )
104
146
  end
105
147
 
@@ -27,11 +27,12 @@ describe Chione::System do
27
27
  end
28
28
 
29
29
 
30
- describe "a subclass" do
30
+ describe "subclass" do
31
31
 
32
32
  let( :subclass ) do
33
33
  Class.new(described_class)
34
34
  end
35
+ let( :world ) { Chione::World.new }
35
36
 
36
37
 
37
38
  it "has a default Aspect which matches all entities" do
@@ -57,6 +58,39 @@ describe Chione::System do
57
58
  end
58
59
 
59
60
 
61
+ describe "instance" do
62
+
63
+ let( :subclass ) do
64
+ subclass = super()
65
+ subclass.aspect all_of: volition_component,
66
+ one_of: [ tags_component, location_component ]
67
+ subclass
68
+ end
69
+
70
+ let( :instance ) do
71
+ subclass.new( world )
72
+ end
73
+
74
+
75
+ it "can enumerate the entities from the world that match its aspect" do
76
+ ent1 = world.create_entity
77
+ ent1.add_component( volition_component )
78
+ ent1.add_component( tags_component )
79
+
80
+ ent2 = world.create_entity
81
+ ent2.add_component( volition_component )
82
+ ent2.add_component( location_component )
83
+
84
+ ent3 = world.create_entity
85
+ ent3.add_component( volition_component )
86
+
87
+ expect( instance.entities ).to be_a( Enumerator )
88
+ expect( instance.entities ).to contain_exactly( ent1, ent2 )
89
+ end
90
+
91
+
92
+ end
93
+
60
94
  end
61
95
 
62
96
  end
@@ -5,7 +5,7 @@ require_relative '../spec_helper'
5
5
  require 'chione/world'
6
6
 
7
7
  require 'chione/aspect'
8
- require 'chione/assemblage'
8
+ require 'chione/archetype'
9
9
  require 'chione/component'
10
10
  require 'chione/entity'
11
11
  require 'chione/manager'
@@ -82,9 +82,9 @@ describe Chione::World do
82
82
  end
83
83
  end
84
84
 
85
- let( :assemblage ) do
85
+ let( :archetype ) do
86
86
  mod = Module.new
87
- mod.extend( Chione::Assemblage )
87
+ mod.extend( Chione::Archetype )
88
88
  mod.add( location_component, x: 10, y: 8 )
89
89
  mod.add( tags_component, tags: [:foo, :bar] )
90
90
  mod
@@ -255,11 +255,11 @@ describe Chione::World do
255
255
  end
256
256
 
257
257
 
258
- it "can create entities using an Assemblage" do
259
- entity = world.create_entity( assemblage )
258
+ it "can create entities using an Archetype" do
259
+ entity = world.create_entity( archetype )
260
260
 
261
261
  expect( entity ).to be_a( Chione::Entity )
262
- expect( entity.components.keys ).to include( *assemblage.components.keys )
262
+ expect( entity.components.keys ).to include( *archetype.components.keys )
263
263
  end
264
264
 
265
265
 
@@ -5,6 +5,35 @@ require_relative 'spec_helper'
5
5
  require 'chione'
6
6
 
7
7
  describe Chione do
8
+
9
+ after( :all ) do
10
+ Chione::Component.derivatives.clear
11
+ end
12
+
13
+
14
+ it "can coerce Chione::Component classes into instances" do
15
+ component_class = Class.new( Chione::Component )
16
+ expect( Chione::Component(component_class) ).to be_instance_of( component_class )
17
+ end
18
+
19
+
20
+ it "can coerce Chione::Component class names into instances" do
21
+ component_class = Class.new( Chione::Component ) do
22
+ def self::name; "Thermidore"; end
23
+ end
24
+ Chione::Component.derivatives[ 'thermidore' ] = component_class
25
+
26
+ expect( Chione::Component(:thermidore) ).to be_instance_of( component_class )
27
+ end
28
+
29
+
30
+ it "returns coerced Chione::Component unchanged" do
31
+ component_class = Class.new( Chione::Component )
32
+ instance = component_class.new
33
+
34
+ expect( Chione::Component(instance) ).to equal( instance )
35
+ end
36
+
8
37
  end
9
38
 
10
39
  # vim: set nosta noet ts=4 sw=4:
@@ -4,10 +4,13 @@
4
4
  require 'pathname'
5
5
  require 'simplecov' if ENV['COVERAGE']
6
6
  require 'rspec'
7
+ require 'deprecatable'
7
8
  require 'loggability/spechelpers'
8
9
 
9
10
  require 'chione'
10
11
 
12
+ Deprecatable.options.alert_frequency = :never
13
+ Deprecatable.options.has_at_exit_report = false
11
14
 
12
15
  module Chione::TestHelpers
13
16
  end
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.2.0
4
+ version: 0.3.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-26 00:00:00.000000000 Z
38
+ date: 2017-05-31 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: loggability
@@ -93,6 +93,20 @@ dependencies:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
95
  version: '2.3'
96
+ - !ruby/object:Gem::Dependency
97
+ name: deprecatable
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1.0'
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.0'
96
110
  - !ruby/object:Gem::Dependency
97
111
  name: hoe-mercurial
98
112
  requirement: !ruby/object:Gem::Requirement
@@ -218,6 +232,7 @@ files:
218
232
  - README.md
219
233
  - Rakefile
220
234
  - lib/chione.rb
235
+ - lib/chione/archetype.rb
221
236
  - lib/chione/aspect.rb
222
237
  - lib/chione/assemblage.rb
223
238
  - lib/chione/behaviors.rb
@@ -227,8 +242,8 @@ files:
227
242
  - lib/chione/mixins.rb
228
243
  - lib/chione/system.rb
229
244
  - lib/chione/world.rb
245
+ - spec/chione/archetype_spec.rb
230
246
  - spec/chione/aspect_spec.rb
231
- - spec/chione/assemblage_spec.rb
232
247
  - spec/chione/component_spec.rb
233
248
  - spec/chione/entity_spec.rb
234
249
  - spec/chione/manager_spec.rb
@@ -259,7 +274,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
259
274
  version: '0'
260
275
  requirements: []
261
276
  rubyforge_project:
262
- rubygems_version: 2.6.12
277
+ rubygems_version: 2.6.11
263
278
  signing_key:
264
279
  specification_version: 4
265
280
  summary: An Entity/Component System framework inspired by Artemis
metadata.gz.sig CHANGED
Binary file
@@ -1,60 +0,0 @@
1
- #!/usr/bin/env rspec -cfd
2
-
3
- require_relative '../spec_helper'
4
-
5
- require 'chione/assemblage'
6
- require 'chione/component'
7
- require 'chione/entity'
8
- require 'chione/world'
9
-
10
- describe Chione::Assemblage do
11
-
12
- let( :world ) { Chione::World.new }
13
-
14
- let( :location_component ) do
15
- Class.new( Chione::Component ) do
16
- field :x, default: 0
17
- field :y, default: 0
18
- end
19
- end
20
-
21
- let( :tags_component ) do
22
- Class.new( Chione::Component ) do
23
- field :tags, default: []
24
- end
25
- end
26
-
27
-
28
- it "acts as a factory for entities with pre-set components" do
29
- assemblage = Module.new
30
- assemblage.extend( described_class )
31
- assemblage.add( location_component, x: 10, y: 8 )
32
- assemblage.add( tags_component, tags: [:foo, :bar] )
33
-
34
- entity = assemblage.construct_for( world )
35
-
36
- expect( entity ).to be_a( Chione::Entity )
37
- expect( entity.world ).to be( world )
38
- expect( entity.components ).to include( location_component, tags_component )
39
- end
40
-
41
-
42
- it "can include other assemblages" do
43
- general_assemblage = Module.new
44
- general_assemblage.extend( described_class )
45
- general_assemblage.add( location_component, x: 10, y: 8 )
46
-
47
- specific_assemblage = Module.new
48
- specific_assemblage.extend( described_class )
49
- specific_assemblage.send( :include, general_assemblage )
50
- specific_assemblage.add( tags_component, tags: [:foo, :bar] )
51
-
52
- entity = specific_assemblage.construct_for( world )
53
-
54
- expect( entity ).to be_a( Chione::Entity )
55
- expect( entity.world ).to be( world )
56
- expect( entity.components ).to include( location_component, tags_component )
57
- end
58
-
59
- end
60
-