shattered 0.5.0.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (223) hide show
  1. data/History.txt +6 -0
  2. data/INSTALL.txt +5 -0
  3. data/License.txt +18 -0
  4. data/Manifest.txt +175 -0
  5. data/README.txt +39 -0
  6. data/Rakefile +6 -0
  7. data/app_generators/actor/USAGE +6 -0
  8. data/app_generators/actor/actor_generator.rb +51 -0
  9. data/app_generators/actor/templates/actor.rb +4 -0
  10. data/app_generators/actor/templates/spec.rb +11 -0
  11. data/app_generators/actor/templates/unit_test.rb +9 -0
  12. data/app_generators/commands/console.rb +6 -0
  13. data/{lib/rails_generator/generators/applications/shattered_app → app_generators/shattered}/USAGE +1 -1
  14. data/app_generators/shattered/shattered_generator.rb +67 -0
  15. data/{lib → app_generators/shattered}/templates/Rakefile +4 -4
  16. data/app_generators/shattered/templates/configs/game.controls +16 -0
  17. data/app_generators/shattered/templates/configs/ogre_plugins.linux.cfg +12 -0
  18. data/app_generators/shattered/templates/configs/ogre_plugins.osx.cfg +12 -0
  19. data/{lib → app_generators/shattered}/templates/configs/ogre_plugins.windows.cfg +2 -2
  20. data/app_generators/shattered/templates/game.rb +50 -0
  21. data/{lib → app_generators/shattered}/templates/media/basic.rmaterial +0 -0
  22. data/app_generators/shattered/templates/spec/game_spec.rb +5 -0
  23. data/app_generators/shattered/templates/spec/spec_helper.rb +12 -0
  24. data/bin/shattered +39 -0
  25. data/config/hoe.rb +77 -0
  26. data/config/requirements.rb +15 -0
  27. data/lib/shattered.rb +40 -0
  28. data/lib/shattered_game/actor.rb +6 -0
  29. data/lib/shattered_game/game.rb +285 -0
  30. data/lib/{tasks → shattered_game/rake_tasks}/framework.rake +19 -24
  31. data/lib/{tasks → shattered_game/rake_tasks}/log.rake +0 -0
  32. data/lib/{tasks → shattered_game/rake_tasks}/misc.rake +1 -2
  33. data/lib/{tasks → shattered_game/rake_tasks}/pre_namespace_aliases.rake +0 -0
  34. data/lib/{tasks → shattered_game/rake_tasks}/shattered.rb +0 -0
  35. data/lib/shattered_game/rake_tasks/spec.rake +9 -0
  36. data/lib/{tasks → shattered_game/rake_tasks}/statistics.rake +0 -0
  37. data/lib/shattered_game/required.rb +2 -0
  38. data/lib/shattered_game/version.rb +9 -0
  39. data/lib/shattered_model/controls.rb +67 -0
  40. data/lib/shattered_model/input.rb +171 -0
  41. data/lib/shattered_model/key_converter.rb +44 -0
  42. data/lib/shattered_model/required.rb +4 -0
  43. data/lib/shattered_model/shattered_model.rb +28 -0
  44. data/lib/shattered_model/timed_event.rb +120 -0
  45. data/lib/shattered_model/timer.rb +78 -0
  46. data/lib/shattered_support/core_ext.rb +1 -0
  47. data/lib/shattered_support/core_ext/class.rb +3 -0
  48. data/lib/shattered_support/core_ext/class/attribute_accessors.rb +44 -0
  49. data/lib/shattered_support/core_ext/class/inheritable_attributes.rb +115 -0
  50. data/lib/shattered_support/core_ext/class/removal.rb +24 -0
  51. data/lib/shattered_support/core_ext/dir.rb +5 -0
  52. data/lib/shattered_support/core_ext/dir/search.rb +25 -0
  53. data/lib/shattered_support/core_ext/file.rb +5 -0
  54. data/lib/shattered_support/core_ext/file/search.rb +64 -0
  55. data/lib/shattered_support/core_ext/numeric.rb +5 -0
  56. data/lib/shattered_support/core_ext/numeric/time.rb +72 -0
  57. data/lib/shattered_support/core_ext/string.rb +13 -0
  58. data/lib/shattered_support/core_ext/string/access.rb +58 -0
  59. data/lib/shattered_support/core_ext/string/conversions.rb +19 -0
  60. data/lib/shattered_support/core_ext/string/inflections.rb +64 -0
  61. data/lib/shattered_support/core_ext/string/iterators.rb +17 -0
  62. data/lib/shattered_support/core_ext/string/starts_ends_with.rb +20 -0
  63. data/lib/shattered_support/error.rb +12 -0
  64. data/lib/shattered_support/inflections.rb +53 -0
  65. data/lib/shattered_support/inflector.rb +178 -0
  66. data/lib/shattered_support/pre_initialize.rb +153 -0
  67. data/lib/shattered_support/required.rb +9 -0
  68. data/lib/shattered_support/unload.rb +18 -0
  69. data/lib/shattered_view/camera.rb +7 -0
  70. data/lib/shattered_view/ogrerb/base.rb +28 -0
  71. data/lib/shattered_view/ogrerb/camera.rb +14 -0
  72. data/lib/shattered_view/ogrerb/key_manager.rb +54 -0
  73. data/lib/shattered_view/ogrerb/light.rb +25 -0
  74. data/lib/shattered_view/ogrerb/material.rb +5 -0
  75. data/lib/shattered_view/ogrerb/mesh_instance.rb +85 -0
  76. data/lib/shattered_view/ogrerb/mouse_manager.rb +109 -0
  77. data/lib/shattered_view/ogrerb/particle_system.rb +24 -0
  78. data/lib/shattered_view/ogrerb/rgb.rb +6 -0
  79. data/lib/shattered_view/ogrerb/rmaterial.rb +87 -0
  80. data/lib/shattered_view/ogrerb/scene_node.rb +76 -0
  81. data/lib/shattered_view/ogrerb/vector.rb +243 -0
  82. data/lib/shattered_view/ogrerb/window_event.rb +14 -0
  83. data/lib/shattered_view/resources.rb +64 -0
  84. data/lib/shattered_view/shattered_view.rb +248 -0
  85. data/script/destroy +14 -0
  86. data/script/generate +14 -0
  87. data/setup.rb +1585 -0
  88. data/tasks/deployment.rake +30 -0
  89. data/tasks/environment.rake +7 -0
  90. data/tasks/rcov.rake +7 -0
  91. data/tasks/testing.rake +46 -0
  92. data/tasks/website.rake +15 -0
  93. data/test/acceptance/Rakefile +10 -0
  94. data/test/acceptance/config/game.controls +17 -0
  95. data/test/acceptance/config/ogre_plugins.linux.cfg +12 -0
  96. data/test/acceptance/config/ogre_plugins.osx.cfg +12 -0
  97. data/test/acceptance/config/ogre_plugins.windows.cfg +14 -0
  98. data/test/acceptance/config/ogrerb_defaults.save +8 -0
  99. data/test/acceptance/game.rb +120 -0
  100. data/test/acceptance/lib/acceptance_test.rb +20 -0
  101. data/test/acceptance/lib/console.rb +54 -0
  102. data/test/acceptance/lib/input_test.rb +8 -0
  103. data/test/acceptance/lib/label.rb +30 -0
  104. data/test/acceptance/lib/light_test.rb +60 -0
  105. data/test/acceptance/lib/mesh_test.rb +69 -0
  106. data/test/acceptance/lib/particle_test.rb +9 -0
  107. data/test/acceptance/media/GreenSkin.jpg +0 -0
  108. data/test/acceptance/media/Ogre.material +86 -0
  109. data/test/acceptance/media/WeirdEye.png +0 -0
  110. data/test/acceptance/media/basic.rmaterial +18 -0
  111. data/test/acceptance/media/console.fontdef +7 -0
  112. data/test/acceptance/media/console.material +13 -0
  113. data/test/acceptance/media/console.png +0 -0
  114. data/test/acceptance/media/console.ttf +0 -0
  115. data/test/acceptance/media/dirt01.png +0 -0
  116. data/test/acceptance/media/fountain.material +19 -0
  117. data/test/acceptance/media/fountain.particle +40 -0
  118. data/test/acceptance/media/fountain.png +0 -0
  119. data/test/acceptance/media/fountaincolors.png +0 -0
  120. data/test/acceptance/media/ogre.mesh +0 -0
  121. data/test/acceptance/media/spheremap.png +0 -0
  122. data/test/acceptance/media/win.png +0 -0
  123. data/test/acceptance/spec/spec_helper.rb +7 -0
  124. data/test/integration/actor_generator_test.rb +43 -0
  125. data/test/integration/shattered_generator_test.rb +43 -0
  126. data/test/integration/test_helper.rb +20 -0
  127. data/test/ogre_test_defaults.save +8 -0
  128. data/test/ogre_test_plugins.linux.cfg +12 -0
  129. data/test/ogre_test_plugins.osx.cfg +12 -0
  130. data/test/ogre_test_plugins.windows.cfg +14 -0
  131. data/test/test_helper.rb +109 -0
  132. data/test/unit/shattered_game/actor_test.rb +9 -0
  133. data/test/unit/shattered_game/game_test.rb +49 -0
  134. data/test/unit/shattered_game/runner_test.rb +56 -0
  135. data/test/unit/shattered_model/controls/mouse.controls +4 -0
  136. data/test/unit/shattered_model/controls/player.controls +4 -0
  137. data/test/unit/shattered_model/controls/too_many_delims.controls +1 -0
  138. data/test/unit/shattered_model/key_controls_test.rb +89 -0
  139. data/test/unit/shattered_model/key_converter_test.rb +37 -0
  140. data/test/unit/shattered_model/keyboard_input_test.rb +32 -0
  141. data/test/unit/shattered_model/mouse_controls_test.rb +50 -0
  142. data/test/unit/shattered_model/mouse_input_test.rb +61 -0
  143. data/test/unit/shattered_model/shattered_model_test.rb +117 -0
  144. data/test/unit/shattered_model/timed_event_test.rb +79 -0
  145. data/test/unit/shattered_model/timer_test.rb +325 -0
  146. data/{lib/rails_generator/generators/components/actor/templates/actor.rb → test/unit/shattered_support/directory_test/file.test} +0 -0
  147. data/test/unit/shattered_support/numeric_ext_test.rb +38 -0
  148. data/test/unit/shattered_support/pre_initialize_test.rb +63 -0
  149. data/test/unit/shattered_support/shattered_support_test.rb +39 -0
  150. data/test/unit/shattered_support/unload_test.rb +17 -0
  151. data/test/unit/shattered_view/light_test.rb +38 -0
  152. data/test/unit/shattered_view/material_test.rb +41 -0
  153. data/test/unit/shattered_view/media_test/basic.rmaterial +18 -0
  154. data/{lib/templates/configs/empty.log → test/unit/shattered_view/media_test/beltch.ogg} +0 -0
  155. data/test/unit/shattered_view/media_test/test.mesh +0 -0
  156. data/test/unit/shattered_view/mesh_test.rb +59 -0
  157. data/test/unit/shattered_view/node_test.rb +11 -0
  158. data/test/unit/shattered_view/ogrerb/camera_test.rb +12 -0
  159. data/test/unit/shattered_view/ogrerb/key_manager_test.rb +42 -0
  160. data/test/unit/shattered_view/ogrerb/media/basic.rmaterial +18 -0
  161. data/test/unit/shattered_view/ogrerb/media/test.mesh +0 -0
  162. data/test/unit/shattered_view/ogrerb/media/test.rmaterial +1 -0
  163. data/test/unit/shattered_view/ogrerb/mesh_instance_test.rb +74 -0
  164. data/test/unit/shattered_view/ogrerb/mouse_manager_test.rb +104 -0
  165. data/test/unit/shattered_view/ogrerb/ogrerb.log +51 -0
  166. data/test/unit/shattered_view/ogrerb/resolve_ogrerb_test.rb +13 -0
  167. data/test/unit/shattered_view/ogrerb/rgb_test.rb +10 -0
  168. data/test/unit/shattered_view/ogrerb/rmaterial_test.rb +28 -0
  169. data/test/unit/shattered_view/ogrerb/scene_type_test.rb +12 -0
  170. data/test/unit/shattered_view/ogrerb/vector_test.rb +206 -0
  171. data/test/unit/shattered_view/particle_test.rb +23 -0
  172. data/test/unit/shattered_view/resources_test.rb +45 -0
  173. data/test/unit/shattered_view/test_helper.rb +1 -0
  174. data/test/unit/shattered_view/window_event_test.rb +19 -0
  175. data/test/unit/test_helper.rb +1 -0
  176. metadata +205 -121
  177. data/bin/console +0 -4
  178. data/bin/destroy +0 -9
  179. data/bin/generate +0 -7
  180. data/bin/runner +0 -9
  181. data/bin/shatter +0 -22
  182. data/lib/commands/console.rb +0 -23
  183. data/lib/game_loader.rb +0 -118
  184. data/lib/rails_generator.rb +0 -43
  185. data/lib/rails_generator/base.rb +0 -203
  186. data/lib/rails_generator/commands.rb +0 -519
  187. data/lib/rails_generator/generators/applications/shattered_app/shattered_app_generator.rb +0 -103
  188. data/lib/rails_generator/generators/components/actor/actor_generator.rb +0 -22
  189. data/lib/rails_generator/generators/components/model/USAGE +0 -17
  190. data/lib/rails_generator/generators/components/model/model_generator.rb +0 -22
  191. data/lib/rails_generator/generators/components/model/templates/fixtures.yml +0 -5
  192. data/lib/rails_generator/generators/components/model/templates/model.rb +0 -2
  193. data/lib/rails_generator/generators/components/model/templates/unit_test.rb +0 -11
  194. data/lib/rails_generator/generators/components/state/USAGE +0 -30
  195. data/lib/rails_generator/generators/components/state/state_generator.rb +0 -19
  196. data/lib/rails_generator/generators/components/state/templates/state.rb +0 -20
  197. data/lib/rails_generator/generators/components/view/USAGE +0 -30
  198. data/lib/rails_generator/generators/components/view/templates/material +0 -4
  199. data/lib/rails_generator/generators/components/view/templates/view.rb +0 -7
  200. data/lib/rails_generator/generators/components/view/view_generator.rb +0 -28
  201. data/lib/rails_generator/lookup.rb +0 -209
  202. data/lib/rails_generator/manifest.rb +0 -53
  203. data/lib/rails_generator/options.rb +0 -143
  204. data/lib/rails_generator/scripts.rb +0 -83
  205. data/lib/rails_generator/scripts/destroy.rb +0 -7
  206. data/lib/rails_generator/scripts/generate.rb +0 -7
  207. data/lib/rails_generator/scripts/update.rb +0 -12
  208. data/lib/rails_generator/simple_logger.rb +0 -46
  209. data/lib/rails_generator/spec.rb +0 -44
  210. data/lib/shatter.rb +0 -7
  211. data/lib/tasks/documentation.rake +0 -46
  212. data/lib/tasks/testing.rake +0 -102
  213. data/lib/templates/MIT-LICENSE +0 -20
  214. data/lib/templates/README +0 -35
  215. data/lib/templates/configs/boot.rb +0 -35
  216. data/lib/templates/configs/ogre.cfg +0 -4
  217. data/lib/templates/configs/runner.rb +0 -5
  218. data/lib/templates/doc/README_FOR_APP +0 -2
  219. data/lib/templates/environments/environment.rb +0 -10
  220. data/lib/templates/media/default.mesh +0 -0
  221. data/lib/templates/media/default.png +0 -0
  222. data/lib/templates/media/offset_map.rmaterial +0 -117
  223. data/lib/templates/test/test_helper.rb +0 -5
