limelight 0.2.1-java → 0.3.0-java

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.
Files changed (111) hide show
  1. data/bin/ll.bat +1 -1
  2. data/lib/i4jruntime.jar +0 -0
  3. data/lib/junit-4.4.jar +0 -0
  4. data/lib/limelight.jar +0 -0
  5. data/lib/limelight/animation.rb +3 -3
  6. data/lib/limelight/builtin/players.rb +2 -1
  7. data/lib/limelight/builtin/players/combo_box.rb +8 -2
  8. data/lib/limelight/builtin/players/image.rb +47 -0
  9. data/lib/limelight/builtin/styles.rb +1 -1
  10. data/lib/limelight/casting_director.rb +70 -39
  11. data/lib/limelight/commands/command.rb +150 -0
  12. data/lib/limelight/commands/create_command.rb +79 -0
  13. data/lib/limelight/commands/freeze_command.rb +113 -0
  14. data/lib/limelight/commands/open_command.rb +49 -0
  15. data/lib/limelight/commands/pack_command.rb +45 -0
  16. data/lib/limelight/dsl/build_exception.rb +51 -0
  17. data/lib/limelight/dsl/menu_bar.rb +71 -0
  18. data/lib/limelight/dsl/production_builder.rb +71 -0
  19. data/lib/limelight/dsl/prop_builder.rb +155 -0
  20. data/lib/limelight/dsl/stage_builder.rb +105 -0
  21. data/lib/limelight/dsl/styles_builder.rb +134 -0
  22. data/lib/limelight/file_loader.rb +46 -0
  23. data/lib/limelight/gems.rb +45 -0
  24. data/lib/limelight/java_couplings.rb +7 -2
  25. data/lib/limelight/java_util.rb +2 -15
  26. data/lib/limelight/main.rb +7 -5
  27. data/lib/limelight/producer.rb +87 -66
  28. data/lib/limelight/production.rb +42 -4
  29. data/lib/limelight/prop.rb +84 -70
  30. data/lib/limelight/scene.rb +75 -20
  31. data/lib/limelight/specs/spec_helper.rb +58 -0
  32. data/lib/limelight/stage.rb +11 -6
  33. data/lib/limelight/string.rb +35 -0
  34. data/lib/limelight/studio.rb +29 -0
  35. data/lib/limelight/templates/production_templater.rb +42 -0
  36. data/lib/limelight/templates/scene_templater.rb +41 -0
  37. data/lib/limelight/templates/sources/freezing/limelight_init.rb.template +5 -0
  38. data/lib/limelight/templates/sources/production/init.rb.template +15 -0
  39. data/lib/limelight/templates/sources/production/production.rb.template +9 -0
  40. data/lib/limelight/templates/sources/production/stages.rb.template +17 -0
  41. data/lib/limelight/templates/sources/production/styles.rb.template +12 -0
  42. data/lib/limelight/templates/sources/scene/props.rb.template +6 -0
  43. data/lib/limelight/templates/sources/scene/styles.rb.template +18 -0
  44. data/lib/limelight/templates/templater.rb +128 -0
  45. data/lib/limelight/templates/templater_logger.rb +36 -0
  46. data/lib/limelight/theater.rb +21 -7
  47. data/lib/limelight/util.rb +22 -6
  48. data/lib/limelight/version.rb +2 -2
  49. data/productions/examples/8thlight.com/styles.rb +1 -1
  50. data/productions/examples/langstons_ant/html_javascript/ant.html +1 -1
  51. data/productions/examples/langstons_ant/init.rb +1 -0
  52. data/productions/examples/langstons_ant/players/log.rb +2 -2
  53. data/productions/examples/langstons_ant/players/world.rb +0 -26
  54. data/productions/examples/sandbox.llp +0 -0
  55. data/productions/examples/sandbox/click_me/players/chromaton.rb +10 -4
  56. data/productions/examples/sandbox/floaters/players/floater.rb +4 -2
  57. data/productions/examples/sandbox/gradients/players/spinner.rb +5 -1
  58. data/productions/examples/sandbox/gradients/players/teaser.rb +2 -2
  59. data/productions/examples/sandbox/gradients/players/wave.rb +2 -2
  60. data/productions/examples/sandbox/gradients/players/waves.rb +2 -2
  61. data/productions/examples/sandbox/header.rb +1 -0
  62. data/productions/examples/sandbox/images/logo.png +0 -0
  63. data/productions/examples/sandbox/images_scene/props.rb +25 -0
  64. data/productions/examples/sandbox/images_scene/styles.rb +30 -0
  65. data/productions/examples/sandbox/inputs/styles.rb +1 -1
  66. data/productions/examples/sandbox/scrolling/props.rb +12 -12
  67. data/productions/examples/sandbox/teaser/players/fader.rb +2 -8
  68. data/productions/stage_composer/inspector/styles.rb +2 -2
  69. data/productions/startup/styles.rb +2 -2
  70. data/spec/builtin/players/button_spec.rb +0 -1
  71. data/spec/builtin/players/image_spec.rb +41 -0
  72. data/spec/casting_director_spec.rb +114 -44
  73. data/spec/commands/command_spec.rb +18 -0
  74. data/spec/commands/create_command_spec.rb +74 -0
  75. data/spec/commands/freeze_command_spec.rb +59 -0
  76. data/spec/commands/open_command_spec.rb +30 -0
  77. data/spec/commands/pack_command_spec.rb +23 -0
  78. data/spec/dsl/production_builder_spec.rb +46 -0
  79. data/spec/{prop_builder_spec.rb → dsl/prop_builder_spec.rb} +80 -24
  80. data/spec/{stage_builder_spec.rb → dsl/stage_builder_spec.rb} +4 -4
  81. data/spec/{styles_builder_spec.rb → dsl/styles_builder_spec.rb} +6 -6
  82. data/spec/{loaders/file_loader_spec.rb → file_loader_spec.rb} +4 -4
  83. data/spec/gems_spec.rb +83 -0
  84. data/spec/java_util_spec.rb +1 -17
  85. data/spec/main_spec.rb +17 -0
  86. data/spec/producer_spec.rb +89 -79
  87. data/spec/production_spec.rb +28 -3
  88. data/spec/prop_spec.rb +82 -16
  89. data/spec/scene_spec.rb +73 -3
  90. data/spec/spec_helper.rb +37 -1
  91. data/spec/stage_spec.rb +10 -1
  92. data/spec/string_spec.rb +35 -0
  93. data/spec/studio_spec.rb +14 -0
  94. data/spec/styles_spec.rb +14 -0
  95. data/spec/templates/production_templater_spec.rb +44 -0
  96. data/spec/templates/scene_templater_spec.rb +25 -0
  97. data/spec/templates/templater_logger_spec.rb +38 -0
  98. data/spec/templates/templater_spec.rb +104 -0
  99. data/spec/theater_spec.rb +12 -21
  100. metadata +75 -23
  101. data/bin/icons/splash.png +0 -0
  102. data/lib/limelight/build_exception.rb +0 -48
  103. data/lib/limelight/commands.rb +0 -52
  104. data/lib/limelight/loaders/file_scene_loader.rb +0 -49
  105. data/lib/limelight/menu_bar.rb +0 -68
  106. data/lib/limelight/production_builder.rb +0 -66
  107. data/lib/limelight/prop_builder.rb +0 -119
  108. data/lib/limelight/stage_builder.rb +0 -103
  109. data/lib/limelight/styles_builder.rb +0 -131
  110. data/spec/commands_spec.rb +0 -34
  111. data/spec/production_builder_spec.rb +0 -48
