Changeset 91546cff3cf17814c900b8eaead1a8ff33160ce3 for ooxcb
- Timestamp:
- 07/24/2009 12:32:14 AM (12 months ago)
- Children:
- d8178792f331c687d0273d1d87ef1e48f518843d
- Parents:
- 571cafadff22c94e7940c41c4edd505ef3872849
- git-committer:
- Friedrich Weber <fred@samurai-x.org> / 2009-07-24T01:32:14Z+0200
- Location:
- ooxcb/ooxcb
- Files:
-
- 2 modified
-
eventsys.py (modified) (13 diffs)
-
util.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
ooxcb/ooxcb/eventsys.py
r7383ac r91546c 28 28 # Copyright (c) 2006-2008 Alex Holkner 29 29 # All rights reserved. 30 # 30 # 31 31 # Redistribution and use in source and binary forms, with or without 32 # modification, are permitted provided that the following conditions 32 # modification, are permitted provided that the following conditions 33 33 # are met: 34 34 # 35 35 # * Redistributions of source code must retain the above copyright 36 36 # notice, this list of conditions and the following disclaimer. 37 # * Redistributions in binary form must reproduce the above copyright 37 # * Redistributions in binary form must reproduce the above copyright 38 38 # notice, this list of conditions and the following disclaimer in 39 39 # the documentation and/or other materials provided with the … … 167 167 import inspect 168 168 169 EVENT_HANDLED = True 169 from .util import cached_classproperty 170 171 EVENT_HANDLED = True 170 172 EVENT_UNHANDLED = None 171 173 … … 175 177 pass 176 178 179 class EventDispatcherMeta(type): 180 """ 181 just a meta class making sure that each EventDispatcher subclass 182 has its own `event_types` descriptor. 183 """ 184 def __new__(mcs, name, bases, dct): 185 @cached_classproperty 186 def event_types(cls): 187 """ 188 get the event types of me and all of my bases! 189 """ 190 types = [] 191 for base in cls.__bases__: 192 if hasattr(base, 'event_types'): 193 types.extend(base.event_types) 194 if hasattr(cls, 'local_event_types'): 195 types.extend(cls.local_event_types) 196 return types 197 198 dct['event_types'] = event_types 199 return type.__new__(mcs, name, bases, dct) 200 201 177 202 class EventDispatcher(object): 178 203 '''Generic event dispatcher interface. … … 180 205 See the module docstring for usage. 181 206 ''' 207 208 __metaclass__ = EventDispatcherMeta 209 182 210 # Placeholder empty stack; real stack is created only if needed 183 211 _event_stack = () … … 196 224 197 225 ''' 198 if not hasattr(cls, ' event_types'):199 cls. event_types = []200 cls. event_types.append(name)226 if not hasattr(cls, 'local_event_types'): 227 cls.local_event_types = [] 228 cls.local_event_types.append(name) 201 229 return name 230 202 231 203 232 def push_handlers(self, *args, **kwargs): … … 243 272 '''Attach one or more event handlers to the top level of the handler 244 273 stack. 245 274 246 275 See `push_handlers` for the accepted argument types. 247 276 ''' … … 284 313 frame, or if no stack frame contains any of the given handlers. 285 314 286 If the stack frame is empty after removing the handlers, it is 315 If the stack frame is empty after removing the handlers, it is 287 316 removed from the stack. Note that this interferes with the expected 288 317 symmetry of `push_handlers` and `pop_handlers`. … … 343 372 def dispatch_event(self, event_type, *args): 344 373 '''Dispatch a single event to the attached handlers. 345 374 346 375 The event is propogated to all handlers from from the top of the stack 347 376 until one returns `EVENT_HANDLED`. This method should be used only by … … 361 390 362 391 :rtype: bool or None 363 :return: (Since pyglet 1.2) `EVENT_HANDLED` if an event handler 392 :return: (Since pyglet 1.2) `EVENT_HANDLED` if an event handler 364 393 returned `EVENT_HANDLED`; `EVENT_UNHANDLED` if one or more event 365 394 handlers were invoked but returned only `EVENT_UNHANDLED`; … … 403 432 # arguments in an event handler. This is caught as a TypeError in 404 433 # dispatch_event but the error message is obfuscated. 405 # 434 # 406 435 # Here we check if there is indeed a mismatch in argument count, 407 436 # and construct a more useful exception message if so. If this method … … 425 454 426 455 # Allow default values to overspecify arguments 427 if (n_handler_args > n_args and 456 if (n_handler_args > n_args and 428 457 handler_defaults and 429 458 n_handler_args - len(handler_defaults) <= n_args): … … 438 467 else: 439 468 descr = repr(handler) 440 469 441 470 raise TypeError( 442 471 '%s event was dispatched with %d arguments, but ' 443 'handler %s has an incompatible function signature' % 472 'handler %s has an incompatible function signature' % 444 473 (event_type, len(args), descr)) 445 474 else: … … 447 476 448 477 def event(self, *args): 449 '''Function decorator for an event handler. 450 478 '''Function decorator for an event handler. 479 451 480 Usage:: 452 481 -
ooxcb/ooxcb/util.py
r4a478d r91546c 46 46 result = self.func(obj) 47 47 setattr(obj, self.name, result) 48 return result 49 50 class cached_classproperty(object): 51 """ 52 a modified version of :class:`cached_property` that allows to define 53 cached properties on classes. 54 """ 55 def __init__(self, func): 56 self.func = func 57 self.name = func.__name__ 58 59 def __get__(self, obj, type): 60 # equal if we call it bound to an instance or not. 61 result = self.func(type) 62 setattr(type, self.name, result) 48 63 return result 49 64
