peregrine 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,9 @@
1
1
  # Peregrine
2
+ [![Build Status](https://travis-ci.org/solucet/peregrine.png?branch=master)][travis]
3
+ [![Coverage Status](https://coveralls.io/repos/solucet/peregrine/badge.png)][coverage]
4
+ [![Gem Version](https://badge.fury.io/rb/peregrine.png)][gem]
5
+ [![Documentation](http://b.repl.ca/v1/yard-docs-blue.png)][yard]
6
+
2
7
  1. _adjective: foreign; alien; wandering, traveling, or migrating._
3
8
  2. _noun: a kick-ass falcon._
4
9
 
@@ -21,7 +26,7 @@ $ cd peregrine/ && bundle
21
26
  ```
22
27
 
23
28
  ## Documentation
24
- The framework has been heavily documented with information and should serve you well. If you installed Peregrine from the GitHub repository and installed the development dependencies, you can generate a local copy of its RDoc documentation by running `rake rdoc`.
29
+ The framework has been heavily documented with information and should serve you well. If you installed Peregrine from the GitHub repository and installed the development dependencies, you can generate a local copy of its RDoc documentation by running `rake rdoc`. The documentation is also available [online from RubyDoc][yard].
25
30
 
26
31
  If you are unfamiliar with Entity-Component design, it is highly recommended that you read about it in addition to reading the documentation for the Peregrine framework. Chris Powell wrote a [great series of tutorials][recf-tutorial] on using EC design in JRuby on his blog which also includes links to further reading on the subject.
27
32
 
@@ -31,6 +36,11 @@ Special thanks go to Chris Powell, as the Peregrine framework was conceptually i
31
36
  ## License
32
37
  Peregrine is made available under the terms of the MIT License. See the included LICENSE file for more information.
33
38
 
39
+
40
+ [coverage]: https://coveralls.io/r/solucet/peregrine
41
+ [gem]: http://badge.fury.io/rb/peregrine
34
42
  [peregrine]: https://github.com/solucet/peregrine
35
43
  [recf]: https://github.com/cpowell/ruby-entity-component-framework
36
- [recf-tutorial]: http://cbpowell.wordpress.com/2012/10/30/
44
+ [recf-tutorial]: http://cbpowell.wordpress.com/2012/10/30/
45
+ [travis]: https://travis-ci.org/solucet/peregrine
46
+ [yard]: http://rubydoc.info/gems/peregrine/frames
@@ -154,6 +154,18 @@ module Peregrine
154
154
  removed.extend(Collections::Common, Collections::Systemic)
155
155
  end
156
156
 
157
+ # Unwraps the given Package, adding any included System and Entity instances
158
+ # directly to the EntityManager. Returns +true+ if the package was unwrapped
159
+ # successfully, +false+ otherwise.
160
+ def add_package(package)
161
+ return false unless package.respond_to?(:unwrap)
162
+ package.unwrap.each do |item|
163
+ add_system(item) if item.kind_of?(Peregrine::System)
164
+ add_entity(item) if item.kind_of?(Peregrine::Entity)
165
+ end
166
+ true
167
+ end
168
+
157
169
  # Presents a human-readable summary of the EntityManager.
158
170
  def to_s
159
171
  "Entity Manager '#{name}' #{id} " <<
@@ -0,0 +1,6 @@
1
+ # Require all Ruby files in the 'handlers/' directory. Using +File.join+ to
2
+ # ensure that all files are properly required regardless of the directory
3
+ # separator in use.
4
+ Dir[File.join(File.dirname(__FILE__), 'handlers', '*.rb')].each do |file|
5
+ require file
6
+ end
@@ -0,0 +1,34 @@
1
+ module Peregrine
2
+ module Handlers
3
+ # This module provides methods which allow Component objects to be wrapped
4
+ # and unwrapped for use by an instance of the Package class.
5
+ module ComponentPackage
6
+ # Returns +true+ if this package handler can +wrap+ and +unwrap+ the given
7
+ # object, +false+ otherwise.
8
+ def self.handles?(object)
9
+ if object.class == Class
10
+ object.ancestors.include?(Peregrine::Component)
11
+ else
12
+ object.kind_of?(Peregrine::Component)
13
+ end
14
+ end
15
+
16
+ # Wraps the given Component into a generic hash.
17
+ def self.wrap(component)
18
+ return nil unless handles?(component)
19
+ { :name => component.name,
20
+ :tags => component.tags,
21
+ :type => component.class }
22
+ end
23
+
24
+ # Unwraps a generic hash into a newly instanced Component.
25
+ def self.unwrap(hash)
26
+ return nil unless handles?(hash[:type])
27
+ hash[:type].new do |component|
28
+ component.name = hash[:name]
29
+ component.add_tags(*hash[:tags])
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,35 @@
1
+ module Peregrine
2
+ module Handlers
3
+ # This module provides methods which allow Entity objects to be wrapped and
4
+ # unwrapped for use by an instance of the Package class.
5
+ module EntityPackage
6
+ # Returns +true+ if this package handler can +wrap+ and +unwrap+ the given
7
+ # object, +false+ otherwise.
8
+ def self.handles?(object)
9
+ if object.class == Class
10
+ object.ancestors.include?(Peregrine::Entity)
11
+ else
12
+ object.kind_of?(Peregrine::Entity)
13
+ end
14
+ end
15
+
16
+ # Wraps the given Entity into a generic hash.
17
+ def self.wrap(entity)
18
+ return nil unless handles?(entity)
19
+ { :data => entity.components,
20
+ :name => entity.name,
21
+ :tags => entity.tags,
22
+ :type => entity.class }
23
+ end
24
+
25
+ # Unwraps a generic hash into a newly instanced Entity.
26
+ def self.unwrap(hash)
27
+ return nil unless handles?(hash[:type])
28
+ hash[:type].new(*hash[:data]) do |entity|
29
+ entity.name = hash[:name]
30
+ entity.add_tags(*hash[:tags])
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,36 @@
1
+ module Peregrine
2
+ module Handlers
3
+ # This module provides methods which allow System objects to be wrapped and
4
+ # unwrapped for use by an instance of the Package class.
5
+ module SystemPackage
6
+ # Returns +true+ if this package handler can +wrap+ and +unwrap+ the given
7
+ # object, +false+ otherwise.
8
+ def self.handles?(object)
9
+ if object.class == Class
10
+ object.ancestors.include?(Peregrine::System)
11
+ else
12
+ object.kind_of?(Peregrine::System)
13
+ end
14
+ end
15
+
16
+ # Wraps the given System into a generic hash.
17
+ def self.wrap(system)
18
+ return nil unless handles?(system)
19
+ { :name => system.name,
20
+ :status => system.enabled?,
21
+ :tags => system.tags,
22
+ :type => system.class }
23
+ end
24
+
25
+ # Unwraps a generic hash into a newly instanced System.
26
+ def self.unwrap(hash)
27
+ return nil unless handles?(hash[:type])
28
+ hash[:type].new do |system|
29
+ system.name = hash[:name]
30
+ system.disable unless hash[:status]
31
+ system.add_tags(*hash[:tags])
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,97 @@
1
+ require 'peregrine/features'
2
+ require 'peregrine/handlers'
3
+
4
+ module Peregrine
5
+ # == Summary
6
+ #
7
+ # A Package is essentially a fast and easy way to package multiple commonly
8
+ # used items into an archive that can quickly recreate new instances of those
9
+ # items. Packages are especially useful for grouping together Components and
10
+ # Entities, and can be used to create 'templates' for instantiating objects
11
+ # that will be used often.
12
+ #
13
+ # == Usage
14
+ #
15
+ # By default, a Package may contain items that are children of the Component,
16
+ # Entity, and System classes. A single Package may contain any combination of
17
+ # these items. Items are added to the Package with the +wrap+ method, while
18
+ # instantiation of wrapped items is performed with the +unwrap+ method. The
19
+ # +unwrap+ method returns an array of instantiated objects built from the
20
+ # Package's internal archive of object data.
21
+ #
22
+ # When used in conjunction with the EntityManager's +add_package+ method, the
23
+ # Package class truly shines.
24
+ #
25
+ # == Example
26
+ #
27
+ # Let's assume that we're building a role-playing game and need a common
28
+ # template for creating non-playable characters. That package may look
29
+ # something like this:
30
+ #
31
+ # include Peregrine
32
+ # template = Package.new { |pkg| pkg.name = 'NPC' }
33
+ # template.wrap(Entity.new(Renderable, Autonomous, Conversational) do |npc|
34
+ # npc.name = 'Generic NPC'
35
+ # npc.add_tags(:npc)
36
+ # end)
37
+ # template.unwrap # => [Entity 'Generic NPC' ... (3)]
38
+ #
39
+ # The newly instanced Entity generated from the package will have a different
40
+ # ID and UUID each time it is created, but will always have the same name,
41
+ # components, and tags.
42
+ class Package
43
+ include Peregrine::Features
44
+
45
+ # Array of objects used to build instances for the +unwrap+ method.
46
+ attr_reader :archive
47
+
48
+ # Array of package handling modules used to facilitate wrapping and
49
+ # unwrapping of objects.
50
+ attr_reader :handlers
51
+
52
+ # Creates a new Package instance and adds the given objects to the Package.
53
+ # Yields the newly created Package if a block is given.
54
+ def initialize(*objects)
55
+ @archive = []
56
+ @handlers = [ Peregrine::Handlers::ComponentPackage,
57
+ Peregrine::Handlers::EntityPackage,
58
+ Peregrine::Handlers::SystemPackage ]
59
+ wrap(*objects)
60
+ yield self if block_given?
61
+ end
62
+
63
+ # Wraps the given objects into the Package. Returns the array of archived
64
+ # objects in the Package.
65
+ def wrap(*objects)
66
+ objects.each do |object|
67
+ @handlers.each do |handler|
68
+ next unless handler.handles?(object)
69
+ item = handler.wrap(object)
70
+ @archive.push(item) unless item.nil?
71
+ end
72
+ end
73
+ @archive
74
+ end
75
+
76
+ # Unwraps all objects in the package into newly instanced objects. Returns
77
+ # the array of instanced objects. Yields each unwrapped item if a block is
78
+ # given.
79
+ def unwrap
80
+ unwrapped = []
81
+ @archive.each do |object|
82
+ @handlers.each do |handler|
83
+ item = handler.unwrap(object)
84
+ unwrapped.push(item) unless item.nil?
85
+ end
86
+ end
87
+ unwrapped.each { |item| yield item if block_given? }
88
+ unwrapped
89
+ end
90
+
91
+ # Presents a human-readable summary of the Package.
92
+ def to_s
93
+ "Package '#{name}' #{id} (#{@archive.size})"
94
+ end
95
+ alias :inspect :to_s
96
+ end
97
+ end
@@ -1,4 +1,4 @@
1
1
  module Peregrine
2
2
  # Semantic version of the Peregrine framework.
3
- VERSION = '0.1.1'
3
+ VERSION = '0.2.0'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: peregrine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-11 00:00:00.000000000 Z
12
+ date: 2014-02-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -81,6 +81,11 @@ files:
81
81
  - lib/peregrine/features/nameable.rb
82
82
  - lib/peregrine/features/taggable.rb
83
83
  - lib/peregrine/features.rb
84
+ - lib/peregrine/handlers/component_package.rb
85
+ - lib/peregrine/handlers/entity_package.rb
86
+ - lib/peregrine/handlers/system_package.rb
87
+ - lib/peregrine/handlers.rb
88
+ - lib/peregrine/package.rb
84
89
  - lib/peregrine/system.rb
85
90
  - lib/peregrine/version.rb
86
91
  - lib/peregrine.rb