lib/flok/user_compiler.rb in flok-0.0.100 vs lib/flok/user_compiler.rb in flok-0.0.101

- old
+ new

@@ -20,21 +20,36 @@ return @src end end end -#Compiler executes all rb code inside this context +#Compiler executes all rb code (ERB) inside this context module Flok class UserCompilerContext attr_accessor :controllers, :actions, :ons def initialize @controllers = [] @actions = [] @ons = [] + + @debug = ENV["FLOK_ENV"] ? true : false end + #Returns a list of events that this controller 'might' respond to + #Used for things like hook event handlers to provide queryable + #information. + def might_respond_to + @actions.map{|e| e.ons}.flatten.map{|e| e[:name]} + end + + #actions_responds_to looks like {"action1" => ["event_a", ..."], "action2" => }... + #where each action list contains all the events this action responds to + def actions_respond_to + @actions.map{|e| [e.name.to_s, e.ons.map{|e| e[:name].to_s}]}.to_h + end + def get_binding return binding end def controller name, &block @@ -83,12 +98,22 @@ spot_index = @controller.spots.index(spot_name) raise "controller #{@controller.name.inspect} attempted to embed #{spot_name.inspect} inside #{@name.inspect}, but #{spot_name.inspect} was not defined in 'spots' (#{@controller.spots.inspect})" unless spot_index #Calculate spot index as an offset from the base address using the index of the spot in the spots #address offset - res = %{ - + res = "" + + if @debug + res += %{ + } + end + + res += %{ + <% if @debug %> + if (__base__.constructor !== Number) { throw "Embed for the controller: #{@controller.name} was not given a number for it's __base__ pointer, but of type: " + __base__.constructor + "with the value: " + __base__}; + <% end %> + var ptr = _embed("#{vc_name}", __base__+#{spot_index}+1, #{context}, __base__); __info__.embeds[#{spot_index-1}].push(ptr); } out.puts res #Send(event_name, info) @@ -156,10 +181,12 @@ #Switch the actions, reset embeds, and call on_entry res = %{ var old_action = __info__.action; __info__.action = "#{action_name}"; + //HOOK_ENTRY[controller_will_goto] #{{"controller_name" => @controller.name, "might_respond_to" => @ctx.might_respond_to, "actions_responds_to" => @ctx.actions_respond_to, "from_action" => @name, "to_action" => action_name}.to_json} + //Remove all views, we don't have to recurse because removal of a view //is supposed to remove *all* view controllers of that tree as well. var embeds = __info__.embeds; for (var i = 0; i < __info__.embeds.length; ++i) { for (var j = 0; j < __info__.embeds[i].length; ++j) { @@ -492,19 +519,19 @@ end end class UserCompilerAction - attr_accessor :controller, :name, :ons, :every_handlers + attr_accessor :controller, :name, :every_handlers include UserCompilerMacro def initialize controller, name, ctx, &block @controller = controller @name = name @ctx = ctx @_on_entry_src = "" - @ons = [] #Event handlers + @_ons = [] #Event handlers @every_handlers = [] self.instance_eval(&block) end @@ -516,10 +543,33 @@ def on_entry_src return @_on_entry_src end def on name, js_src - @ons << {:name => name, :src => _macro(js_src)} + #We need this guard because we run a two pass compile on the ons. When 'ons' is accessed, it is assumed that we are now + #in the compilation phase and we build all the entries. This is because some macros in the ons source code requires + #prior-knowledge of controller-level information like all possible events in all actions for hooks + raise "Uh oh, you tried to add an event handler but we already assumed that compilation took place so we cached everything..." if @__ons_did_build or @__ons_is_building + + @_ons << {:name => name, :src => js_src} + end + + def ons + #Return the un-compiled version as some macros access this data and the real ons + #would cause infinite recursion + return @_ons if @__ons_is_building + @__ons_is_building = true + + #We need this guard because we run a two pass compile on the ons. When 'ons' is accessed, it is assumed that we are now + #in the compilation phase and we build all the entries. This is because some macros in the ons source code requires + #prior-knowledge of controller-level information like all possible events in all actions for hooks + unless @__ons_did_build + @__ons_did_build = true + @__ons = @_ons.map{|e| {:name => e[:name], :src => _macro(e[:src])}} + end + + @__ons_is_building = false + return @__ons end def every seconds, str @every_handlers << { :name => "#{seconds}_sec_#{SecureRandom.hex[0..6]}",