peregrine 0.1.1 → 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.
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