From: Rowland S. <mon...@us...> - 2004-05-02 22:09:39
|
Update of /cvsroot/pythoncard/PythonCard In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22762 Modified Files: event.py component.py Log Message: Simplified Scriptable. Created IScriptable interface, extended by Scriptable and NullScriptable. NullScriptable gets installed as the parent of a Scriptable if the parent=None. Index: component.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/component.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** component.py 2 May 2004 16:32:23 -0000 1.10 --- component.py 2 May 2004 22:09:29 -0000 1.11 *************** *** 8,12 **** from PythonCard.event import EventLog ! class Scriptable: """ RDS - 2004-05-02 --- 8,35 ---- from PythonCard.event import EventLog ! ! class IScriptable( object ) : ! """ ! RDS - 2004-05-02 ! The public interface for all scriptable objects. ! """ ! def execute( self, name, event ) : ! raise NotImplementedError ! ! ! class NullScriptable( IScriptable ) : ! """ ! RDS - 2004-05-02 ! Installed as the parent of any Scriptable ! object that is instantiated with a ! parent=None. This implementation calls the ! EventLog when an event is executed and logs ! it as *not* used. ! """ ! def execute( self, name, event ) : ! EventLog.getInstance().log( event, '(not handled)', False ) ! ! ! class Scriptable( IScriptable ) : """ RDS - 2004-05-02 *************** *** 15,147 **** execution of it's handlers. ! All classes that may contain PythonCard Handler definitions must implement Scriptable. A Scriptable object may be specified as the parent of ! this object. The parent will be searched for Handlers ! if a Handler can't be found in this object. """ ! ! def __init__(self, aScriptableParent): ! self._parentScript = aScriptableParent self._handlers = {} self._parseHandlers() - if False: - print "Scriptable init", self._handlers.keys() ! def _parseHandlers(self): """ Find all of the methods in this object that are PythonCard handlers, and register them. """ ! # KEA 2004-03-05 ! # an even slicker way of finding event handlers ! # using the inspect module ! pythoncardMethods = [] ! methods = inspect.getmembers(self.__class__, inspect.ismethod) ! for m in methods: ! if m[0].split('_')[0] == 'on': ! pythoncardMethods.append(m[1]) ! print pythoncardMethods ! ! map(self._addHandler, pythoncardMethods) ! ! def _isPythonCardHandler(self, aObject): """ Return true if the object is a PythonCard handler. """ ! print 'found handler', aObject ! return isinstance(aObject, types.FunctionType) and aObject.__name__.split('_')[0] == 'on' ! def _addHandler(self, aMethod): ! # Add the Handler to our Handler list. ! if aMethod.__name__ not in self._handlers: ! log.debug("_addHandler: " + aMethod.__name__) ! self._handlers[aMethod.__name__] = event.Handler(aMethod) ! ! """ ! RDS - Never gets called - Remove. ! ! def addMethod(self, aFunction): ! if isinstance(aFunction, types.FunctionType): ! if self._isPythonCardHandler(aFunction) : ! #aMethod = new.instancemethod(aFunction, self, self.__class__) ! aMethod = new.instancemethod(aFunction, None, self.__class__) ! #print aFunction ! #print self.__class__ ! #print aMethod.__name__ ! #print aMethod ! self.__class__.__dict__[aMethod.__name__] = aMethod ! # now add the method info to our handler lookup dictionary ! # KEA 2001-11-29 simplified _addHandler ! #handler = event.Handler(aMethod.__name__, aMethod) ! #self._addHandler(aMethod.__name__, handler) ! self._addHandler(aMethod) ! """ ! def _findHandler(self, aString): """ ! Look for a Handler that matches aString in our ! list of Handlers. If a Handler is not found, ! ask our parent script to look for the Handler, ! continuing up the Scriptable hierarchy until ! either a Handler is found, or None is returned. """ ! # KEA 2004-04-26 ! # findHandler is actually called for each event dispatch ! # depending on the level of dynamic code we think we're going ! # to have it might be simpler to just statically bind when ! # the component is created ! if True: ! print "findHandler", aString, self ! handler = self._handlers.get(aString, None) ! ! if handler: ! return self, handler ! ! # We couldn't find a handler, so look in our parent. ! if self._parentScript: ! print 'looking for handler in parent', self._parentScript ! script, handler = self._parentScript._findHandler( aString ) ! # have we found a Handler yet? ! if handler: ! return script, handler ! # Change the handler name to target this Scriptable object ! # and look in our list of Handlers. ! ! words = aString.split('_') ! #print words, self._getName() ! #if len(words) == 2: ! # print words ! # aString = words[ 0 ] + '_' + words[ 1 ] ! #else: ! aString = words[0] + '_' + self.getName() + '_' + words[len(words) - 1] ! temp = self._handlers.get(aString, None) ! if temp: ! return ( self, temp ) ! else: ! # search for Background and Stack handlers like ! # on_mouseClick, on_initialize ! aString = words[0] + '_' + words[len(words) - 1] ! return self._handlers.get(aString, None) ! ! def execute( self, handlerName, event ) : """ RDS - 2004-05-02 Find the handler that matches handlerName and execute it. ! Should we throw an exception if the handlerName ! is not found? The caller would be responsible ! for reporting a missing handler as an error. """ ! print 'finding handler', handlerName ! script, handler = self._findHandler( handlerName ) if handler is not None : ! print script, handler ! handler.execute( script, event ) EventLog.getInstance().log( event, handler.getSourceName(), True ) --- 38,123 ---- execution of it's handlers. ! All classes that may contain PythonCard EventHandler definitions must implement Scriptable. A Scriptable object may be specified as the parent of ! this object. The parent will be searched for EventHandlers ! if a EventHandler can't be found in this object. """ ! def __init__( self, parent=None ) : ! if parent is None : ! parent = NullScriptable() ! self._parent = parent self._handlers = {} self._parseHandlers() ! def _parseHandlers( self ) : """ Find all of the methods in this object that are PythonCard handlers, and register them. """ + found = [] + methods = inspect.getmembers( self, inspect.ismethod ) + for m in methods : + if m[ 0 ].split( '_' )[ 0 ] == 'on' : + found.append( m[ 1 ] ) + map( self._addHandler, found ) ! def _isPythonCardHandler( self, aObject ) : """ Return true if the object is a PythonCard handler. """ ! return isinstance( aObject, types.FunctionType ) and aObject.__name__.split('_')[0] == 'on' ! def _addHandler( self, method ) : ! # Add the EventHandlers to our EventHandler list. ! if method.__name__ not in self._handlers : ! log.debug("_addHandler: " + method.__name__) ! self._handlers[ method.__name__ ] = event.EventHandler( method ) ! def _findHandler( self, name ) : """ ! Look for a EventHandlers that matches 'name' in our ! list of EventHandlers. """ ! handler = self._handlers.get( name, None ) ! if handler is None : ! # Change the handler name to target this Scriptable object ! # and look in our list of EventHandlers. ! ! words = name.split('_') ! s = words[ 0 ] + '_' + self.getName() + '_' + words[ len( words ) - 1 ] ! h = self._handlers.get( s, None ) ! if h is not None : ! return ( h ) ! else: ! # search for Background and Stack handlers like ! # on_mouseClick, on_initialize ! s = words[ 0 ] + '_' + words[ len( words ) - 1 ] ! return self._handlers.get( s, None ) ! return handler ! ! def execute( self, name, event ) : """ RDS - 2004-05-02 + Find the handler that matches handlerName and execute it. ! ! Should we throw an exception if the handler name ! is not found? ! ! The caller would be responsible for reporting ! a missing handler as an error. """ ! handler = self._findHandler( name ) ! if handler is not None : ! handler.execute( event ) EventLog.getInstance().log( event, handler.getSourceName(), True ) + else : + self._parent.execute( name, event ) Index: event.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/event.py,v retrieving revision 1.63 retrieving revision 1.64 diff -C2 -d -r1.63 -r1.64 *** event.py 2 May 2004 19:49:56 -0000 1.63 --- event.py 2 May 2004 22:09:29 -0000 1.64 *************** *** 10,13 **** --- 10,66 ---- import wx + class EventHandler: + """ + RDS - 2004-05-02 + Future replacement for Handler. + Maps a function name to an instance method. + """ + def __init__( self, method ) : + + # Grab the method object. + self._method = method + # Hold on to the full name. + self._name = method.__name__ + # Parse the function/method name. + parts = self._name.split('_') + # The 'on' prefix, i.e. on_button1_click + self._prefix = parts[ 0 ] + + if len( parts ) == 3 : + # The name of the Widget instance that is the target. + self._sourceName = parts[ 1 ] + # The Event class identifier. + self._eventName = parts[ 2 ] + else: + # KEA 2001-09-06 + # need to pass in the name of the Background subclass instance ? + # RDS 2004-05-02 + # What? + self._sourceName = '' + self._eventName = parts[ 1 ] + + def getName( self ) : + return self._name + + def getSourceName( self ) : + return self._sourceName + + def getEventName( self ) : + return self._eventName + + def execute( self, event ) : + """ + RDS - 2004-05-02 + Added to support new Scriptable design in + component.Scriptable. Ask the Handler to + execute itself instead of getting it's + function and calling it. + """ + self._method( event ) + + def __repr__( self ) : + return str( self.__dict__ ) + + class Handler: |