Class: PureMVC::Controller
- Inherits:
-
Object
- Object
- PureMVC::Controller
- Defined in:
- src/core/controller.rb
Overview
A Multiton IController
implementation.
In PureMVC, the Controller
class follows the ‘Command and Controller’ strategy and assumes these responsibilities:
-
Remembering which
ICommand
s are intended to handle whichINotifications
. -
Registering itself as an
IObserver
with theView
for eachINotification
that has anICommand
mapping. -
Creating a new instance of the proper
ICommand
to handle a givenINotification
when notified by theView
. -
Calling the
ICommand
‘sexecute
method, passing in theINotification
.
Your application must register ICommands
with the Controller
.
The simplest way is to subclass Facade
, and use its initializeController
method. to add your registrations.
Constant Summary collapse
- MULTITON_MSG =
Message Constants
'Controller instance for this Multiton key already constructed!'
Class Method Summary collapse
-
.get_instance(key, &factory) ⇒ IController
Gets an instance using the provided factory block.
-
.instance_map ⇒ Hash{String => IController}
The Multiton IController instanceMap.
-
.mutex ⇒ Mutex
Mutex used to synchronize access to the instance map for thread safety.
-
.remove_controller(key) ⇒ Object
Remove an IController instance.
Instance Method Summary collapse
-
#execute_command(notification) ⇒ Object
If an ICommand has previously been registered to handle the given INotification, then it is executed.
-
#has_command?(notification_name) ⇒ Boolean
Check if a Command is registered for a given Notification.
-
#initialize(key) ⇒ Controller
constructor
Constructor.
-
#initialize_controller ⇒ Object
Initialize the Multiton Controller instance.
-
#register_command(notification_name, &factory) ⇒ Object
Register a particular ICommand class as the handler for a particular INotification.
-
#remove_command(notification_name) ⇒ Object
Remove a previously registered ICommand to INotification mapping.
Constructor Details
#initialize(key) ⇒ Controller
Constructor.
This IController implementation is a Multiton, so you should not call the constructor directly. Instead, call the static factory method, passing the unique key for this instance: PureMVC::Controller.getInstance(key) { |key| PureMVC::Controller.new(key) }
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'src/core/controller.rb', line 76 def initialize(key) raise MULTITON_MSG if self.class.instance_map[key] self.class.instance_map[key] = self # The Multiton Key for this Core # @type var multiton_key: String @multiton_key = key # Local reference to View # @type var component: _IView? @view = nil # Mapping of Notification names to Command factories # @type var command_map: Hash[String, ^() -> _ICommand] @command_map = {} # Mutex used to synchronize access to the @command_map # @type var command_mutex: Mutex @command_mutex = Mutex.new initialize_controller end |
Class Method Details
.get_instance(key, &factory) ⇒ IController
Gets an instance using the provided factory block
52 53 54 55 56 |
# File 'src/core/controller.rb', line 52 def get_instance(key, &factory) mutex.synchronize do instance_map[key] ||= factory.call(key) end end |
.instance_map ⇒ Hash{String => IController}
The Multiton IController instanceMap.
41 |
# File 'src/core/controller.rb', line 41 def instance_map = (@instance_map ||= {}) |
.mutex ⇒ Mutex
Mutex used to synchronize access to the instance map for thread safety.
45 |
# File 'src/core/controller.rb', line 45 def mutex = (@mutex ||= Mutex.new) |
.remove_controller(key) ⇒ Object
Remove an IController instance
61 62 63 64 65 |
# File 'src/core/controller.rb', line 61 def remove_controller(key) mutex.synchronize do instance_map.delete(key) end end |
Instance Method Details
#execute_command(notification) ⇒ Object
If an ICommand has previously been registered to handle the given INotification, then it is executed.
136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'src/core/controller.rb', line 136 def execute_command(notification) @command_mutex.synchronize do # @type factory: [^() -> ICommand]? factory = @command_map[notification.name] return if factory.nil? # @type var command: _ICommand command = factory.call command.initialize_notifier(@multiton_key) command.execute(notification) end end |
#has_command?(notification_name) ⇒ Boolean
Check if a Command is registered for a given Notification.
153 154 155 156 157 |
# File 'src/core/controller.rb', line 153 def has_command?(notification_name) @command_mutex.synchronize do @command_map.key?(notification_name) end end |
#initialize_controller ⇒ Object
Initialize the Multiton Controller instance.
Called automatically by the constructor.
Note that if you are using a subclass of View in your application, you should also subclass Controller and override the initialize_controller method in the following way:
110 111 112 |
# File 'src/core/controller.rb', line 110 def initialize_controller @view = View.get_instance(@multiton_key) { |key| View.new(key) } end |
#register_command(notification_name, &factory) ⇒ Object
Register a particular ICommand class as the handler for a particular INotification.
If an ICommand has already been registered to handle INotifications with this name, it is replaced by the new ICommand.
The Observer for the new ICommand is only created if this is the first time an ICommand has been registered for this notification name.
124 125 126 127 128 129 130 131 |
# File 'src/core/controller.rb', line 124 def register_command(notification_name, &factory) @command_mutex.synchronize do if @command_map[notification_name].nil? @view&.register_observer(notification_name, Observer.new(method(:execute_command), self)) end @command_map[notification_name] = factory end end |
#remove_command(notification_name) ⇒ Object
Remove a previously registered ICommand to INotification mapping.
162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'src/core/controller.rb', line 162 def remove_command(notification_name) @command_mutex.synchronize do # @type var command: [^() -> ICommand]? command = @command_map[notification_name] # if the Command is registered... if command # remove the observer @view&.remove_observer(notification_name, self) # remove the command @command_map.delete(notification_name) end end end |