RUIC 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/HISTORY +23 -0
- data/README.md +2 -2
- data/lib/ruic.rb +11 -3
- data/lib/ruic/application.rb +28 -22
- data/lib/ruic/attributes.rb +10 -2
- data/lib/ruic/behaviors.rb +2 -15
- data/lib/ruic/effect.rb +32 -0
- data/lib/ruic/interfaces.rb +51 -13
- data/lib/ruic/presentation.rb +46 -20
- data/lib/ruic/renderplugin.rb +18 -0
- data/lib/ruic/ripl.rb +45 -0
- data/lib/ruic/statemachine.rb +142 -25
- data/lib/ruic/version.rb +1 -1
- data/test/customclasses.ruic +0 -1
- data/test/filtering.ruic +0 -1
- data/test/futureassets.ruic +0 -1
- data/test/nonmaster.ruic +0 -1
- data/test/paths.ruic +0 -2
- data/test/projects/MissingAssets/Existing.uip +87 -0
- data/test/projects/MissingAssets/MissingAssets.uia +21 -0
- data/test/projects/MissingAssets/MissingAssets.uia-user +14 -0
- data/test/projects/MissingAssets/RoundedPlane-1/RoundedPlane-1.import +18 -0
- data/test/projects/MissingAssets/RoundedPlane-1/meshes/RoundedPlane.mesh +0 -0
- data/test/projects/MissingAssets/effects/effects.txt +3 -0
- data/test/projects/MissingAssets/effects/existing.effect +38 -0
- data/test/projects/MissingAssets/fonts/Arimo-Regular.ttf +0 -0
- data/test/projects/MissingAssets/fonts/Chivo-Black.ttf +0 -0
- data/test/projects/MissingAssets/fonts/OFL.txt +92 -0
- data/test/projects/MissingAssets/maps/effects/brushnoise.dds +0 -0
- data/test/projects/MissingAssets/maps/existing.png +0 -0
- data/test/projects/MissingAssets/maps/existing2.png +0 -0
- data/test/projects/MissingAssets/maps/maps.txt +2 -0
- data/test/projects/MissingAssets/maps/materials/concrete_plain.png +0 -0
- data/test/projects/MissingAssets/maps/materials/concrete_plain_bump.png +0 -0
- data/test/projects/MissingAssets/maps/materials/spherical_checker.png +0 -0
- data/test/projects/MissingAssets/maps/unused.png +0 -0
- data/test/projects/MissingAssets/materials/concrete.material +251 -0
- data/test/projects/MissingAssets/materials/materials.txt +3 -0
- data/test/projects/MissingAssets/scripts/existing1.lua +2 -0
- data/test/projects/MissingAssets/scripts/existing2.lua +470 -0
- data/test/projects/MissingAssets/states/existing.scxml +4 -0
- data/test/projects/MissingAssets/tests/interface-navigation.scxml-test +3 -0
- data/test/properties.ruic +0 -2
- data/test/referencematerials.ruic +0 -2
- data/test/usage.ruic +38 -4
- metadata +53 -3
- data/lib/ruic/ripl-after-result.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a99bfd85a630d1804e5c38b33296883a2f43342
|
4
|
+
data.tar.gz: f3233b7830899344bcee0c969fdb130e88143b1d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 474bf2cda9e565b3a050fadb9b266980f3b36075f0a953eabf69106695e623575e980fab75c007e78e47f6de6f5e58f0fad217261008392616b47eeca66207d7
|
7
|
+
data.tar.gz: 5a3066ad987ce4597b0ef47d935c8db28bc477ffb281300406184d1119539f84d6130478e3f7ca6dbb3b025d0603567cea0c208fa89867c75d81031832d1a8a0
|
data/HISTORY
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
## v0.6.0
|
2
|
+
|
3
|
+
### Backwards Incompatible Changes
|
4
|
+
|
5
|
+
* Changed `FileBacked#resolve_file_path` to `FileBacked#absolute_path`, and added `FileBacked#relative_path`.
|
6
|
+
* Removed `.errors?` and `.errors` for application and assets.
|
7
|
+
|
8
|
+
### New/Changed Features
|
9
|
+
|
10
|
+
* State machines properly report on visual actions.
|
11
|
+
* _Only `<set-attribute>` properly implemented so far._
|
12
|
+
* Added much improved `Presentation#referenced_files`, `Application#missing_files`, `Application#unused_files`.
|
13
|
+
* Tweaked REPL output.
|
14
|
+
* `nil` results no longer print `#=> nil` in the REPL.
|
15
|
+
* `show` prefixes the result with `#=>`.
|
16
|
+
* Multi-line results are now wrapped, with each line prefixed with `#=>`.
|
17
|
+
* Added beginnings of support for effects and renderplugins.
|
18
|
+
* Presentations do not cause a runtime error if a custom class (e.g. behavior, effect, custom material) cannot be found.
|
19
|
+
|
20
|
+
### Bug Fixes
|
21
|
+
* Fix bug that caused some properties to report their type as `nil` or `float` instead of `Float`.
|
22
|
+
* Presentations are slightly more capable if they are created without an existing file.
|
23
|
+
|
1
24
|
## v0.5.0 - 2014-Nov-26
|
2
25
|
|
3
26
|
* Fix bug that prevented loading an application from the command line in another directory.
|
data/README.md
CHANGED
@@ -167,7 +167,7 @@ There are two ways to enter interactive mode:
|
|
167
167
|
the application and enter the REPL:
|
168
168
|
|
169
169
|
$ ruic myapp.uia
|
170
|
-
(RUIC v0.
|
170
|
+
(RUIC v0.6.0 interactive session; 'quit' or ctrl-d to end)
|
171
171
|
|
172
172
|
uia "test/projects/SimpleScene/SimpleScene.uia"
|
173
173
|
#=> <UIC::Application 'SimpleScene.uia'>
|
@@ -176,7 +176,7 @@ There are two ways to enter interactive mode:
|
|
176
176
|
by supplying the `-i` command-line switch:
|
177
177
|
|
178
178
|
$ ruic -i test/referencematerials.ruic
|
179
|
-
(RUIC v0.
|
179
|
+
(RUIC v0.6.0 interactive session; 'quit' or ctrl-d to end)
|
180
180
|
|
181
181
|
app
|
182
182
|
#=> <UIC::Application 'ReferencedMaterials.uia'>
|
data/lib/ruic.rb
CHANGED
@@ -10,8 +10,11 @@ require_relative 'ruic/assets'
|
|
10
10
|
require_relative 'ruic/interfaces'
|
11
11
|
require_relative 'ruic/application'
|
12
12
|
require_relative 'ruic/behaviors'
|
13
|
+
require_relative 'ruic/effect'
|
14
|
+
require_relative 'ruic/renderplugin'
|
13
15
|
require_relative 'ruic/statemachine'
|
14
16
|
require_relative 'ruic/presentation'
|
17
|
+
require_relative 'ruic/ripl'
|
15
18
|
|
16
19
|
# The `RUIC` class provides the interface for running scripts using the special DSL,
|
17
20
|
# and for running the interactive REPL.
|
@@ -67,11 +70,11 @@ class RUIC
|
|
67
70
|
require 'ripl/irb'
|
68
71
|
require 'ripl/multi_line'
|
69
72
|
require 'ripl/multi_line/live_error.rb'
|
70
|
-
require_relative 'ruic/ripl-after-result'
|
71
73
|
Ripl::MultiLine.engine = Ripl::MultiLine::LiveError
|
72
74
|
Ripl::Shell.include Ripl::MultiLine.engine
|
73
75
|
Ripl::Shell.include Ripl::AfterResult
|
74
|
-
Ripl.
|
76
|
+
Ripl::Shell.include Ripl::FormatResult
|
77
|
+
Ripl.config.merge! prompt:"", result_prompt:'#=> ', multi_line_prompt:' ', irb_verbose:false, after_result:"\n", result_line_limit:120, prefix_result_lines:true, skip_nil_results:true
|
75
78
|
ARGV.clear # So that RIPL doesn't try to interpret the options
|
76
79
|
puts "(RUIC v#{RUIC::VERSION} interactive session; 'quit' or ctrl-d to end)"
|
77
80
|
ruic.instance_eval{ puts @apps.map{ |n,app| "(#{n} is #{app.inspect})" } }
|
@@ -150,7 +153,12 @@ class RUIC
|
|
150
153
|
|
151
154
|
# Nicer name for `puts` to be used in the DSL, printing the
|
152
155
|
# 'nice' string equivalent for all supplied arguments.
|
153
|
-
def show(*a)
|
156
|
+
def show(*a)
|
157
|
+
a=a.first if a.length==1 && a.first.is_a?(Array)
|
158
|
+
opts = { result_prompt:'# ', result_line_limit:120, prefix_result_lines:true, to_s:true }
|
159
|
+
a.each{ |x| puts Ripl::FormatResult.format_result(x,opts) }
|
160
|
+
nil # so that Ripl won't show the result
|
161
|
+
end
|
154
162
|
|
155
163
|
def inspect
|
156
164
|
"<RUIC #{@apps.empty? ? "(no app loaded)" : Hash[ @apps.map{ |id,app| [id,File.basename(app.file)] } ]}>"
|
data/lib/ruic/application.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# The `Application` represents the root of your UIC application, corresponding to a `.uia` file.
|
2
2
|
class UIC::Application
|
3
|
-
include UIC::
|
3
|
+
include UIC::XMLFileBacked
|
4
4
|
|
5
5
|
def inspect
|
6
6
|
"<UIC::Application '#{File.basename(file)}'#{:' FILENOTFOUND' unless file_found?}>"
|
@@ -14,18 +14,16 @@ class UIC::Application
|
|
14
14
|
# If omitted you will need to later set the `.file = ` for the
|
15
15
|
# instance and then call {#load_from_file}.
|
16
16
|
def initialize(metadata,uia_path=nil)
|
17
|
+
@assets = {}
|
17
18
|
@metadata = metadata
|
18
19
|
self.file = uia_path
|
19
|
-
@assets = {}
|
20
|
-
load_from_file if file_found?
|
21
20
|
end
|
22
21
|
|
23
22
|
# Loads the application from the file. If you pass the path to your `.uia`
|
24
23
|
# to {#initialize} then this method is called automatically.
|
25
24
|
#
|
26
25
|
# @return [nil]
|
27
|
-
def
|
28
|
-
self.doc = Nokogiri.XML(File.read(file,encoding:'utf-8'))
|
26
|
+
def on_doc_loaded
|
29
27
|
@assets = @doc.search('assets *').map do |el|
|
30
28
|
case el.name
|
31
29
|
when 'behavior' then UIC::Application::Behavior
|
@@ -37,18 +35,6 @@ class UIC::Application
|
|
37
35
|
nil
|
38
36
|
end
|
39
37
|
|
40
|
-
# @return [Boolean] true if there are any errors with the application.
|
41
|
-
def errors?
|
42
|
-
!errors.empty?
|
43
|
-
end
|
44
|
-
|
45
|
-
# @example
|
46
|
-
# show app.errors if app.errors?
|
47
|
-
# @return [Array<String>] an array (possibly empty) of all errors in this application (including referenced assets).
|
48
|
-
def errors
|
49
|
-
file_found? ? assets.flat_map(&:errors) : ["File not found: '#{file}'"]
|
50
|
-
end
|
51
|
-
|
52
38
|
# Find an asset by `.uia` identifier or path to the asset.
|
53
39
|
# @example
|
54
40
|
# main1 = app['#main']
|
@@ -71,17 +57,37 @@ class UIC::Application
|
|
71
57
|
end
|
72
58
|
end
|
73
59
|
|
74
|
-
#
|
60
|
+
# Files in the application directory not used by the application.
|
61
|
+
#
|
62
|
+
# @return [Array<String>] absolute paths of files in the directory not used by the application.
|
75
63
|
def unused_files
|
76
|
-
|
64
|
+
(directory_files - referenced_files).sort
|
77
65
|
end
|
78
66
|
|
79
|
-
#
|
67
|
+
# Files referenced by the application but not present in the directory.
|
68
|
+
#
|
69
|
+
# @return [Array<String>] absolute paths of files referenced but gone.
|
70
|
+
def missing_files
|
71
|
+
(referenced_files - directory_files).sort
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
# @return [Array<String>] absolute paths of files referenced by the application.
|
80
76
|
def referenced_files
|
81
77
|
# TODO: state machines can reference external scripts
|
82
78
|
# TODO: behaviors can reference external scripts
|
83
|
-
|
84
|
-
|
79
|
+
(
|
80
|
+
[file] +
|
81
|
+
assets.map{ |asset| absolute_path(asset.src) } +
|
82
|
+
statemachines.flat_map(&:referenced_files) +
|
83
|
+
presentations.flat_map(&:referenced_files)
|
84
|
+
).uniq
|
85
|
+
end
|
86
|
+
|
87
|
+
# @return [Array<String>] absolute paths of all files present in the application directory (used or not).
|
88
|
+
def directory_files
|
89
|
+
dir = File.dirname(file)
|
90
|
+
Dir.chdir(dir){ Dir['**/*.*'] }.map{ |f| File.expand_path(f,dir) }
|
85
91
|
end
|
86
92
|
|
87
93
|
# @return [Array] all assets referenced by the application. Ordered by the order they appear in the `.uia`.
|
data/lib/ruic/attributes.rb
CHANGED
@@ -7,7 +7,7 @@ class UIC::Property
|
|
7
7
|
attr_accessor :default
|
8
8
|
def initialize(el); @el = el; end
|
9
9
|
def name; @name||=@el['name']; end
|
10
|
-
def type; @type||=@el['type']; end
|
10
|
+
def type; @type||=@el['type'] ? (@el['type']=='float' ? 'Float' : @el['type']) : 'Float'; end
|
11
11
|
def formal; @formal||=@el['formalName'] || @el['name']; end
|
12
12
|
def min; @el['min']; end
|
13
13
|
def max; @el['max']; end
|
@@ -129,10 +129,18 @@ class UIC::Property
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
+
class Font < self
|
133
|
+
self.default = 'Arimo-Regular'
|
134
|
+
def get(asset,slide); "fonts/#{super}.ttf"; end # TODO: how to support non-ttf fonts?
|
135
|
+
def set(asset,new_value,slide_name_or_index)
|
136
|
+
# TODO: how to support non-ttf fonts?
|
137
|
+
super( asset, new_value.sub(%r{^\.[/\\]},'').sub(%r{^fonts[/\\]},'').sub(%r{\.ttf$},''), slide_name_or_index )
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
132
141
|
Import = String #TODO: a real class
|
133
142
|
Mesh = String #TODO: a real class
|
134
143
|
Renderable = String #TODO: a real class
|
135
|
-
Font = String #TODO: a real class
|
136
144
|
FontSize = Long
|
137
145
|
|
138
146
|
StringListOrInt = String #TODO: a real class
|
data/lib/ruic/behaviors.rb
CHANGED
@@ -1,22 +1,9 @@
|
|
1
1
|
class UIC::Behavior
|
2
2
|
include UIC::FileBacked
|
3
|
-
attr_reader :lua
|
4
3
|
def initialize( lua_path )
|
5
4
|
self.file = lua_path
|
6
|
-
load_from_file if file_found?
|
7
5
|
end
|
8
|
-
|
9
|
-
@lua = File.read(file,encoding:'utf-8')
|
10
|
-
end
|
11
|
-
|
12
|
-
def errors?
|
13
|
-
!errors.empty?
|
14
|
-
end
|
15
|
-
|
16
|
-
def errors
|
17
|
-
file_found? ? [] : ["File not found: '#{file}'"]
|
18
|
-
end
|
19
|
-
|
6
|
+
alias_method :lua, :file_content
|
20
7
|
end
|
21
8
|
|
22
9
|
class UIC::Application::Behavior < UIC::Behavior
|
@@ -27,6 +14,6 @@ class UIC::Application::Behavior < UIC::Behavior
|
|
27
14
|
def initialize(application,el)
|
28
15
|
self.owner = application
|
29
16
|
self.el = el
|
30
|
-
super( application.
|
17
|
+
super( application.absolute_path(src) )
|
31
18
|
end
|
32
19
|
end
|
data/lib/ruic/effect.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
class UIC::Effect
|
2
|
+
include UIC::FileBacked
|
3
|
+
attr_reader :lua
|
4
|
+
def initialize( lua_path )
|
5
|
+
self.file = lua_path
|
6
|
+
load_from_file if file_found?
|
7
|
+
end
|
8
|
+
def load_from_file
|
9
|
+
@lua = File.read(file,encoding:'utf-8')
|
10
|
+
end
|
11
|
+
|
12
|
+
def errors?
|
13
|
+
!errors.empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
def errors
|
17
|
+
file_found? ? [] : ["File not found: '#{file}'"]
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
class UIC::Application::Effect < UIC::Effect
|
23
|
+
include UIC::ElementBacked
|
24
|
+
# @!parse extend UIC::ElementBacked::ClassMethods
|
25
|
+
xmlattribute :id
|
26
|
+
xmlattribute :src
|
27
|
+
def initialize(application,el)
|
28
|
+
self.owner = application
|
29
|
+
self.el = el
|
30
|
+
super( application.absolute_path(src) )
|
31
|
+
end
|
32
|
+
end
|
data/lib/ruic/interfaces.rb
CHANGED
@@ -1,17 +1,23 @@
|
|
1
|
-
# Supports classes that represent
|
1
|
+
# Supports classes that represent a file on disk (e.g. `.uia` and `.uip`).
|
2
2
|
module UIC::FileBacked
|
3
|
-
# @return [Nokogiri::XML::Document] the Nokogiri document representing the instance.
|
4
|
-
attr_accessor :doc
|
5
|
-
|
6
3
|
# @return [String] the absolute path to the underlying file.
|
7
4
|
attr_accessor :file
|
8
5
|
|
6
|
+
# @return [String] the content of the file.
|
7
|
+
attr_accessor :file_content
|
8
|
+
|
9
9
|
# @param relative [String] a file path relative to this file.
|
10
10
|
# @return [String] the full path resolved relative to this file.
|
11
|
-
def
|
11
|
+
def absolute_path( relative )
|
12
12
|
File.expand_path( relative.gsub('\\','/'), File.dirname(file) )
|
13
13
|
end
|
14
14
|
|
15
|
+
def relative_path(path)
|
16
|
+
my_dir = File.dirname(file) << "/"
|
17
|
+
absolute_path(path).tap{ |s| s.slice!(my_dir) }
|
18
|
+
|
19
|
+
end
|
20
|
+
|
15
21
|
# @return [String] the name of the file (without any directories).
|
16
22
|
def filename
|
17
23
|
File.basename(file)
|
@@ -27,6 +33,39 @@ module UIC::FileBacked
|
|
27
33
|
# @return [String]
|
28
34
|
def file=( new_path )
|
29
35
|
@file = File.expand_path(new_path)
|
36
|
+
if file_found?
|
37
|
+
@file_content = File.read(@file,encoding:'utf-8')
|
38
|
+
on_file_loaded if respond_to?(:on_file_loaded)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Overwrite the associated file on disk with the `@file_content` of this class.
|
43
|
+
# @return [true]
|
44
|
+
def save!
|
45
|
+
File.open(file,'w:utf-8'){ |f| f << @file_content }
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
# Save to the supplied file path. Subsequent calls to {#save!} will save to the new file, not the original file name.
|
50
|
+
def save_as(new_file)
|
51
|
+
File.open(new_file,'w:utf-8'){ |f| f << @file_content }
|
52
|
+
self.file = new_file
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Supports classes that represent an XML file on disk.
|
57
|
+
module UIC::XMLFileBacked
|
58
|
+
include UIC::FileBacked
|
59
|
+
|
60
|
+
# @return [Nokogiri::XML::Document] the Nokogiri document representing the instance.
|
61
|
+
attr_accessor :doc
|
62
|
+
|
63
|
+
def file=( new_path )
|
64
|
+
super
|
65
|
+
if file_found?
|
66
|
+
@doc = Nokogiri.XML(file_content,&:noblanks)
|
67
|
+
on_doc_loaded if respond_to?(:on_doc_loaded)
|
68
|
+
end
|
30
69
|
end
|
31
70
|
|
32
71
|
# @return [String] the XML representation of the document.
|
@@ -37,20 +76,19 @@ module UIC::FileBacked
|
|
37
76
|
# Overwrite the associated file on disk with the {#to_xml} representation of this class.
|
38
77
|
# @return [true]
|
39
78
|
def save!
|
40
|
-
|
41
|
-
|
79
|
+
self.file_content = to_xml
|
80
|
+
super
|
42
81
|
end
|
43
82
|
|
44
83
|
# Save to the supplied file path. Subsequent calls to {#save!} will save to the new file, not the original file name.
|
45
84
|
def save_as(new_file)
|
46
|
-
|
47
|
-
|
85
|
+
self.file_content = to_xml
|
86
|
+
super
|
48
87
|
end
|
49
88
|
end
|
50
89
|
|
51
90
|
# Supports classes that represent an XML element (e.g. `<presentation id="main" src="foo.uip"/>`).
|
52
91
|
module UIC::ElementBacked
|
53
|
-
|
54
92
|
# @return [Object] the object in charge of this instance.
|
55
93
|
attr_accessor :owner
|
56
94
|
|
@@ -65,10 +103,10 @@ module UIC::ElementBacked
|
|
65
103
|
module ClassMethods
|
66
104
|
# Add methods to instances of the class which gets/sets from an XML attribute.
|
67
105
|
# @param name [String] the name of an XML attribute to expose.
|
68
|
-
# @param getblock [Proc] a proc to run
|
106
|
+
# @param getblock [Proc] a proc to run to fetch the value.
|
69
107
|
def xmlattribute(name,getblock=nil,&setblock)
|
70
|
-
define_method(name){ getblock ? getblock[@el[name]] : @el[name] }
|
71
|
-
define_method("#{name}="){ |new_value| @el[name] = (setblock ? setblock[new_value] : new_value).to_s }
|
108
|
+
define_method(name){ getblock ? getblock[@el[name],self] : @el[name] }
|
109
|
+
define_method("#{name}="){ |new_value| @el[name] = (setblock ? setblock[new_value,self] : new_value).to_s }
|
72
110
|
end
|
73
111
|
end
|
74
112
|
end
|
data/lib/ruic/presentation.rb
CHANGED
@@ -1,22 +1,28 @@
|
|
1
1
|
# A `Presentation` represents a `.uip` presentation, created and edited by UI Composer Studio.
|
2
2
|
class UIC::Presentation
|
3
|
-
include UIC::
|
3
|
+
include UIC::XMLFileBacked
|
4
4
|
|
5
5
|
# Create a new presentation. If you do not specify the `uip_path` to load from, you must
|
6
6
|
# later set the `.file = `for the presentation, and then call the {#load_from_file} method.
|
7
7
|
# @param uip_path [String] path to the `.uip` to load.
|
8
8
|
def initialize( uip_path=nil )
|
9
|
-
|
10
|
-
|
9
|
+
@doc = Nokogiri.XML('<UIP version="3"><Project><Graph><Scene id="Scene"/></Graph><Logic><State name="Master Slide" component="#Scene"/></Logic></Project></UIP>')
|
10
|
+
@graph = @doc.at('Graph')
|
11
|
+
@scene = @graph.at('Scene')
|
12
|
+
@logic = @doc.at('Logic')
|
13
|
+
@missing_classes = []
|
14
|
+
@asset_by_el = {} # indexed by asset graph element
|
15
|
+
@slides_for = {} # indexed by asset graph element
|
16
|
+
@slides_by_el = {} # indexed by slide state element
|
17
|
+
self.file = uip_path if uip_path
|
11
18
|
end
|
12
19
|
|
13
20
|
# Load information for the presentation from disk.
|
14
21
|
# If you supply a path to a `.uip` file when creating the presentation
|
15
22
|
# this method is automatically called.
|
23
|
+
#
|
16
24
|
# @return [nil]
|
17
|
-
def
|
18
|
-
# TODO: this method assumes an application to find the metadata on; the metadata should be part of this class instance instead, shared with the app when present
|
19
|
-
@doc = Nokogiri.XML( File.read( file, encoding:'utf-8' ), &:noblanks )
|
25
|
+
def on_doc_loaded
|
20
26
|
@graph = @doc.at('Graph')
|
21
27
|
@scene = @graph.at('Scene')
|
22
28
|
@logic = @doc.at('Logic')
|
@@ -24,10 +30,6 @@ class UIC::Presentation
|
|
24
30
|
generate_custom_classes
|
25
31
|
rebuild_caches_from_document
|
26
32
|
|
27
|
-
@asset_by_el = {} # indexed by asset graph element
|
28
|
-
@slides_for = {} # indexed by asset graph element
|
29
|
-
@slides_by_el = {} # indexed by slide state element
|
30
|
-
|
31
33
|
nil
|
32
34
|
end
|
33
35
|
|
@@ -42,6 +44,7 @@ class UIC::Presentation
|
|
42
44
|
# Called once during initial load of the file.
|
43
45
|
# @return [nil]
|
44
46
|
def generate_custom_classes
|
47
|
+
# TODO: this method assumes an application to find the metadata on; the metadata should be part of this class instance instead, shared with the app when present
|
45
48
|
parent_class_name = {
|
46
49
|
'CustomMaterial' => 'MaterialBase',
|
47
50
|
'Effect' => 'Effect',
|
@@ -49,8 +52,8 @@ class UIC::Presentation
|
|
49
52
|
}
|
50
53
|
@class_by_ref = {}
|
51
54
|
@doc.xpath('/UIP/Project/Classes/*').each do |reference|
|
52
|
-
path =
|
53
|
-
|
55
|
+
path = absolute_path( reference['sourcepath'] )
|
56
|
+
next unless File.exist?( path )
|
54
57
|
parent_class = app.metadata.by_name[ parent_class_name[reference.name] ]
|
55
58
|
parent_props = parent_class.properties
|
56
59
|
new_defaults = Hash[ reference.attributes.map{ |name,attr| [name,attr.value] }.select{ |name,val| parent_props[name] } ]
|
@@ -169,16 +172,39 @@ class UIC::Presentation
|
|
169
172
|
# Find or create an asset for a scene graph element.
|
170
173
|
# @param el [Nokogiri::XML::Element] the scene graph element.
|
171
174
|
def asset_for_el(el)
|
172
|
-
|
175
|
+
@asset_by_el[el] ||= begin
|
176
|
+
if el['class'] && @class_by_ref[el['class']]
|
177
|
+
@class_by_ref[el['class']].new(self,el)
|
178
|
+
else
|
179
|
+
app.metadata.new_instance(self,el)
|
180
|
+
end
|
181
|
+
end
|
173
182
|
end
|
174
183
|
private :asset_for_el
|
175
184
|
|
185
|
+
# Which files are used by the presentation.
|
186
|
+
# @return [Array<String>] array of absolute file paths referenced by this presentation.
|
176
187
|
def referenced_files
|
177
188
|
(
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
189
|
+
[file] +
|
190
|
+
%w[sourcepath importfile].flat_map do |att|
|
191
|
+
find(att=>/./).flat_map do |asset|
|
192
|
+
asset[att].values.compact.map do |path|
|
193
|
+
path.sub!(/#.+/,'')
|
194
|
+
absolute_path(path) unless path.empty?
|
195
|
+
end.compact
|
196
|
+
end
|
197
|
+
end +
|
198
|
+
find.flat_map do |asset|
|
199
|
+
asset.properties.select{ |name,prop| prop.type=='Texture' }.flat_map do |name,prop|
|
200
|
+
asset[name].values.compact.uniq.map{ |path| absolute_path(path) }
|
201
|
+
end
|
202
|
+
end +
|
203
|
+
find(_type:'Text').flat_map do |asset|
|
204
|
+
asset['font'].values.compact.map{ |font| absolute_path(font) }
|
205
|
+
end +
|
206
|
+
@doc.xpath('/UIP/Project/Classes/*/@sourcepath').map{ |att| absolute_path att.value }
|
207
|
+
).uniq
|
182
208
|
end
|
183
209
|
|
184
210
|
# @return [MetaData::Scene] the root scene asset for the presentation.
|
@@ -243,7 +269,7 @@ class UIC::Presentation
|
|
243
269
|
|
244
270
|
# @return [Array<String>] an array (possibly empty) of all errors in this presentation.
|
245
271
|
def errors
|
246
|
-
|
272
|
+
@errors
|
247
273
|
end
|
248
274
|
|
249
275
|
# Find an element or asset in this presentation by scripting path.
|
@@ -599,7 +625,7 @@ class UIC::Presentation
|
|
599
625
|
cols = hier.map{ |i,a| a ? [ [i,a.name].join, a.type, elide[a.path] ] : [i,"",""] }
|
600
626
|
maxs = cols.transpose.map{ |col| col.map(&:length).max }
|
601
627
|
tmpl = maxs.map{ |n| "%-#{n}s" }.join(' ')
|
602
|
-
cols.map{ |a| tmpl % a }.join("\n").
|
628
|
+
cols.map{ |a| tmpl % a }.join("\n").extend(RUIC::SelfInspecting)
|
603
629
|
end
|
604
630
|
|
605
631
|
# @private
|
@@ -643,7 +669,7 @@ class UIC::Application::Presentation < UIC::Presentation
|
|
643
669
|
def initialize(application,el)
|
644
670
|
self.owner = application
|
645
671
|
self.el = el
|
646
|
-
super( application.
|
672
|
+
super( application.absolute_path(src) )
|
647
673
|
end
|
648
674
|
alias_method :app, :owner
|
649
675
|
|