metro 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/changelog.md +9 -0
- data/lib/commands/generate_model.rb +2 -2
- data/lib/commands/generate_scene.rb +2 -2
- data/lib/commands/generate_view.rb +1 -1
- data/lib/gosu_ext/color.rb +16 -2
- data/lib/metro.rb +50 -10
- data/lib/metro/events/event_data.rb +61 -0
- data/lib/metro/events/event_relay.rb +10 -3
- data/lib/metro/events/hit_list.rb +77 -0
- data/lib/metro/models/draws.rb +6 -1
- data/lib/metro/models/grid_drawer.rb +57 -0
- data/lib/metro/models/image.rb +18 -2
- data/lib/metro/models/label.rb +22 -6
- data/lib/metro/models/menu.rb +20 -0
- data/lib/metro/models/model.rb +47 -6
- data/lib/metro/models/model_factory.rb +2 -2
- data/lib/metro/models/rectangle_bounds.rb +28 -0
- data/lib/metro/scene.rb +46 -11
- data/lib/metro/scenes.rb +10 -9
- data/lib/metro/transitions/edit_transition_scene.rb +73 -0
- data/lib/metro/transitions/scene_transitions.rb +8 -2
- data/lib/metro/transitions/transition_scene.rb +2 -1
- data/lib/metro/version.rb +1 -1
- data/lib/metro/views/json_view.rb +60 -0
- data/lib/metro/{scene_view → views}/no_view.rb +12 -4
- data/lib/metro/views/parsers.rb +26 -0
- data/lib/metro/views/scene_view.rb +107 -0
- data/lib/metro/views/view.rb +125 -0
- data/lib/metro/views/writers.rb +28 -0
- data/lib/metro/views/yaml_view.rb +94 -0
- data/lib/metro/window.rb +19 -0
- data/metro.gemspec +1 -0
- data/spec/core_ext/string_spec.rb +13 -13
- 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 +1 -1
- data/spec/metro/views/view_spec.rb +53 -0
- metadata +41 -11
- data/lib/core_ext/string.rb +0 -15
- data/lib/metro/scene_view/json_view.rb +0 -41
- data/lib/metro/scene_view/scene_view.rb +0 -83
- data/lib/metro/scene_view/yaml_view.rb +0 -45
@@ -6,6 +6,7 @@ module Metro
|
|
6
6
|
|
7
7
|
def insert_transition(scene,options)
|
8
8
|
return scene unless options.key?(:with)
|
9
|
+
name = options[:with]
|
9
10
|
generate_transition(name,scene,options)
|
10
11
|
end
|
11
12
|
|
@@ -19,11 +20,16 @@ module Metro
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def find_transition(name)
|
22
|
-
supported_transitions[name]
|
23
|
+
transition_name = supported_transitions[name]
|
24
|
+
transition_name.constantize
|
23
25
|
end
|
24
26
|
|
25
27
|
def supported_transitions
|
26
|
-
|
28
|
+
@supported_transitions ||= begin
|
29
|
+
hash = Hash.new("Metro::FadeTransitionScene")
|
30
|
+
hash[:edit] = "Metro::EditTransitionScene"
|
31
|
+
hash
|
32
|
+
end
|
27
33
|
end
|
28
34
|
|
29
35
|
end
|
data/lib/metro/version.rb
CHANGED
@@ -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
|
@@ -1,15 +1,15 @@
|
|
1
1
|
module Metro
|
2
|
-
module
|
2
|
+
module Views
|
3
3
|
|
4
4
|
class NoView
|
5
5
|
|
6
6
|
#
|
7
7
|
# A NoView is a last resort view which means this is will always will exist.
|
8
8
|
#
|
9
|
-
# @param [String]
|
9
|
+
# @param [String] view_path the name of the view to find
|
10
10
|
# @return a true if the json view exists and false if it does not exist.
|
11
11
|
#
|
12
|
-
def self.exists?(
|
12
|
+
def self.exists?(view_path)
|
13
13
|
true
|
14
14
|
end
|
15
15
|
|
@@ -17,9 +17,17 @@ module Metro
|
|
17
17
|
# A NoView will return an empty Hash to provide compatibility with other view
|
18
18
|
# types.
|
19
19
|
#
|
20
|
-
def self.parse(
|
20
|
+
def self.parse(view_path)
|
21
21
|
{}
|
22
22
|
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# @return the file type format of this view.
|
26
|
+
#
|
27
|
+
def self.format
|
28
|
+
:none
|
29
|
+
end
|
30
|
+
|
23
31
|
end
|
24
32
|
|
25
33
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative 'yaml_view'
|
2
|
+
require_relative 'json_view'
|
3
|
+
require_relative 'no_view'
|
4
|
+
|
5
|
+
module Metro
|
6
|
+
module Views
|
7
|
+
|
8
|
+
module Parsers
|
9
|
+
extend self
|
10
|
+
|
11
|
+
def register(parser)
|
12
|
+
parsers.push parser
|
13
|
+
end
|
14
|
+
|
15
|
+
def parsers
|
16
|
+
@parsers ||= []
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Parsers.register YAMLView
|
21
|
+
Parsers.register JSONView
|
22
|
+
Parsers.register NoView
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require_relative 'view'
|
2
|
+
|
3
|
+
module Metro
|
4
|
+
|
5
|
+
#
|
6
|
+
# SceneView provides support for a Scene to have a view as well as giving
|
7
|
+
# additional tools to also help draw that view.
|
8
|
+
#
|
9
|
+
module SceneView
|
10
|
+
|
11
|
+
#
|
12
|
+
# A Scene by default uses the name of the Scene to find it's associated
|
13
|
+
# view.
|
14
|
+
#
|
15
|
+
# @example Standard View Name
|
16
|
+
#
|
17
|
+
# class OpeningScene < Metro::Scene
|
18
|
+
#
|
19
|
+
# def show
|
20
|
+
# puts "View Brought To You By: #{view_name} # => View Brought To You By opening
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# @example Custom View Name
|
25
|
+
#
|
26
|
+
# class ClosingScene < Metro::Scene
|
27
|
+
# view_name 'alternative'
|
28
|
+
#
|
29
|
+
# def show
|
30
|
+
# puts "View Brought To You By: #{view_name} # => View Brought To You By alternative
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
def view_name
|
35
|
+
self.class.view_name
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# @return the view for this scene.
|
40
|
+
#
|
41
|
+
def view
|
42
|
+
self.class.view
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Loads and caches the view content based on the avilable view parsers and
|
47
|
+
# the view files defined.
|
48
|
+
#
|
49
|
+
# @return the content contained within the view
|
50
|
+
#
|
51
|
+
def view_content
|
52
|
+
view.content
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# Saves the current content of the view back through the view's writer
|
57
|
+
#
|
58
|
+
def save_view
|
59
|
+
view.content = self.to_hash
|
60
|
+
view.save
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# When the module is included insure that all the class helper methods are added
|
65
|
+
# at the same time.
|
66
|
+
#
|
67
|
+
def self.included(base)
|
68
|
+
base.extend ClassMethods
|
69
|
+
end
|
70
|
+
|
71
|
+
module ClassMethods
|
72
|
+
|
73
|
+
#
|
74
|
+
# A Scene by default uses the name of the Scene to find it's associated
|
75
|
+
# view.
|
76
|
+
#
|
77
|
+
# @example Custom View Name
|
78
|
+
#
|
79
|
+
# class ClosingScene < Metro::Scene
|
80
|
+
# view_name 'alternative'
|
81
|
+
# end
|
82
|
+
#
|
83
|
+
# ClosingScene.view_name # => views/alternative
|
84
|
+
#
|
85
|
+
def view_name(name = nil)
|
86
|
+
name ? view.name = name : view.name
|
87
|
+
view.name
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Loads and caches the view content based on the avilable view parsers and
|
92
|
+
# the view files defined.
|
93
|
+
#
|
94
|
+
# @return a view object
|
95
|
+
#
|
96
|
+
def view
|
97
|
+
@view ||=begin
|
98
|
+
view = View.new
|
99
|
+
view.name = scene_name
|
100
|
+
view
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require_relative 'parsers'
|
2
|
+
require_relative 'writers'
|
3
|
+
|
4
|
+
module Metro
|
5
|
+
|
6
|
+
#
|
7
|
+
# A view represents the representation of the content found within
|
8
|
+
# the view file. A view has the ability to save/load the content
|
9
|
+
# as well.
|
10
|
+
#
|
11
|
+
class View
|
12
|
+
|
13
|
+
#
|
14
|
+
# The name of the view, which is used to influence the file path.
|
15
|
+
#
|
16
|
+
attr_accessor :name
|
17
|
+
|
18
|
+
#
|
19
|
+
# The content contained within the view.
|
20
|
+
#
|
21
|
+
def content
|
22
|
+
@content ||= begin
|
23
|
+
parsed_content = parse
|
24
|
+
parsed_content.default = {}
|
25
|
+
parsed_content
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_writer :content
|
30
|
+
|
31
|
+
#
|
32
|
+
# A Scene view path is based on the view name.
|
33
|
+
#
|
34
|
+
# @example Standard View Path
|
35
|
+
#
|
36
|
+
# class OpeningScene < Metro::Scene
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# OpeniningScene.view_path # => views/opening
|
40
|
+
#
|
41
|
+
# @example Custom View Path
|
42
|
+
#
|
43
|
+
# class ClosingScene < Metro::Scene
|
44
|
+
# view_name 'alternative'
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# ClosingScene.view_path # => views/alternative
|
48
|
+
#
|
49
|
+
def view_path
|
50
|
+
File.join "views", name
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Parse the content found at the view path for the view.
|
55
|
+
#
|
56
|
+
# @return the hash of content stored within the view file.
|
57
|
+
#
|
58
|
+
def parse
|
59
|
+
parser.parse(view_path)
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# The parser for this view is one of the supported parsers. A parser
|
64
|
+
# is selected if the parser is capable of finding the content to
|
65
|
+
# load.
|
66
|
+
#
|
67
|
+
def parser
|
68
|
+
@parser ||= supported_parsers.find { |parser| parser.exists? view_path }
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# Supported view formats
|
73
|
+
#
|
74
|
+
def supported_parsers
|
75
|
+
Views::Parsers.parsers
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# Ask the parser to save the current content of the view at the view path
|
80
|
+
#
|
81
|
+
def save
|
82
|
+
writer.write(view_path,content)
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# Return the format of the view. By default the format of the view is dictated
|
87
|
+
# by the format of the content that is parsed.
|
88
|
+
#
|
89
|
+
def format
|
90
|
+
@format || parser.format
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# Setting the format allows the view to be changed from the current format as
|
95
|
+
# dictated what is parsed by the parser.
|
96
|
+
#
|
97
|
+
# This is mostly to benefit the edit transition scene which inherits all the view
|
98
|
+
# related data from the scene that is being edited but does not inherit the
|
99
|
+
# the view (which would have the parser).
|
100
|
+
#
|
101
|
+
# @see EditTransitionScene
|
102
|
+
#
|
103
|
+
attr_writer :format
|
104
|
+
|
105
|
+
#
|
106
|
+
# The writer for this view. If the view has already been parsed then use
|
107
|
+
#
|
108
|
+
def writer
|
109
|
+
@writer ||= begin
|
110
|
+
writer_matching_existing_parser = supported_writers.find { |writer| writer.format == format }
|
111
|
+
writer_matching_existing_parser || default_writer
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def supported_writers
|
116
|
+
Views::Writers.writers
|
117
|
+
end
|
118
|
+
|
119
|
+
def default_writer
|
120
|
+
Views::Writers.default_writer
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative 'yaml_view'
|
2
|
+
require_relative 'json_view'
|
3
|
+
|
4
|
+
module Metro
|
5
|
+
module Views
|
6
|
+
|
7
|
+
module Writers
|
8
|
+
extend self
|
9
|
+
|
10
|
+
def register(writer)
|
11
|
+
writers.push writer
|
12
|
+
end
|
13
|
+
|
14
|
+
def writers
|
15
|
+
@writers ||= []
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_accessor :default_writer
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
Writers.register YAMLView
|
23
|
+
Writers.register JSONView
|
24
|
+
Writers.default_writer = YAMLView
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Metro
|
4
|
+
module Views
|
5
|
+
|
6
|
+
class YAMLView
|
7
|
+
|
8
|
+
#
|
9
|
+
# Determine if a view exists for this specified format
|
10
|
+
#
|
11
|
+
# @param [String] view_path the name of the view to find
|
12
|
+
# @return a true if the yaml view exists and false if it does not exist.
|
13
|
+
#
|
14
|
+
def self.exists?(view_path)
|
15
|
+
yaml_view_paths(view_path).find { |view_path| File.exists? view_path }
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Parse the contents of the view given the name.
|
20
|
+
#
|
21
|
+
# @param [String] view_path the name of the view to read
|
22
|
+
# @return a Hash that contains the contents of the view.
|
23
|
+
#
|
24
|
+
def self.parse(view_path)
|
25
|
+
YAML.load File.read yaml_view_path(view_path)
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# @return the file type format of this view.
|
30
|
+
#
|
31
|
+
def self.format
|
32
|
+
:yaml
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# @param [String] view_path the file path to the view which to save the content
|
37
|
+
# @param [Hash] content the content to save within the view
|
38
|
+
#
|
39
|
+
def self.write(view_path,content)
|
40
|
+
filename = write_filepath(view_path)
|
41
|
+
yaml_content = content.to_yaml
|
42
|
+
File.write(filename,yaml_content)
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# @return the default extension to use when saving yaml files.
|
47
|
+
#
|
48
|
+
def self.default_extname
|
49
|
+
@default_extname || ".yaml"
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# Set the default extname
|
54
|
+
#
|
55
|
+
# @example
|
56
|
+
#
|
57
|
+
# Metro::Views::YAMLView.default_extname = ".yml"
|
58
|
+
#
|
59
|
+
def self.default_extname=(value)
|
60
|
+
@default_extname = value
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
#
|
66
|
+
# If a file already exists with .yaml or .yml use that extension. Otherwise, we
|
67
|
+
# will fall back to the default extension name.
|
68
|
+
#
|
69
|
+
def self.write_filepath(view_path)
|
70
|
+
if existing_file = exists?(view_path)
|
71
|
+
existing_file
|
72
|
+
else
|
73
|
+
"#{view_path}#{default_extname}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# A helper method to get the view file.
|
79
|
+
#
|
80
|
+
def self.yaml_view_path(view_path)
|
81
|
+
yaml_view_paths(view_path).find { |view_path| File.exists? view_path }
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# A helper method to generate the name of the yaml view file. In this case
|
86
|
+
# it is the view name with the suffix `.yaml` or `.yml`.
|
87
|
+
#
|
88
|
+
def self.yaml_view_paths(view_path)
|
89
|
+
File.extname(view_path) == "" ? [ "#{view_path}.yaml", "#{view_path}.yml" ] : [ view_path ]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|