module Apotomo
class RequestProcessor
attr_reader :session, :root
def initialize(controller, session, options={}, has_widgets_blocks=[])
@session = session
@widgets_flushed = false
@root = Widget.new(controller, 'root', :display)
attach_stateless_blocks_for(has_widgets_blocks, @root, controller)
if options[:flush_widgets].blank? and ::Apotomo::StatefulWidget.frozen_widget_in?(session)
@root = ::Apotomo::StatefulWidget.thaw_for(controller, session, @root)
else
#@root = flushed_root
flushed_root ### FIXME: set internal mode to flushed
end
end
def attach_stateless_blocks_for(blocks, root, controller)
blocks.each { |blk| controller.instance_exec(root, &blk) }
end
def flushed_root
StatefulWidget.flush_storage(session)
@widgets_flushed = true
#widget('apotomo/widget', 'root')
end
def widgets_flushed?; @widgets_flushed; end
# Fires the request event in the widget tree and collects the rendered page updates.
def process_for(request_params)
source = self.root.find_widget(request_params[:source]) or raise "Source #{request_params[:source].inspect} non-existent."
source.fire(request_params[:type].to_sym)
source.root.page_updates ### DISCUSS: that's another dependency.
end
### FIXME: remove me!
def render_page_updates(page_updates)
page_updates.join("\n")
end
# Serializes the current widget tree to the storage that was passed in the constructor.
# Call this at the end of a request.
def freeze!
Apotomo::StatefulWidget.freeze_for(@session, root)
end
# Renders the widget named widget_id, passing optional opts and a block to it.
# Use this in your #render_widget wrapper.
def render_widget_for(widget_id, opts, &block)
if widget_id.kind_of?(::Apotomo::Widget)
widget = widget_id
else
widget = root.find_widget(widget_id)
raise "Couldn't render non-existent widget `#{widget_id}`" unless widget
end
### TODO: pass options in invoke.
widget.opts = opts unless opts.empty?
widget.invoke(&block)
end
# Computes the address hash for a +:source+ widget and an event +:type+.
# Additional parameters will be merged.
def address_for(options)
raise "You forgot to provide :source or :type" unless options.has_key?(:source) and options.has_key?(:type)
options
end
end
end