metro-ld25 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/.travis.yml +6 -0
- data/Gemfile +12 -0
- data/Guardfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +189 -0
- data/Rakefile +18 -0
- data/bin/metro +16 -0
- data/changelog.md +157 -0
- data/lib/assets/menu-movement.wav +0 -0
- data/lib/assets/menu-selection.wav +0 -0
- data/lib/assets/missing.ogg +0 -0
- data/lib/assets/missing.png +0 -0
- data/lib/assets/missing.wav +0 -0
- data/lib/assets/missing_animation.png +0 -0
- data/lib/commands/generate_game.rb +13 -0
- data/lib/commands/generate_model.rb +25 -0
- data/lib/commands/generate_scene.rb +36 -0
- data/lib/commands/generate_view.rb +21 -0
- data/lib/commands/thor.rb +83 -0
- data/lib/core_ext/class.rb +14 -0
- data/lib/core_ext/numeric.rb +59 -0
- data/lib/gosu_ext/color.rb +62 -0
- data/lib/gosu_ext/gosu_constants.rb +53 -0
- data/lib/locale/en.yml +35 -0
- data/lib/locale/locale.rb +1 -0
- data/lib/metro.rb +140 -0
- data/lib/metro/animation.rb +135 -0
- data/lib/metro/animation/after_interval_factory.rb +12 -0
- data/lib/metro/animation/animation_factory.rb +15 -0
- data/lib/metro/animation/easing/ease_in.rb +15 -0
- data/lib/metro/animation/easing/easing.rb +51 -0
- data/lib/metro/animation/easing/linear.rb +15 -0
- data/lib/metro/animation/has_animations.rb +70 -0
- data/lib/metro/animation/implicit_animation.rb +100 -0
- data/lib/metro/animation/on_update_operation.rb +96 -0
- data/lib/metro/animation/scene_animation.rb +16 -0
- data/lib/metro/asset_path.rb +97 -0
- data/lib/metro/events/control_definition.rb +11 -0
- data/lib/metro/events/controls.rb +42 -0
- data/lib/metro/events/event_data.rb +60 -0
- data/lib/metro/events/event_dictionary.rb +52 -0
- data/lib/metro/events/event_factory.rb +17 -0
- data/lib/metro/events/event_relay.rb +300 -0
- data/lib/metro/events/event_state_manager.rb +63 -0
- data/lib/metro/events/events.rb +3 -0
- data/lib/metro/events/has_events.rb +108 -0
- data/lib/metro/events/hit_list.rb +75 -0
- data/lib/metro/events/unknown_sender.rb +5 -0
- data/lib/metro/font.rb +69 -0
- data/lib/metro/game.rb +102 -0
- data/lib/metro/game/dsl.rb +68 -0
- data/lib/metro/image.rb +68 -0
- data/lib/metro/logging.rb +33 -0
- data/lib/metro/missing_scene.rb +21 -0
- data/lib/metro/models/audio/song.rb +33 -0
- data/lib/metro/models/draws.rb +86 -0
- data/lib/metro/models/key_value_coding.rb +38 -0
- data/lib/metro/models/model.rb +236 -0
- data/lib/metro/models/model_factory.rb +32 -0
- data/lib/metro/models/models.rb +62 -0
- data/lib/metro/models/properties/animation_property.rb +115 -0
- data/lib/metro/models/properties/array_property.rb +24 -0
- data/lib/metro/models/properties/boolean_property.rb +27 -0
- data/lib/metro/models/properties/color_property.rb +116 -0
- data/lib/metro/models/properties/dimensions_property.rb +84 -0
- data/lib/metro/models/properties/font_property.rb +130 -0
- data/lib/metro/models/properties/image_property.rb +96 -0
- data/lib/metro/models/properties/model_property.rb +84 -0
- data/lib/metro/models/properties/numeric_property.rb +29 -0
- data/lib/metro/models/properties/options_property/no_option.rb +29 -0
- data/lib/metro/models/properties/options_property/options.rb +94 -0
- data/lib/metro/models/properties/options_property/options_property.rb +125 -0
- data/lib/metro/models/properties/position_property.rb +90 -0
- data/lib/metro/models/properties/property.rb +221 -0
- data/lib/metro/models/properties/property_owner.rb +137 -0
- data/lib/metro/models/properties/sample_property.rb +84 -0
- data/lib/metro/models/properties/scale_property.rb +80 -0
- data/lib/metro/models/properties/song_property.rb +89 -0
- data/lib/metro/models/properties/text_property.rb +75 -0
- data/lib/metro/models/ui/animated_sprite.rb +85 -0
- data/lib/metro/models/ui/border.rb +95 -0
- data/lib/metro/models/ui/fps.rb +54 -0
- data/lib/metro/models/ui/generic.rb +66 -0
- data/lib/metro/models/ui/grid_drawer.rb +74 -0
- data/lib/metro/models/ui/image.rb +87 -0
- data/lib/metro/models/ui/label.rb +175 -0
- data/lib/metro/models/ui/menu.rb +214 -0
- data/lib/metro/models/ui/model_label.rb +65 -0
- data/lib/metro/models/ui/model_labeler.rb +79 -0
- data/lib/metro/models/ui/rectangle.rb +59 -0
- data/lib/metro/models/ui/sprite.rb +79 -0
- data/lib/metro/models/ui/tile_map.rb +162 -0
- data/lib/metro/models/ui/ui.rb +13 -0
- data/lib/metro/parameters/command_line_args_parser.rb +68 -0
- data/lib/metro/parameters/options.rb +25 -0
- data/lib/metro/parameters/parameters.rb +2 -0
- data/lib/metro/sample.rb +40 -0
- data/lib/metro/scene.rb +477 -0
- data/lib/metro/scenes.rb +154 -0
- data/lib/metro/song.rb +56 -0
- data/lib/metro/template_message.rb +60 -0
- data/lib/metro/transitions/edit_transition_scene.rb +100 -0
- data/lib/metro/transitions/fade_transition_scene.rb +66 -0
- data/lib/metro/transitions/scene_transitions.rb +44 -0
- data/lib/metro/transitions/transition_scene.rb +19 -0
- data/lib/metro/units/bounds.rb +8 -0
- data/lib/metro/units/calculation_validations.rb +74 -0
- data/lib/metro/units/dimensions.rb +60 -0
- data/lib/metro/units/point.rb +51 -0
- data/lib/metro/units/rectangle_bounds.rb +85 -0
- data/lib/metro/units/scale.rb +46 -0
- data/lib/metro/units/units.rb +6 -0
- data/lib/metro/version.rb +32 -0
- data/lib/metro/views/json_view.rb +60 -0
- data/lib/metro/views/no_view.rb +34 -0
- data/lib/metro/views/parsers.rb +42 -0
- data/lib/metro/views/scene_view.rb +107 -0
- data/lib/metro/views/view.rb +133 -0
- data/lib/metro/views/writers.rb +43 -0
- data/lib/metro/views/yaml_view.rb +94 -0
- data/lib/metro/window.rb +94 -0
- data/lib/setup_handlers/exit_if_dry_run.rb +26 -0
- data/lib/setup_handlers/game_execution.rb +65 -0
- data/lib/setup_handlers/load_game_configuration.rb +65 -0
- data/lib/setup_handlers/load_game_files.rb +101 -0
- data/lib/setup_handlers/move_to_game_directory.rb +25 -0
- data/lib/setup_handlers/reload_game_on_game_file_changes.rb +79 -0
- data/lib/templates/game/README.md.tt +52 -0
- data/lib/templates/game/assets/brand.jpg +0 -0
- data/lib/templates/game/assets/hero.png +0 -0
- data/lib/templates/game/lib/custom_easing.rb +32 -0
- data/lib/templates/game/metro.tt +63 -0
- data/lib/templates/game/models/hero.rb +62 -0
- data/lib/templates/game/scenes/brand_scene.rb +19 -0
- data/lib/templates/game/scenes/brand_to_title_scene.rb +13 -0
- data/lib/templates/game/scenes/first_scene.rb +28 -0
- data/lib/templates/game/scenes/game_scene.rb +43 -0
- data/lib/templates/game/scenes/title_scene.rb +15 -0
- data/lib/templates/game/views/brand.yaml +4 -0
- data/lib/templates/game/views/brand_to_title.yaml +8 -0
- data/lib/templates/game/views/first.yaml +26 -0
- data/lib/templates/game/views/title.yaml +11 -0
- data/lib/templates/message.erb +23 -0
- data/lib/templates/model.rb.tt +111 -0
- data/lib/templates/scene.rb.tt +140 -0
- data/lib/templates/view.yaml.tt +11 -0
- data/lib/tmxed_ext/tile_set.rb +34 -0
- data/metro.gemspec +56 -0
- data/spec/core_ext/numeric_spec.rb +78 -0
- data/spec/core_ext/string_spec.rb +33 -0
- data/spec/gosu_ext/color_spec.rb +80 -0
- data/spec/metro/events/event_state_manager_spec.rb +5 -0
- data/spec/metro/models/key_value_coding_spec.rb +61 -0
- data/spec/metro/models/properties/array_property_spec.rb +60 -0
- data/spec/metro/models/properties/color_property_spec.rb +85 -0
- data/spec/metro/models/properties/dimensions_spec.rb +29 -0
- data/spec/metro/models/properties/font_property_spec.rb +127 -0
- data/spec/metro/models/properties/numeric_property_spec.rb +46 -0
- data/spec/metro/models/properties/options_property/no_option_spec.rb +25 -0
- data/spec/metro/models/properties/options_property/options_property_spec.rb +133 -0
- data/spec/metro/models/properties/options_property/options_spec.rb +125 -0
- data/spec/metro/models/properties/position_property_spec.rb +90 -0
- data/spec/metro/models/ui/label_spec.rb +259 -0
- data/spec/metro/parameters/command_line_args_parser_spec.rb +42 -0
- data/spec/metro/scene_spec.rb +15 -0
- data/spec/metro/scene_views/json_view_spec.rb +27 -0
- data/spec/metro/scene_views/yaml_view_spec.rb +38 -0
- data/spec/metro/scenes_spec.rb +77 -0
- data/spec/metro/units/point_spec.rb +132 -0
- data/spec/metro/views/view_spec.rb +53 -0
- data/spec/setup_handlers/exit_if_dry_run_spec.rb +27 -0
- data/spec/setup_handlers/reload_game_on_game_file_changes_spec.rb +68 -0
- data/spec/spec_helper.rb +20 -0
- metadata +374 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
module Metro
|
2
|
+
class TransitionScene < Scene
|
3
|
+
|
4
|
+
attr_accessor :next_scene, :previous_scene, :options
|
5
|
+
|
6
|
+
def prepare_transition_from(old_scene)
|
7
|
+
next_scene.prepare_transition_from(old_scene)
|
8
|
+
@previous_scene = old_scene
|
9
|
+
end
|
10
|
+
|
11
|
+
def prepare_transition_to(new_scene)
|
12
|
+
previous_scene.prepare_transition_to(new_scene)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
require_relative 'fade_transition_scene'
|
19
|
+
require_relative 'edit_transition_scene'
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Metro
|
2
|
+
module Units
|
3
|
+
module CalculationValidations
|
4
|
+
|
5
|
+
#
|
6
|
+
# @param [Object] value the other object that needs to be validated.
|
7
|
+
#
|
8
|
+
def check_calculation_requirements(value)
|
9
|
+
if calculation_requirements.find { |method| ! value.respond_to?(method) }
|
10
|
+
raise "Unable to perform operation with #{value} #{value.class} It is missing a property #{calculation_requirements.join(",")}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
# @return [Array] an array of methods that are required to be on the
|
16
|
+
# object for it to be correctly calculated.
|
17
|
+
#
|
18
|
+
# @note this method is intended to be defined in the including class. This
|
19
|
+
# method is included here when one has not been provided.
|
20
|
+
def calculation_requirements
|
21
|
+
[]
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Add this object to another object.
|
26
|
+
#
|
27
|
+
# @return a new object that is the sum of the two objects
|
28
|
+
#
|
29
|
+
def +(value)
|
30
|
+
self.class.new *calculate(value,:+)
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Subtract the other object from this object.
|
35
|
+
#
|
36
|
+
# @return a new object that is the difference of the original object
|
37
|
+
# and the value specified.
|
38
|
+
#
|
39
|
+
def -(value)
|
40
|
+
self.class.new *calculate(value,:-)
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Multiply this object and another object.
|
45
|
+
#
|
46
|
+
# @return a new object that is the product of the two objects.
|
47
|
+
#
|
48
|
+
def *(value)
|
49
|
+
self.class.new *calculate(value,:*)
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# This generic method will perform the calculation defined by the
|
54
|
+
# operation for all the calculation requirements defined.
|
55
|
+
#
|
56
|
+
# @param [value] value this is the other value that is being added,
|
57
|
+
# subtracted, etc. to the current object.
|
58
|
+
# @param [Symbol] operation this is the mathematical operation that
|
59
|
+
# is being performed between all the calc requirements of the current
|
60
|
+
# object and other value.
|
61
|
+
#
|
62
|
+
# @return [Array] an array of reults from the calculations of all the
|
63
|
+
# requirements.
|
64
|
+
#
|
65
|
+
def calculate(value,operation)
|
66
|
+
check_calculation_requirements(value)
|
67
|
+
calculation_requirements.map do |requirement|
|
68
|
+
send(requirement).send(operation,value.send(requirement))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Metro
|
2
|
+
module Units
|
3
|
+
|
4
|
+
#
|
5
|
+
# Represents an object that contains both the width and height.
|
6
|
+
#
|
7
|
+
class Dimensions < Struct.new(:width,:height)
|
8
|
+
include CalculationValidations
|
9
|
+
|
10
|
+
#
|
11
|
+
# Create a dimensions objects with zero width and zero height.
|
12
|
+
#
|
13
|
+
def self.none
|
14
|
+
of 0.0, 0.0
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# Parse a string representation of a dimensions object. The
|
19
|
+
# supported formated is a comma-delimited string that contains
|
20
|
+
# two attributes width and height.
|
21
|
+
#
|
22
|
+
def self.parse(string)
|
23
|
+
of *string.to_s.split(",",2).map(&:to_f)
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
#
|
28
|
+
# An alternate way of creating a dimensions object which
|
29
|
+
# will enforce that the values added are converted to floating
|
30
|
+
# point numbers.
|
31
|
+
#
|
32
|
+
def self.of(width=0.0,height=0.0)
|
33
|
+
new width.to_f, height.to_f
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
"#{width},#{height}"
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Compare the dimension to another dimensions-like structure.
|
42
|
+
#
|
43
|
+
# @return [Fixnum] -1 if the dimensions is smaller than the other dimension,
|
44
|
+
# 0 if the dimensions are exactly the same, 1 if the dimensions are bigger
|
45
|
+
# then the other dimensions.
|
46
|
+
#
|
47
|
+
def <=>(value)
|
48
|
+
check_calculation_requirements(value)
|
49
|
+
(width * height) <=> (value.width * value.height)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def calculation_requirements
|
55
|
+
[ :width, :height ]
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Metro
|
2
|
+
module Units
|
3
|
+
|
4
|
+
#
|
5
|
+
# Represents and object that contains the x, y, and z position.
|
6
|
+
#
|
7
|
+
class Point < Struct.new(:x,:y,:z)
|
8
|
+
include CalculationValidations
|
9
|
+
|
10
|
+
#
|
11
|
+
# Generate a point at 0,0,0.
|
12
|
+
#
|
13
|
+
def self.zero
|
14
|
+
new 0.0, 0.0, 0.0
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# An alternate way of creating a point. Creation here converts
|
19
|
+
# all inputs to floating point and assumes that the z-value is
|
20
|
+
# zero (as this is a 2D universe).
|
21
|
+
#
|
22
|
+
def self.at(x=0.0,y=0.0,z=0.0)
|
23
|
+
new x.to_f, y.to_f, z.to_f
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Parse a string representation of a point object. The
|
28
|
+
# supported formated is a comma-delimited string that contains
|
29
|
+
# either "x,y" or "x,y,z".
|
30
|
+
#
|
31
|
+
def self.parse(string)
|
32
|
+
at *string.to_s.split(",",3).map(&:to_f)
|
33
|
+
end
|
34
|
+
|
35
|
+
# As this is a 2D world, the Z is often refered to as a the z-ordering
|
36
|
+
alias_method :z_order, :z
|
37
|
+
alias_method :z_order=, :z=
|
38
|
+
|
39
|
+
def to_s
|
40
|
+
"#{x},#{y},#{z}"
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def calculation_requirements
|
46
|
+
[ :x, :y, :z ]
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Metro
|
2
|
+
module Units
|
3
|
+
|
4
|
+
#
|
5
|
+
# An object that represents a rectanglar bounds.
|
6
|
+
#
|
7
|
+
class RectangleBounds
|
8
|
+
include CalculationValidations
|
9
|
+
|
10
|
+
attr_accessor :left, :right, :top, :bottom
|
11
|
+
|
12
|
+
def self.none
|
13
|
+
new left: 0, right: 0, top: 0, bottom: 0
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Create a bounds with bounds.
|
18
|
+
#
|
19
|
+
def initialize(params = {})
|
20
|
+
@left = params[:left].to_f
|
21
|
+
@top = params[:top].to_f
|
22
|
+
@right = params[:right].to_f
|
23
|
+
@bottom = params[:bottom].to_f
|
24
|
+
end
|
25
|
+
|
26
|
+
def shift(point)
|
27
|
+
self.left = self.left + point.x
|
28
|
+
self.right = self.right + point.x
|
29
|
+
self.top = self.top + point.y
|
30
|
+
self.bottom = self.bottom + point.y
|
31
|
+
end
|
32
|
+
|
33
|
+
def top_left
|
34
|
+
Point.at(left,top)
|
35
|
+
end
|
36
|
+
|
37
|
+
def top_right
|
38
|
+
Point.at(right,top)
|
39
|
+
end
|
40
|
+
|
41
|
+
def bottom_right
|
42
|
+
Point.at(right,bottom)
|
43
|
+
end
|
44
|
+
|
45
|
+
def bottom_left
|
46
|
+
Point.at(left,bottom)
|
47
|
+
end
|
48
|
+
|
49
|
+
def dimensions
|
50
|
+
Dimensions.of (right - left), (bottom - top)
|
51
|
+
end
|
52
|
+
|
53
|
+
def ==(value)
|
54
|
+
check_calculation_requirements(value)
|
55
|
+
left == value.left and right == value.right and top == value.top and bottom == value.bottom
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Does this bounds contain the following point?
|
60
|
+
#
|
61
|
+
def contains?(point)
|
62
|
+
point.x > left and point.x < right and point.y > top and point.y < bottom
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Does this rectanglular bounds intersect with another rectanglular bounds?
|
67
|
+
#
|
68
|
+
def intersect?(b)
|
69
|
+
not(b.left > right or b.right < left or b.top > bottom or b.bottom < top)
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_s
|
73
|
+
"(#{left},#{top}) to (#{right},#{bottom})"
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def calculation_requirements
|
79
|
+
[ :left, :right, :top, :bottom ]
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Metro
|
2
|
+
module Units
|
3
|
+
|
4
|
+
#
|
5
|
+
# Represents an object that contains the x scale factor, and y scale factor.
|
6
|
+
#
|
7
|
+
class Scale < Struct.new(:x_factor,:y_factor)
|
8
|
+
include CalculationValidations
|
9
|
+
|
10
|
+
#
|
11
|
+
# Create a scale that is 1:1.
|
12
|
+
#
|
13
|
+
def self.one
|
14
|
+
new 1.0, 1.0
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# An alternative way to create a scale which will automatically convert
|
19
|
+
# the inputs into floating numbers.
|
20
|
+
#
|
21
|
+
def self.to(x,y)
|
22
|
+
new x.to_f, y.to_f
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Parse a string representation of a scale object. The
|
27
|
+
# supported formated is a comma-delimited string that contains
|
28
|
+
# two attributes x-factor and y-factor.
|
29
|
+
#
|
30
|
+
def self.parse(string)
|
31
|
+
to *string.split(",",2).map(&:to_f)
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
"#{x_factor},#{y_factor}"
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def calculation_requirements
|
41
|
+
[ :x_factor, :y_factor ]
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Metro
|
2
|
+
VERSION = "0.3.3"
|
3
|
+
WEBSITE = "https://github.com/burtlo/metro"
|
4
|
+
CONTACT_EMAILS = ["dev@rubymetro.com"]
|
5
|
+
|
6
|
+
def self.changes_for_version(version)
|
7
|
+
|
8
|
+
change = Struct::Changes.new(nil,[])
|
9
|
+
|
10
|
+
grab_changes = false
|
11
|
+
|
12
|
+
changelog_filename = "#{File.dirname(__FILE__)}/../../changelog.md"
|
13
|
+
|
14
|
+
File.open(changelog_filename,'r') do |file|
|
15
|
+
while (line = file.gets) do
|
16
|
+
|
17
|
+
if line =~ /^##\s*#{version.gsub('.','\.')}\s*\/\s*(.+)\s*$/
|
18
|
+
grab_changes = true
|
19
|
+
change.date = $1.strip
|
20
|
+
elsif line =~ /^##\s*.+$/
|
21
|
+
grab_changes = false
|
22
|
+
elsif grab_changes
|
23
|
+
change.changes.push line
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
change
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Metro
|
4
|
+
module Views
|
5
|
+
|
6
|
+
#
|
7
|
+
# Provides support for a JSON Representation of a view.
|
8
|
+
#
|
9
|
+
class JSONView
|
10
|
+
|
11
|
+
#
|
12
|
+
# Determine if a view exists for this specified format
|
13
|
+
#
|
14
|
+
# @param [String] view_path the name of the view to find
|
15
|
+
# @return a true if the json view exists and false if it does not exist.
|
16
|
+
#
|
17
|
+
def self.exists?(view_path)
|
18
|
+
File.exists? json_view_path(view_path)
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Parse the contents of the view given the name.
|
23
|
+
#
|
24
|
+
# @param [String] view_path the name of the view to read
|
25
|
+
# @return a Hash that contains the contents of the view.
|
26
|
+
#
|
27
|
+
def self.parse(view_path)
|
28
|
+
JSON.parse File.read json_view_path(view_path)
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# @return the file type format of this view.
|
33
|
+
#
|
34
|
+
def self.format
|
35
|
+
:json
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Writes the content out to the spcified view path
|
40
|
+
#
|
41
|
+
def self.write(view_path,content)
|
42
|
+
filename = json_view_path(view_path)
|
43
|
+
json_content = JSON.pretty_generate(content)
|
44
|
+
File.write(filename,json_content)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
#
|
50
|
+
# A helper method to generate the name of the json view file. In this case
|
51
|
+
# it is the view name with the suffix .json.
|
52
|
+
#
|
53
|
+
def self.json_view_path(view_path)
|
54
|
+
File.extname(view_path) == "" ? "#{view_path}.json" : view_path
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|