RUIC 0.6.0 → 0.6.1
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/.yardopts +3 -3
 - data/HISTORY +110 -86
 - data/README.md +220 -220
 - data/bin/ruic +61 -61
 - data/gui/TODO +2 -2
 - data/gui/appattributesmodel.rb +51 -51
 - data/gui/appelementsmodel.rb +126 -126
 - data/gui/launch.rb +19 -19
 - data/gui/makefile +14 -14
 - data/gui/resources/style/dark.qss +459 -459
 - data/gui/window.rb +90 -90
 - data/gui/window.ui +753 -753
 - data/lib/ruic.rb +191 -190
 - data/lib/ruic/application.rb +25 -3
 - data/lib/ruic/assets.rb +441 -436
 - data/lib/ruic/attributes.rb +179 -178
 - data/lib/ruic/behaviors.rb +0 -0
 - data/lib/ruic/effect.rb +31 -31
 - data/lib/ruic/interfaces.rb +0 -0
 - data/lib/ruic/nicebytes.rb +29 -0
 - data/lib/ruic/presentation.rb +6 -3
 - data/lib/ruic/renderplugin.rb +17 -17
 - data/lib/ruic/ripl.rb +45 -45
 - data/lib/ruic/statemachine.rb +6 -0
 - data/lib/ruic/version.rb +3 -3
 - data/ruic.gemspec +25 -25
 - data/test/MetaData-simple.xml +28 -28
 - data/test/MetaData.xml +435 -435
 - data/test/customclasses.ruic +29 -29
 - data/test/filtering.ruic +42 -42
 - data/test/futureassets.ruic +7 -7
 - data/test/nonmaster.ruic +20 -20
 - data/test/paths.ruic +16 -16
 - data/test/projects/CustomClasses/CustomClasses.uia +7 -7
 - data/test/projects/CustomClasses/CustomClasses.uip +40 -40
 - data/test/projects/CustomClasses/FutureAsset.uip +17 -17
 - data/test/projects/MissingAssets/Existing.uip +87 -87
 - data/test/projects/MissingAssets/MissingAssets.uia +0 -0
 - data/test/projects/MissingAssets/MissingAssets.uia-user +14 -14
 - data/test/projects/MissingAssets/RoundedPlane-1/RoundedPlane-1.import +18 -18
 - data/test/projects/MissingAssets/RoundedPlane-1/meshes/RoundedPlane.mesh +0 -0
 - data/test/projects/MissingAssets/effects/effects.txt +0 -0
 - data/test/projects/MissingAssets/effects/existing.effect +0 -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 +0 -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/maps.txt +0 -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/materials/concrete.material +0 -0
 - data/test/projects/MissingAssets/materials/materials.txt +0 -0
 - data/test/projects/MissingAssets/scripts/existing1.lua +0 -0
 - data/test/projects/MissingAssets/scripts/existing2.lua +0 -0
 - data/test/projects/MissingAssets/states/existing.scxml +0 -0
 - data/test/projects/MissingAssets/tests/interface-navigation.scxml-test +0 -0
 - data/test/projects/Paths/Paths.uia +4 -4
 - data/test/projects/Paths/Paths.uip +98 -98
 - data/test/projects/SimpleScene/SimpleScene.uia +4 -4
 - data/test/projects/SimpleScene/SimpleScene.uip +35 -35
 - data/test/properties.ruic +80 -80
 - data/test/referencematerials.ruic +50 -50
 - data/test/usage.ruic +54 -54
 - metadata +5 -54
 
    
        data/lib/ruic.rb
    CHANGED
    
    | 
         @@ -1,191 +1,192 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #encoding:utf-8
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            class RUIC; end
         
     | 
| 
       4 
     | 
    
         
            -
            module UIC; end
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            require 'nokogiri'
         
     | 
| 
       7 
     | 
    
         
            -
            require_relative 'ruic/version'
         
     | 
| 
       8 
     | 
    
         
            -
            require_relative 'ruic/attributes'
         
     | 
| 
       9 
     | 
    
         
            -
            require_relative 'ruic/assets'
         
     | 
| 
       10 
     | 
    
         
            -
            require_relative 'ruic/interfaces'
         
     | 
| 
       11 
     | 
    
         
            -
            require_relative 'ruic/application'
         
     | 
| 
       12 
     | 
    
         
            -
            require_relative 'ruic/behaviors'
         
     | 
| 
       13 
     | 
    
         
            -
            require_relative 'ruic/effect'
         
     | 
| 
       14 
     | 
    
         
            -
            require_relative 'ruic/renderplugin'
         
     | 
| 
       15 
     | 
    
         
            -
            require_relative 'ruic/statemachine'
         
     | 
| 
       16 
     | 
    
         
            -
            require_relative 'ruic/presentation'
         
     | 
| 
       17 
     | 
    
         
            -
            require_relative 'ruic/ripl'
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
            #  
     | 
| 
       21 
     | 
    
         
            -
            #  
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
            	#
         
     | 
| 
       27 
     | 
    
         
            -
            	# 
     | 
| 
       28 
     | 
    
         
            -
            	#  
     | 
| 
       29 
     | 
    
         
            -
            	#
         
     | 
| 
       30 
     | 
    
         
            -
            	# 
     | 
| 
       31 
     | 
    
         
            -
            	#      
     | 
| 
       32 
     | 
    
         
            -
            	#
         
     | 
| 
       33 
     | 
    
         
            -
            	# 
     | 
| 
       34 
     | 
    
         
            -
            	#      
     | 
| 
       35 
     | 
    
         
            -
            	#
         
     | 
| 
       36 
     | 
    
         
            -
            	# 
     | 
| 
       37 
     | 
    
         
            -
            	#      
     | 
| 
       38 
     | 
    
         
            -
            	#
         
     | 
| 
       39 
     | 
    
         
            -
            	# 
     | 
| 
       40 
     | 
    
         
            -
            	#
         
     | 
| 
       41 
     | 
    
         
            -
            	# 
     | 
| 
       42 
     | 
    
         
            -
            	#  
     | 
| 
       43 
     | 
    
         
            -
            	#  
     | 
| 
       44 
     | 
    
         
            -
            	# failing that, the  
     | 
| 
       45 
     | 
    
         
            -
            	#
         
     | 
| 
       46 
     | 
    
         
            -
            	# 
     | 
| 
       47 
     | 
    
         
            -
            	# @option opts [String] : 
     | 
| 
       48 
     | 
    
         
            -
            	# @option opts [ 
     | 
| 
       49 
     | 
    
         
            -
            	# @ 
     | 
| 
       50 
     | 
    
         
            -
            	 
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
            		 
     | 
| 
       53 
     | 
    
         
            -
            		 
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
            			 
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
            				ruic 
     | 
| 
       58 
     | 
    
         
            -
            				ruic. 
     | 
| 
       59 
     | 
    
         
            -
            				ruic. 
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
            			 
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
            					r. 
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
            				 
     | 
| 
       71 
     | 
    
         
            -
            				require 'ripl/ 
     | 
| 
       72 
     | 
    
         
            -
            				require 'ripl/multi_line 
     | 
| 
       73 
     | 
    
         
            -
            				 
     | 
| 
       74 
     | 
    
         
            -
            				Ripl:: 
     | 
| 
       75 
     | 
    
         
            -
            				Ripl::Shell.include Ripl:: 
     | 
| 
       76 
     | 
    
         
            -
            				Ripl::Shell.include Ripl:: 
     | 
| 
       77 
     | 
    
         
            -
            				Ripl. 
     | 
| 
       78 
     | 
    
         
            -
            				 
     | 
| 
       79 
     | 
    
         
            -
            				 
     | 
| 
       80 
     | 
    
         
            -
            				 
     | 
| 
       81 
     | 
    
         
            -
            				puts " 
     | 
| 
       82 
     | 
    
         
            -
            				 
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
            	#  
     | 
| 
       89 
     | 
    
         
            -
            	 
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
            		@ 
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
            	#  
     | 
| 
       96 
     | 
    
         
            -
            	 
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
            	#  
     | 
| 
       102 
     | 
    
         
            -
            	# @ 
     | 
| 
       103 
     | 
    
         
            -
            	 
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
            		 
     | 
| 
       106 
     | 
    
         
            -
            		 
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
             
     | 
| 
       110 
     | 
    
         
            -
            	 
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
            	 
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
            	#  
     | 
| 
       119 
     | 
    
         
            -
            	 
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
            	#
         
     | 
| 
       125 
     | 
    
         
            -
            	# 
     | 
| 
       126 
     | 
    
         
            -
            	# 
     | 
| 
       127 
     | 
    
         
            -
            	#      
     | 
| 
       128 
     | 
    
         
            -
            	#      
     | 
| 
       129 
     | 
    
         
            -
            	#
         
     | 
| 
       130 
     | 
    
         
            -
            	# 
     | 
| 
       131 
     | 
    
         
            -
            	#      
     | 
| 
       132 
     | 
    
         
            -
            	#      
     | 
| 
       133 
     | 
    
         
            -
            	#
         
     | 
| 
       134 
     | 
    
         
            -
            	# 
     | 
| 
       135 
     | 
    
         
            -
            	# 
     | 
| 
       136 
     | 
    
         
            -
            	#      
     | 
| 
       137 
     | 
    
         
            -
            	#      
     | 
| 
       138 
     | 
    
         
            -
            	#
         
     | 
| 
       139 
     | 
    
         
            -
            	# 
     | 
| 
       140 
     | 
    
         
            -
            	# @param  
     | 
| 
       141 
     | 
    
         
            -
            	# @ 
     | 
| 
       142 
     | 
    
         
            -
            	 
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
       145 
     | 
    
         
            -
            			 
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
            		 
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
       149 
     | 
    
         
            -
            			 
     | 
| 
       150 
     | 
    
         
            -
            			 
     | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
       152 
     | 
    
         
            -
             
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
            	#  
     | 
| 
       156 
     | 
    
         
            -
            	 
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
            		 
     | 
| 
       159 
     | 
    
         
            -
            		 
     | 
| 
       160 
     | 
    
         
            -
            		 
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
            end
         
     | 
| 
       167 
     | 
    
         
            -
             
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
       169 
     | 
    
         
            -
            #
         
     | 
| 
       170 
     | 
    
         
            -
            # 
     | 
| 
       171 
     | 
    
         
            -
            # 
     | 
| 
       172 
     | 
    
         
            -
            #    
     | 
| 
       173 
     | 
    
         
            -
            # 
     | 
| 
       174 
     | 
    
         
            -
            #      
     | 
| 
       175 
     | 
    
         
            -
            #      
     | 
| 
       176 
     | 
    
         
            -
            # 
     | 
| 
       177 
     | 
    
         
            -
            #
         
     | 
| 
       178 
     | 
    
         
            -
            # 
     | 
| 
       179 
     | 
    
         
            -
            #  
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
     | 
    
         
            -
             
     | 
| 
       182 
     | 
    
         
            -
             
     | 
| 
       183 
     | 
    
         
            -
             
     | 
| 
       184 
     | 
    
         
            -
             
     | 
| 
       185 
     | 
    
         
            -
            				r. 
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
             
     | 
| 
       188 
     | 
    
         
            -
             
     | 
| 
       189 
     | 
    
         
            -
             
     | 
| 
       190 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            #encoding:utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class RUIC; end
         
     | 
| 
      
 4 
     | 
    
         
            +
            module UIC; end
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            require 'nokogiri'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require_relative 'ruic/version'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require_relative 'ruic/attributes'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require_relative 'ruic/assets'
         
     | 
| 
      
 10 
     | 
    
         
            +
            require_relative 'ruic/interfaces'
         
     | 
| 
      
 11 
     | 
    
         
            +
            require_relative 'ruic/application'
         
     | 
| 
      
 12 
     | 
    
         
            +
            require_relative 'ruic/behaviors'
         
     | 
| 
      
 13 
     | 
    
         
            +
            require_relative 'ruic/effect'
         
     | 
| 
      
 14 
     | 
    
         
            +
            require_relative 'ruic/renderplugin'
         
     | 
| 
      
 15 
     | 
    
         
            +
            require_relative 'ruic/statemachine'
         
     | 
| 
      
 16 
     | 
    
         
            +
            require_relative 'ruic/presentation'
         
     | 
| 
      
 17 
     | 
    
         
            +
            require_relative 'ruic/ripl'
         
     | 
| 
      
 18 
     | 
    
         
            +
            require_relative 'ruic/nicebytes'
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            # The `RUIC` class provides the interface for running scripts using the special DSL,
         
     | 
| 
      
 21 
     | 
    
         
            +
            # and for running the interactive REPL.
         
     | 
| 
      
 22 
     | 
    
         
            +
            # See the {file:README.md README} file for description of the DSL.
         
     | 
| 
      
 23 
     | 
    
         
            +
            class RUIC
         
     | 
| 
      
 24 
     | 
    
         
            +
            	DEFAULTMETADATA = 'C:/Program Files (x86)/NVIDIA Corporation/UI Composer 8.0/res/DataModelMetadata/en-us/MetaData.xml'
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            	# Execute a script and/or launch the interactive REPL.
         
     | 
| 
      
 27 
     | 
    
         
            +
            	#
         
     | 
| 
      
 28 
     | 
    
         
            +
            	# If you both run a `:script` and then enter the `:repl` all local variables created
         
     | 
| 
      
 29 
     | 
    
         
            +
            	# by the script will be available in the REPL.
         
     | 
| 
      
 30 
     | 
    
         
            +
            	#
         
     | 
