shattered_support 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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'
@@ -1,64 +1,2 @@
1
- require 'rubygems'
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.10
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.2
7
- date: 2006-06-04
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
- - lib
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
- - !ruby/object:Gem::Version
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
- - lib/base.rb
30
- - lib/runner.rb
31
- - lib/shattered_support.rb
32
- - lib/vector.rb
33
- - lib/timer/timed_event.rb
34
- - lib/timer/timer.rb
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
- - Shattered Support is a base for the rest of shattered.
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
@@ -1,11 +0,0 @@
1
- module ShatteredSupport
2
- class Configuration #:nodoc:
3
- def self.environment
4
- @@environment={} unless defined? @@environment
5
- return @@environment
6
- end
7
- def self.environment=(environment)
8
- @@environment=environment
9
- end
10
- end
11
- end
@@ -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