1 """
2 PureMVC Python Port by Toby de Havilland <toby.de.havilland@puremvc.org>
3 PureMVC - Copyright(c) 2006-08 Futurescale, Inc., Some rights reserved.
4 Your reuse is governed by the Creative Commons Attribution 3.0 License
5 """
6
7 import puremvc.interfaces
8 import puremvc.patterns.observer
9
10 -class Controller(object,puremvc.interfaces.IController):
11 """
12 A Singleton C{IController} implementation.
13
14 In PureMVC, the C{Controller} class follows the
15 'Command and Controller' strategy, and assumes these
16 responsibilities:
17
18 Remembering which C{ICommand}s
19 are intended to handle which C{INotifications}.
20
21 Registering itself as an C{IObserver} with
22 the C{View} for each C{INotification}
23 that it has an C{ICommand} mapping for.
24
25 Creating a new instance of the proper C{ICommand}
26 to handle a given C{INotification} when notified by the C{View}.
27
28 Calling the C{ICommand}'s C{execute}
29 method, passing in the C{INotification}.
30
31 Your application must register C{ICommands} with the
32 Controller.
33
34 The simplest way is to subclass C{Facade},
35 and use its C{initializeController} method to add your
36 registrations.
37
38 @see: L{View<puremvc.core.view.View>}
39 @see: L{Observer<puremvc.patterns.observer.Observer>}
40 @see: L{Notification<puremvc.patterns.observer.Notification>}
41 @see: L{SimpleCommand<puremvc.patterns.command.SimpleCommand>}
42 @see: L{MacroCommand<puremvc.patterns.command.MacroCommand>}
43 """
44 instance = None
45 view = None
46 commandMap = None
47
49 """
50 This C{IController} implementation is a Singleton, so you should not call the constructor
51 directly, but instead call the static Singleton method C{Controller.getInstance()}
52 """
53 if not cls.instance or not isinstance(cls.instance, cls):
54 cls.instance = super(Controller, cls).__new__(cls, *args, **kwargs)
55 cls.instance.initializeController()
56 return cls.instance
57
58 @staticmethod
60 """
61 C{Controller} Singleton Static method.
62
63 @return: the Singleton instance of C{Controller}
64 """
65 return Controller()
66
68 """
69 Initialize the Singleton C{Controller} instance.
70
71 Called automatically by the constructor.
72
73 Note that if you are using a subclass of C{View}
74 in your application, you will need to initialize the view property
75 """
76 self.view = View.getInstance()
77 self.commandMap = {}
78
80 """
81 If an C{ICommand} has previously been registered
82 to handle a the given C{INotification}, then it is executed.
83
84 @param note: an C{INotification}
85 """
86 commandClassRef = self.commandMap.get(note.getName(),None)
87 if (commandClassRef == None):
88 return
89
90 commandInstance = commandClassRef()
91 commandInstance.execute(note)
92
94 """
95 Register a particular C{ICommand} class as the handler
96 for a particular C{INotification}.
97
98 If an C{ICommand} has already been registered to
99 handle C{INotification}s with this name, it is no longer
100 used, the new C{ICommand} is used instead.
101
102 The Observer for the new ICommand is only created if this the
103 first time an ICommand has been regisered for this Notification name.
104
105 @param notificationName: the name of the C{INotification}
106 @param commandClassRef: the C{Class} of the C{ICommand}
107 """
108 if (self.commandMap.get(notificationName,None) == None):
109 self.view.registerObserver(notificationName, puremvc.patterns.observer.Observer(self.executeCommand, self))
110
111 self.commandMap[notificationName] = commandClassRef
112
114 """
115 Check if a Command is registered for a given Notification
116
117 @param notificationName: the name of the C{INotification}
118 @return: whether a Command is currently registered for the given C{notificationName}.
119 """
120 return self.commandMap.get(notificationName,None) is not None
121
123 """
124 Remove a previously registered C{ICommand} to C{INotification} mapping.
125
126 @param notificationName: the name of the C{INotification} to remove the C{ICommand} mapping for
127 """
128 if self.hasCommand(notificationName):
129 self.view.removeObserver(notificationName, self)
130 del self.commandMap[notificationName]
131
132
133 -class Model(object,puremvc.interfaces.IModel):
134 """
135 A Singleton C{IModel} implementation.
136
137 In PureMVC, the C{Model} class provides
138 access to model objects (Proxies) by named lookup.
139
140 The C{Model} assumes these responsibilities:
141
142 Maintain a cache of C{IProxy} instances.
143
144 Provide methods for registering, retrieving, and removing C{IProxy} instances.
145
146 Your application must register C{IProxy} instances
147 with the C{Model}. Typically, you use an
148 C{ICommand} to create and register C{IProxy}
149 instances once the C{Facade} has initialized the Core
150 actors.
151
152 @see: L{Proxy<puremvc.patterns.proxy.Proxy>}
153 @see: L{IProxy<puremvc.interfaces.IProxy>}
154 """
155 instance = None
156 proxyMap = None
157
158 - def __new__(cls, *args, **kwargs):
159 """
160 This C{IModel} implementation is a Singleton, so you should not call the constructor
161 directly, but instead call the static Singleton method C{Model.getInstance()}
162 """
163 if not cls.instance or not isinstance(cls.instance, cls):
164 cls.instance = super(Model, cls).__new__(cls, *args, **kwargs)
165 cls.instance.initializeModel()
166 return cls.instance
167
168 @staticmethod
170 """
171 C{Model} Singleton Static method.
172
173 @return: the Singleton instance of C{Model}
174 """
175 return Model()
176
178 """
179 Initialize the Singleton C{Model} instance.
180
181 Called automatically by the constructor.
182 """
183 self.proxyMap = {}
184
193
195 """
196 Retrieve an C{IProxy} from the C{Model}.
197
198 @param proxyName: the name of the C{IProxy}
199 @return: the C{IProxy} instance previously registered with the given C{proxyName}.
200 """
201 return self.proxyMap.get(proxyName,None)
202
204 """
205 Check if a Proxy is registered
206
207 @param proxyName: the name of the C{IProxy}
208 @return: whether a Proxy is currently registered with the given C{proxyName}.
209 """
210 return self.proxyMap.get(proxyName,None) is not None
211
213 """
214 Remove an C{IProxy} from the C{Model}.
215
216 @param proxyName: name of the C{IProxy} instance to be removed.
217 @return: the C{IProxy} that was removed from the C{Model}
218 """
219 proxy = self.proxyMap.get(proxyName,None)
220 if proxy:
221 del self.proxyMap[proxyName]
222 proxy.onRemove()
223 return proxy
224
225 -class View(object,puremvc.interfaces.IView):
226 """
227 A Singleton C{IView} implementation.
228
229 In PureMVC, the C{View} class assumes these responsibilities:
230
231 Maintain a cache of C{IMediator} instances.
232
233 Provide methods for registering, retrieving, and removing C{IMediators}.
234
235 Notifiying C{IMediators} when they are registered or removed.
236
237 Managing the observer lists for each C{INotification} in the application.
238
239 Providing a method for attaching C{IObservers} to an C{INotification}'s observer list.
240
241 Providing a method for broadcasting an C{INotification}.
242
243 Notifying the C{IObservers} of a given C{INotification} when it broadcast.
244
245
246 @see: L{Mediator<puremvc.patterns.mediator.Mediator>}
247 @see: L{Observer<puremvc.patterns.observer.Observer>}
248 @see: L{Notification<puremvc.patterns.observer.Notification>}
249 """
250 instance = None
251 observerMap = None
252 mediatorMap = None
253
254 - def __new__(cls, *args, **kwargs):
255 """
256 This C{iView} implementation is a Singleton, so you should not call the constructor
257 directly, but instead call the static Singleton method C{View.getInstance()}
258 """
259 if not cls.instance or not isinstance(cls.instance, cls):
260 cls.instance = super(View, cls).__new__(cls, *args, **kwargs)
261 cls.instance.initializeView()
262 return cls.instance
263
264 @staticmethod
266 """
267 C{View} Singleton Static method.
268
269 @return: the Singleton instance of C{View}
270 """
271 return View()
272
274 """
275 Initialize the Singleton C{View} instance.
276
277 Called automatically by the constructor.
278 """
279 self.observerMap = {}
280 self.mediatorMap = {}
281
283 """
284 Register an C{IObserver} to be notified
285 of C{INotifications} with a given name.
286
287 @param notificationName: the name of the C{INotifications} to notify this C{IObserver} of
288 @param observer: the C{IObserver} to register
289 """
290 if self.observerMap.get(notificationName,None) == None:
291 self.observerMap[notificationName] = []
292 self.observerMap[notificationName].append(observer)
293
295 """
296 Notify the C{IObservers} for a particular C{INotification}.
297
298 All previously attached C{IObservers} for this C{INotification}'s
299 list are notified and are passed a reference to the C{INotification} in
300 the order in which they were registered.
301
302 @param notification: the C{INotification} to notify C{IObservers} of.
303 """
304 if self.observerMap.get(notification.getName(),None) is not None:
305 observers = self.observerMap[notification.getName()]
306 for i in range(0,len(observers)):
307 obsvr = observers[i]
308 obsvr.notifyObserver(notification)
309
311 """
312 Remove the observer for a given notifyContext from an observer list for a given Notification name.
313
314 @param notificationName: which observer list to remove from
315 @param notifyContext: remove the observer with this object as its notifyContext
316 """
317 observers = self.observerMap[notificationName]
318
319 for i in range(len(observers)):
320 if observers[i].compareNotifyContext(notifyContext):
321 observers.pop(i)
322 break
323
324 if len(observers) == 0:
325 del self.observerMap[notificationName]
326
356
365
366
409
418