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]}",