@@ -0,0 +1,13 @@
1
+ require File.dirname(__FILE__) + '/string/inflections'
2
+ require File.dirname(__FILE__) + '/string/conversions'
3
+ require File.dirname(__FILE__) + '/string/access'
4
+ require File.dirname(__FILE__) + '/string/starts_ends_with'
5
+ require File.dirname(__FILE__) + '/string/iterators'
6
+
7
+ class String #:nodoc:
8
+ include ShatteredSupport::CoreExtensions::String::Access
9
+ include ShatteredSupport::CoreExtensions::String::Conversions
10
+ include ShatteredSupport::CoreExtensions::String::Inflections
11
+ include ShatteredSupport::CoreExtensions::String::StartsEndsWith
12
+ include ShatteredSupport::CoreExtensions::String::Iterators
13
+ end
@@ -0,0 +1,58 @@
1
+ module ShatteredSupport #:nodoc:
2
+ module CoreExtensions #:nodoc:
3
+ module String #:nodoc:
4
+ # Makes it easier to access parts of a string, such as specific characters and substrings.
5
+ module Access
6
+ # Returns the character at the +position+ treating the string as an array (where 0 is the first character).
7
+ #
8
+ # Examples:
9
+ # "hello".at(0) # => "h"
10
+ # "hello".at(4) # => "o"
11
+ # "hello".at(10) # => nil
12
+ def at(position)
13
+ self[position, 1]
14
+ end
15
+
16
+ # Returns the remaining of the string from the +position+ treating the string as an array (where 0 is the first character).
17
+ #
18
+ # Examples:
19
+ # "hello".from(0) # => "hello"
20
+ # "hello".from(2) # => "llo"
21
+ # "hello".from(10) # => nil
22
+ def from(position)
23
+ self[position..-1]
24
+ end
25
+
26
+ # Returns the beginning of the string up to the +position+ treating the string as an array (where 0 is the first character).
27
+ #
28
+ # Examples:
29
+ # "hello".to(0) # => "h"
30
+ # "hello".to(2) # => "hel"
31
+ # "hello".to(10) # => "hello"
32
+ def to(position)
33
+ self[0..position]
34
+ end
35
+
36
+ # Returns the first character of the string or the first +limit+ characters.
37
+ #
38
+ # Examples:
39
+ # "hello".first # => "h"
40
+ # "hello".first(2) # => "he"
41
+ # "hello".first(10) # => "hello"
42
+ def first(limit = 1)
43
+ self[0..(limit - 1)]
44
+ end
45
+
46
+ # Returns the last character of the string or the last +limit+ characters.
47
+ #
48
+ # Examples:
49
+ # "hello".last # => "o"
50
+ # "hello".last(2) # => "lo"
51
+ # "hello".last(10) # => "hello"
52
+ def last(limit = 1)
53
+ self[(-limit)..-1] || self
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,19 @@
1
+ require 'parsedate'
2
+
3
+ module ShatteredSupport #:nodoc:
4
+ module CoreExtensions #:nodoc:
5
+ module String #:nodoc:
6
+ # Converting strings to other objects
7
+ module Conversions
8
+ # Form can be either :utc (default) or :local.
9
+ def to_time(form = :utc)
10
+ ::Time.send(form, *ParseDate.parsedate(self))
11
+ end
12
+
13
+ def to_date
14
+ ::Date.new(*ParseDate.parsedate(self)[0..2])
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,64 @@
1
+ require File.dirname(__FILE__) + '/../../inflector' unless defined? Inflector
2
+ module ShatteredSupport #:nodoc:
3
+ module CoreExtensions #:nodoc:
4
+ module String #:nodoc:
5
+ # Makes it possible to do "posts".singularize that returns "post" and "MegaCoolClass".underscore that returns "mega_cool_class".
6
+ module Inflections
7
+ def pluralize
8
+ Inflector.pluralize(self)
9
+ end
10
+
11
+ def singularize
12
+ Inflector.singularize(self)
13
+ end
14
+
15
+ def camelize(first_letter = :upper)
16
+ case first_letter
17
+ when :upper then Inflector.camelize(self, true)
18
+ when :lower then Inflector.camelize(self, false)
19
+ end
20
+ end
21
+ alias_method :camelcase, :camelize
22
+
23
+ def titleize
24
+ Inflector.titleize(self)
25
+ end
26
+ alias_method :titlecase, :titleize
27
+
28
+ def underscore
29
+ Inflector.underscore(self)
30
+ end
31
+
32
+ def dasherize
33
+ Inflector.dasherize(self)
34
+ end
35
+
36
+ def demodulize
37
+ Inflector.demodulize(self)
38
+ end
39
+
40
+ def tableize
41
+ Inflector.tableize(self)
42
+ end
43
+
44
+ def classify
45
+ Inflector.classify(self)
46
+ end
47
+
48
+ # Capitalizes the first word and turns underscores into spaces and strips _id, so "employee_salary" becomes "Employee salary"
49
+ # and "author_id" becomes "Author".
50
+ def humanize
51
+ Inflector.humanize(self)
52
+ end
53
+
54
+ def foreign_key(separate_class_name_and_id_with_underscore = true)
55
+ Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
56
+ end
57
+
58
+ def constantize
59
+ Inflector.constantize(self)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,17 @@
1
+ require 'strscan'
2
+
3
+ module ShatteredSupport #:nodoc:
4
+ module CoreExtensions #:nodoc:
5
+ module String #:nodoc:
6
+ # Custom string iterators
7
+ module Iterators
8
+ # Yields a single-character string for each character in the string.
9
+ # When $KCODE = 'UTF8', multi-byte characters are yielded appropriately.
10
+ def each_char
11
+ scanner, char = StringScanner.new(self), /./mu
12
+ loop { yield(scanner.scan(char) || break) }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ module ShatteredSupport #:nodoc:
2
+ module CoreExtensions #:nodoc:
3
+ module String #:nodoc:
4
+ # Additional string tests.
5
+ module StartsEndsWith
6
+ # Does the string start with the specified +prefix+?
7
+ def starts_with?(prefix)
8
+ prefix = prefix.to_s
9
+ self[0, prefix.length] == prefix
10
+ end
11
+
12
+ # Does the string end with the specified +suffix+?
13
+ def ends_with?(suffix)
14
+ suffix = suffix.to_s
15
+ self[-suffix.length, suffix.length] == suffix
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ module Shattered
2
+ class Error < StandardError
3
+ end
4
+
5
+ class MetaMethodError < StandardError # :nodoc:
6
+ attr_accessor :message
7
+ def initialize(error, message)
8
+ self.message = message
9
+ set_backtrace error.backtrace
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,53 @@
1
+ Inflector.inflections do |inflect|
2
+ inflect.plural(/$/, 's')
3
+ inflect.plural(/s$/i, 's')
4
+ inflect.plural(/(ax|test)is$/i, '\1es')
5
+ inflect.plural(/(octop|vir)us$/i, '\1i')
6
+ inflect.plural(/(alias|status)$/i, '\1es')
7
+ inflect.plural(/(bu)s$/i, '\1ses')
8
+ inflect.plural(/(buffal|tomat)o$/i, '\1oes')
9
+ inflect.plural(/([ti])um$/i, '\1a')
10
+ inflect.plural(/sis$/i, 'ses')
11
+ inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
12
+ inflect.plural(/(hive)$/i, '\1s')
13
+ inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
14
+ inflect.plural(/([^aeiouy]|qu)ies$/i, '\1y')
15
+ inflect.plural(/(x|ch|ss|sh)$/i, '\1es')
16
+ inflect.plural(/(matr|vert|ind)ix|ex$/i, '\1ices')
17
+ inflect.plural(/([m|l])ouse$/i, '\1ice')
18
+ inflect.plural(/^(ox)$/i, '\1en')
19
+ inflect.plural(/(quiz)$/i, '\1zes')
20
+
21
+ inflect.singular(/s$/i, '')
22
+ inflect.singular(/(n)ews$/i, '\1ews')
23
+ inflect.singular(/([ti])a$/i, '\1um')
24
+ inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis')
25
+ inflect.singular(/(^analy)ses$/i, '\1sis')
26
+ inflect.singular(/([^f])ves$/i, '\1fe')
27
+ inflect.singular(/(hive)s$/i, '\1')
28
+ inflect.singular(/(tive)s$/i, '\1')
29
+ inflect.singular(/([lr])ves$/i, '\1f')
30
+ inflect.singular(/([^aeiouy]|qu)ies$/i, '\1y')
31
+ inflect.singular(/(s)eries$/i, '\1eries')
32
+ inflect.singular(/(m)ovies$/i, '\1ovie')
33
+ inflect.singular(/(x|ch|ss|sh)es$/i, '\1')
34
+ inflect.singular(/([m|l])ice$/i, '\1ouse')
35
+ inflect.singular(/(bus)es$/i, '\1')
36
+ inflect.singular(/(o)es$/i, '\1')
37
+ inflect.singular(/(shoe)s$/i, '\1')
38
+ inflect.singular(/(cris|ax|test)es$/i, '\1is')
39
+ inflect.singular(/([octop|vir])i$/i, '\1us')
40
+ inflect.singular(/(alias|status)es$/i, '\1')
41
+ inflect.singular(/^(ox)en/i, '\1')
42
+ inflect.singular(/(vert|ind)ices$/i, '\1ex')
43
+ inflect.singular(/(matr)ices$/i, '\1ix')
44
+ inflect.singular(/(quiz)zes$/i, '\1')
45
+
46
+ inflect.irregular('person', 'people')
47
+ inflect.irregular('man', 'men')
48
+ inflect.irregular('child', 'children')
49
+ inflect.irregular('sex', 'sexes')
50
+ inflect.irregular('move', 'moves')
51
+
52
+ inflect.uncountable(%w(equipment information rice money species series fish sheep))
53
+ end
@@ -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'
@@ -0,0 +1,153 @@
1
+ module PreInitialize #:nodoc:all
2
+ def self.append_features(base)
3
+ super
4
+ base.extend(ClassMethods)
5
+ base.send(:include, InstanceMethods)
6
+ end
7
+
8
+ def self.included(mod)
9
+ return if mod == Object # This is to allow include Shattered::Timer at the top of files
10
+ class << mod
11
+ # This is overwritten to allow for a pre_initialize before initialize
12
+ def new(*options) #:nodoc
13
+ new_base = allocate
14
+ new_base.pre_initialize
15
+ new_base.send(:initialize, *options)
16
+ return new_base
17
+ end
18
+ end
19
+ end
20
+
21
+ BEFORE_INIT_CALL_VALUES = :before_init_call_values
22
+ BEFORE_INIT_SET_VALUES = :before_init_set_values
23
+
24
+ module ClassMethods
25
+
26
+
27
+ # In the pre_initialization phase (see #before_init_call), send an object a bunch of sets.
28
+ #
29
+ # This is used in actor, camera, mesh, and virtually everywhere to support the format of:
30
+ # mesh "ruby", :position => v(1,0,0)
31
+ #
32
+ # becomes
33
+ # before_init_set( :ruby, {:position => v(1,0,0) } )
34
+ # becomes
35
+ # ruby.position=v(1,0,0)
36
+ # when the obect is initialized.
37
+ def before_init_set(variable, options={})
38
+ self.write_inheritable_array(BEFORE_INIT_SET_VALUES, [[ variable, options ]] )
39
+ end
40
+
41
+ # All shattered objects have a pre_initialization phase. Use this to specify that
42
+ # a function should be called when the object is created.
43
+ #
44
+ # _Example_:
45
+ # class BulletModel < ShatteredModel::Base
46
+ # before_init_call(:calculate_trajectory, v(0,0,0), v(0,0,1))
47
+ # def calculate_trajectory
48
+ # #called before initialize is
49
+ # end
50
+ # end
51
+ #
52
+ def before_init_call(function, *arguments)
53
+ self.write_inheritable_array(BEFORE_INIT_CALL_VALUES, [[function, [*arguments]]])
54
+ end
55
+ end
56
+ module InstanceMethods
57
+
58
+ protected
59
+
60
+ def attr_define(accessor_level, name, value)
61
+ self.class.send("attr_#{accessor_level}".to_sym, "#{name}".to_sym)
62
+ instance_variable_set("@#{name}".to_sym, value) if !value.nil?
63
+ end
64
+
65
+ public
66
+
67
+ # attr helpers. These are instance level attr_* functions.
68
+ def attr_reader(*args)
69
+ name, value = args
70
+ attr_define(:reader, name, value)
71
+ end
72
+
73
+ # attr helpers. These are instance level attr_* functions.
74
+ # attr_writer accepts a value as the second argument
75
+ def attr_writer(*args)
76
+ name, value = args
77
+ attr_define(:writer, name, value)
78
+ end
79
+
80
+ # attr helpers. These are instance level attr_* functions.
81
+ # attr_accessor accepts a value as the se puts modcond argument
82
+ def attr_accessor(*args)
83
+ name, value = args
84
+ attr_define(:accessor, name, value)
85
+ end
86
+
87
+ # This function is called after an object is allocated, but before it's initialized.
88
+ #
89
+ # See Shattered::ClassMethods#before_init_call for usage.
90
+ def pre_initialize #:nodoc:
91
+ pre_initialize_set
92
+ pre_initialize_call
93
+ end
94
+
95
+ # Used in pre_initialize
96
+ def each_init_value(name) #:nodoc:
97
+ startup_attributes = self.class.read_inheritable_attribute( name ) || []
98
+ startup_attributes.each do |actor, options|
99
+ next if options.nil?
100
+ yield actor, options
101
+ end
102
+ end
103
+
104
+ # Used in pre_initialize for before_init_set
105
+ def pre_initialize_set #:nodoc:
106
+ each_init_value(BEFORE_INIT_SET_VALUES) do |variable, options|
107
+ call_object_function_for_each_key( variable, options )
108
+ end
109
+ end
110
+
111
+ # Used in pre_initialize for before_init_call
112
+ def pre_initialize_call #:nodoc:
113
+ each_init_value(BEFORE_INIT_CALL_VALUES) do |function, args|
114
+ call_object_function( :self, function, args )
115
+ end
116
+ end
117
+
118
+ def call_object_function_for_each_key( actor, options, evaluate_symbols=true )
119
+ options.each_pair do |action, params|
120
+ call_object_function actor, "#{action}=", params, evaluate_symbols
121
+ end
122
+ end
123
+
124
+ # TODO: This is bad - this method needs to be refactored and/or nuked.
125
+ def call_object_function(actor, action, params, evaluate_symbols=true)
126
+ begin
127
+ if params.is_a?(Symbol) && evaluate_symbols
128
+ params = eval(params.to_s)
129
+ end
130
+ rescue NameError
131
+ puts "It is not advisable to pass #{params.inspect} to #{action.inspect} for #{actor.inspect}."
132
+ puts " It will try to be evaluated. Use a string instead."
133
+ end
134
+ begin
135
+ if(actor.is_a?(String) || actor.is_a?(Symbol))
136
+ sendee = eval(actor.to_s)
137
+ else
138
+ sendee = actor
139
+ end
140
+ if(params.is_a? Array)
141
+ sendee.send( action.to_sym, *params )
142
+ else
143
+ sendee.send( action.to_sym, params )
144
+ end
145
+ rescue NoMethodError, ArgumentError => bang
146
+ message="Error upon #{actor.to_s}.send(#{action.to_sym.inspect}, #{params.inspect}):\n\r #{bang.class}: \n\r\t #{bang.message}\n\r #{bang.backtrace[0]}\n\r"
147
+ bang = Shattered::MetaMethodError.new(bang,message)
148
+ raise bang
149
+ end
150
+ end
151
+ end
152
+ end
153
+