| 
      
 31 
     | 
    
         
            +
            	#     # Just run a script
         
     | 
| 
      
 32 
     | 
    
         
            +
            	#     RUIC.run script:'my.ruic'
         
     | 
| 
      
 33 
     | 
    
         
            +
            	#
         
     | 
| 
      
 34 
     | 
    
         
            +
            	#     # Load an application and then enter the REPL
         
     | 
| 
      
 35 
     | 
    
         
            +
            	#     RUIC.run uia:'my.uia', repl:true
         
     | 
| 
      
 36 
     | 
    
         
            +
            	#
         
     | 
| 
      
 37 
     | 
    
         
            +
            	#     # Run a script and then drop into the REPL
         
     | 
| 
      
 38 
     | 
    
         
            +
            	#     RUIC.run script:'my.ruic', repl:true
         
     | 
| 
      
 39 
     | 
    
         
            +
            	#
         
     | 
| 
      
 40 
     | 
    
         
            +
            	# The working directory for scripts is set to the directory of the script.
         
     | 
| 
      
 41 
     | 
    
         
            +
            	#
         
     | 
| 
      
 42 
     | 
    
         
            +
            	# The working directory for the repl is set to the directory of the first
         
     | 
| 
      
 43 
     | 
    
         
            +
            	# loaded application (if any);
         
     | 
| 
      
 44 
     | 
    
         
            +
            	# failing that, the directory of the script (if any);
         
     | 
| 
      
 45 
     | 
    
         
            +
            	# failing that, the current directory.
         
     | 
| 
      
 46 
     | 
    
         
            +
            	#
         
     | 
| 
      
 47 
     | 
    
         
            +
            	# @option opts [String] :script A path to a `.ruic` script to run _(optional)_.
         
     | 
| 
      
 48 
     | 
    
         
            +
            	# @option opts [String] :uia An `.uia` file to load (before running the script and/or REPL) _(optional)_.
         
     | 
| 
      
 49 
     | 
    
         
            +
            	# @option opts [Boolean] :repl Pass `true` to enter the command-line REPL after executing the script (if any).
         
     | 
| 
      
 50 
     | 
    
         
            +
            	# @return [nil]
         
     | 
| 
      
 51 
     | 
    
         
            +
            	def self.run(opts={})
         
     | 
| 
      
 52 
     | 
    
         
            +
            		opts = opts
         
     | 
| 
      
 53 
     | 
    
         
            +
            		ruic = nil
         
     | 
| 
      
 54 
     | 
    
         
            +
            		if opts[:script]
         
     | 
| 
      
 55 
     | 
    
         
            +
            			script = File.read(opts[:script],encoding:'utf-8')
         
     | 
| 
      
 56 
     | 
    
         
            +
            			Dir.chdir(File.dirname(opts[:script])) do
         
     | 
| 
      
 57 
     | 
    
         
            +
            				ruic = self.new
         
     | 
| 
      
 58 
     | 
    
         
            +
            				ruic.metadata opts[:metadata] if opts[:metadata]
         
     | 
| 
      
 59 
     | 
    
         
            +
            				ruic.uia      opts[:uia]      if opts[:uia]
         
     | 
| 
      
 60 
     | 
    
         
            +
            				ruic.env.eval(script,opts[:script])
         
     | 
| 
      
 61 
     | 
    
         
            +
            			end
         
     | 
| 
      
 62 
     | 
    
         
            +
            		end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            		if opts[:repl]
         
     | 
| 
      
 65 
     | 
    
         
            +
            			location = (ruic && ruic.app && ruic.app.respond_to?(:file) && ruic.app.file) || opts[:uia] || opts[:script] || '.'
         
     | 
| 
      
 66 
     | 
    
         
            +
            			Dir.chdir( File.dirname(location) ) do
         
     | 
| 
      
 67 
     | 
    
         
            +
            				ruic ||= self.new.tap do |r|
         
     | 
| 
      
 68 
     | 
    
         
            +
            					r.metadata opts[:metadata] if opts[:metadata]
         
     | 
| 
      
 69 
     | 
    
         
            +
            					r.uia      opts[:uia]      if opts[:uia]
         
     | 
| 
      
 70 
     | 
    
         
            +
            				end
         
     | 
| 
      
 71 
     | 
    
         
            +
            				require 'ripl/irb'
         
     | 
| 
      
 72 
     | 
    
         
            +
            				require 'ripl/multi_line'
         
     | 
| 
      
 73 
     | 
    
         
            +
            				require 'ripl/multi_line/live_error.rb'
         
     | 
| 
      
 74 
     | 
    
         
            +
            				Ripl::MultiLine.engine = Ripl::MultiLine::LiveError
         
     | 
| 
      
 75 
     | 
    
         
            +
            				Ripl::Shell.include Ripl::MultiLine.engine
         
     | 
| 
      
 76 
     | 
    
         
            +
            				Ripl::Shell.include Ripl::AfterResult
         
     | 
| 
      
 77 
     | 
    
         
            +
            				Ripl::Shell.include Ripl::FormatResult
         
     | 
| 
      
 78 
     | 
    
         
            +
            				Ripl.config.merge! prompt:"", result_prompt:'#=> ', multi_line_prompt:'  ', irb_verbose:false, after_result:"\n", result_line_limit:200, prefix_result_lines:true, skip_nil_results:true
         
     | 
| 
      
 79 
     | 
    
         
            +
            				ARGV.clear # So that RIPL doesn't try to interpret the options
         
     | 
| 
      
 80 
     | 
    
         
            +
            				puts "(RUIC v#{RUIC::VERSION} interactive session; 'quit' or ctrl-d to end)"
         
     | 
| 
      
 81 
     | 
    
         
            +
            				ruic.instance_eval{ puts @apps.map{ |n,app| "(#{n} is #{app.inspect})" } }
         
     | 
| 
      
 82 
     | 
    
         
            +
            				puts "" # blank line before first input
         
     | 
| 
      
 83 
     | 
    
         
            +
            				Ripl.start binding:ruic.env
         
     | 
| 
      
 84 
     | 
    
         
            +
            			end
         
     | 
| 
      
 85 
     | 
    
         
            +
            		end
         
     | 
| 
      
 86 
     | 
    
         
            +
            	end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
            	# Creates a new environment for executing a RUIC script.
         
     | 
| 
      
 89 
     | 
    
         
            +
            	# @param metadata [String] Path to the `MetaData.xml` file to use.
         
     | 
| 
      
 90 
     | 
    
         
            +
            	def initialize( metadata=DEFAULTMETADATA )
         
     | 
| 
      
 91 
     | 
    
         
            +
            		@metadata = metadata
         
     | 
| 
      
 92 
     | 
    
         
            +
            		@apps = {}
         
     | 
| 
      
 93 
     | 
    
         
            +
            	end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            	# Set the metadata to use; generally called from the RUIC DSL.
         
     | 
| 
      
 96 
     | 
    
         
            +
            	# @param path [String] Path to the `MetaData.xml` file, either absolute or relative to the working directory.
         
     | 
| 
      
 97 
     | 
    
         
            +
            	def metadata(path)
         
     | 
| 
      
 98 
     | 
    
         
            +
            		@metadata = path
         
     | 
| 
      
 99 
     | 
    
         
            +
            	end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            	# Load an application, making it available as `app`, `app2`, etc.
         
     | 
| 
      
 102 
     | 
    
         
            +
            	# @param path [String] Path to the `*.uia` application file.
         
     | 
| 
      
 103 
     | 
    
         
            +
            	# @return [UIC::Application] The new application loaded.
         
     | 
| 
      
 104 
     | 
    
         
            +
            	def uia(path)
         
     | 
| 
      
 105 
     | 
    
         
            +
            		meta = UIC.MetaData @metadata
         
     | 
| 
      
 106 
     | 
    
         
            +
            		name = @apps.empty? ? :app : :"app#{@apps.length+1}"
         
     | 
| 
      
 107 
     | 
    
         
            +
            		@apps[name] = UIC.Application(meta,path)
         
     | 
| 
      
 108 
     | 
    
         
            +
            	end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
            	# @return [Binding] the shared binding used for evaluating the script and REPL
         
     | 
| 
      
 111 
     | 
    
         
            +
            	def env
         
     | 
| 
      
 112 
     | 
    
         
            +
            		@env ||= binding
         
     | 
| 
      
 113 
     | 
    
         
            +
            	end
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
            	# @private used as a one-off
         
     | 
| 
      
 116 
     | 
    
         
            +
            	module SelfInspecting; def inspect; to_s; end; end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            	# Used to resolve bare `app` and `app2` calls to a loaded {UIC::Application Application}.
         
     | 
| 
      
 119 
     | 
    
         
            +
            	# @return [UIC::Application] the new application loaded.
         
     | 
| 
      
 120 
     | 
    
         
            +
            	def method_missing(name,*a)
         
     | 
| 
      
 121 
     | 
    
         
            +
            		@apps[name] || (name=~/^app\d*/ ? "(no #{name} loaded)".extend(SelfInspecting) : super)
         
     | 
| 
      
 122 
     | 
    
         
            +
            	end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
            	# Simple assertion mechanism to be used within scripts.
         
     | 
| 
      
 125 
     | 
    
         
            +
            	#
         
     | 
| 
      
 126 
     | 
    
         
            +
            	# @example 1) simple call syntax
         
     | 
| 
      
 127 
     | 
    
         
            +
            	#     # Provides a generic failure message
         
     | 
| 
      
 128 
     | 
    
         
            +
            	#     assert a==b
         
     | 
| 
      
 129 
     | 
    
         
            +
            	#     #=> assertion failed (my.ruic line 17)
         
     | 
| 
      
 130 
     | 
    
         
            +
            	#
         
     | 
| 
      
 131 
     | 
    
         
            +
            	#     # Provides a custom failure message
         
     | 
| 
      
 132 
     | 
    
         
            +
            	#     assert a==b, "a should equal b"
         
     | 
| 
      
 133 
     | 
    
         
            +
            	#     #=> a should equal b : assertion failed (my.ruic line 17)
         
     | 
| 
      
 134 
     | 
    
         
            +
            	#
         
     | 
| 
      
 135 
     | 
    
         
            +
            	# @example 2) block with string syntax
         
     | 
| 
      
 136 
     | 
    
         
            +
            	#     # The code in the string to eval is also the failure message
         
     | 
| 
      
 137 
     | 
    
         
            +
            	#     assert{ "a==b" }
         
     | 
| 
      
 138 
     | 
    
         
            +
            	#     #=> a==b : assertion failed (my.ruic line 17)
         
     | 
| 
      
 139 
     | 
    
         
            +
            	#
         
     | 
| 
      
 140 
     | 
    
         
            +
            	# @param condition [Boolean] the value to evaluate.
         
     | 
| 
      
 141 
     | 
    
         
            +
            	# @param msg [String] the nice error message to display.
         
     | 
| 
      
 142 
     | 
    
         
            +
            	# @yieldreturn [String] the code to evaluate as a condition.
         
     | 
| 
      
 143 
     | 
    
         
            +
            	def assert(condition=:CONDITIONNOTSUPPLIED,msg=nil,&block)
         
     | 
| 
      
 144 
     | 
    
         
            +
            		if block && condition==:CONDITIONNOTSUPPLIED
         
     | 
| 
      
 145 
     | 
    
         
            +
            			msg = yield
         
     | 
| 
      
 146 
     | 
    
         
            +
            			condition = msg.is_a?(String) ? eval(msg,block.binding) : msg
         
     | 
| 
      
 147 
     | 
    
         
            +
            		end
         
     | 
| 
      
 148 
     | 
    
         
            +
            		condition || begin
         
     | 
| 
      
 149 
     | 
    
         
            +
            			file, line, _ = caller.first.split(':')
         
     | 
| 
      
 150 
     | 
    
         
            +
            			puts "#{"#{msg} : " unless msg.nil?}assertion failed (#{file} line #{line})"
         
     | 
| 
      
 151 
     | 
    
         
            +
            			exit 1
         
     | 
| 
      
 152 
     | 
    
         
            +
            		end
         
     | 
| 
      
 153 
     | 
    
         
            +
            	end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
            	# Nicer name for `puts` to be used in the DSL, printing the
         
     | 
| 
      
 156 
     | 
    
         
            +
            	# 'nice' string equivalent for all supplied arguments.
         
     | 
| 
      
 157 
     | 
    
         
            +
            	def show(*a)
         
     | 
| 
      
 158 
     | 
    
         
            +
            		a=a.first if a.length==1 && a.first.is_a?(Array)
         
     | 
| 
      
 159 
     | 
    
         
            +
            		opts = { result_prompt:'# ', result_line_limit:200, prefix_result_lines:true, to_s:true }
         
     | 
| 
      
 160 
     | 
    
         
            +
            		a.each{ |x| puts Ripl::FormatResult.format_result(x,opts) }
         
     | 
| 
      
 161 
     | 
    
         
            +
            		nil # so that Ripl won't show the result
         
     | 
| 
      
 162 
     | 
    
         
            +
            	end
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
            	def inspect
         
     | 
| 
      
 165 
     | 
    
         
            +
            		"<RUIC #{@apps.empty? ? "(no app loaded)" : Hash[ @apps.map{ |id,app| [id,File.basename(app.file)] } ]}>"
         
     | 
| 
      
 166 
     | 
    
         
            +
            	end
         
     | 
| 
      
 167 
     | 
    
         
            +
            end
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
            # Run a series of commands inside the RUIC DSL.
         
     | 
