class Borges::Controller @@subclasses = [] class << self alias orig_new new def new(*args, &block) inst = orig_new(*args, &block) inst.initialize_controller return inst end def inherited(klass) @@subclasses << klass end def all_subclasses return @@subclasses end end ## # TODO make this a loop def active_controller if self.delegate.nil? then return self else return self.delegate.active_controller end end ## # Return control to caller # # Called when a controller has completed, and needs to return a value. def answer(val = self) return val if @continuation.nil? @continuation.call(val) end def self.application_with_path(path, klass = nil) app = Borges::Application.new(path) app.session_class = klass unless klass.nil? app.preferences[:entry_point] = self return app end ## # Pass control # # Called when a controller desires to pass control to another # controller. # # If no controller is specified, then self is being called. If # self is not going to answer, then don't save a continuation. # # Otherwise, delegate to the controller passed in, then call it. def call(controller = nil) if controller.nil? then unless will_answer? then raise Borges::RenderNotification.new else return callcc do |cc| @continuation = cc raise Borges::RenderNotification.new end end else return delegate_to(controller) do controller.call end end end def clear_delegate self.delegate = nil end def confirm(str) return call(Borges::Dialog.confirmation(str)) end def self.default_session_class return Borges::ControllerSession end def delegate return will_call? ? @delegate.contents : nil end def delegate=(controller) if @delegate.nil? @delegate = Borges::StateHolder.new(controller) else @delegate.contents = controller end return self.delegate end def delegate_to(controller, &block) saved = self.delegate self.delegate = controller value = block.call self.delegate = saved return value end def inform(str) call(Borges::Dialog.message(str)) end def initialize_controller @delegate = Borges::StateHolder.new(nil) @continuation = nil end def on_answer(&block) @continuation = block end def self.register_application(app_name, session_class = default_session_class) app = application_with_path(app_name, session_class) Borges::Dispatcher.instance.register(app, app_name) return app end def self.register_authenticated_application(app_name, user, password) app = register_application(app_name, Borges::AuthenticatedSession) app.preferences[:username] = Borges::Preference.new(user) app.preferences[:password] = Borges::Preference.new(password) return app end def render_active_controller_with(context) del = self.delegate if del.nil? then render_with(context) else del.render_active_controller_with(context) end end ## # for compatibility def render_on(r) render_active_controller_with(r.rendering_context) end def render_with(context) end ## # XXX Fix InputDialog def request(request, label = nil, initial = '') input_dialog = Borges::InputDialog.new input_dialog.message = request input_dialog.label = label input_dialog.default = initial call(input_dialog) end def session return Borges::Session.current_session end ## # Will this component ever call #answer? Used to optimize calling of # Controllers. # # Redefine to return false if this Controller will not call #answer. def will_answer? return true end ## # Will this component ever call #call? Used to optimize calling of # Controllers. # # Redefine to return false if this Controller will not call #call. def will_call? return true end end