[Borges-users] controller and delegate
Слепнев Владимир
slepnev_v at rambler.ru
Mon Apr 12 14:00:07 EDT 2004
Hello,
1) Controller uses StateHolder to store the delegate, and that's
wrong. If the controller is registered for backtracking, the @delegate
instance variable will be backtracked automatically; if it isn't,
what's the point?
2) Controller#delegate_to saves the previous delegate in a local
variable 'saved', which stays in scope forever. I think this is
responsible for part (not all) of SushiNet's memory problem. I don't
think the previous delegate should be saved at all - can't imagine
what for.
3) A question is whether the delegate of a controller registered for
backtracking should also be backtracked. In the current version of
Borges, this isn't done (only the value of @delegate is stored in
StateHolder),and I'm not doing it either; but I'm not yet sure which
way is the proper way.
Here's my take on Controller:
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 @delegate.nil? then
return self
else
return @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
@delegate = nil
end
def confirm(str)
return call(Borges::Dialog.confirmation(str))
end
def self.default_session_class
return Borges::ControllerSession
end
def delegate_to(controller, &block)
@delegate = controller
value = block.call
@delegate = nil
return value
end
def inform(str)
call(Borges::Dialog.message(str))
end
def initialize_controller
@delegate = 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 = @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.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
Vladimir Slepnev
More information about the Borges-users
mailing list