| 
      
 170 
     | 
    
         
            +
            #
         
     | 
| 
      
 171 
     | 
    
         
            +
            # @example
         
     | 
| 
      
 172 
     | 
    
         
            +
            #   require 'ruic'
         
     | 
| 
      
 173 
     | 
    
         
            +
            #   RUIC do
         
     | 
| 
      
 174 
     | 
    
         
            +
            #     uia 'test/MyProject/MyProject.uia'
         
     | 
| 
      
 175 
     | 
    
         
            +
            #     show app
         
     | 
| 
      
 176 
     | 
    
         
            +
            #     #=>UIC::Application 'MyProject.uia'>
         
     | 
| 
      
 177 
     | 
    
         
            +
            #   end
         
     | 
| 
      
 178 
     | 
    
         
            +
            #
         
     | 
| 
      
 179 
     | 
    
         
            +
            # If no block is supplied, this is the same as {RUIC.run RUIC.run(opts)}.
         
     | 
| 
      
 180 
     | 
    
         
            +
            # @option opts [String] :uia Optionally load an application before running the script.
         
     | 
| 
      
 181 
     | 
    
         
            +
            def RUIC(opts={},&block)
         
     | 
| 
      
 182 
     | 
    
         
            +
            	if block
         
     | 
| 
      
 183 
     | 
    
         
            +
            		Dir.chdir(File.dirname($0)) do
         
     | 
| 
      
 184 
     | 
    
         
            +
            			RUIC.new.tap do |r|
         
     | 
| 
      
 185 
     | 
    
         
            +
            				r.metadata opts[:metadata] if opts[:metadata]
         
     | 
| 
      
 186 
     | 
    
         
            +
            				r.uia      opts[:uia]      if opts[:uia]
         
     | 
| 
      
 187 
     | 
    
         
            +
            			end.instance_eval(&block)
         
     | 
| 
      
 188 
     | 
    
         
            +
            		end
         
     | 
| 
      
 189 
     | 
    
         
            +
            	else
         
     | 
| 
      
 190 
     | 
    
         
            +
            		RUIC.run(opts)
         
     | 
| 
      
 191 
     | 
    
         
            +
            	end
         
     | 
| 
       191 
192 
     | 
    
         
             
            end
         
     | 
    
        data/lib/ruic/application.rb
    CHANGED
    
    | 
         @@ -60,8 +60,31 @@ class UIC::Application 
     | 
|
| 
       60 
60 
     | 
    
         
             
            	# Files in the application directory not used by the application.
         
     | 
| 
       61 
61 
     | 
    
         
             
            	#
         
     | 
| 
       62 
62 
     | 
    
         
             
            	# @return [Array<String>] absolute paths of files in the directory not used by the application.
         
     | 
| 
       63 
     | 
    
         
            -
            	def unused_files
         
     | 
| 
       64 
     | 
    
         
            -
            		(directory_files - referenced_files).sort
         
     | 
| 
      
 63 
     | 
    
         
            +
            	def unused_files( hierarchy=false )
         
     | 
| 
      
 64 
     | 
    
         
            +
            		unused = (directory_files - referenced_files).sort
         
     | 
| 
      
 65 
     | 
    
         
            +
            		if hierarchy
         
     | 
| 
      
 66 
     | 
    
         
            +
            			root = File.dirname(file)
         
     | 
| 
      
 67 
     | 
    
         
            +
            			UIC.tree_hierarchy(root) do |dir|
         
     | 
| 
      
 68 
     | 
    
         
            +
            				File.directory?(dir) ? Dir.chdir(dir){ Dir['*'].map{ |f| File.expand_path(f) } } : []
         
     | 
| 
      
 69 
     | 
    
         
            +
            			end.map do |prefix,file|
         
     | 
| 
      
 70 
     | 
    
         
            +
            				if file
         
     | 
