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.core
8 import puremvc.interfaces
9 import puremvc.patterns.observer
10
11 -class Facade(object,puremvc.interfaces.IFacade):
12 """
13 A base Singleton C{IFacade} implementation.
14
15 In PureMVC, the C{Facade} class assumes these
16 responsibilities:
17
18 Initializing the C{Model}, C{View} and C{Controller} Singletons.
19
20 Providing all the methods defined by the C{IModel, IView, & IController} interfaces.
21
22 Providing the ability to override the specific C{Model}, C{View} and C{Controller} Singletons created.
23
24 Providing a single point of contact to the application for registering C{Commands} and notifying C{Observers}
25
26
27 @see: L{Model<org.puremvc.as3.core.model.Model>}
28 @see: L{View<org.puremvc.as3.core.view.View>}
29 @see: L{Controller<org.puremvc.as3.core.controller.Controller>}
30 @see: L{Notification<org.puremvc.as3.patterns.observer.Notification>}
31 @see: L{Mediator<org.puremvc.as3.patterns.mediator.Mediator>}
32 @see: L{Proxy<org.puremvc.as3.patterns.proxy.Proxy>}
33 @see: L{SimpleCommand<org.puremvc.as3.patterns.command.SimpleCommand>}
34 @see: L{MacroCommand<org.puremvc.as3.patterns.command.MacroCommand>}
35 """
36
37 instance = None
38 controller = None
39 model = None
40 view = None
41
43 """
44 This C{IFacade} implementation is a Singleton, so you should not call the constructor
45 directly, but instead call the static Singleton method C{Facade.getInstance()}
46 """
47 if not cls.instance or not isinstance(cls.instance, cls):
48 cls.instance = super(Facade, cls).__new__(cls, *args, **kwargs)
49 cls.instance.initializeFacade()
50 return cls.instance
51
52 @staticmethod
54 """
55 C{Facade} Singleton Static method.
56
57 @return: the Singleton instance of C{Facade}
58 """
59 return Facade()
60
62 """
63 Initialize the Singleton C{Facade} instance.
64
65 Called automatically by the constructor. Override in your
66 subclass to do any subclass specific initializations. Be
67 sure to call C{Facade.initializeFacade()}, though.
68 """
69 self.initializeController()
70 self.initializeModel()
71 self.initializeView()
72
74 """
75 Initialize the C{Controller}.
76
77 Called by the C{initializeFacade} method.
78 Override this method in your subclass of C{Facade}
79 if one or both of the following are true:
80
81 You wish to initialize a different C{IController}.
82 You have C{Commands} to register with the C{Controller} at startup.
83
84 If you don't want to initialize a different C{IController},
85 call C{super.initializeController()} at the beginning of your method, then register C{Proxy}s.
86
87 Note: This method is I{rarely} overridden; in practice you are more
88 likely to use a C{Command} to create and register C{Proxy}s
89 with the C{Model}, since C{Proxy}s with mutable data will likely
90 need to send C{INotification}s and thus will likely want to fetch a reference to
91 the C{Facade} during their construction.
92 """
93 if (self.controller is not None):
94 return
95 self.controller = puremvc.core.Controller.getInstance()
96
98 """
99 Initialize the C{Model}.
100
101 Called by the C{initializeFacade} method.
102 Override this method in your subclass of C{Facade}
103 if one or both of the following are true:
104
105 You wish to initialize a different C{IModel}.
106
107 You have C{Proxy}s to register with the Model that do not
108 retrieve a reference to the Facade at construction time.
109
110 If you don't want to initialize a different C{IModel},
111 call C{super.initializeModel()} at the beginning of your
112 method, then register C{Proxy}s.
113
114 Note: This method is I{rarely} overridden; in practice you are more
115 likely to use a C{Command} to create and register C{Proxy}s
116 with the C{Model}, since C{Proxy}s with mutable data will likely
117 need to send C{INotification}s and thus will likely want to fetch a reference to
118 the C{Facade} during their construction.
119 """
120 if (self.model is not None):
121 return
122 self.model = puremvc.core.Model.getInstance()
123
125 """
126 Initialize the C{View}.
127
128
129 Called by the C{initializeFacade} method.
130 Override this method in your subclass of C{Facade}
131 if one or both of the following are true:
132
133 You wish to initialize a different C{IView}.
134
135 You have C{Observers} to register with the C{View}
136
137 If you don't want to initialize a different C{IView},
138 call C{super.initializeView()} at the beginning of your
139 method, then register C{IMediator} instances.
140
141 Note: This method is I{rarely} overridden; in practice you are more
142 likely to use a C{Command} to create and register C{Mediator}s
143 with the C{View}, since C{IMediator} instances will need to send
144 C{INotification}s and thus will likely want to fetch a reference
145 to the C{Facade} during their construction.
146 """
147 if (self.view is not None):
148 return
149 self.view = puremvc.core.View.getInstance()
150
152 """
153 Register an C{ICommand} with the C{Controller} by Notification name.
154
155 @param notificationName: the name of the C{INotification} to associate the C{ICommand} with
156 @param commandClassRef: a reference to the Class of the C{ICommand}
157 """
158 self.controller.registerCommand(notificationName, commandClassRef)
159
161 """
162 Remove a previously registered C{ICommand} to C{INotification} mapping from the Controller.
163
164 @param notificationName: the name of the C{INotification} to remove the C{ICommand} mapping for
165 """
166 self.controller.removeCommand(notificationName)
167
169 """
170 Check if a Command is registered for a given Notification
171
172 @param notificationName: the name of the C{INotification}
173 @return: whether a Command is currently registered for the given C{notificationName}.
174 """
175 return self.controller.hasCommand(notificationName)
176
178 """
179 Register an C{IProxy} with the C{Model} by name.
180
181 @param proxy: the C{IProxy} instance to be registered with the C{Model}.
182 """
183 self.model.registerProxy(proxy)
184
186 """
187 Retrieve an C{IProxy} from the C{Model} by name.
188
189 @param proxyName: the name of the proxy to be retrieved.
190 @return: the C{IProxy} instance previously registered with the given C{proxyName}.
191 """
192 return self.model.retrieveProxy(proxyName)
193
195 """
196 Remove an C{IProxy} from the C{Model} by name.
197
198 @param proxyName: the C{IProxy} to remove from the C{Model}.
199 @return: the C{IProxy} that was removed from the C{Model}
200 """
201 proxy = None
202 if (self.model is not None):
203 proxy = self.model.removeProxy(proxyName)
204 return proxy
205
207 """
208 Check if a Proxy is registered
209
210 @param proxyName: the name of the C{IProxy}
211 @return: whether a Proxy is currently registered with the given C{proxyName}.
212 """
213 return self.model.hasProxy(proxyName)
214
223
232
244
253
255 """
256 Create and send an C{INotification}.
257
258 Keeps us from having to construct new notification
259 instances in our implementation code.
260
261 @param notificationName: the name of the notiification to send
262 @param body: the body of the notification (optional)
263 @param type: the type of the notification (optional)
264 """
265 self.notifyObservers(puremvc.patterns.observer.Notification(notificationName, body, type))
266
268 """
269 Notify C{Observer}s.
270
271 This method is left public mostly for backward
272 compatibility, and to allow you to send custom
273 notification classes using the facade.
274
275 Usually you should just call sendNotification
276 and pass the parameters, never having to
277 construct the notification yourself.
278
279 @param notification: the C{INotification} to have the C{View} notify C{Observers} of.
280 """
281 if (self.view is not None):
282 self.view.notifyObservers(notification)
283