RUIC 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|