chione 0.1.0 → 0.2.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.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +163 -1
- data/History.md +13 -0
- data/Rakefile +7 -4
- data/lib/chione.rb +1 -1
- data/lib/chione/assemblage.rb +6 -1
- data/lib/chione/component.rb +4 -0
- data/lib/chione/manager.rb +6 -1
- data/lib/chione/system.rb +9 -12
- data/lib/chione/world.rb +76 -15
- data/spec/chione/system_spec.rb +16 -25
- data/spec/chione/world_spec.rb +50 -19
- metadata +20 -6
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: e97a13cf34e52ecdafa6435e9f8a6a055b0491d8
|
|
4
|
+
data.tar.gz: c166e2cf474f7eadd82c8974ce30cdab06961e2e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f3d4d5d410fe1a8b41dd56f5ed5888d2e9a553c55a279857fb1759ce9e9b40c3e4b763aabaed899e04375b539b6143f1f526637d3db81e955a6f0d185c3b5644
|
|
7
|
+
data.tar.gz: de83ffeaefad492c73ca249f3af9ebfbb8d0371ec955a39c0f35938131be8fe95f4c140e3789404d88b147afb522ddcac1dcc19289c8c8ec404c5e71dcfdaa2e
|
checksums.yaml.gz.sig
CHANGED
|
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]
|
|
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
|
|
39
|
+
spec.dependency 'hoe-deveiate', '~> 1.0', :developer
|
|
39
40
|
spec.dependency 'simplecov', '~> 0.12', :developer
|
|
40
|
-
spec.dependency 'rdoc-generator-fivefish', '~> 0.
|
|
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.
|
|
78
|
+
rdoc.main = "README.md"
|
|
77
79
|
rdoc.markup = 'markdown'
|
|
78
|
-
rdoc.rdoc_files.include( "*.
|
|
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
|
data/lib/chione.rb
CHANGED
data/lib/chione/assemblage.rb
CHANGED
|
@@ -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 )
|
data/lib/chione/component.rb
CHANGED
|
@@ -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
|
data/lib/chione/manager.rb
CHANGED
|
@@ -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, * )
|
data/lib/chione/system.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
data/lib/chione/world.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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)
|
data/spec/chione/system_spec.rb
CHANGED
|
@@ -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)
|
|
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
|
|
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.
|
|
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 "
|
|
55
|
-
|
|
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
|
-
|
|
62
|
-
|
|
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
|
data/spec/chione/world_spec.rb
CHANGED
|
@@ -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
|
|
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.
|
|
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-
|
|
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.
|
|
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.
|
|
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: '
|
|
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: '
|
|
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
|