| 
      
 71 
     | 
    
         
            +
            					all = unused.select{ |path| path[/^#{file}/] }
         
     | 
| 
      
 72 
     | 
    
         
            +
            					unless all.empty?
         
     | 
| 
      
 73 
     | 
    
         
            +
            						size = NiceBytes.nice_bytes(all.map{ |f| File.size(f) }.inject(:+))
         
     | 
| 
      
 74 
     | 
    
         
            +
            						partial = file.sub(/^#{root}\//o,'')
         
     | 
| 
      
 75 
     | 
    
         
            +
            						if File.directory?(file)
         
     | 
| 
      
 76 
     | 
    
         
            +
            							"%s %s (%d files, %s)" % [prefix,partial,all.length,size]
         
     | 
| 
      
 77 
     | 
    
         
            +
            						else
         
     | 
| 
      
 78 
     | 
    
         
            +
            							"%s %s (%s)" % [prefix,partial,size]
         
     | 
| 
      
 79 
     | 
    
         
            +
            						end
         
     | 
| 
      
 80 
     | 
    
         
            +
            					end
         
     | 
| 
      
 81 
     | 
    
         
            +
            				else
         
     | 
| 
      
 82 
     | 
    
         
            +
            					prefix
         
     | 
| 
      
 83 
     | 
    
         
            +
            				end
         
     | 
| 
      
 84 
     | 
    
         
            +
            			end.compact.join("\n")
         
     | 
| 
      
 85 
     | 
    
         
            +
            		else
         
     | 
| 
      
 86 
     | 
    
         
            +
            			unused
         
     | 
| 
      
 87 
     | 
    
         
            +
            		end
         
     | 
| 
       65 
88 
     | 
    
         
             
            	end
         
     | 
| 
       66 
89 
     | 
    
         | 
| 
       67 
90 
     | 
    
         
             
            	# Files referenced by the application but not present in the directory.
         
     | 
| 
         @@ -71,7 +94,6 @@ class UIC::Application 
     | 
|
| 
       71 
94 
     | 
    
         
             
            		(referenced_files - directory_files).sort
         
     | 
| 
       72 
95 
     | 
    
         
             
            	end
         
     | 
| 
       73 
96 
     | 
    
         | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
97 
     | 
    
         
             
            	# @return [Array<String>] absolute paths of files referenced by the application.
         
     | 
| 
       76 
98 
     | 
    
         
             
            	def referenced_files
         
     | 
| 
       77 
99 
     | 
    
         
             
            		# TODO: state machines can reference external scripts
         
     | 
    
        data/lib/ruic/assets.rb
    CHANGED
    
    | 
         @@ -1,437 +1,442 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #encoding: utf-8
         
     | 
| 
       2 
     | 
    
         
            -
            class UIC::MetaData
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
            	# The base class for all assets. All other classes are dynamically created when a `MetaData.xml` file is loaded.
         
     | 
| 
       5 
     | 
    
         
            -
            	class AssetBase
         
     | 
| 
       6 
     | 
    
         
            -
            		@properties = {}
         
     | 
| 
       7 
     | 
    
         
            -
            		@name = "AssetBase"
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            		class << self
         
     | 
| 
       10 
     | 
    
         
            -
            			# @return [String] The scene graph name of the asset.
         
     | 
| 
       11 
     | 
    
         
            -
            			attr_reader :name
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            			# @return [Hash] a hash mapping attribute names to {Property} instances.
         
     | 
| 
       14 
     | 
    
         
            -
            			def properties
         
     | 
| 
       15 
     | 
    
         
            -
            				(ancestors[1].respond_to?(:properties) ? ancestors[1].properties : {}).merge(@properties)
         
     | 
| 
       16 
     | 
    
         
            -
            			end
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
            			# @private
         
     | 
| 
       19 
     | 
    
         
            -
            			def inspect
         
     | 
| 
       20 
     | 
    
         
            -
            				"<#{@name}>"
         
     | 
| 
       21 
     | 
    
         
            -
            			end
         
     | 
| 
       22 
     | 
    
         
            -
            		end
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
            		# @return [Hash] a hash mapping attribute names to {Property} instances.
         
     | 
| 
       25 
     | 
    
         
            -
            		def properties
         
     | 
| 
       26 
     | 
    
         
            -
            			self.class.properties
         
     | 
| 
       27 
     | 
    
         
            -
            		end
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
            		# Find an asset by relative scripting path.
         
     | 
| 
       30 
     | 
    
         
            -
            		#
         
     | 
| 
       31 
     | 
    
         
            -
            		# @example
         
     | 
| 
       32 
     | 
    
         
            -
            		#  preso = app.main
         
     | 
| 
       33 
     | 
    
         
            -
            		#  layer = preso/"Scene.Layer"
         
     | 
| 
       34 
     | 
    
         
            -
            		#  cam1  = app/"main:Scene.Layer.Camera"
         
     | 
| 
       35 
     | 
    
         
            -
            		#  cam2  = preso/"Scene.Layer.Camera"
         
     | 
| 
       36 
     | 
    
         
            -
            		#  cam3  = layer/"Camera"
         
     | 
| 
       37 
     | 
    
         
            -
            		#  cam4  = cam1/"parent.Camera"
         
     | 
| 
       38 
     | 
    
         
            -
            		#
         
     | 
| 
       39 
     | 
    
         
            -
            		#  assert cam1==cam2 && cam2==cam3 && cam3==cam4
         
     | 
| 
       40 
     | 
    
         
            -
            		#
         
     | 
| 
       41 
     | 
    
         
            -
            		# @return [MetaData::AssetBase] The found asset, or `nil` if it cannot be found.
         
     | 
| 
       42 
     | 
    
         
            -
            		#
         
     | 
| 
       43 
     | 
    
         
            -
            		# @see Application#at
         
     | 
| 
       44 
     | 
    
         
            -
            		# @see Presentation#at
         
     | 
| 
       45 
     | 
    
         
            -
            		def at(sub_path)
         
     | 
| 
       46 
     | 
    
         
            -
            			presentation.at(sub_path,@el)
         
     | 
| 
       47 
     | 
    
         
            -
            		end
         
     | 
| 
       48 
     | 
    
         
            -
            		alias_method :/, :at
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
            		# @return [Presentation] the presentation that this asset is part of.
         
     | 
| 
       51 
     | 
    
         
            -
            		attr_accessor :presentation
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
            		# @return [Nokogiri::XML::Element] the internal XML element in the scene graph of the presentation.
         
     | 
| 
       54 
     | 
    
         
            -
            		attr_accessor :el
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
            		# Create a new asset. This is called for you automatically; you likely should not be using it.
         
     | 
| 
       57 
     | 
    
         
            -
            		# @param presentation [Presentation] the presentation owning this asset.
         
     | 
| 
       58 
     | 
    
         
            -
            		# @param element [Nokogiri::XML::Element] the internal XML element in the scene graph of the presentation.
         
     | 
| 
       59 
     | 
    
         
            -
            		def initialize( presentation, element )
         
     | 
| 
       60 
     | 
    
         
            -
            			@presentation = presentation
         
     | 
| 
       61 
     | 
    
         
            -
            			@el = element
         
     | 
| 
       62 
     | 
    
         
            -
            		end
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
            		# @return [String] the type of this asset. For example: `"Model"`, `"Material"`, `"ReferencedMaterial"`, `"PathAnchorPoint"`, etc.
         
     | 
| 
       65 
     | 
    
         
            -
            		def type
         
     | 
| 
       66 
     | 
    
         
            -
            			self.class.name
         
     | 
| 
       67 
     | 
    
         
            -
            		end
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
            		# @return [AssetBase] the parent of this asset in the scene graph.
         
     | 
| 
       70 
     | 
    
         
            -
            		# @see Presentation#parent_asset
         
     | 
| 
       71 
     | 
    
         
            -
            		def parent
         
     | 
| 
       72 
     | 
    
         
            -
            			presentation.parent_asset(self)
         
     | 
| 
       73 
     | 
    
         
            -
            		end
         
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
            		# @return [Array<AssetBase>] array of child assets in the scene graph. Children are in scene graph order.
         
     | 
| 
       76 
     | 
    
         
            -
            		# @see Presentation#child_assets
         
     | 
| 
       77 
     | 
    
         
            -
            		def children
         
     | 
| 
       78 
     | 
    
         
            -
            			presentation.child_assets(self)
         
     | 
| 
       79 
     | 
    
         
            -
            		end
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
            		# @return [String] the hierarchy under the element (for debugging purposes).
         
     | 
| 
       82 
     | 
    
         
            -
            		def hierarchy
         
     | 
| 
       83 
     | 
    
         
            -
            			presentation.hierarchy(self)
         
     | 
| 
       84 
     | 
    
         
            -
            		end
         
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
            		# Find descendant assets matching criteria.
         
     | 
| 
       87 
     | 
    
         
            -
            		# This method is the same as (but more convenient than) {Presentation#find} using the `:_under` criteria.
         
     | 
| 
       88 
     | 
    
         
            -
            		# See that method for documentation of the `criteria`.
         
     | 
| 
       89 
     | 
    
         
            -
            		#
         
     | 
| 
       90 
     | 
    
         
            -
            		# @example
         
     | 
| 
       91 
     | 
    
         
            -
            		#  preso = app.main
         
     | 
| 
       92 
     | 
    
         
            -
            		#  group = preso/"Scene.Layer.Vehicle"
         
     | 
| 
       93 
     | 
    
         
            -
            		#  tires = group.find name:/^Tire/
         
     | 
| 
       94 
     | 
    
         
            -
            		#
         
     | 
| 
       95 
     | 
    
         
            -
            		#  # alternative
         
     | 
| 
       96 
     | 
    
         
            -
            		#  tires = preso.find name:/^Tire/, _under:group
         
     | 
| 
       97 
     | 
    
         
            -
            		#
         
     | 
| 
       98 
     | 
    
         
            -
            		# @return [Array<AssetBase>]
         
     | 
| 
       99 
     | 
    
         
            -
            		#
         
     | 
| 
       100 
     | 
    
         
            -
            		# @see Presentation#find
         
     | 
| 
       101 
     | 
    
         
            -
            		def find(criteria={},&block)
         
     | 
| 
       102 
     | 
    
         
            -
            			criteria[:_under] ||= self
         
     | 
| 
       103 
     | 
    
         
            -
            			presentation.find(criteria,&block)
         
     | 
| 
       104 
     | 
    
         
            -
            		end
         
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
            		# @return [AssetBase] the component or scene that owns this asset.
         
     | 
| 
       107 
     | 
    
         
            -
            		#         If this asset is a component, does not return itself.
         
     | 
| 
       108 
     | 
    
         
            -
            		# @see Presentation#owning_component
         
     | 
| 
       109 
     | 
    
         
            -
            		def component
         
     | 
| 
       110 
     | 
    
         
            -
            			presentation.owning_component(self)
         
     | 
| 
       111 
     | 
    
         
            -
            		end
         
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
            		# @return [Boolean] `true` if this asset is a component or Scene.
         
     | 
| 
       114 
     | 
    
         
            -
            		def component?
         
     | 
| 
       115 
     | 
    
         
            -
            			@el.name=='Component' || @el.name=='Scene'
         
     | 
| 
       116 
     | 
    
         
            -
            		end
         
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
            		# @return [Boolean] `true` if this asset is on the master slide.
         
     | 
| 
       119 
     | 
    
         
            -
            		# @see Presentation#master?
         
     | 
| 
       120 
     | 
    
         
            -
            		def master?
         
     | 
| 
       121 
     | 
    
         
            -
            			presentation.master?(self)
         
     | 
| 
       122 
     | 
    
         
            -
            		end
         
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
            		# @return [Boolean] `true` if this asset is a Slide.
         
     | 
| 
       125 
     | 
    
         
            -
            		def slide?
         
     | 
| 
       126 
     | 
    
         
            -
            			false
         
     | 
| 
       127 
     | 
    
         
            -
            		end
         
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
            		# @param slide_name_or_index [Integer,String] the slide number of name to check for presence on.
         
     | 
| 
       130 
     | 
    
         
            -
            		# @return [Boolean] `true` if this asset is present on the specified slide.
         
     | 
| 
       131 
     | 
    
         
            -
            		# @see Presentation#has_slide?
         
     | 
| 
       132 
     | 
    
         
            -
            		def has_slide?(slide_name_or_index)
         
     | 
| 
       133 
     | 
    
         
            -
            			presentation.has_slide?(self,slide_name_or_index)
         
     | 
| 
       134 
     | 
    
         
            -
            		end
         
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
            		# @return [SlideCollection] an array-like collection of all slides that the asset is available on.
         
     | 
| 
       137 
     | 
    
         
            -
            		# @see Presentation#slides_for
         
     | 
| 
       138 
     | 
    
         
            -
            		def slides
         
     | 
| 
       139 
     | 
    
         
            -
            			presentation.slides_for(self)
         
     | 
| 
       140 
     | 
    
         
            -
            		end
         
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
            		# @example
         
     | 
| 
       143 
     | 
    
         
            -
            		#  logo = app/"main:Scene.UI.Logo"
         
     | 
| 
       144 
     | 
    
         
            -
            		#  assert logo.master?             # It's a master object
         
     | 
| 
       145 
     | 
    
         
            -
            		#
         
     | 
| 
       146 
     | 
    
         
            -
            		#  show logo['endtime'].values     #=> [10000,500,1000,750]
         
     | 
| 
       147 
     | 
    
         
            -
            		#  show logo['opacity'].values     #=> [100,0,0,100]
         
     | 
| 
       148 
     | 
    
         
            -
            		#  logo1 = logo.on_slide(1)
         
     | 
| 
       149 
     | 
    
         
            -
            		#  logo2 = logo.on_slide(2)
         
     | 
| 
       150 
     | 
    
         
            -
            		#  show logo1['endtime']           #=> 500
         
     | 
| 
       151 
     | 
    
         
            -
            		#  show logo2['endtime']           #=> 1000
         
     | 
| 
       152 
     | 
    
         
            -
            		#  show logo1['opacity']           #=> 0
         
     | 
| 
       153 
     | 
    
         
            -
            		#  show logo2['opacity']           #=> 0
         
     | 
| 
       154 
     | 
    
         
            -
            		#
         
     | 
| 
       155 
     | 
    
         
            -
            		#  logo2['opacity'] = 66
         
     | 
| 
       156 
     | 
    
         
            -
            		#  show logo['opacity'].values     #=> [100,0,66,100]
         
     | 
| 
       157 
     | 
    
         
            -
            		#
         
     | 
| 
       158 
     | 
    
         
            -
            		# @param slide_name_or_index [Integer,String] the slide number or name to create the proxy for.
         
     | 
| 
       159 
     | 
    
         
            -
            		# @return [SlideValues] a proxy that yields attribute values for a specific slide.
         
     | 
| 
       160 
     | 
    
         
            -
            		def on_slide(slide_name_or_index)
         
     | 
| 
       161 
     | 
    
         
            -
            			if has_slide?(slide_name_or_index)
         
     | 
| 
       162 
     | 
    
         
            -
            				UIC::SlideValues.new( self, slide_name_or_index )
         
     | 
| 
       163 
     | 
    
         
            -
            			end
         
     | 
| 
       164 
     | 
    
         
            -
            		end
         
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
            		# @return [String] the script path to this asset.
         
     | 
| 
       167 
     | 
    
         
            -
            		# @see #path_to
         
     | 
| 
       168 
     | 
    
         
            -
            		# @see Presentation#path_to
         
     | 
| 
       169 
     | 
    
         
            -
            		def path
         
     | 
| 
       170 
     | 
    
         
            -
            			@path ||= @presentation.path_to(self)
         
     | 
| 
       171 
     | 
    
         
            -
            		end
         
     | 
| 
       172 
     | 
    
         
            -
             
     | 
| 
       173 
     | 
    
         
            -
            		# @param other_asset [AssetBase] the asset to find the relative path to.
         
     | 
| 
       174 
     | 
    
         
            -
            		# @return [String] the script path to another asset, relative to this one.
         
     | 
| 
       175 
     | 
    
         
            -
            		# @see #path
         
     | 
| 
       176 
     | 
    
         
            -
            		# @see Presentation#path_to
         
     | 
| 
       177 
     | 
    
         
            -
            		def path_to(other_asset)
         
     | 
| 
       178 
     | 
    
         
            -
            			@presentation.path_to(other_asset,self)
         
     | 
| 
       179 
     | 
    
         
            -
            		end
         
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
     | 
    
         
            -
            		# @return [String] the name of this asset in the scene graph.
         
     | 
| 
       182 
     | 
    
         
            -
            		def name
         
     | 
| 
       183 
     | 
    
         
            -
            			properties['name'] ? properties['name'].get( self, presentation.slide_index(self) ) : type
         
     | 
| 
       184 
     | 
    
         
            -
            		end
         
     | 
| 
       185 
     | 
    
         
            -
             
     | 
| 
       186 
     | 
    
         
            -
            		# Change the name of the asset in the scene graph.
         
     | 
| 
       187 
     | 
    
         
            -
            		# @param new_name [String] the new name for this asset.
         
     | 
| 
       188 
     | 
    
         
            -
            		# @return [String] the new name.
         
     | 
| 
       189 
     | 
    
         
            -
            		def name=( new_name )
         
     | 
| 
       190 
     | 
    
         
            -
            			@path = nil # invalidate the memoization
         
     | 
| 
       191 
     | 
    
         
            -
            			properties['name'].set( self, new_name, presentation.slide_index(self) )
         
     | 
| 
       192 
     | 
    
         
            -
            		end
         
     | 
| 
       193 
     | 
    
         
            -
             
     | 
| 
       194 
     | 
    
         
            -
            		# Get the value(s) of an attribute.
         
     | 
| 
       195 
     | 
    
         
            -
            		# If `slide_name_or_index` is omitted, creates a ValuesPerSlide proxy for the specified attribute.
         
     | 
| 
       196 
     | 
    
         
            -
            		# @example
         
     | 
| 
       197 
     | 
    
         
            -
            		#  logo = app/"main:Scene.UI.Logo"
         
     | 
| 
       198 
     | 
    
         
            -
            		#  show logo.master?               #=> true  (it's a master object)
         
     | 
| 
       199 
     | 
    
         
            -
            		#  show logo['endtime'].linked?    #=> false (the endtime property is unlinked)
         
     | 
| 
       200 
     | 
    
         
            -
            		#  show logo['endtime'].values     #=> [10000,500,1000,750]
         
     | 
| 
       201 
     | 
    
         
            -
            		#  show logo['endtime',0]          #=> 10000 (the master slide value)
         
     | 
| 
       202 
     | 
    
         
            -
            		#  show logo['endtime',"Slide 1"]  #=> 500
         
     | 
| 
       203 
     | 
    
         
            -
            		#  show logo['endtime',2]          #=> 1000
         
     | 
| 
       204 
     | 
    
         
            -
            		#
         
     | 
| 
       205 
     | 
    
         
            -
            		# @param attribute_name [String,Symbol] the name of the attribute.
         
     | 
| 
       206 
     | 
    
         
            -
            		# @param slide_name_or_index [Integer,String] the slide number or name to find the value on.
         
     | 
| 
       207 
     | 
    
         
            -
            		# @return [Object] the value of the property on the given slide.
         
     | 
| 
       208 
     | 
    
         
            -
            		# @return [ValuesPerSlide] if no slide is specified.
         
     | 
| 
       209 
     | 
    
         
            -
            		# @see #on_slide
         
     | 
| 
       210 
     | 
    
         
            -
            		# @see Presentation#get_attribute
         
     | 
| 
       211 
     | 
    
         
            -
            		def [](attribute_name, slide_name_or_index=nil)
         
     | 
| 
       212 
     | 
    
         
            -
            			if property = properties[attribute_name.to_s]
         
     | 
| 
       213 
     | 
    
         
            -
            				if slide_name_or_index
         
     | 
| 
       214 
     | 
    
         
            -
            					property.get( self, slide_name_or_index ) if has_slide?(slide_name_or_index)
         
     | 
| 
       215 
     | 
    
         
            -
            				else
         
     | 
| 
       216 
     | 
    
         
            -
            					UIC::ValuesPerSlide.new(@presentation,self,property)
         
     | 
| 
       217 
     | 
    
         
            -
            				end
         
     | 
| 
       218 
     | 
    
         
            -
            			end
         
     | 
| 
       219 
     | 
    
         
            -
            		end
         
     | 
| 
       220 
     | 
    
         
            -
             
     | 
| 
       221 
     | 
    
         
            -
            		# Set the value of an attribute, either across all slides, or on a particular slide.
         
     | 
| 
       222 
     | 
    
         
            -
            		#
         
     | 
| 
       223 
     | 
    
         
            -
            		# @example
         
     | 
| 
       224 
     | 
    
         
            -
            		#  logo = app/"main:Scene.UI.Logo"
         
     | 
| 
       225 
     | 
    
         
            -
            		#  show logo.master?               #=> true  (it's a master object)
         
     | 
| 
       226 
     | 
    
         
            -
            		#  show logo['endtime'].linked?    #=> false (the endtime property is unlinked)
         
     | 
| 
       227 
     | 
    
         
            -
            		#  show logo['endtime'].values     #=> [10000,500,1000,750]
         
     | 
| 
       228 
     | 
    
         
            -
            		#
         
     | 
| 
       229 
     | 
    
         
            -
            		#  logo['endtime',1] = 99
         
     | 
| 
       230 
     | 
    
         
            -
            		#  show logo['endtime'].values     #=> [10000,99,1000,750]
         
     | 
| 
       231 
     | 
    
         
            -
            		#
         
     | 
| 
       232 
     | 
    
         
            -
            		#  logo['endtime'] = 42
         
     | 
| 
       233 
     | 
    
         
            -
            		#  show logo['endtime'].values     #=> [42,42,42,42]
         
     | 
| 
       234 
     | 
    
         
            -
            		#  show logo['endtime'].linked?    #=> false (the endtime property is still unlinked)
         
     | 
| 
       235 
     | 
    
         
            -
            		#
         
     | 
| 
       236 
     | 
    
         
            -
            		# @param attribute_name [String,Symbol] the name of the attribute.
         
     | 
| 
       237 
     | 
    
         
            -
            		# @param slide_name_or_index [Integer,String] the slide number or name to set the value on.
         
     | 
| 
       238 
     | 
    
         
            -
            		# @param new_value [Numeric,String] the new value for the attribute.
         
     | 
| 
       239 
     | 
    
         
            -
            		# @see Presentation#set_attribute
         
     | 
| 
       240 
     | 
    
         
            -
            		def []=( attribute_name, slide_name_or_index=nil, new_value )
         
     | 
| 
       241 
     | 
    
         
            -
            			if property = properties[attribute_name.to_s] then
         
     | 
| 
       242 
     | 
    
         
            -
            				property.set(self,new_value,slide_name_or_index)
         
     | 
| 
       243 
     | 
    
         
            -
            			end
         
     | 
| 
       244 
     | 
    
         
            -
            		end
         
     | 
| 
       245 
     | 
    
         
            -
             
     | 
| 
       246 
     | 
    
         
            -
            		# @return [String] the XML representation of the scene graph element.
         
     | 
| 
       247 
     | 
    
         
            -
            		def to_xml
         
     | 
| 
       248 
     | 
    
         
            -
            			@el.to_xml
         
     | 
| 
       249 
     | 
    
         
            -
            		end
         
     | 
| 
       250 
     | 
    
         
            -
             
     | 
| 
       251 
     | 
    
         
            -
            		# @private no need to document this
         
     | 
| 
       252 
     | 
    
         
            -
            		def to_s
         
     | 
| 
       253 
     | 
    
         
            -
            			"<#{type} #{path}>"
         
     | 
| 
       254 
     | 
    
         
            -
            		end
         
     | 
| 
       255 
     | 
    
         
            -
            		alias_method :inspect, :to_s
         
     | 
| 
       256 
     | 
    
         
            -
             
     | 
| 
       257 
     | 
    
         
            -
            		# @private no need to document this
         
     | 
| 
       258 
     | 
    
         
            -
            		def ==(other)
         
     | 
| 
       259 
     | 
    
         
            -
            			(self.class==other.class) && (el==other.el)
         
     | 
| 
       260 
     | 
    
         
            -
            		end
         
     | 
| 
       261 
     | 
    
         
            -
            		alias_method :eql?, :==
         
     | 
| 
       262 
     | 
    
         
            -
            	end
         
     | 
| 
       263 
     | 
    
         
            -
             
     | 
| 
       264 
     | 
    
         
            -
            	attr_reader :by_name
         
     | 
| 
       265 
     | 
    
         
            -
             
     | 
| 
       266 
     | 
    
         
            -
            	HIER = {}
         
     | 
| 
       267 
     | 
    
         
            -
             
     | 
| 
       268 
     | 
    
         
            -
            	%w[Asset Slide Scene].each{ |s| HIER[s] = 'AssetBase' }
         
     | 
| 
       269 
     | 
    
         
            -
            	%w[Node Behavior Effect Image Layer MaterialBase PathAnchorPoint RenderPlugin].each{ |s| HIER[s]='Asset' }
         
     | 
| 
       270 
     | 
    
         
            -
            	%w[Alias Camera Component Group Light Model Text Path].each{ |s| HIER[s]='Node' }
         
     | 
| 
       271 
     | 
    
         
            -
            	%w[Material ReferencedMaterial].each{ |s| HIER[s]='MaterialBase' }
         
     | 
| 
       272 
     | 
    
         
            -
             
     | 
| 
       273 
     | 
    
         
            -
            	def initialize(xml)
         
     | 
| 
       274 
     | 
    
         
            -
            		@by_name = {'AssetBase'=>AssetBase}
         
     | 
| 
       275 
     | 
    
         
            -
             
     | 
| 
       276 
     | 
    
         
            -
            		doc = Nokogiri.XML(xml)
         
     | 
| 
       277 
     | 
    
         
            -
            		hack_in_slide_names!(doc)
         
     | 
| 
       278 
     | 
    
         
            -
             
     | 
| 
       279 
     | 
    
         
            -
            		HIER.each do |class_name,parent_class_name|
         
     | 
| 
       280 
     | 
    
         
            -
            			parent_class = @by_name[parent_class_name]
         
     | 
| 
       281 
     | 
    
         
            -
            			el = doc.root.at(class_name)
         
     | 
| 
       282 
     | 
    
         
            -
            			@by_name[class_name] = create_class(el,parent_class,el.name)
         
     | 
| 
       283 
     | 
    
         
            -
            		end
         
     | 
| 
       284 
     | 
    
         
            -
             
     | 
| 
       285 
     | 
    
         
            -
            		# Extend well-known classes with script interfaces after they are created
         
     | 
| 
       286 
     | 
    
         
            -
            		@by_name['State'] = @by_name['Slide']
         
     | 
| 
       287 
     | 
    
         
            -
            		@by_name['Slide'].instance_eval do
         
     | 
| 
       288 
     | 
    
         
            -
            			attr_accessor :index, :name
         
     | 
| 
       289 
     | 
    
         
            -
            			define_method :inspect do
         
     | 
| 
       290 
     | 
    
         
            -
            				"<slide ##{index} of #{@el['component'] || @el.parent['component']}>"
         
     | 
| 
       291 
     | 
    
         
            -
            			end
         
     | 
| 
       292 
     | 
    
         
            -
            			define_method(:slide?){ true }
         
     | 
| 
       293 
     | 
    
         
            -
            		end
         
     | 
| 
       294 
     | 
    
         
            -
             
     | 
| 
       295 
     | 
    
         
            -
            		refmat = @by_name['ReferencedMaterial']
         
     | 
| 
       296 
     | 
    
         
            -
            		@by_name['MaterialBase'].instance_eval do
         
     | 
| 
       297 
     | 
    
         
            -
            			define_method :replace_with_referenced_material do
         
     | 
| 
       298 
     | 
    
         
            -
            				type=='ReferencedMaterial' ? self : presentation.replace_asset( self, 'ReferencedMaterial', name:name )
         
     | 
| 
       299 
     | 
    
         
            -
            			end
         
     | 
| 
       300 
     | 
    
         
            -
            		end
         
     | 
| 
       301 
     | 
    
         
            -
             
     | 
| 
       302 
     | 
    
         
            -
            		@by_name['Path'].instance_eval do
         
     | 
| 
       303 
     | 
    
         
            -
            			define_method(:anchors){ find _type:'PathAnchorPoint' }
         
     | 
| 
       304 
     | 
    
         
            -
            		end
         
     | 
| 
       305 
     | 
    
         
            -
             
     | 
| 
       306 
     | 
    
         
            -
            	end
         
     | 
| 
       307 
     | 
    
         
            -
             
     | 
| 
       308 
     | 
    
         
            -
            	# Creates a class from MetaData.xml with accessors for the <Property> listed.
         
     | 
| 
       309 
     | 
    
         
            -
            	# Instances of the class are associated with a presentation and know how to
         
     | 
| 
       310 
     | 
    
         
            -
            	# get/set values in that XML based on value types, slides, defaults.
         
     | 
| 
       311 
     | 
    
         
            -
            	# Also used to create classes from effects, materials, and behavior preambles.
         
     | 
| 
       312 
     | 
    
         
            -
            	# @param el [Nokogiri::XML::Element] the element in MetaData.xml representing this class.
         
     | 
| 
       313 
     | 
    
         
            -
            	# @param parent_class [Class] the asset class to inherit from.
         
     | 
| 
       314 
     | 
    
         
            -
            	# @param name [String] the name of this class.
         
     | 
| 
       315 
     | 
    
         
            -
            	# @param new_defaults [Hash] hash mapping attribute name to a custom default value (as string) for this class.
         
     | 
| 
       316 
     | 
    
         
            -
            	def create_class(el,parent_class,name,new_defaults={})
         
     | 
| 
       317 
     | 
    
         
            -
            		Class.new(parent_class) do
         
     | 
| 
       318 
     | 
    
         
            -
            			@name = name.to_s
         
     | 
| 
       319 
     | 
    
         
            -
            			@properties = Hash[ el.css("Property").map do |e|
         
     | 
| 
       320 
     | 
    
         
            -
            				type = e['type'] || (e['list'] ? 'String' : 'Float')
         
     | 
| 
       321 
     | 
    
         
            -
            				type = "Float" if type=="float"
         
     | 
| 
       322 
     | 
    
         
            -
            				property =  
     | 
| 
       323 
     | 
    
         
            -
             
     | 
| 
       324 
     | 
    
         
            -
            				 
     | 
| 
       325 
     | 
    
         
            -
             
     | 
| 
       326 
     | 
    
         
            -
             
     | 
| 
       327 
     | 
    
         
            -
             
     | 
| 
       328 
     | 
    
         
            -
            				 
     | 
| 
       329 
     | 
    
         
            -
             
     | 
| 
       330 
     | 
    
         
            -
             
     | 
| 
       331 
     | 
    
         
            -
             
     | 
| 
       332 
     | 
    
         
            -
            			 
     | 
| 
       333 
     | 
    
         
            -
             
     | 
| 
       334 
     | 
    
         
            -
             
     | 
| 
       335 
     | 
    
         
            -
             
     | 
| 
       336 
     | 
    
         
            -
             
     | 
| 
       337 
     | 
    
         
            -
             
     | 
| 
       338 
     | 
    
         
            -
             
     | 
| 
       339 
     | 
    
         
            -
             
     | 
| 
       340 
     | 
    
         
            -
             
     | 
| 
       341 
     | 
    
         
            -
             
     | 
| 
       342 
     | 
    
         
            -
            		 
     | 
| 
       343 
     | 
    
         
            -
            	end
         
     | 
| 
       344 
     | 
    
         
            -
             
     | 
| 
       345 
     | 
    
         
            -
            	def  
     | 
| 
       346 
     | 
    
         
            -
            		 
     | 
| 
       347 
     | 
    
         
            -
             
     | 
| 
       348 
     | 
    
         
            -
            end
         
     | 
| 
       349 
     | 
    
         
            -
             
     | 
| 
       350 
     | 
    
         
            -
            def  
     | 
| 
       351 
     | 
    
         
            -
             
     | 
| 
       352 
     | 
    
         
            -
            	 
     | 
| 
       353 
     | 
    
         
            -
            end
         
     | 
| 
       354 
     | 
    
         
            -
             
     | 
| 
       355 
     | 
    
         
            -
             
     | 
| 
       356 
     | 
    
         
            -
            	 
     | 
| 
       357 
     | 
    
         
            -
            	 
     | 
| 
       358 
     | 
    
         
            -
             
     | 
| 
       359 
     | 
    
         
            -
             
     | 
| 
       360 
     | 
    
         
            -
             
     | 
| 
       361 
     | 
    
         
            -
             
     | 
| 
       362 
     | 
    
         
            -
             
     | 
| 
       363 
     | 
    
         
            -
             
     | 
| 
       364 
     | 
    
         
            -
             
     | 
| 
       365 
     | 
    
         
            -
            		 
     | 
| 
       366 
     | 
    
         
            -
             
     | 
| 
       367 
     | 
    
         
            -
             
     | 
| 
       368 
     | 
    
         
            -
             
     | 
| 
       369 
     | 
    
         
            -
             
     | 
| 
       370 
     | 
    
         
            -
             
     | 
| 
       371 
     | 
    
         
            -
             
     | 
| 
       372 
     | 
    
         
            -
            	 
     | 
| 
       373 
     | 
    
         
            -
             
     | 
| 
       374 
     | 
    
         
            -
             
     | 
| 
       375 
     | 
    
         
            -
            	 
     | 
| 
       376 
     | 
    
         
            -
             
     | 
| 
       377 
     | 
    
         
            -
             
     | 
| 
       378 
     | 
    
         
            -
            	 
     | 
| 
       379 
     | 
    
         
            -
             
     | 
| 
       380 
     | 
    
         
            -
             
     | 
| 
       381 
     | 
    
         
            -
             
     | 
| 
       382 
     | 
    
         
            -
             
     | 
| 
       383 
     | 
    
         
            -
             
     | 
| 
       384 
     | 
    
         
            -
             
     | 
| 
       385 
     | 
    
         
            -
             
     | 
| 
       386 
     | 
    
         
            -
             
     | 
| 
       387 
     | 
    
         
            -
             
     | 
| 
       388 
     | 
    
         
            -
            		 
     | 
| 
       389 
     | 
    
         
            -
             
     | 
| 
       390 
     | 
    
         
            -
            		 
     | 
| 
       391 
     | 
    
         
            -
             
     | 
| 
       392 
     | 
    
         
            -
             
     | 
| 
       393 
     | 
    
         
            -
            		 
     | 
| 
       394 
     | 
    
         
            -
             
     | 
| 
       395 
     | 
    
         
            -
             
     | 
| 
       396 
     | 
    
         
            -
             
     | 
| 
       397 
     | 
    
         
            -
            	 
     | 
| 
       398 
     | 
    
         
            -
             
     | 
| 
       399 
     | 
    
         
            -
             
     | 
| 
       400 
     | 
    
         
            -
            	 
     | 
| 
       401 
     | 
    
         
            -
             
     | 
| 
       402 
     | 
    
         
            -
             
     | 
| 
       403 
     | 
    
         
            -
            	 
     | 
| 
       404 
     | 
    
         
            -
             
     | 
| 
       405 
     | 
    
         
            -
             
     | 
| 
       406 
     | 
    
         
            -
            	 
     | 
| 
       407 
     | 
    
         
            -
             
     | 
| 
       408 
     | 
    
         
            -
             
     | 
| 
       409 
     | 
    
         
            -
            	 
     | 
| 
       410 
     | 
    
         
            -
             
     | 
| 
       411 
     | 
    
         
            -
             
     | 
| 
       412 
     | 
    
         
            -
            	 
     | 
| 
       413 
     | 
    
         
            -
             
     | 
| 
       414 
     | 
    
         
            -
             
     | 
| 
       415 
     | 
    
         
            -
            	 
     | 
| 
       416 
     | 
    
         
            -
             
     | 
| 
       417 
     | 
    
         
            -
            end
         
     | 
| 
       418 
     | 
    
         
            -
             
     | 
| 
       419 
     | 
    
         
            -
             
     | 
| 
       420 
     | 
    
         
            -
            	 
     | 
| 
       421 
     | 
    
         
            -
            	 
     | 
| 
       422 
     | 
    
         
            -
             
     | 
| 
       423 
     | 
    
         
            -
             
     | 
| 
       424 
     | 
    
         
            -
             
     | 
| 
       425 
     | 
    
         
            -
            	 
     | 
| 
       426 
     | 
    
         
            -
             
     | 
| 
       427 
     | 
    
         
            -
             
     | 
| 
       428 
     | 
    
         
            -
             
     | 
| 
       429 
     | 
    
         
            -
             
     | 
| 
       430 
     | 
    
         
            -
            	 
     | 
| 
       431 
     | 
    
         
            -
             
     | 
| 
       432 
     | 
    
         
            -
             
     | 
| 
       433 
     | 
    
         
            -
            	 
     | 
| 
       434 
     | 
    
         
            -
             
     | 
| 
       435 
     | 
    
         
            -
             
     | 
| 
       436 
     | 
    
         
            -
            	 
     | 
| 
      
 1 
     | 
    
         
            +
            #encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            class UIC::MetaData
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            	# The base class for all assets. All other classes are dynamically created when a `MetaData.xml` file is loaded.
         
     | 
| 
      
 5 
     | 
    
         
            +
            	class AssetBase
         
     | 
| 
      
 6 
     | 
    
         
            +
            		@properties = {}
         
     | 
| 
      
 7 
     | 
    
         
            +
            		@name = "AssetBase"
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            		class << self
         
     | 
| 
      
 10 
     | 
    
         
            +
            			# @return [String] The scene graph name of the asset.
         
     | 
| 
      
 11 
     | 
    
         
            +
            			attr_reader :name
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            			# @return [Hash] a hash mapping attribute names to {Property} instances.
         
     | 
| 
      
 14 
     | 
    
         
            +
            			def properties
         
     | 
| 
      
 15 
     | 
    
         
            +
            				(ancestors[1].respond_to?(:properties) ? ancestors[1].properties : {}).merge(@properties)
         
     | 
| 
      
 16 
     | 
    
         
            +
            			end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            			# @private
         
     | 
| 
      
 19 
     | 
    
         
            +
            			def inspect
         
     | 
| 
      
 20 
     | 
    
         
            +
            				"<#{@name}>"
         
     | 
| 
      
 21 
     | 
    
         
            +
            			end
         
     | 
| 
      
 22 
     | 
    
         
            +
            		end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            		# @return [Hash] a hash mapping attribute names to {Property} instances.
         
     | 
| 
      
 25 
     | 
    
         
            +
            		def properties
         
     | 
| 
      
 26 
     | 
    
         
            +
            			self.class.properties
         
     | 
| 
      
 27 
     | 
    
         
            +
            		end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            		# Find an asset by relative scripting path.
         
     | 
| 
      
 30 
     | 
    
         
            +
            		#
         
     | 
| 
      
 31 
     | 
    
         
            +
            		# @example
         
     | 
| 
      
 32 
     | 
    
         
            +
            		#  preso = app.main
         
     | 
| 
      
 33 
     | 
    
         
            +
            		#  layer = preso/"Scene.Layer"
         
     | 
| 
      
 34 
     | 
    
         
            +
            		#  cam1  = app/"main:Scene.Layer.Camera"
         
     | 
| 
      
 35 
     | 
    
         
            +
            		#  cam2  = preso/"Scene.Layer.Camera"
         
     | 
| 
      
 36 
     | 
    
         
            +
            		#  cam3  = layer/"Camera"
         
     | 
| 
      
 37 
     | 
    
         
            +
            		#  cam4  = cam1/"parent.Camera"
         
     | 
| 
      
 38 
     | 
    
         
            +
            		#
         
     | 
| 
      
 39 
     | 
    
         
            +
            		#  assert cam1==cam2 && cam2==cam3 && cam3==cam4
         
     | 
| 
      
 40 
     | 
    
         
            +
            		#
         
     | 
| 
      
 41 
     | 
    
         
            +
            		# @return [MetaData::AssetBase] The found asset, or `nil` if it cannot be found.
         
     | 
| 
      
 42 
     | 
    
         
            +
            		#
         
     | 
| 
      
 43 
     | 
    
         
            +
            		# @see Application#at
         
     | 
| 
      
 44 
     | 
    
         
            +
            		# @see Presentation#at
         
     | 
| 
      
 45 
     | 
    
         
            +
            		def at(sub_path)
         
     | 
| 
      
 46 
     | 
    
         
            +
            			presentation.at(sub_path,@el)
         
     | 
| 
      
 47 
     | 
    
         
            +
            		end
         
     | 
| 
      
 48 
     | 
    
         
            +
            		alias_method :/, :at
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            		# @return [Presentation] the presentation that this asset is part of.
         
     | 
| 
      
 51 
     | 
    
         
            +
            		attr_accessor :presentation
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            		# @return [Nokogiri::XML::Element] the internal XML element in the scene graph of the presentation.
         
     | 
| 
      
 54 
     | 
    
         
            +
            		attr_accessor :el
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            		# Create a new asset. This is called for you automatically; you likely should not be using it.
         
     | 
| 
      
 57 
     | 
    
         
            +
            		# @param presentation [Presentation] the presentation owning this asset.
         
     | 
| 
      
 58 
     | 
    
         
            +
            		# @param element [Nokogiri::XML::Element] the internal XML element in the scene graph of the presentation.
         
     | 
| 
      
 59 
     | 
    
         
            +
            		def initialize( presentation, element )
         
     | 
| 
      
 60 
     | 
    
         
            +
            			@presentation = presentation
         
     | 
| 
      
 61 
     | 
    
         
            +
            			@el = element
         
     | 
| 
      
 62 
     | 
    
         
            +
            		end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            		# @return [String] the type of this asset. For example: `"Model"`, `"Material"`, `"ReferencedMaterial"`, `"PathAnchorPoint"`, etc.
         
     | 
| 
      
 65 
     | 
    
         
            +
            		def type
         
     | 
| 
      
 66 
     | 
    
         
            +
            			self.class.name
         
     | 
| 
      
 67 
     | 
    
         
            +
            		end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            		# @return [AssetBase] the parent of this asset in the scene graph.
         
     | 
| 
      
 70 
     | 
    
         
            +
            		# @see Presentation#parent_asset
         
     | 
| 
      
 71 
     | 
    
         
            +
            		def parent
         
     | 
| 
      
 72 
     | 
    
         
            +
            			presentation.parent_asset(self)
         
     | 
| 
      
 73 
     | 
    
         
            +
            		end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            		# @return [Array<AssetBase>] array of child assets in the scene graph. Children are in scene graph order.
         
     | 
| 
      
 76 
     | 
    
         
            +
            		# @see Presentation#child_assets
         
     | 
| 
      
 77 
     | 
    
         
            +
            		def children
         
     | 
| 
      
 78 
     | 
    
         
            +
            			presentation.child_assets(self)
         
     | 
| 
      
 79 
     | 
    
         
            +
            		end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
            		# @return [String] the hierarchy under the element (for debugging purposes).
         
     | 
| 
      
 82 
     | 
    
         
            +
            		def hierarchy
         
     | 
| 
      
 83 
     | 
    
         
            +
            			presentation.hierarchy(self)
         
     | 
| 
      
 84 
     | 
    
         
            +
            		end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            		# Find descendant assets matching criteria.
         
     | 
| 
      
 87 
     | 
    
         
            +
            		# This method is the same as (but more convenient than) {Presentation#find} using the `:_under` criteria.
         
     | 
| 
      
 88 
     | 
    
         
            +
            		# See that method for documentation of the `criteria`.
         
     | 
| 
      
 89 
     | 
    
         
            +
            		#
         
     | 
| 
      
 90 
     | 
    
         
            +
            		# @example
         
     | 
| 
      
 91 
     | 
    
         
            +
            		#  preso = app.main
         
     | 
| 
      
 92 
     | 
    
         
            +
            		#  group = preso/"Scene.Layer.Vehicle"
         
     | 
| 
      
 93 
     | 
    
         
            +
            		#  tires = group.find name:/^Tire/
         
     | 
| 
      
 94 
     | 
    
         
            +
            		#
         
     | 
| 
      
 95 
     | 
    
         
            +
            		#  # alternative
         
     | 
| 
      
 96 
     | 
    
         
            +
            		#  tires = preso.find name:/^Tire/, _under:group
         
     | 
| 
      
 97 
     | 
    
         
            +
            		#
         
     | 
| 
      
 98 
     | 
    
         
            +
            		# @return [Array<AssetBase>]
         
     | 
| 
      
 99 
     | 
    
         
            +
            		#
         
     | 
| 
      
 100 
     | 
    
         
            +
            		# @see Presentation#find
         
     | 
| 
      
 101 
     | 
    
         
            +
            		def find(criteria={},&block)
         
     | 
| 
      
 102 
     | 
    
         
            +
            			criteria[:_under] ||= self
         
     | 
| 
      
 103 
     | 
    
         
            +
            			presentation.find(criteria,&block)
         
     | 
| 
      
 104 
     | 
    
         
            +
            		end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
            		# @return [AssetBase] the component or scene that owns this asset.
         
     | 
| 
      
 107 
     | 
    
         
            +
            		#         If this asset is a component, does not return itself.
         
     | 
| 
      
 108 
     | 
    
         
            +
            		# @see Presentation#owning_component
         
     | 
| 
      
 109 
     | 
    
         
            +
            		def component
         
     | 
| 
      
 110 
     | 
    
         
            +
            			presentation.owning_component(self)
         
     | 
| 
      
 111 
     | 
    
         
            +
            		end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
            		# @return [Boolean] `true` if this asset is a component or Scene.
         
     | 
| 
      
 114 
     | 
    
         
            +
            		def component?
         
     | 
| 
      
 115 
     | 
    
         
            +
            			@el.name=='Component' || @el.name=='Scene'
         
     | 
| 
      
 116 
     | 
    
         
            +
            		end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            		# @return [Boolean] `true` if this asset is on the master slide.
         
     | 
| 
      
 119 
     | 
    
         
            +
            		# @see Presentation#master?
         
     | 
| 
      
 120 
     | 
    
         
            +
            		def master?
         
     | 
| 
      
 121 
     | 
    
         
            +
            			presentation.master?(self)
         
     | 
| 
      
 122 
     | 
    
         
            +
            		end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
            		# @return [Boolean] `true` if this asset is a Slide.
         
     | 
| 
      
 125 
     | 
    
         
            +
            		def slide?
         
     | 
| 
      
 126 
     | 
    
         
            +
            			false
         
     | 
| 
      
 127 
     | 
    
         
            +
            		end
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
            		# @param slide_name_or_index [Integer,String] the slide number of name to check for presence on.
         
     | 
| 
      
 130 
     | 
    
         
            +
            		# @return [Boolean] `true` if this asset is present on the specified slide.
         
     | 
| 
      
 131 
     | 
    
         
            +
            		# @see Presentation#has_slide?
         
     | 
| 
      
 132 
     | 
    
         
            +
            		def has_slide?(slide_name_or_index)
         
     | 
| 
      
 133 
     | 
    
         
            +
            			presentation.has_slide?(self,slide_name_or_index)
         
     | 
| 
      
 134 
     | 
    
         
            +
            		end
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
            		# @return [SlideCollection] an array-like collection of all slides that the asset is available on.
         
     | 
| 
      
 137 
     | 
    
         
            +
            		# @see Presentation#slides_for
         
     | 
| 
      
 138 
     | 
    
         
            +
            		def slides
         
     | 
| 
      
 139 
     | 
    
         
            +
            			presentation.slides_for(self)
         
     | 
| 
      
 140 
     | 
    
         
            +
            		end
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
            		# @example
         
     | 
| 
      
 143 
     | 
    
         
            +
            		#  logo = app/"main:Scene.UI.Logo"
         
     | 
| 
      
 144 
     | 
    
         
            +
            		#  assert logo.master?             # It's a master object
         
     | 
| 
      
 145 
     | 
    
         
            +
            		#
         
     | 
| 
      
 146 
     | 
    
         
            +
            		#  show logo['endtime'].values     #=> [10000,500,1000,750]
         
     | 
| 
      
 147 
     | 
    
         
            +
            		#  show logo['opacity'].values     #=> [100,0,0,100]
         
     | 
| 
      
 148 
     | 
    
         
            +
            		#  logo1 = logo.on_slide(1)
         
     | 
| 
      
 149 
     | 
    
         
            +
            		#  logo2 = logo.on_slide(2)
         
     | 
| 
      
 150 
     | 
    
         
            +
            		#  show logo1['endtime']           #=> 500
         
     | 
| 
      
 151 
     | 
    
         
            +
            		#  show logo2['endtime']           #=> 1000
         
     | 
| 
      
 152 
     | 
    
         
            +
            		#  show logo1['opacity']           #=> 0
         
     | 
| 
      
 153 
     | 
    
         
            +
            		#  show logo2['opacity']           #=> 0
         
     | 
| 
      
 154 
     | 
    
         
            +
            		#
         
     | 
| 
      
 155 
     | 
    
         
            +
            		#  logo2['opacity'] = 66
         
     | 
| 
      
 156 
     | 
    
         
            +
            		#  show logo['opacity'].values     #=> [100,0,66,100]
         
     | 
| 
      
 157 
     | 
    
         
            +
            		#
         
     | 
| 
      
 158 
     | 
    
         
            +
            		# @param slide_name_or_index [Integer,String] the slide number or name to create the proxy for.
         
     | 
| 
      
 159 
     | 
    
         
            +
            		# @return [SlideValues] a proxy that yields attribute values for a specific slide.
         
     | 
| 
      
 160 
     | 
    
         
            +
            		def on_slide(slide_name_or_index)
         
     | 
| 
      
 161 
     | 
    
         
            +
            			if has_slide?(slide_name_or_index)
         
     | 
| 
      
 162 
     | 
    
         
            +
            				UIC::SlideValues.new( self, slide_name_or_index )
         
     | 
| 
      
 163 
     | 
    
         
            +
            			end
         
     | 
| 
      
 164 
     | 
    
         
            +
            		end
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
            		# @return [String] the script path to this asset.
         
     | 
| 
      
 167 
     | 
    
         
            +
            		# @see #path_to
         
     | 
| 
      
 168 
     | 
    
         
            +
            		# @see Presentation#path_to
         
     | 
| 
      
 169 
     | 
    
         
            +
            		def path
         
     | 
| 
      
 170 
     | 
    
         
            +
            			@path ||= @presentation.path_to(self)
         
     | 
| 
      
 171 
     | 
    
         
            +
            		end
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
            		# @param other_asset [AssetBase] the asset to find the relative path to.
         
     | 
| 
      
 174 
     | 
    
         
            +
            		# @return [String] the script path to another asset, relative to this one.
         
     | 
| 
      
 175 
     | 
    
         
            +
            		# @see #path
         
     | 
| 
      
 176 
     | 
    
         
            +
            		# @see Presentation#path_to
         
     | 
| 
      
 177 
     | 
    
         
            +
            		def path_to(other_asset)
         
     | 
| 
      
 178 
     | 
    
         
            +
            			@presentation.path_to(other_asset,self)
         
     | 
| 
      
 179 
     | 
    
         
            +
            		end
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
            		# @return [String] the name of this asset in the scene graph.
         
     | 
| 
      
 182 
     | 
    
         
            +
            		def name
         
     | 
| 
      
 183 
     | 
    
         
            +
            			properties['name'] ? properties['name'].get( self, presentation.slide_index(self) ) : type
         
     | 
| 
      
 184 
     | 
    
         
            +
            		end
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
            		# Change the name of the asset in the scene graph.
         
     | 
| 
      
 187 
     | 
    
         
            +
            		# @param new_name [String] the new name for this asset.
         
     | 
| 
      
 188 
     | 
    
         
            +
            		# @return [String] the new name.
         
     | 
| 
      
 189 
     | 
    
         
            +
            		def name=( new_name )
         
     | 
| 
      
 190 
     | 
    
         
            +
            			@path = nil # invalidate the memoization
         
     | 
| 
      
 191 
     | 
    
         
            +
            			properties['name'].set( self, new_name, presentation.slide_index(self) )
         
     | 
| 
      
 192 
     | 
    
         
            +
            		end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
            		# Get the value(s) of an attribute.
         
     | 
| 
      
 195 
     | 
    
         
            +
            		# If `slide_name_or_index` is omitted, creates a ValuesPerSlide proxy for the specified attribute.
         
     | 
| 
      
 196 
     | 
    
         
            +
            		# @example
         
     | 
| 
      
 197 
     | 
    
         
            +
            		#  logo = app/"main:Scene.UI.Logo"
         
     | 
| 
      
 198 
     | 
    
         
            +
            		#  show logo.master?               #=> true  (it's a master object)
         
     | 
| 
      
 199 
     | 
    
         
            +
            		#  show logo['endtime'].linked?    #=> false (the endtime property is unlinked)
         
     | 
| 
      
 200 
     | 
    
         
            +
            		#  show logo['endtime'].values     #=> [10000,500,1000,750]
         
     | 
| 
      
 201 
     | 
    
         
            +
            		#  show logo['endtime',0]          #=> 10000 (the master slide value)
         
     | 
| 
      
 202 
     | 
    
         
            +
            		#  show logo['endtime',"Slide 1"]  #=> 500
         
     | 
| 
      
 203 
     | 
    
         
            +
            		#  show logo['endtime',2]          #=> 1000
         
     | 
| 
      
 204 
     | 
    
         
            +
            		#
         
     | 
| 
      
 205 
     | 
    
         
            +
            		# @param attribute_name [String,Symbol] the name of the attribute.
         
     | 
| 
      
 206 
     | 
    
         
            +
            		# @param slide_name_or_index [Integer,String] the slide number or name to find the value on.
         
     | 
| 
      
 207 
     | 
    
         
            +
            		# @return [Object] the value of the property on the given slide.
         
     | 
| 
      
 208 
     | 
    
         
            +
            		# @return [ValuesPerSlide] if no slide is specified.
         
     | 
| 
      
 209 
     | 
    
         
            +
            		# @see #on_slide
         
     | 
| 
      
 210 
     | 
    
         
            +
            		# @see Presentation#get_attribute
         
     | 
| 
      
 211 
     | 
    
         
            +
            		def [](attribute_name, slide_name_or_index=nil)
         
     | 
| 
      
 212 
     | 
    
         
            +
            			if property = properties[attribute_name.to_s]
         
     | 
| 
      
 213 
     | 
    
         
            +
            				if slide_name_or_index
         
     | 
| 
      
 214 
     | 
    
         
            +
            					property.get( self, slide_name_or_index ) if has_slide?(slide_name_or_index)
         
     | 
| 
      
 215 
     | 
    
         
            +
            				else
         
     | 
| 
      
 216 
     | 
    
         
            +
            					UIC::ValuesPerSlide.new(@presentation,self,property)
         
     | 
| 
      
 217 
     | 
    
         
            +
            				end
         
     | 
| 
      
 218 
     | 
    
         
            +
            			end
         
     | 
| 
      
 219 
     | 
    
         
            +
            		end
         
     | 
| 
      
 220 
     | 
    
         
            +
             
     | 
| 
      
 221 
     | 
    
         
            +
            		# Set the value of an attribute, either across all slides, or on a particular slide.
         
     | 
| 
      
 222 
     | 
    
         
            +
            		#
         
     | 
| 
      
 223 
     | 
    
         
            +
            		# @example
         
     | 
| 
      
 224 
     | 
    
         
            +
            		#  logo = app/"main:Scene.UI.Logo"
         
     | 
| 
      
 225 
     | 
    
         
            +
            		#  show logo.master?               #=> true  (it's a master object)
         
     | 
| 
      
 226 
     | 
    
         
            +
            		#  show logo['endtime'].linked?    #=> false (the endtime property is unlinked)
         
     | 
| 
      
 227 
     | 
    
         
            +
            		#  show logo['endtime'].values     #=> [10000,500,1000,750]
         
     | 
| 
      
 228 
     | 
    
         
            +
            		#
         
     | 
| 
      
 229 
     | 
    
         
            +
            		#  logo['endtime',1] = 99
         
     | 
| 
      
 230 
     | 
    
         
            +
            		#  show logo['endtime'].values     #=> [10000,99,1000,750]
         
     | 
| 
      
 231 
     | 
    
         
            +
            		#
         
     | 
| 
      
 232 
     | 
    
         
            +
            		#  logo['endtime'] = 42
         
     | 
| 
      
 233 
     | 
    
         
            +
            		#  show logo['endtime'].values     #=> [42,42,42,42]
         
     | 
| 
      
 234 
     | 
    
         
            +
            		#  show logo['endtime'].linked?    #=> false (the endtime property is still unlinked)
         
     | 
| 
      
 235 
     | 
    
         
            +
            		#
         
     | 
| 
      
 236 
     | 
    
         
            +
            		# @param attribute_name [String,Symbol] the name of the attribute.
         
     | 
| 
      
 237 
     | 
    
         
            +
            		# @param slide_name_or_index [Integer,String] the slide number or name to set the value on.
         
     | 
| 
      
 238 
     | 
    
         
            +
            		# @param new_value [Numeric,String] the new value for the attribute.
         
     | 
| 
      
 239 
     | 
    
         
            +
            		# @see Presentation#set_attribute
         
     | 
| 
      
 240 
     | 
    
         
            +
            		def []=( attribute_name, slide_name_or_index=nil, new_value )
         
     | 
| 
      
 241 
     | 
    
         
            +
            			if property = properties[attribute_name.to_s] then
         
     | 
| 
      
 242 
     | 
    
         
            +
            				property.set(self,new_value,slide_name_or_index)
         
     | 
| 
      
 243 
     | 
    
         
            +
            			end
         
     | 
| 
      
 244 
     | 
    
         
            +
            		end
         
     | 
| 
      
 245 
     | 
    
         
            +
             
     | 
| 
      
 246 
     | 
    
         
            +
            		# @return [String] the XML representation of the scene graph element.
         
     | 
| 
      
 247 
     | 
    
         
            +
            		def to_xml
         
     | 
| 
      
 248 
     | 
    
         
            +
            			@el.to_xml
         
     | 
| 
      
 249 
     | 
    
         
            +
            		end
         
     | 
| 
      
 250 
     | 
    
         
            +
             
     | 
| 
      
 251 
     | 
    
         
            +
            		# @private no need to document this
         
     | 
| 
      
 252 
     | 
    
         
            +
            		def to_s
         
     | 
| 
      
 253 
     | 
    
         
            +
            			"<#{type} #{path}>"
         
     | 
| 
      
 254 
     | 
    
         
            +
            		end
         
     | 
| 
      
 255 
     | 
    
         
            +
            		alias_method :inspect, :to_s
         
     | 
| 
      
 256 
     | 
    
         
            +
             
     | 
| 
      
 257 
     | 
    
         
            +
            		# @private no need to document this
         
     | 
| 
      
 258 
     | 
    
         
            +
            		def ==(other)
         
     | 
| 
      
 259 
     | 
    
         
            +
            			(self.class==other.class) && (el==other.el)
         
     | 
| 
      
 260 
     | 
    
         
            +
            		end
         
     | 
| 
      
 261 
     | 
    
         
            +
            		alias_method :eql?, :==
         
     | 
| 
      
 262 
     | 
    
         
            +
            	end
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
            	attr_reader :by_name
         
     | 
| 
      
 265 
     | 
    
         
            +
             
     | 
| 
      
 266 
     | 
    
         
            +
            	HIER = {}
         
     | 
| 
      
 267 
     | 
    
         
            +
             
     | 
| 
      
 268 
     | 
    
         
            +
            	%w[Asset Slide Scene].each{ |s| HIER[s] = 'AssetBase' }
         
     | 
| 
      
 269 
     | 
    
         
            +
            	%w[Node Behavior Effect Image Layer MaterialBase PathAnchorPoint RenderPlugin].each{ |s| HIER[s]='Asset' }
         
     | 
| 
      
 270 
     | 
    
         
            +
            	%w[Alias Camera Component Group Light Model Text Path].each{ |s| HIER[s]='Node' }
         
     | 
| 
      
 271 
     | 
    
         
            +
            	%w[Material ReferencedMaterial].each{ |s| HIER[s]='MaterialBase' }
         
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
      
 273 
     | 
    
         
            +
            	def initialize(xml)
         
     | 
| 
      
 274 
     | 
    
         
            +
            		@by_name = {'AssetBase'=>AssetBase}
         
     | 
| 
      
 275 
     | 
    
         
            +
             
     | 
| 
      
 276 
     | 
    
         
            +
            		doc = Nokogiri.XML(xml)
         
     | 
| 
      
 277 
     | 
    
         
            +
            		hack_in_slide_names!(doc)
         
     | 
| 
      
 278 
     | 
    
         
            +
             
     | 
| 
      
 279 
     | 
    
         
            +
            		HIER.each do |class_name,parent_class_name|
         
     | 
| 
      
 280 
     | 
    
         
            +
            			parent_class = @by_name[parent_class_name]
         
     | 
| 
      
 281 
     | 
    
         
            +
            			el = doc.root.at(class_name)
         
     | 
| 
      
 282 
     | 
    
         
            +
            			@by_name[class_name] = create_class(el,parent_class,el.name)
         
     | 
| 
      
 283 
     | 
    
         
            +
            		end
         
     | 
| 
      
 284 
     | 
    
         
            +
             
     | 
| 
      
 285 
     | 
    
         
            +
            		# Extend well-known classes with script interfaces after they are created
         
     | 
| 
      
 286 
     | 
    
         
            +
            		@by_name['State'] = @by_name['Slide']
         
     | 
| 
      
 287 
     | 
    
         
            +
            		@by_name['Slide'].instance_eval do
         
     | 
| 
      
 288 
     | 
    
         
            +
            			attr_accessor :index, :name
         
     | 
| 
      
 289 
     | 
    
         
            +
            			define_method :inspect do
         
     | 
| 
      
 290 
     | 
    
         
            +
            				"<slide ##{index} of #{@el['component'] || @el.parent['component']}>"
         
     | 
| 
      
 291 
     | 
    
         
            +
            			end
         
     | 
| 
      
 292 
     | 
    
         
            +
            			define_method(:slide?){ true }
         
     | 
| 
      
 293 
     | 
    
         
            +
            		end
         
     | 
| 
      
 294 
     | 
    
         
            +
             
     | 
| 
      
 295 
     | 
    
         
            +
            		refmat = @by_name['ReferencedMaterial']
         
     | 
| 
      
 296 
     | 
    
         
            +
            		@by_name['MaterialBase'].instance_eval do
         
     | 
| 
      
 297 
     | 
    
         
            +
            			define_method :replace_with_referenced_material do
         
     | 
| 
      
 298 
     | 
    
         
            +
            				type=='ReferencedMaterial' ? self : presentation.replace_asset( self, 'ReferencedMaterial', name:name )
         
     | 
| 
      
 299 
     | 
    
         
            +
            			end
         
     | 
| 
      
 300 
     | 
    
         
            +
            		end
         
     | 
| 
      
 301 
     | 
    
         
            +
             
     | 
| 
      
 302 
     | 
    
         
            +
            		@by_name['Path'].instance_eval do
         
     | 
| 
      
 303 
     | 
    
         
            +
            			define_method(:anchors){ find _type:'PathAnchorPoint' }
         
     | 
| 
      
 304 
     | 
    
         
            +
            		end
         
     | 
| 
      
 305 
     | 
    
         
            +
             
     | 
| 
      
 306 
     | 
    
         
            +
            	end
         
     | 
| 
      
 307 
     | 
    
         
            +
             
     | 
| 
      
 308 
     | 
    
         
            +
            	# Creates a class from MetaData.xml with accessors for the <Property> listed.
         
     | 
| 
      
 309 
     | 
    
         
            +
            	# Instances of the class are associated with a presentation and know how to
         
     | 
| 
      
 310 
     | 
    
         
            +
            	# get/set values in that XML based on value types, slides, defaults.
         
     | 
| 
      
 311 
     | 
    
         
            +
            	# Also used to create classes from effects, materials, and behavior preambles.
         
     | 
| 
      
 312 
     | 
    
         
            +
            	# @param el [Nokogiri::XML::Element] the element in MetaData.xml representing this class.
         
     | 
| 
      
 313 
     | 
    
         
            +
            	# @param parent_class [Class] the asset class to inherit from.
         
     | 
| 
      
 314 
     | 
    
         
            +
            	# @param name [String] the name of this class.
         
     | 
| 
      
 315 
     | 
    
         
            +
            	# @param new_defaults [Hash] hash mapping attribute name to a custom default value (as string) for this class.
         
     | 
| 
      
 316 
     | 
    
         
            +
            	def create_class(el,parent_class,name,new_defaults={})
         
     | 
| 
      
 317 
     | 
    
         
            +
            		Class.new(parent_class) do
         
     | 
| 
      
 318 
     | 
    
         
            +
            			@name = name.to_s
         
     | 
| 
      
 319 
     | 
    
         
            +
            			@properties = Hash[ el.css("Property").map do |e|
         
     | 
| 
      
 320 
     | 
    
         
            +
            				type = e['type'] || (e['list'] ? 'String' : 'Float')
         
     | 
| 
      
 321 
     | 
    
         
            +
            				type = "Float" if type=="float"
         
     | 
| 
      
 322 
     | 
    
         
            +
            				property = begin
         
     | 
| 
      
 323 
     | 
    
         
            +
            					UIC::Property.const_get(type).new(e)
         
     | 
| 
      
 324 
     | 
    
         
            +
            				rescue NameError
         
     | 
| 
      
 325 
     | 
    
         
            +
            					warn "WARNING: Unsupported property type '#{type}' on\n#{e}\nTreating this as a String."
         
     | 
| 
      
 326 
     | 
    
         
            +
            					UIC::Property::String.new(e)
         
     | 
| 
      
 327 
     | 
    
         
            +
            				end
         
     | 
| 
      
 328 
     | 
    
         
            +
            				new_defaults.delete(property.name)
         
     | 
| 
      
 329 
     | 
    
         
            +
            				[ property.name, property ]
         
     | 
| 
      
 330 
     | 
    
         
            +
            			end ]
         
     | 
| 
      
 331 
     | 
    
         
            +
             
     | 
| 
      
 332 
     | 
    
         
            +
            			new_defaults.each do |name,value|
         
     | 
| 
      
 333 
     | 
    
         
            +
            				if prop=properties[name] # look in ancestor classes
         
     | 
| 
      
 334 
     | 
    
         
            +
            					@properties[name] = prop.dup
         
     | 
| 
      
 335 
     | 
    
         
            +
            					@properties[name].default = value
         
     | 
| 
      
 336 
     | 
    
         
            +
            				end
         
     | 
| 
      
 337 
     | 
    
         
            +
            			end
         
     | 
| 
      
 338 
     | 
    
         
            +
             
     | 
| 
      
 339 
     | 
    
         
            +
            			def self.inspect
         
     | 
| 
      
 340 
     | 
    
         
            +
            				@name
         
     | 
| 
      
 341 
     | 
    
         
            +
            			end
         
     | 
| 
      
 342 
     | 
    
         
            +
            		end
         
     | 
| 
      
 343 
     | 
    
         
            +
            	end
         
     | 
| 
      
 344 
     | 
    
         
            +
             
     | 
| 
      
 345 
     | 
    
         
            +
            	def new_instance(presentation,el)
         
     | 
| 
      
 346 
     | 
    
         
            +
            		klass = @by_name[el.name] || create_class(el,@by_name['Asset'],el.name)
         
     | 
| 
      
 347 
     | 
    
         
            +
            		klass.new(presentation,el)
         
     | 
| 
      
 348 
     | 
    
         
            +
            	end
         
     | 
| 
      
 349 
     | 
    
         
            +
             
     | 
| 
      
 350 
     | 
    
         
            +
            	def hack_in_slide_names!(doc)
         
     | 
| 
      
 351 
     | 
    
         
            +
            		doc.at('Slide') << '<Property name="name" formalName="Name" type="String" default="Slide" hidden="True" />'
         
     | 
| 
      
 352 
     | 
    
         
            +
            	end
         
     | 
| 
      
 353 
     | 
    
         
            +
            end
         
     | 
| 
      
 354 
     | 
    
         
            +
             
     | 
| 
      
 355 
     | 
    
         
            +
            def UIC.MetaData(metadata_path)
         
     | 
| 
      
 356 
     | 
    
         
            +
            	raise %Q{Cannot find MetaData.xml at "#{metadata_path}"} unless File.exist?(metadata_path)
         
     | 
| 
      
 357 
     | 
    
         
            +
            	UIC::MetaData.new(File.read(metadata_path,encoding:'utf-8'))
         
     | 
| 
      
 358 
     | 
    
         
            +
            end
         
     | 
| 
      
 359 
     | 
    
         
            +
             
     | 
| 
      
 360 
     | 
    
         
            +
            class UIC::SlideCollection
         
     | 
| 
      
 361 
     | 
    
         
            +
            	include Enumerable
         
     | 
| 
      
 362 
     | 
    
         
            +
            	attr_reader :length
         
     | 
| 
      
 363 
     | 
    
         
            +
            	def initialize(slides)
         
     | 
| 
      
 364 
     | 
    
         
            +
            		@length = slides.length-1
         
     | 
| 
      
 365 
     | 
    
         
            +
            		@slides = slides
         
     | 
| 
      
 366 
     | 
    
         
            +
            		@lookup = {}
         
     | 
| 
      
 367 
     | 
    
         
            +
            		slides.each do |s|
         
     | 
| 
      
 368 
     | 
    
         
            +
            			@lookup[s.index] = s
         
     | 
| 
      
 369 
     | 
    
         
            +
            			@lookup[s.name]  = s
         
     | 
| 
      
 370 
     | 
    
         
            +
            		end
         
     | 
| 
      
 371 
     | 
    
         
            +
            	end
         
     | 
| 
      
 372 
     | 
    
         
            +
            	def each
         
     | 
| 
      
 373 
     | 
    
         
            +
            		@slides.each{ |s| yield(s) }
         
     | 
| 
      
 374 
     | 
    
         
            +
            	end
         
     | 
| 
      
 375 
     | 
    
         
            +
            	def [](index_or_name)
         
     | 
| 
      
 376 
     | 
    
         
            +
            		@lookup[ index_or_name ]
         
     | 
| 
      
 377 
     | 
    
         
            +
            	end
         
     | 
| 
      
 378 
     | 
    
         
            +
            	def inspect
         
     | 
| 
      
 379 
     | 
    
         
            +
            		"[ #{@slides.map(&:inspect).join ', '} ]"
         
     | 
| 
      
 380 
     | 
    
         
            +
            	end
         
     | 
| 
      
 381 
     | 
    
         
            +
            	def to_ary
         
     | 
| 
      
 382 
     | 
    
         
            +
            		@slides
         
     | 
| 
      
 383 
     | 
    
         
            +
            	end
         
     | 
| 
      
 384 
     | 
    
         
            +
            end
         
     | 
| 
      
 385 
     | 
    
         
            +
             
     | 
| 
      
 386 
     | 
    
         
            +
            class UIC::ValuesPerSlide
         
     | 
| 
      
 387 
     | 
    
         
            +
            	def initialize(presentation,asset,property)
         
     | 
| 
      
 388 
     | 
    
         
            +
            		raise unless presentation.is_a?(UIC::Presentation)
         
     | 
| 
      
 389 
     | 
    
         
            +
             
     | 
| 
      
 390 
     | 
    
         
            +
            		raise unless asset.is_a?(UIC::MetaData::AssetBase)
         
     | 
| 
      
 391 
     | 
    
         
            +
            		raise unless property.is_a?(UIC::Property)
         
     | 
| 
      
 392 
     | 
    
         
            +
            		@preso    = presentation
         
     | 
| 
      
 393 
     | 
    
         
            +
            		@asset    = asset
         
     | 
| 
      
 394 
     | 
    
         
            +
            		@el       = asset.el
         
     | 
| 
      
 395 
     | 
    
         
            +
            		@property = property
         
     | 
| 
      
 396 
     | 
    
         
            +
            	end
         
     | 
| 
      
 397 
     | 
    
         
            +
            	def value
         
     | 
| 
      
 398 
     | 
    
         
            +
            		values.first
         
     | 
| 
      
 399 
     | 
    
         
            +
            	end
         
     | 
| 
      
 400 
     | 
    
         
            +
            	def [](slide_name_or_index)
         
     | 
| 
      
 401 
     | 
    
         
            +
            		@property.get( @asset, slide_name_or_index )
         
     | 
| 
      
 402 
     | 
    
         
            +
            	end
         
     | 
| 
      
 403 
     | 
    
         
            +
            	def []=(slide_name_or_index,new_value)
         
     | 
| 
      
 404 
     | 
    
         
            +
            		@property.set( @asset, new_value, slide_name_or_index )
         
     | 
| 
      
 405 
     | 
    
         
            +
            	end
         
     | 
| 
      
 406 
     | 
    
         
            +
            	def linked?
         
     | 
| 
      
 407 
     | 
    
         
            +
            		@preso.attribute_linked?( @asset, @property.name )
         
     | 
| 
      
 408 
     | 
    
         
            +
            	end
         
     | 
| 
      
 409 
     | 
    
         
            +
            	def unlink
         
     | 
| 
      
 410 
     | 
    
         
            +
            		@preso.unlink_attribute( @asset, @property.name )
         
     | 
| 
      
 411 
     | 
    
         
            +
            	end
         
     | 
| 
      
 412 
     | 
    
         
            +
            	def link
         
     | 
| 
      
 413 
     | 
    
         
            +
            		@preso.link_attribute( @asset, @property.name )
         
     | 
| 
      
 414 
     | 
    
         
            +
            	end
         
     | 
| 
      
 415 
     | 
    
         
            +
            	def values
         
     | 
| 
      
 416 
     | 
    
         
            +
            		@asset.slides.map{ |s| self[s.name] }
         
     | 
| 
      
 417 
     | 
    
         
            +
            	end
         
     | 
| 
      
 418 
     | 
    
         
            +
            	def inspect
         
     | 
| 
      
 419 
     | 
    
         
            +
            		"<Values of '#{@asset.name}.#{@property.name}' across slides>"
         
     | 
| 
      
 420 
     | 
    
         
            +
            	end
         
     | 
| 
      
 421 
     | 
    
         
            +
            	alias_method :to_s, :inspect
         
     | 
| 
      
 422 
     | 
    
         
            +
            end
         
     | 
| 
      
 423 
     | 
    
         
            +
             
     | 
| 
      
 424 
     | 
    
         
            +
            class UIC::SlideValues
         
     | 
| 
      
 425 
     | 
    
         
            +
            	attr_reader :asset
         
     | 
| 
      
 426 
     | 
    
         
            +
            	def initialize( asset, slide )
         
     | 
| 
      
 427 
     | 
    
         
            +
            		@asset = asset
         
     | 
| 
      
 428 
     | 
    
         
            +
            		@slide = slide
         
     | 
| 
      
 429 
     | 
    
         
            +
            	end
         
     | 
| 
      
 430 
     | 
    
         
            +
            	def [](attribute_name)
         
     | 
| 
      
 431 
     | 
    
         
            +
            		@asset[attribute_name,@slide]
         
     | 
| 
      
 432 
     | 
    
         
            +
            	end
         
     | 
| 
      
 433 
     | 
    
         
            +
            	def []=( attribute_name, new_value )
         
     | 
| 
      
 434 
     | 
    
         
            +
            		@asset[attribute_name,@slide] = new_value
         
     | 
| 
      
 435 
     | 
    
         
            +
            	end
         
     | 
| 
      
 436 
     | 
    
         
            +
            	def method_missing( name, *args, &blk )
         
     | 
| 
      
 437 
     | 
    
         
            +
            		asset.send(name,*args,&blk)
         
     | 
| 
      
 438 
     | 
    
         
            +
            	end
         
     | 
| 
      
 439 
     | 
    
         
            +
            	def inspect
         
     | 
| 
      
 440 
     | 
    
         
            +
            		"<#{@asset.inspect} on slide #{@slide.inspect}>"
         
     | 
| 
      
 441 
     | 
    
         
            +
            	end
         
     | 
| 
       437 
442 
     | 
    
         
             
            end
         
     |