# $Id: BaseObject.py,v 1.13 2005/12/24 11:31:52 marcusva Exp $ # # Copyright (c) 2004-2005, Marcus von Appen # All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. """Basic object class, used as abstract class definition for event capable objects.""" from ocempgui.events import EventManager, EventCallback, INotifyable class BaseObject (INotifyable): """BaseObject () -> BaseObject An object class, which is able to receive events. The BaseObject provides a basic set of methods, which enable it to be suitable for event driven systems. It is able to listen to specific event types and runs connected callback functions upon their occurance. It is designed for usage with the EventManager class from the ocempgui.events package and needs to be inherited to be fully usable. It can be easily connected to an instance of the EventManager via the 'manager' attribute (or using the set_manager() method), which also will remove it from another instance, it was connected to before. Thus the BaseObject can be only connected to ONE EventManager instance at a time by default. The BaseObject class does not provide any predefined signals, it listens on (those will be called slots here). Instead an inherited class has to provide its own signal types within the private '_signals' dictionary. The entries within the '_signals' dictionary need to be key-value pairs, which have a list as value and a free choosable type as key (if the default EventCallback class is used). A typical example about how to create own signal slots follows: class OwnObject (BaseObject): ... def __init__ (self): BaseObject.__init__ (self) self._signals['ping'] = [] self._signals['pong'] = [] The OwnObject class can listen to signals, which are strings being 'ping' and 'pong'. It is now possible to connect a callback to those signals: obj = OwnObject () obj.connect_signal ('ping', cb_func, ...) obj.connect_signal ('pong', cb_func, ...) Any instance of the BaseObject class should be explicitly destroyed using the destroy() method, if it is not needed anymore. This method takes care of the deletion any callback objects and removes the object from the connected event manager. Attributes: manager - The event manager for emitting events. """ def __init__ (self): self._signals = {} self._manager = None def connect_signal (self, signal, callback, *data): """B.connect_signal (...) -> EventCallback Connects a function or method to a signal. The function or method is invoked as soon as the signal is emitted on the object. If *data is supplied, it will be passed as argument(s) to the connected function. The returned EventCallback can be used to disconnect the function using disconnect_signal(). """ ev = EventCallback (signal, callback, *data) self._signals[signal].append (ev) return ev def disconnect_signal (self, event): """B.disconnect_signal (...) -> None Removes a connected EventCallback from the object. """ self._signals[event.signal].remove (event) def run_signal_handlers (self, signal, *data): """B.run_signal_handlers (...) -> None Invokes all connected EventCallbacks for a specific signal. The method invokes all connected callbacks for the given signal. Additional data will be passed to the callback invoke, if given. """ for callback in self._signals[signal]: callback.run (*data) def set_event_manager (self, manager): """B.set_event_manager (...) -> None Sets the event manager to use by the object. In case the new event manager to set differs from the current event manager, the object will be removed from the current one and added to the new event manager. It is possible to remove the object only by passing a None value to the method. The object then will remove itself from the connected event manager only. Raises a TypeError, if the passed manager does not inherit from the EventManager class. """ if (manager != None) and not isinstance (manager, EventManager): raise TypeError ("manager must inherit from EventManager") if (self._manager != None) and (self._manager != manager): self._manager.remove_object (self) self._manager = manager # An empty list or pygame.sprite.Group evaluates to False in a # boolean expression, thus we need to explicitly check for such # objects. if self._manager != None: self._manager.add_object (self, *self._signals.keys ()) def emit (self, signal, data): """B.emit (...) -> bool Emits a signal through the connected event manager. Emits a signal using the connected event manager (if any), and returns True upon success or False upon an error. """ if self.manager != None: self.manager.emit (signal, data) return True return False def destroy (self): """B.destroy () -> None Destroys the object and disconnects it from its event manager. This method should be called, if the object is not needed anymore. """ del self._signals if self.manager != None: self.manager.remove_object (self) del self._manager manager = property (lambda self: self._manager, lambda self, var: self.set_event_manager (var), doc = "The event manager to use by the object.")