Package puremvc :: Module core
[hide private]
[frames] | no frames]

Source Code for Module puremvc.core

  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
48 - def __new__(cls, *args, **kwargs):
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
59 - def getInstance():
60 """ 61 C{Controller} Singleton Static method. 62 63 @return: the Singleton instance of C{Controller} 64 """ 65 return Controller()
66
67 - def initializeController(self):
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
79 - def executeCommand(self, note):
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
93 - def registerCommand(self, notificationName, commandClassRef):
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
113 - def hasCommand(self, notificationName):
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
122 - def removeCommand(self, notificationName):
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
169 - def getInstance():
170 """ 171 C{Model} Singleton Static method. 172 173 @return: the Singleton instance of C{Model} 174 """ 175 return Model()
176
177 - def initializeModel(self):
178 """ 179 Initialize the Singleton C{Model} instance. 180 181 Called automatically by the constructor. 182 """ 183 self.proxyMap = {}
184
185 - def registerProxy(self, proxy):
186 """ 187 Register an C{IProxy} with the C{Model}. 188 189 @param proxy: an C{IProxy} to be held by the C{Model}. 190 """ 191 self.proxyMap[proxy.getProxyName()] = proxy 192 proxy.onRegister()
193
194 - def retrieveProxy(self, proxyName):
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
203 - def hasProxy(self, proxyName):
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
212 - def removeProxy(self, proxyName):
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
265 - def getInstance():
266 """ 267 C{View} Singleton Static method. 268 269 @return: the Singleton instance of C{View} 270 """ 271 return View()
272
273 - def initializeView(self):
274 """ 275 Initialize the Singleton C{View} instance. 276 277 Called automatically by the constructor. 278 """ 279 self.observerMap = {} 280 self.mediatorMap = {}
281
282 - def registerObserver(self, notificationName, observer):
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
294 - def notifyObservers(self, notification):
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
310 - def removeObserver(self, notificationName, notifyContext):
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
327 - def registerMediator(self, mediator):
328 """ 329 Register an C{IMediator} instance with the C{View}. 330 331 Registers the C{IMediator} so that it can be retrieved by name, 332 and further interrogates the C{IMediator} for its 333 C{INotification} interests. 334 335 If the C{IMediator} returns any C{INotification} 336 names to be notified about, an C{Observer} is created encapsulating 337 the C{IMediator} instance's C{handleNotification} method 338 and registering it as an C{Observer} for all C{INotifications} the 339 C{IMediator} is interested in. 340 341 @param mediator: a reference to the C{IMediator} instance 342 """ 343 # do not allow re-registration (you must to removeMediator fist) 344 if mediator.getMediatorName() in self.mediatorMap.keys(): 345 return 346 347 self.mediatorMap[mediator.getMediatorName()] = mediator 348 interests = mediator.listNotificationInterests() 349 if len(interests) > 0: 350 obsvr = puremvc.patterns.observer.Observer(mediator.handleNotification, mediator) 351 352 for i in range(0,len(interests)): 353 self.registerObserver(interests[i], obsvr) 354 355 mediator.onRegister()
356
357 - def retrieveMediator(self, mediatorName):
358 """ 359 Retrieve an C{IMediator} from the C{View}. 360 361 @param mediatorName: the name of the C{IMediator} instance to retrieve. 362 @return: the C{IMediator} instance previously registered with the given C{mediatorName}. 363 """ 364 return self.mediatorMap.get(mediatorName,None)
365 366
367 - def removeMediator(self, mediatorName):
368 """ 369 Remove an C{IMediator} from the C{View}. 370 371 @param mediatorName: name of the C{IMediator} instance to be removed. 372 @return: the C{IMediator} that was removed from the C{View} 373 """ 374 for notificationName in self.observerMap.keys(): 375 observers = self.observerMap[notificationName] 376 removalTargets = [] 377 for i in range(0,len(observers)): 378 if observers[i].compareNotifyContext(self.retrieveMediator(mediatorName)) == True: 379 removalTargets.append(i) 380 381 target = 0 382 while len(removalTargets) > 0: 383 target = removalTargets.pop() 384 del observers[target] 385 386 if len(observers) == 0: 387 del self.observerMap[notificationName] 388 else: 389 self.observerMap[notificationName] = observers 390 391 mediator = self.mediatorMap.get(mediatorName,None) 392 393 if mediator is not None: 394 del self.mediatorMap[mediatorName] 395 mediator.onRemove() 396 return mediator 397 398 mediator = self.mediatorMap.get(mediatorName,None) 399 400 if mediator: 401 interests = mediator.listNotificationInterests() 402 for i in range(len(interests)): 403 removeObserver(interests[i], mediator) 404 405 del self.mediatorMap[mediatorName] 406 mediator.onRemove() 407 408 return mediator
409
410 - def hasMediator(self, mediatorName):
411 """ 412 Check if a Mediator is registered or not 413 414 @param mediatorName: the name of the C{IMediator} 415 @return: whether a Mediator is registered with the given C{mediatorName}. 416 """ 417 return self.mediatorMap.get(mediatorName,None) is not None
418