Class: PureMVC::View
- Inherits:
-
Object
- Object
- PureMVC::View
- Defined in:
- src/core/view.rb
Overview
A Multiton IView
implementation.
In PureMVC, the IView
class assumes these responsibilities:
-
Maintains a cache of
IMediator
instances. -
Provides methods for registering, retrieving, and removing
IMediators
. -
Notifies
IMediators
when they are registered or removed. -
Manages the observer lists for each
INotification
in the application. -
Provides a method for attaching
IObservers
to anINotification
‘s observer list. -
Provides a method for broadcasting an
INotification
. -
Notifies the
IObservers
of a givenINotification
when it is broadcast.
Constant Summary collapse
- MULTITON_MSG =
'View instance for this Multiton key already constructed!'
Class Method Summary collapse
-
.get_instance(key, &factory) ⇒ _IView
View Multiton Factory method.
-
.instance_map ⇒ Hash{String => IView}
The Multiton IModel instanceMap.
-
.mutex ⇒ Mutex
Mutex used to synchronize access to the instance map for thread safety.
-
.remove_view(key) ⇒ Object
Remove an
IView
instance.
Instance Method Summary collapse
-
#has_mediator?(mediator_name) ⇒ Boolean
Check if a Mediator is registered or not.
-
#initialize(key) ⇒ View
constructor
Constructor.
-
#initialize_view ⇒ Object
Initialize the Multiton
View
instance. -
#notify_observers(notification) ⇒ Object
Notify the
IObservers
for a particularINotification
. -
#register_mediator(mediator) ⇒ Object
Register an
IMediator
instance with theView
. -
#register_observer(notification_name, observer) ⇒ Object
Register an
IObserver
to be notified ofINotifications
with a given name. -
#remove_mediator(mediator_name) ⇒ IMediator?
Remove an
IMediator
from theView
. -
#remove_observer(notification_name, notify_context) ⇒ Object
Remove the observer for a given notifyContext from an observer list for a given Notification name.
-
#retrieve_mediator(mediator_name) ⇒ IMediator?
Retrieve an
IMediator
from theView
.
Constructor Details
#initialize(key) ⇒ View
Constructor.
This IView
implementation is a Multiton, so you should not call the constructor directly. Instead, call the static Multiton factory method View.get_instance(multiton_key) { |key| View.new(key) }
.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'src/core/view.rb', line 68 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 # Mapping of Notification names to Observer lists # @type var observer_map: Hash[String, Array[_IObserver]] @observer_map = {} # Mutex used to synchronize access to the observer_map # @type var observer_mutex: Mutex @observer_mutex = Mutex.new # Mapping of Mediator names to Mediator instances # @type var mediator_map: Hash[String, _IMediator] @mediator_map = {} # Mutex used to synchronize access to the mediator_map # @type var mediator_mutex: Mutex @mediator_mutex = Mutex.new initialize_view end |
Class Method Details
.get_instance(key, &factory) ⇒ _IView
View Multiton Factory method.
44 45 46 47 48 |
# File 'src/core/view.rb', line 44 def get_instance(key, &factory) mutex.synchronize do instance_map[key] ||= factory.call(key) end end |
.instance_map ⇒ Hash{String => IView}
The Multiton IModel instanceMap.
33 |
# File 'src/core/view.rb', line 33 def instance_map = (@instance_map ||= {}) |
.mutex ⇒ Mutex
Mutex used to synchronize access to the instance map for thread safety.
37 |
# File 'src/core/view.rb', line 37 def mutex = (@mutex ||= Mutex.new) |
.remove_view(key) ⇒ Object
Remove an IView
instance.
53 54 55 56 57 |
# File 'src/core/view.rb', line 53 def remove_view(key) mutex.synchronize do instance_map.delete(key) end end |
Instance Method Details
#has_mediator?(mediator_name) ⇒ Boolean
Check if a Mediator is registered or not.
199 200 201 202 203 |
# File 'src/core/view.rb', line 199 def has_mediator?(mediator_name) @mediator_mutex.synchronize do @mediator_map.key?(mediator_name) end end |
#initialize_view ⇒ Object
Initialize the Multiton View
instance.
Called automatically by the constructor, this is your opportunity to initialize the Multiton instance in your subclass without overriding the constructor.
96 |
# File 'src/core/view.rb', line 96 def initialize_view; end |
#notify_observers(notification) ⇒ Object
Notify the IObservers
for a particular INotification
.
All previously attached IObservers
for this INotification
‘s list are notified and are passed a reference to the INotification
in the order in which they were registered.
117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'src/core/view.rb', line 117 def notify_observers(notification) # @type var observers: Array[_IObserver]? observers = nil @observer_mutex.synchronize do # Get a reference to the observers list for this notification name # Iteration safe, copy observers from reference array to working array, # since the reference array may change during the notification loop observers = @observer_map[notification.name].dup end # Notify Observers from the working array observers&.each { |observer| observer.notify_observer(notification) } end |
#register_mediator(mediator) ⇒ Object
Register an IMediator
instance with the View
.
Registers the IMediator
so that it can be retrieved by name, and further interrogates the IMediator
for its INotification
interests.
If the IMediator
returns any INotification
names to be notified about, an Observer
is created encapsulating the IMediator
instance’s handleNotification
method and registering it as an Observer
for all INotifications
the IMediator
is interested in.
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'src/core/view.rb', line 162 def register_mediator(mediator) @mediator_mutex.synchronize do return if @mediator_map.key?(mediator.name) @mediator_map[mediator.name] = mediator end mediator.initialize_notifier(@multiton_key) # Create Observer referencing this mediator's handleNotification method # @type observer [IObserver] observer = Observer.new(mediator.method(:handle_notification), mediator) # Get Notification interests, if any. # @type interests [Array<String>] interests = mediator.list_notification_interests # Register Mediator as Observer for its list of Notification interests interests.each { |interest| register_observer(interest, observer) } # alert the mediator that it has been registered mediator.on_register end |
#register_observer(notification_name, observer) ⇒ Object
Register an IObserver
to be notified of INotifications
with a given name.
103 104 105 106 107 108 |
# File 'src/core/view.rb', line 103 def register_observer(notification_name, observer) @observer_mutex.synchronize do observers = (@observer_map[notification_name] ||= []) observers << observer end end |
#remove_mediator(mediator_name) ⇒ IMediator?
Remove an IMediator
from the View
.
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'src/core/view.rb', line 209 def remove_mediator(mediator_name) # @type var mediator: _IMediator? mediator = nil @mediator_mutex.synchronize do # retrieve the named mediator and delete from the mediator map mediator = @mediator_map.delete(mediator_name) end return unless mediator # for every notification this mediator is interested in... # @type var interests: Array[String] interests = mediator.list_notification_interests # remove the observer linking the mediator # to the notification interest interests.each { |interest| remove_observer(interest, mediator) } # alert the mediator that it has been removed mediator.on_remove mediator end |
#remove_observer(notification_name, notify_context) ⇒ Object
Remove the observer for a given notifyContext from an observer list for a given Notification name.
134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'src/core/view.rb', line 134 def remove_observer(notification_name, notify_context) @observer_mutex.synchronize do # the observer list for the notification under inspection # @type var observers: Array[_IObserver]? observers = @observer_map[notification_name] # find and remove the sole Observer for the given notify_context # there can only be one Observer for a given notify_context # in any given Observer list, so remove it observers&.reject! { |observer| observer.compare_notify_context?(notify_context) } # Also, when a Notification's Observer list length falls to # zero, delete the notification key from the observer map @observer_map.delete(notification_name) if observers&.empty? end end |
#retrieve_mediator(mediator_name) ⇒ IMediator?
Retrieve an IMediator
from the View
.
189 190 191 192 193 |
# File 'src/core/view.rb', line 189 def retrieve_mediator(mediator_name) @mediator_mutex.synchronize do @mediator_map[mediator_name] end end |