pytilities.event.decorators

Package pytilities :: Package event :: Module decorators |
[hide private]
[frames] | no frames]

# Source Code for Module pytilities.event.decorators

      1  # Copyright (C) 2010 Tim Diels <limyreth@users.sourceforge.net>
      2  #
      3  # This file is part of pytilities.
      4  #
      5  # pytilities is free software: you can redistribute it and/or modify
      6  # it under the terms of the GNU General Public License as published by
      7  # the Free Software Foundation, either version 3 of the License, or
      8  # (at your option) any later version.
      9  #
     10  # pytilities is distributed in the hope that it will be useful,
     11  # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  # GNU General Public License for more details.
     14  #
     15  # You should have received a copy of the GNU General Public License
     16  # along with pytilities.  If not, see <http://www.gnu.org/licenses/>.
     17  #
     18
     19  """
     20  Various decorators to ease event dispatching.
     21  """
     22
     23  __docformat__ = 'reStructuredText'
     24
     25  from pytilities import mangle
     26  from . import Dispatcher, DispatcherSwitch
     27
     28 -def dispatcher(*event_names):
     29      """
     30      Installs a `Dispatcher` on an `AttributeCollectionBase`.
     31
     32      This class decorator does the following:
     33          - create a `Dispatcher` and store it in `self.__dispatcher`
     34          - delegate to all methods of the dispatcher's public delegation profile
     35          - add a `self.__dispatch` method that delegates to
     36            `self.__dispatcher.dispatch`
     37          - register the `event_names` on the dispatcher
     38
     39      Note on ctor usage: though `self.__dispatcher` already exists, the delegation
     40      to it is not yet installed. You can use `self.__dispatcher`, but you can't
     41      yet e.g. call `self.add_handler`, write `self.__dispatcher.add_handler`
     42      instead.
     43
     44      Parameters:
     45          event_names :: (::string...)
     46              collection of events to register on the dispatcher
     47      """
     48
     49      def _dispatcher(cls):
     50          # remember the original init
     51          true_init = cls.__init__
     52
     53          def init(self, *args, **kwargs):
     54              # create dispatcher and register events
     55              dispatcher = Dispatcher()
     56              dispatcher.register_events(*event_names)
     57
     58              # store the dispatcher on the instance
     59              setattr(self, mangle(cls.__name__, "__dispatcher"), dispatcher)
     60
     61              # call original init
     62              true_init(self, *args, **kwargs)
     63
     64              # delegate public + dispatch()
     65              delegator = Dispatcher.Delegator("public", dispatcher)
     66              delegator.profile.add_mappings(
     67                  "r", **{mangle(cls.__name__, "__dispatch"): "dispatch"})
     68
     69              self._append_attribute_collection(delegator)
     70
     71          # replace init with our init
     72          cls.__init__ = init
     73
     74          return cls
     75
     76      return _dispatcher
     77
     78 -def dispatcher_switch(cls):
     79      """
     80      Installs a `DispatcherSwitch` on an `AttributeCollectionBase`.
     81
     82      This class decorator does the following:
     83          - create a `DispatcherSwitch` and store it in self.__dispatcher_switch
     84          - delegate to all methods of the switch's public delegation profile
     85          - add a `self.__dispatch` method that delegates to
     86            `self.__dispatcher_switch.dispatch`
     87
     88      Note on ctor usage: though `self.__dispatcher_switch` already exists, the
     89      delegation to it is not yet installed. You can use
     90      `self.__dispatcher_switch`, but you can't yet e.g. call `self.add_handler`,
     91      write `self.__dispatcher_switch.add_handler` instead.
     92      """
     93
     94      # remember the original init
     95      true_init = cls.__init__
     96
     97      def init(self, *args, **kwargs):
     98          # create switch
     99          switch = DispatcherSwitch()
    100
    101          # store on the instance
    102          setattr(self, mangle(cls.__name__, "__dispatcher_switch"), switch)
    103
    104          # call original init
    105          true_init(self, *args, **kwargs)
    106
    107          # delegate public
    108          delegator = Dispatcher.Delegator("public", switch)
    109          delegator.profile.add_mappings(
    110              "r", **{mangle(cls.__name__, "__dispatch"): "dispatch"})
    111          self._append_attribute_collection(delegator)
    112
    113      # replace init with our init
    114      cls.__init__ = init
    115
    116      return cls
    117