@@ -0,0 +1,113 @@
1
+ require 'limelight/commands/command'
2
+
3
+ module Limelight
4
+ module Commands
5
+
6
+ # Freeze a gem into the production. Frozen gems are unpacked into the root level gem directory.
7
+ # Limelight will automatically require a production's frozen gems when loaded.
8
+ #
9
+ # Usage: limelight freeze [options] <gem_name|gem_file>
10
+ # freeze a gem into a production.
11
+ # options:
12
+ # -h, --help Prints this usage summary.
13
+ # -p, --production=<production> Specify the production where the gem will be frozen. Default is '.'.
14
+ # -v, --version=<version> Specify the gem version. Defaults to latest. Ignored if file provided.
15
+ #
16
+ class FreezeCommand < Command
17
+
18
+ install_as "freeze"
19
+
20
+ def self.description #:nodoc:
21
+ return "freeze a gem into a production."
22
+ end
23
+
24
+ attr_reader :gem_name, :production_path, :gem_version
25
+
26
+ def initialize() #:nodoc:
27
+ @production_path = "."
28
+ # self.print_backtrace = true
29
+ end
30
+
31
+ def is_gem_file?(name) #:nodoc:
32
+ return File.extname(name) == ".gem"
33
+ end
34
+
35
+ protected ###########################################
36
+
37
+ def process #:nodoc:
38
+ check_production_path
39
+ gem_path = is_gem_file?(@gem_name) ? @gem_name : find_system_gem
40
+ raise "Gem file does not exist: #{gem_path}" if !File.exists?(gem_path)
41
+ freeze_gem(gem_path)
42
+ end
43
+
44
+ def parse_remainder(args) #:nodoc:
45
+ @gem_name = args.shift
46
+ raise "Gem name paramter missing." if @gem_name.nil?
47
+ end
48
+
49
+ def build_options(spec) #:nodoc:
50
+ spec.on("-p <production>", "--production=<production>", "Specify the production where the gem will be frozen. Default is '.'.") { |value| @production_path = value }
51
+ spec.on("-v <version>", "--version=<version>", "Specify the gem version. Defaults to latest. Ignored if file provided.") { |value| @gem_version = value }
52
+ end
53
+
54
+ def parameter_description #:nodoc:
55
+ return "[options] <gem_name|gem_file>"
56
+ end
57
+
58
+ def do_requires #:nodoc:
59
+ require 'limelight/util'
60
+ require 'limelight/templates/templater'
61
+ require 'rubygems'
62
+ require 'rubygems/commands/unpack_command'
63
+ end
64
+
65
+ private #############################################
66
+
67
+ def check_production_path
68
+ if !(Util.is_limelight_production?(@production_path) || Util.is_limelight_scene?(@production_path))
69
+ raise "The production path '#{@production_path}' doesn't appear to be a Limelight production directory."
70
+ end
71
+ end
72
+
73
+ def find_system_gem
74
+ if @gem_version
75
+ @gem_spec = Gem.cache.find_name(@gem_name, "= #{@gem_version}").first
76
+ raise "Could not find gem (#{@gem_name}-#{@gem_version})." if @gem_spec.nil?
77
+ else
78
+ @gem_spec = Gem.cache.find_name(@gem_name).sort_by { |g| g.version }.last
79
+ raise "Could not find gem (#{@gem_name})." if @gem_spec.nil?
80
+ end
81
+
82
+ return Gem::Commands::UnpackCommand.new.get_path(@gem_name, @gem_spec.version.version)
83
+ end
84
+
85
+ def freeze_gem(gem_path)
86
+ @gem_spec = Gem::Format.from_file_by_path(gem_path).spec unless @gem_spec
87
+ @gem_dir_name = "#{@gem_spec.name}-#{@gem_spec.version}"
88
+
89
+ establish_gem_dir
90
+
91
+ gem_installer = Gem::Installer.new(gem_path)
92
+ @templater.logger.log("unpacking gem", @gem_dir_path)
93
+ gem_installer.unpack(@gem_dir_path)
94
+
95
+ install_limelight_hook
96
+ end
97
+
98
+ def establish_gem_dir
99
+ @templater = Templates::Templater.new(@production_path)
100
+ @gem_dir_path = File.join(@production_path, "__resources", "gems", @gem_dir_name)
101
+ raise "The gem (#{@gem_dir_name}) is already frozen." if File.exists?(@gem_dir_path)
102
+ @templater.directory(File.join("__resources", "gems", @gem_dir_name))
103
+ end
104
+
105
+ def install_limelight_hook
106
+ tokens = { :GEM_NAME => @gem_dir_name, :PATHS => @gem_spec.require_paths.inspect }
107
+ @templater.file(File.join("__resources", "gems", @gem_dir_name, "limelight_init.rb"), "freezing/limelight_init.rb.template", tokens)
108
+ end
109
+
110
+ end
111
+
112
+ end
113
+ end
@@ -0,0 +1,49 @@
1
+ require 'limelight/commands/command'
2
+
3
+ module Limelight
4
+ module Commands
5
+
6
+ # See the following usage summary.
7
+ #
8
+ # Usage: limelight open <production_path>
9
+ # Open a limelight production.
10
+ # options:
11
+ # -h, --help Prints this usage summary.
12
+ #
13
+ class OpenCommand < Command
14
+
15
+ install_as "open"
16
+
17
+ DEFAULT_PRODUCTION = File.expand_path($LIMELIGHT_HOME + "/productions/startup")
18
+
19
+ def initialize
20
+ self.print_backtrace = true
21
+ end
22
+
23
+ def self.description
24
+ return "Open a limelight production."
25
+ end
26
+
27
+ protected ###########################################
28
+
29
+ def parameter_description
30
+ return "<production_path>"
31
+ end
32
+
33
+ def do_requires
34
+ Main.initialize_context
35
+ require 'limelight/producer'
36
+ end
37
+
38
+ def parse_remainder(args)
39
+ @production_path = args.shift || DEFAULT_PRODUCTION
40
+ end
41
+
42
+ def process
43
+ Limelight::Producer.open(@production_path)
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,45 @@
1
+ #- Copyright 2008 8th Light, Inc. All Rights Reserved.
2
+ #- Limelight and all included source files are distributed under terms of the GNU LGPL.
3
+
4
+ require 'limelight/commands/command'
5
+
6
+ module Limelight
7
+ module Commands
8
+
9
+ # See the following usage summary.
10
+ #
11
+ # Usage: limelight pack <production_path>
12
+ # Pack a limelight production into a .llp file.
13
+ # options:
14
+ # -h, --help Prints this usage summary.
15
+ #
16
+ class PackCommand < Command
17
+
18
+ install_as "pack"
19
+
20
+ def self.description #:nodoc:
21
+ return "Pack a limelight production into a .llp file."
22
+ end
23
+
24
+ protected ###########################################
25
+
26
+ def parameter_description #:nodoc:
27
+ return "<production_path>"
28
+ end
29
+
30
+ def parse_remainder(args) #:nodoc:
31
+ @production_path = args.shift
32
+ raise "Missing production path" if @production_path.nil?
33
+ end
34
+
35
+ def process #:nodoc:
36
+ packer = Limelight::Util::Packer.new
37
+ packer.pack(@production_path)
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
44
+
45
+ end
@@ -0,0 +1,51 @@
1
+ #- Copyright 2008 8th Light, Inc. All Rights Reserved.
2
+ #- Limelight and all included source files are distributed under terms of the GNU LGPL.
3
+
4
+ module Limelight
5
+
6
+ module DSL
7
+
8
+ # An Exception used by many of the DSL Builders. Allows nice errors messages, with line numbers, to be printed.
9
+ #
10
+ class BuildException < Exception
11
+
12
+ attr_reader :filename, :line_number
13
+
14
+ def initialize(filename, file_contents, e)
15
+ @filename = filename
16
+ @file_contents = file_contents
17
+ @original_exception = e
18
+ @line_number = find_line_number
19
+ super(build_error_message)
20
+ set_backtrace(e.backtrace)
21
+ end
22
+
23
+ def find_line_number
24
+ lines = [@original_exception.message].concat @original_exception.backtrace
25
+ line_number = nil
26
+ lines.each do |line|
27
+ match = line.match(/\(eval\):(\d+):/)
28
+ if (match)
29
+ line_number = match[1].to_i
30
+ break
31
+ end
32
+ end
33
+ return line_number
34
+ end
35
+
36
+ def build_error_message
37
+ lines = @file_contents.split("\n")
38
+ start_line = @line_number - 4 < 0 ? 0 : @line_number - 4
39
+ end_line = @line_number + 2 >= lines.size ? lines.size - 1: @line_number + 2
40
+ message = "#{@filename}:#{@line_number}: #{@original_exception.message}"
41
+ message << "\n\t----- #{@filename} lines #{start_line + 1} - #{end_line + 1} -----"
42
+ (start_line..end_line).each do |i|
43
+ message << "\n\t#{i == @line_number - 1 ? "*": " "} #{i+1}: #{lines[i]}"
44
+ end
45
+ message << "\n"
46
+ return message
47
+ end
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,71 @@
1
+ #- Copyright 2008 8th Light, Inc. All Rights Reserved.
2
+ #- Limelight and all included source files are distributed under terms of the GNU LGPL.
3
+
4
+ module Limelight
5
+
6
+ module DSL
7
+
8
+ class AnonymousActionListener #:nodoc:
9
+ include java.awt.event.ActionListener
10
+
11
+ def initialize(context, symbol)
12
+ @context = context
13
+ @symbol = symbol
14
+ end
15
+
16
+ def actionPerformed(e)
17
+ method = @context.method(@symbol)
18
+ method.call
19
+ end
20
+ end
21
+
22
+ # A class used to build menu bars using a DSL.
23
+ #
24
+ # MenuBar.build(self) do
25
+ # menu("File") do
26
+ # item("Open", :open_chosen_scene)
27
+ # item("Refresh", :reload)
28
+ # end
29
+ # end
30
+ #
31
+ # This example created one menu named 'File' with two menu items: 'Open' and 'Refresh'. The seconds parameter of the
32
+ # menu items is the symbol of a method on the context that will be invoked when the menu item is selected.
33
+ #
34
+ class MenuBar
35
+
36
+ def self.build(context, &prop)
37
+ builder = self.new(context)
38
+ builder.instance_eval(&prop)
39
+ return builder.menu_bar
40
+ end
41
+
42
+ attr_reader :menu_bar
43
+
44
+ # This builder must be provided with a context. All menu item actions will be invoked on the context.
45
+ #
46
+ def initialize(context)
47
+ @context = context
48
+ @menu_bar = javax.swing.JMenuBar.new
49
+ end
50
+
51
+ # Creates a new menu with the provided name
52
+ #
53
+ def menu(name)
54
+ @menu = javax.swing.JMenu.new(name)
55
+ @menu_bar.add(@menu)
56
+ yield
57
+ end
58
+
59
+ # Created a new menu item with the provided name. The symbols paramter is the name of a method on the context
60
+ # that will be invoked when the item is selected.
61
+ #
62
+ def item(name, symbol)
63
+ menu_item = javax.swing.JMenuItem.new(name)
64
+ @menu.add(menu_item)
65
+ menu_item.addActionListener(AnonymousActionListener.new(@context, symbol))
66
+ end
67
+
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,71 @@
1
+ #- Copyright 2008 8th Light, Inc. All Rights Reserved.
2
+ #- Limelight and all included source files are distributed under terms of the GNU LGPL.
3
+
4
+ require 'limelight/production'
5
+ require 'limelight/limelight_exception'
6
+ require 'limelight/util'
7
+
8
+ module Limelight
9
+
10
+ # A trigger to configure Production objects using the ProductionBuilder DSL.
11
+ #
12
+ # See Limelight::ProductionBuilder
13
+ #
14
+ def self.build_production(production, &block)
15
+ builder = DSL::ProductionBuilder.new(production)
16
+ builder.instance_eval(&block) if block
17
+ return builder.__production__
18
+ end
19
+
20
+ module DSL
21
+ # The basis of the DSL for building Style objects.
22
+ #
23
+ # name "Stage Composer"
24
+ # attribute :controller
25
+ # attribute :inspector
26
+ #
27
+ # The above example names the Production 'Stage Composer' and creates two attributes on the Production: 'controller'
28
+ # and 'inspector'
29
+ #
30
+ class ProductionBuilder
31
+
32
+ Limelight::Util.lobotomize(self)
33
+
34
+ class << self
35
+
36
+ attr_accessor :current_attribute
37
+
38
+ end
39
+
40
+ attr_reader :__production__
41
+
42
+ def initialize(production)
43
+ @__production__ = production
44
+ end
45
+
46
+ def method_missing(sym, value) #:nodoc:
47
+ setter_sym = "#{sym}=".to_s
48
+ raise ProductionBuilderException.new(sym) if !@__production__.respond_to?(setter_sym)
49
+ @__production__.send(setter_sym, value)
50
+ end
51
+
52
+ # Creates an attribute on the Production
53
+ #
54
+ def attribute(sym)
55
+ ProductionBuilder.current_attribute = sym
56
+ class << @__production__
57
+ attr_accessor ProductionBuilder.current_attribute
58
+ end
59
+ end
60
+ end
61
+
62
+ # Thrown if there is an error in the ProductionBuilder DSL
63
+ #
64
+ class ProductionBuilderException < LimelightException
65
+ def initialize(name)
66
+ super("'#{name}' is not a valid production property")
67
+ end
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,155 @@
1
+ #- Copyright 2008 8th Light, Inc. All Rights Reserved.
2
+ #- Limelight and all included source files are distributed under terms of the GNU LGPL.
3
+
4
+ require 'limelight/prop'
5
+ require 'limelight/scene'
6
+ require 'limelight/dsl/build_exception'
7
+ require 'limelight/util'
8
+
9
+ module Limelight
10
+
11
+ # A trigger to build a Limelight::Scene using the PropBuilder DSL.
12
+ #
13
+ # See Limelight::PropBuilder
14
+ #
15
+ def self.build_scene(root, options={}, &block)
16
+ loader = options.delete(:build_loader)
17
+ instance_variables = options.delete(:instance_variables)
18
+ root.add_options(options)
19
+ builder = DSL::PropBuilder.new(root)
20
+ builder.__install_instance_variables(instance_variables)
21
+ builder.__loader__ = loader
22
+ builder.instance_eval(&block) if block
23
+ return root
24
+ end
25
+
26
+ module DSL
27
+
28
+ # The basis of the DSL for building Limelight::Prop objects.
29
+ #
30
+ # Sample usage:
31
+ #
32
+ # builder = Limelight::PropBuilder.new(a_prop)
33
+ # builder.instance_eval(&block)
34
+ #
35
+ # The prop passed into the constructor will be the root of the contructed Prop tree.
36
+ # The block passed into instance_eval contains the DSL for building props.
37
+ #
38
+ # Example block/DSL:
39
+ #
40
+ # parent :id => "the_parent" do
41
+ # child_one do
42
+ # grand_child_one :id => "gc_1", :styles => "grand_child"
43
+ # grand_child_two :id => "gc_2", :styles => "grand_child"
44
+ # end
45
+ # child_two
46
+ # end
47
+ #
48
+ # The above example will create a Limelight::Prop named 'parent' and add it to the root prop passed into the builder.
49
+ # The 'parent' prop will contain two props named 'child_one' and 'child_two'. 'child_one' will contain two props named
50
+ # 'grand_child_one' and 'grand_child_two'. 'child_two' has no child props nor do 'grand_child_one' or 'grand_child_two'.
51
+ #
52
+ # An options Hash may be passed into each prop. The key, value pairs in the hash will be used to set properties on the prop
53
+ # when it is added to a Limelight::Scene.
54
+ #
55
+ # See Limelight::Prop
56
+ #
57
+ class PropBuilder
58
+
59
+ alias :__instance_variables :instance_variables
60
+ alias :__instance_variable_get :instance_variable_get
61
+ alias :__instance_variable_set :instance_variable_set
62
+
63
+ Limelight::Util.lobotomize(self)
64
+
65
+ # Returns the root prop either passed in or created by this builder.
66
+ #
67
+ attr_reader :__prop__
68
+ attr_accessor :__loader__
69
+
70
+ # Creates a new builder. If a prop is passed it, it will be the root on which props are created.
71
+ # If the paramter is a Hash, the Hash will be used to construct a prop that will be used as the root.
72
+ #
73
+ def initialize(options)
74
+ if options.is_a?(Prop)
75
+ @__prop__ = options
76
+ else
77
+ @__prop__ = Prop.new(options)
78
+ end
79
+ end
80
+
81
+ # Add extra initialization options to the prop currently under construction.
82
+ #
83
+ # tree :id => "stump" do
84
+ # __ :height => "100%", :width => "30", :background_color => :brown
85
+ # branch :height => "100", :width => "20"
86
+ # branch do
87
+ # __ :height => "100", :width => "20"
88
+ # end
89
+ # end
90
+ #
91
+ # In the above example, the 'tree' prop has the following initialization options: id, height, width, background_color.
92
+ # The two 'branch' child props are identical.
93
+ #
94
+ def __(options)
95
+ @__prop__.add_options(options)
96
+ end
97
+
98
+ # Installs props from another file using the prop DSL. The path will be relative to the
99
+ # root directory of the current production.
100
+ #
101
+ def __install(file, instance_variables = {})
102
+ raise "Cannot install external props because no loader was provided" if @__loader__.nil?
103
+ raise "External prop file: '#{file}' doesn't exist" if !@__loader__.exists?(file)
104
+ content = @__loader__.load(file)
105
+ begin
106
+ self.__install_instance_variables(instance_variables)
107
+ self.instance_eval(content)
108
+ rescue Exception => e
109
+ raise BuildException.new(file, content, e)
110
+ end
111
+ end
112
+
113
+ # Installs instance variables, specified by the passed hash, into the PropBuilder instance.
114
+ # The following call...
115
+ #
116
+ # __install_instance_variables :one => "1", "two" => "two", :three => 3
117
+ #
118
+ # ...will result in the following instance variables.
119
+ #
120
+ # @one = "1"
121
+ # @two = "2"
122
+ # @three = 3
123
+ #
124
+ # Instance variables are propogated to nested builders so that they need only be defined
125
+ # on the top level builder and all children will have access to them.
126
+ #
127
+ def __install_instance_variables(instance_variables)
128
+ return if instance_variables.nil?
129
+ instance_variables.each_pair do |key, value|
130
+ name = "@#{key}"
131
+ __instance_variable_set(name, value)
132
+ end
133
+ end
134
+
135
+ def __install_instance_variables_from_builder(source) #:nodoc:
136
+ source.__instance_variables.each do |name|
137
+ if !__instance_variable_get(name)
138
+ value = source.__instance_variable_get(name)
139
+ __instance_variable_set(name, value)
140
+ end
141
+ end
142
+ end
143
+
144
+ def method_missing(sym, options={}, &prop) # :nodoc:
145
+ options[:name] ||= sym.to_s
146
+ builder = PropBuilder.new(options)
147
+ builder.__install_instance_variables_from_builder(self)
148
+ builder.__loader__ = @__loader__
149
+ builder.instance_eval(&prop) if prop
150
+ @__prop__.add(builder.__prop__)
151
+ end
152
+ end
153
+
154
+ end
155
+ end