shattered_support 0.3.2 → 0.3.3
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/lib/shattered_support/core_ext/class/attribute_accessors.rb +44 -0
- data/lib/shattered_support/core_ext/class/inheritable_attributes.rb +115 -0
- data/lib/shattered_support/core_ext/class/removal.rb +24 -0
- data/lib/shattered_support/core_ext/class.rb +3 -0
- data/lib/shattered_support/core_ext/dir/search.rb +25 -0
- data/lib/shattered_support/core_ext/dir.rb +5 -0
- data/lib/shattered_support/core_ext/file/search.rb +50 -0
- data/lib/shattered_support/core_ext/file.rb +5 -0
- data/lib/shattered_support/core_ext/numeric/time.rb +72 -0
- data/lib/shattered_support/core_ext/numeric.rb +5 -0
- data/lib/shattered_support/core_ext/string/access.rb +58 -0
- data/lib/shattered_support/core_ext/string/conversions.rb +19 -0
- data/lib/shattered_support/core_ext/string/inflections.rb +64 -0
- data/lib/shattered_support/core_ext/string/iterators.rb +17 -0
- data/lib/shattered_support/core_ext/string/starts_ends_with.rb +20 -0
- data/lib/shattered_support/core_ext/string.rb +13 -0
- data/lib/shattered_support/core_ext.rb +1 -0
- data/lib/shattered_support/inflections.rb +53 -0
- data/lib/shattered_support/inflector.rb +178 -0
- data/lib/shattered_support.rb +2 -64
- metadata +38 -16
- data/lib/base.rb +0 -221
- data/lib/runner.rb +0 -11
- data/lib/timer/timed_event.rb +0 -77
- data/lib/timer/timer.rb +0 -67
- data/lib/vector.rb +0 -206
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
# The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without,
|
4
|
+
# and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept
|
5
|
+
# in inflections.rb.
|
6
|
+
module Inflector
|
7
|
+
# A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
|
8
|
+
# inflection rules. Examples:
|
9
|
+
#
|
10
|
+
# Inflector.inflections do |inflect|
|
11
|
+
# inflect.plural /^(ox)$/i, '\1\2en'
|
12
|
+
# inflect.singular /^(ox)en/i, '\1'
|
13
|
+
#
|
14
|
+
# inflect.irregular 'octopus', 'octopi'
|
15
|
+
#
|
16
|
+
# inflect.uncountable "equipment"
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
|
20
|
+
# pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
|
21
|
+
# already have been loaded.
|
22
|
+
class Inflections
|
23
|
+
include Singleton
|
24
|
+
|
25
|
+
attr_reader :plurals, :singulars, :uncountables
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
@plurals, @singulars, @uncountables = [], [], []
|
29
|
+
end
|
30
|
+
|
31
|
+
# Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
|
32
|
+
# The replacement should always be a string that may include references to the matched data from the rule.
|
33
|
+
def plural(rule, replacement)
|
34
|
+
@plurals.insert(0, [rule, replacement])
|
35
|
+
end
|
36
|
+
|
37
|
+
# Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
|
38
|
+
# The replacement should always be a string that may include references to the matched data from the rule.
|
39
|
+
def singular(rule, replacement)
|
40
|
+
@singulars.insert(0, [rule, replacement])
|
41
|
+
end
|
42
|
+
|
43
|
+
# Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
|
44
|
+
# for strings, not regular expressions. You simply pass the irregular in singular and plural form.
|
45
|
+
#
|
46
|
+
# Examples:
|
47
|
+
# irregular 'octopus', 'octopi'
|
48
|
+
# irregular 'person', 'people'
|
49
|
+
def irregular(singular, plural)
|
50
|
+
plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
|
51
|
+
singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
|
52
|
+
end
|
53
|
+
|
54
|
+
# Add uncountable words that shouldn't be attempted inflected.
|
55
|
+
#
|
56
|
+
# Examples:
|
57
|
+
# uncountable "money"
|
58
|
+
# uncountable "money", "information"
|
59
|
+
# uncountable %w( money information rice )
|
60
|
+
def uncountable(*words)
|
61
|
+
(@uncountables << words).flatten!
|
62
|
+
end
|
63
|
+
|
64
|
+
# Clears the loaded inflections within a given scope (default is :all). Give the scope as a symbol of the inflection type,
|
65
|
+
# the options are: :plurals, :singulars, :uncountables
|
66
|
+
#
|
67
|
+
# Examples:
|
68
|
+
# clear :all
|
69
|
+
# clear :plurals
|
70
|
+
def clear(scope = :all)
|
71
|
+
case scope
|
72
|
+
when :all
|
73
|
+
@plurals, @singulars, @uncountables = [], [], []
|
74
|
+
else
|
75
|
+
instance_variable_set "@#{scope}", []
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
extend self
|
81
|
+
|
82
|
+
def inflections
|
83
|
+
if block_given?
|
84
|
+
yield Inflections.instance
|
85
|
+
else
|
86
|
+
Inflections.instance
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def pluralize(word)
|
91
|
+
result = word.to_s.dup
|
92
|
+
|
93
|
+
if inflections.uncountables.include?(result.downcase)
|
94
|
+
result
|
95
|
+
else
|
96
|
+
inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
|
97
|
+
result
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def singularize(word)
|
102
|
+
result = word.to_s.dup
|
103
|
+
|
104
|
+
if inflections.uncountables.include?(result.downcase)
|
105
|
+
result
|
106
|
+
else
|
107
|
+
inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
|
108
|
+
result
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
113
|
+
if first_letter_in_uppercase
|
114
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
115
|
+
else
|
116
|
+
lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def titleize(word)
|
121
|
+
humanize(underscore(word)).gsub(/\b([a-z])/) { $1.capitalize }
|
122
|
+
end
|
123
|
+
|
124
|
+
def underscore(camel_cased_word)
|
125
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
126
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
127
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
128
|
+
tr("-", "_").
|
129
|
+
downcase
|
130
|
+
end
|
131
|
+
|
132
|
+
def dasherize(underscored_word)
|
133
|
+
underscored_word.gsub(/_/, '-')
|
134
|
+
end
|
135
|
+
|
136
|
+
def humanize(lower_case_and_underscored_word)
|
137
|
+
lower_case_and_underscored_word.to_s.gsub(/_id$/, "").gsub(/_/, " ").capitalize
|
138
|
+
end
|
139
|
+
|
140
|
+
def demodulize(class_name_in_module)
|
141
|
+
class_name_in_module.to_s.gsub(/^.*::/, '')
|
142
|
+
end
|
143
|
+
|
144
|
+
def tableize(class_name)
|
145
|
+
pluralize(underscore(class_name))
|
146
|
+
end
|
147
|
+
|
148
|
+
def classify(table_name)
|
149
|
+
camelize(singularize(table_name))
|
150
|
+
end
|
151
|
+
|
152
|
+
def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
|
153
|
+
underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
|
154
|
+
end
|
155
|
+
|
156
|
+
def constantize(camel_cased_word)
|
157
|
+
raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!" unless
|
158
|
+
/^(::)?([A-Z]\w*)(::[A-Z]\w*)*$/ =~ camel_cased_word
|
159
|
+
|
160
|
+
camel_cased_word = "::#{camel_cased_word}" unless $1
|
161
|
+
Object.module_eval(camel_cased_word, __FILE__, __LINE__)
|
162
|
+
end
|
163
|
+
|
164
|
+
def ordinalize(number)
|
165
|
+
if (11..13).include?(number.to_i % 100)
|
166
|
+
"#{number}th"
|
167
|
+
else
|
168
|
+
case number.to_i % 10
|
169
|
+
when 1: "#{number}st"
|
170
|
+
when 2: "#{number}nd"
|
171
|
+
when 3: "#{number}rd"
|
172
|
+
else "#{number}th"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
require File.dirname(__FILE__) + '/inflections'
|
data/lib/shattered_support.rb
CHANGED
@@ -1,64 +1,2 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
class Object
|
4
|
-
def method_defined?(method)
|
5
|
-
return self.class.method_defined?(method)
|
6
|
-
end
|
7
|
-
|
8
|
-
# This is a shorthand to define vector object coordinates.
|
9
|
-
#
|
10
|
-
# Creates a vector object at coordinates x,y,z
|
11
|
-
def v(x, y, z)
|
12
|
-
Vector.new(x, y, z)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class File #:nodoc:
|
17
|
-
# File.each_in_path will recursively look for all files, starting at the given path.
|
18
|
-
# It will yield with each result.
|
19
|
-
def self.each_in_path(path)
|
20
|
-
Dir.each_in_path(path) do |directory|
|
21
|
-
Dir.foreach( directory ) do |filename|
|
22
|
-
resource = directory + "/#{filename}"
|
23
|
-
yield(resource) if File.file? resource
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
# This finds all files in paths (an array or string) matching the given extensions:
|
29
|
-
#
|
30
|
-
# Usage:
|
31
|
-
# -File.find_by_extensions(SHATTERED_ROOT,"ogg","mp3","wav")
|
32
|
-
# -File.find_by_extension(["apps","media","plugins"], "rmaterial")
|
33
|
-
def self.find_by_extensions(paths, *extensions)
|
34
|
-
paths = [paths] if paths.is_a? String
|
35
|
-
extensions.collect! { |ext| ext[0].chr == "." ? ext[1..-1] : ext } # get rid of "." in ".ogg"
|
36
|
-
reg_exp = /\.(#{extensions.join("|")})$/
|
37
|
-
files = []
|
38
|
-
paths.each do |path|
|
39
|
-
each_in_path(path) do |filename|
|
40
|
-
files << filename if filename =~ reg_exp
|
41
|
-
end
|
42
|
-
end
|
43
|
-
return files
|
44
|
-
end
|
45
|
-
# See File#find_by_extensions
|
46
|
-
def self.find_by_extension(paths, extension)
|
47
|
-
find_by_extensions(paths, extension)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
class Dir #:nodoc:
|
52
|
-
# Dir.each_in_path will recursively yield all non-hidden directories from the given path.
|
53
|
-
def self.each_in_path(path, &block)
|
54
|
-
return unless File.directory? path
|
55
|
-
yield path
|
56
|
-
foreach(path) do |directory|
|
57
|
-
next if directory =~ /\..*/
|
58
|
-
each_in_path("#{path}/#{directory}", &block)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
require File.dirname(__FILE__)+"/base"
|
64
|
-
require File.dirname(__FILE__)+"/runner"
|
1
|
+
require 'shattered_support/core_ext'
|
2
|
+
require 'shattered_support/inflector'
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.8.
|
2
|
+
rubygems_version: 0.8.11
|
3
3
|
specification_version: 1
|
4
4
|
name: shattered_support
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.3.
|
7
|
-
date: 2006-06
|
6
|
+
version: 0.3.3
|
7
|
+
date: 2006-07-18 00:00:00 -06:00
|
8
8
|
summary: "Shattered Support: Allows a common derivation point for shattered MVC."
|
9
9
|
require_paths:
|
10
|
-
|
10
|
+
- lib
|
11
11
|
email:
|
12
12
|
homepage: http://www.hastilymade.com
|
13
13
|
rubyforge_project:
|
@@ -18,25 +18,47 @@ bindir: bin
|
|
18
18
|
has_rdoc: "true"
|
19
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
20
|
requirements:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
version: 0.0.0
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
25
24
|
version:
|
26
25
|
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
27
28
|
authors: []
|
29
|
+
|
28
30
|
files:
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
- lib/shattered_support.rb
|
32
|
+
- lib/shattered_support/core_ext.rb
|
33
|
+
- lib/shattered_support/inflections.rb
|
34
|
+
- lib/shattered_support/inflector.rb
|
35
|
+
- lib/shattered_support/core_ext/class.rb
|
36
|
+
- lib/shattered_support/core_ext/dir.rb
|
37
|
+
- lib/shattered_support/core_ext/file.rb
|
38
|
+
- lib/shattered_support/core_ext/numeric.rb
|
39
|
+
- lib/shattered_support/core_ext/string.rb
|
40
|
+
- lib/shattered_support/core_ext/class/attribute_accessors.rb
|
41
|
+
- lib/shattered_support/core_ext/class/inheritable_attributes.rb
|
42
|
+
- lib/shattered_support/core_ext/class/removal.rb
|
43
|
+
- lib/shattered_support/core_ext/dir/search.rb
|
44
|
+
- lib/shattered_support/core_ext/file/search.rb
|
45
|
+
- lib/shattered_support/core_ext/numeric/time.rb
|
46
|
+
- lib/shattered_support/core_ext/string/access.rb
|
47
|
+
- lib/shattered_support/core_ext/string/conversions.rb
|
48
|
+
- lib/shattered_support/core_ext/string/inflections.rb
|
49
|
+
- lib/shattered_support/core_ext/string/iterators.rb
|
50
|
+
- lib/shattered_support/core_ext/string/starts_ends_with.rb
|
35
51
|
test_files: []
|
52
|
+
|
36
53
|
rdoc_options: []
|
54
|
+
|
37
55
|
extra_rdoc_files: []
|
56
|
+
|
38
57
|
executables: []
|
58
|
+
|
39
59
|
extensions: []
|
60
|
+
|
40
61
|
requirements:
|
41
|
-
|
42
|
-
dependencies: []
|
62
|
+
- Shattered Support is a base for the rest of shattered.
|
63
|
+
dependencies: []
|
64
|
+
|
data/lib/base.rb
DELETED
@@ -1,221 +0,0 @@
|
|
1
|
-
|
2
|
-
$:.unshift(File.dirname(__FILE__)) unless
|
3
|
-
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
4
|
-
|
5
|
-
require 'active_support'
|
6
|
-
require 'timer/timer'
|
7
|
-
require 'vector'
|
8
|
-
|
9
|
-
module ShatteredSupport #:nodoc:
|
10
|
-
|
11
|
-
BEFORE_INIT_CALL_VALUES = :before_init_call_values
|
12
|
-
BEFORE_INIT_SET_VALUES = :before_init_set_values
|
13
|
-
|
14
|
-
|
15
|
-
def self.append_features(base)
|
16
|
-
super
|
17
|
-
base.extend(ClassMethods)
|
18
|
-
end
|
19
|
-
module ClassMethods
|
20
|
-
# In the pre_initialization phase (see #before_init_call), send an object a bunch of sets.
|
21
|
-
#
|
22
|
-
# This is used in actor, camera, mesh, and virtually everywhere to support the format of:
|
23
|
-
# mesh "ruby", :position => v(1,0,0)
|
24
|
-
#
|
25
|
-
# becomes
|
26
|
-
# before_init_set( :ruby, {:position => v(1,0,0) } )
|
27
|
-
# becomes
|
28
|
-
# ruby.position=v(1,0,0)
|
29
|
-
# when the obect is initialized.
|
30
|
-
def before_init_set(variable, options={})
|
31
|
-
self.write_inheritable_array(BEFORE_INIT_SET_VALUES, [[ variable, options ]] )
|
32
|
-
end
|
33
|
-
|
34
|
-
# All shattered objects have a pre_initialization phase. Use this to specify that
|
35
|
-
# a function should be called when the object is created.
|
36
|
-
#
|
37
|
-
# _Example_:
|
38
|
-
# class BulletModel < ShatteredModel::Base
|
39
|
-
# before_init_call(:calculate_trajectory, v(0,0,0), v(0,0,1))
|
40
|
-
# def calculate_trajectory
|
41
|
-
# #called before initialize is
|
42
|
-
# end
|
43
|
-
# end
|
44
|
-
#
|
45
|
-
def before_init_call(function, *arguments)
|
46
|
-
self.write_inheritable_array(BEFORE_INIT_CALL_VALUES, [[function, [*arguments]]])
|
47
|
-
end
|
48
|
-
end
|
49
|
-
class Base
|
50
|
-
|
51
|
-
# This is overwritten to allow for a pre_initialize before initialize
|
52
|
-
def self.new(*options) #:nodoc
|
53
|
-
new_base = allocate
|
54
|
-
new_base.pre_initialize
|
55
|
-
new_base.send(:initialize, *options)
|
56
|
-
return new_base
|
57
|
-
end
|
58
|
-
|
59
|
-
# Retrieve the current state
|
60
|
-
def state
|
61
|
-
Configuration.environment[:state]
|
62
|
-
end
|
63
|
-
|
64
|
-
# This function is called after an object is allocated, but before it's initialized.
|
65
|
-
#
|
66
|
-
# See ShatteredSupport::ClassMethods#before_init_call for usage.
|
67
|
-
def pre_initialize #:nodoc:
|
68
|
-
pre_initialize_set
|
69
|
-
pre_initialize_call
|
70
|
-
end
|
71
|
-
|
72
|
-
# Used in pre_initialize
|
73
|
-
def each_init_value(name) #:nodoc:
|
74
|
-
startup_attributes = self.class.read_inheritable_attribute( name ) || []
|
75
|
-
startup_attributes.each do |actor, options|
|
76
|
-
next if options.nil?
|
77
|
-
yield actor, options
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
# Used in pre_initialize for before_init_set
|
82
|
-
def pre_initialize_set #:nodoc:
|
83
|
-
each_init_value(BEFORE_INIT_SET_VALUES) do |variable, options|
|
84
|
-
call_object_function_for_each_key( variable, options )
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
# Used in pre_initialize for before_init_call
|
89
|
-
def pre_initialize_call #:nodoc:
|
90
|
-
each_init_value(BEFORE_INIT_CALL_VALUES) do |function, args|
|
91
|
-
call_object_function( :self, function, args )
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
|
96
|
-
# TODO - is this called anymore?
|
97
|
-
def update_event(time_elapsed) #:nodoc:
|
98
|
-
actors.each do |actor|
|
99
|
-
actor.update_actors(time_elapsed)
|
100
|
-
actor.update(time_elapsed)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
# remove_from_scene? should just be defined in model.
|
105
|
-
# Refactor? TODO
|
106
|
-
def remove_from_scene? #:nodoc:
|
107
|
-
return false
|
108
|
-
end
|
109
|
-
|
110
|
-
# TODO outdated?
|
111
|
-
def update_actors(time_elapsed) #:nodoc:
|
112
|
-
update_event time_elapsed
|
113
|
-
remove_dead_actors
|
114
|
-
end
|
115
|
-
|
116
|
-
# TODO outdated?
|
117
|
-
def remove_dead_actors #:nodoc:
|
118
|
-
actors.each do |actor|
|
119
|
-
remove_from_scene actor if actor.remove_from_scene?
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
# TODO outdated?
|
124
|
-
def remove_from_scene(actor)
|
125
|
-
actors.delete actor
|
126
|
-
actor.unload!
|
127
|
-
end
|
128
|
-
|
129
|
-
protected
|
130
|
-
def call_object_function_for_each_key( actor, options )
|
131
|
-
call_object_function(actor, :position=, options.delete(:position)) if options.has_key? :position
|
132
|
-
options.each_pair do |action, params|
|
133
|
-
call_object_function actor, "#{action}=", params
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def call_object_function(actor, action, params)
|
138
|
-
begin
|
139
|
-
if params.is_a? Symbol #|| (params.length == 1 && params[0].is_a?(Symbol)) this will allow substitution in before_init_call. This may not be intended behavior.
|
140
|
-
params = eval(params.to_s)
|
141
|
-
end
|
142
|
-
rescue NameError
|
143
|
-
puts "It is not advisable to pass #{params.inspect} to #{action.inspect} for #{actor.inspect}."
|
144
|
-
puts " It will try to be evaluated. Use a string instead."
|
145
|
-
end
|
146
|
-
begin
|
147
|
-
sendee = eval(actor.to_s)
|
148
|
-
sendee.send( action.to_sym, *params )
|
149
|
-
rescue NoMethodError, ArgumentError => bang
|
150
|
-
message="Error upon #{actor.to_s}.send(#{action.to_sym.inspect}, #{params.inspect}):\n\r #{bang.class}: #{bang.message}"
|
151
|
-
bang = ShatteredSupport::RetossError.new(bang,message)
|
152
|
-
raise bang
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
public
|
157
|
-
|
158
|
-
# attr helpers. These are instance level attr_* functions.
|
159
|
-
def attr_reader(*args)
|
160
|
-
name, value = args
|
161
|
-
attr_define(:reader, name, value)
|
162
|
-
end
|
163
|
-
|
164
|
-
# attr helpers. These are instance level attr_* functions.
|
165
|
-
# attr_writer accepts a value as the second argument
|
166
|
-
def attr_writer(*args)
|
167
|
-
name, value = args
|
168
|
-
attr_define(:writer, name, value)
|
169
|
-
end
|
170
|
-
|
171
|
-
# attr helpers. These are instance level attr_* functions.
|
172
|
-
# attr_accessor accepts a value as the second argument
|
173
|
-
def attr_accessor(*args)
|
174
|
-
name, value = args
|
175
|
-
attr_define(:accessor, name, value)
|
176
|
-
end
|
177
|
-
|
178
|
-
# Define a block to execute when an object is unloaded.
|
179
|
-
def when_unloaded(&block)
|
180
|
-
@unloaded_events ||= []
|
181
|
-
@unloaded_events << block
|
182
|
-
end
|
183
|
-
|
184
|
-
protected
|
185
|
-
|
186
|
-
def attr_define(accessor_level, name, value)
|
187
|
-
self.class.send("attr_#{accessor_level}".to_sym, "#{name}".to_sym)
|
188
|
-
instance_variable_set("@#{name}".to_sym, value) if !value.nil?
|
189
|
-
end
|
190
|
-
|
191
|
-
private
|
192
|
-
|
193
|
-
def disabled?
|
194
|
-
@unloaded_events == nil
|
195
|
-
end
|
196
|
-
|
197
|
-
def unload!
|
198
|
-
return if disabled?
|
199
|
-
@unloaded_events.each do |event|
|
200
|
-
event.call
|
201
|
-
end
|
202
|
-
@unloaded_events = nil
|
203
|
-
end
|
204
|
-
|
205
|
-
end
|
206
|
-
|
207
|
-
class Error < StandardError # :nodoc:
|
208
|
-
end
|
209
|
-
|
210
|
-
class RetossError < StandardError # :nodoc:
|
211
|
-
attr_accessor :message
|
212
|
-
def initialize(error, message)
|
213
|
-
self.message = message
|
214
|
-
set_backtrace error.backtrace
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
ShatteredSupport::Base.class_eval do
|
220
|
-
include ShatteredSupport::Timer
|
221
|
-
end
|
data/lib/runner.rb
DELETED
data/lib/timer/timed_event.rb
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
module ShatteredSupport
|
2
|
-
module Timer #:nodoc:all
|
3
|
-
|
4
|
-
class Timer
|
5
|
-
attr_reader :events_remaining
|
6
|
-
def initialize
|
7
|
-
@events_remaining = []
|
8
|
-
end
|
9
|
-
def in(seconds, &block)
|
10
|
-
@events_remaining << TimedEvent.new(seconds, &block)
|
11
|
-
end
|
12
|
-
def every(seconds, &block)
|
13
|
-
@events_remaining << ContinuousTimedEvent.new(seconds,&block)
|
14
|
-
end
|
15
|
-
def update(time_elapsed)
|
16
|
-
events_for_update = @events_remaining.dup
|
17
|
-
events_for_update.each do |event|
|
18
|
-
event.update(time_elapsed)
|
19
|
-
@events_remaining.delete(event) if event.processed?
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class TimedEvent
|
25
|
-
attr_accessor :time_remaining
|
26
|
-
def initialize(seconds, &block)
|
27
|
-
@event = block
|
28
|
-
if(seconds != :frame)
|
29
|
-
@time_remaining = seconds
|
30
|
-
@initial_time = @time_remaining
|
31
|
-
else
|
32
|
-
@time_remaining = 0
|
33
|
-
@initial_time = 0
|
34
|
-
end
|
35
|
-
end
|
36
|
-
def update(time_elapsed)
|
37
|
-
return if processed?
|
38
|
-
@time_remaining -= time_elapsed
|
39
|
-
if time_up?
|
40
|
-
process_event
|
41
|
-
@processed=true
|
42
|
-
end
|
43
|
-
end
|
44
|
-
def processed?
|
45
|
-
return @processed == true
|
46
|
-
end
|
47
|
-
def reset
|
48
|
-
@time_remaining = @initial_time
|
49
|
-
end
|
50
|
-
private
|
51
|
-
def process_event
|
52
|
-
@event.call(@initial_time - @time_remaining)
|
53
|
-
end
|
54
|
-
def time_up?
|
55
|
-
return @time_remaining <= 0
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
class ContinuousTimedEvent < TimedEvent
|
60
|
-
def update(time_elapsed)
|
61
|
-
@time_remaining -= time_elapsed
|
62
|
-
if(time_up?)
|
63
|
-
process_event
|
64
|
-
reset
|
65
|
-
end
|
66
|
-
end
|
67
|
-
def reset
|
68
|
-
@time_remaining += @initial_time
|
69
|
-
@time_remaining = 0 if @time_remaining < 0
|
70
|
-
end
|
71
|
-
def processed?
|
72
|
-
false
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
end
|
77
|
-
end
|
data/lib/timer/timer.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__)+'/timed_event'
|
2
|
-
|
3
|
-
module ShatteredSupport
|
4
|
-
module Timer #:nodoc:
|
5
|
-
def self.append_features(base)
|
6
|
-
super
|
7
|
-
base.extend(ClassMethods)
|
8
|
-
base.send(:include, InstanceMethods)
|
9
|
-
end
|
10
|
-
module ClassMethods
|
11
|
-
# Timers are controller events that occur after a specified period of time.
|
12
|
-
# The time values are seconds by default.
|
13
|
-
#
|
14
|
-
# timer :in
|
15
|
-
# If you want an event to occur once after a specified amount of time, use
|
16
|
-
# timer :in => 3.seconds, :action => :method_to_call
|
17
|
-
#
|
18
|
-
# timer :every
|
19
|
-
# If you want an event to occur once every specified amount of time, use
|
20
|
-
# timer :every => 3.seconds, :action => :method_to_call
|
21
|
-
# If you want to be notified of every frame update, use
|
22
|
-
# timer :every => :frame, :action => :method_to_call
|
23
|
-
#
|
24
|
-
# Inside the instance, you can still create timer events, using the timer object:
|
25
|
-
# timer.in( 3.seconds ) { ... }
|
26
|
-
# timer.every( 3.seconds ) { ... }
|
27
|
-
def timer(options = {})
|
28
|
-
if options[:action].nil?
|
29
|
-
throw ShatteredSupport::Error,
|
30
|
-
"Timer event must specify an :action => :method"
|
31
|
-
end
|
32
|
-
if options[:in].nil? && options[:every].nil?
|
33
|
-
throw ShatteredSupport::Error,
|
34
|
-
"Timer event must specify a time. (timer :in or timer :every)"
|
35
|
-
end
|
36
|
-
time = options[:in] || options[:every]
|
37
|
-
action = options[:action]
|
38
|
-
before_init_call(:timer_in, time, action) unless options[:in].nil?
|
39
|
-
before_init_call(:timer_every, time, action) unless options[:every].nil?
|
40
|
-
end
|
41
|
-
end
|
42
|
-
module InstanceMethods
|
43
|
-
def timer
|
44
|
-
@timer ||= Timer.new
|
45
|
-
end
|
46
|
-
private
|
47
|
-
def timer_in(time, action)
|
48
|
-
timer.in(time) do |time_elapsed|
|
49
|
-
timer_enactment(action, time_elapsed)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
def timer_every(time, action)
|
53
|
-
timer.every(time) do |time_elapsed|
|
54
|
-
timer_enactment(action, time_elapsed)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
def timer_enactment(action, time_elapsed)
|
58
|
-
begin
|
59
|
-
send(action.to_sym)
|
60
|
-
rescue ArgumentError => argument_error
|
61
|
-
raise argument_error unless argument_error.message.to_sym == :"wrong number of arguments (0 for 1)"
|
62
|
-
send(action.to_sym,time_elapsed)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|