fix bug in state event notification - moved notify() call to StatefulAdapter

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@2562 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2008-04-27 20:57:32 +00:00
parent 7cd7a574c0
commit 592058cfc5
3 changed files with 27 additions and 22 deletions

View file

@ -28,6 +28,7 @@ state.
We can now execute the `finish` Transition. We can now execute the `finish` Transition.
>>> demo.doTransition('finish') >>> demo.doTransition('finish')
'finish'
>>> demo.getState() >>> demo.getState()
'finished' 'finished'

View file

@ -26,10 +26,13 @@ from persistent.interfaces import IPersistent
from persistent.mapping import PersistentMapping from persistent.mapping import PersistentMapping
from zope import component from zope import component
from zope.component import adapts from zope.component import adapts
from zope.component.interfaces import ObjectEvent
from zope.event import notify
from zope.interface import implements from zope.interface import implements
from cybertools.stateful.interfaces import IStateful, IStatefulIndexInfo
from cybertools.stateful.definition import statesDefinitions from cybertools.stateful.definition import statesDefinitions
from cybertools.stateful.interfaces import IStateful, IStatefulIndexInfo
from cybertools.stateful.interfaces import ITransitionEvent
class Stateful(object): class Stateful(object):
@ -52,12 +55,12 @@ class Stateful(object):
sd = self.getStatesDefinition() sd = self.getStatesDefinition()
if isinstance(transition, basestring): if isinstance(transition, basestring):
sd.doTransitionFor(self, transition) sd.doTransitionFor(self, transition)
return return transition
available = [t.name for t in sd.getAvailableTransitionsFor(self)] available = [t.name for t in sd.getAvailableTransitionsFor(self)]
for tr in transition: for tr in transition:
if tr in available: if tr in available:
sd.doTransitionFor(self, tr) sd.doTransitionFor(self, tr)
return return tr
raise ValueError("None of the transitions '%s' is available for state '%s'." raise ValueError("None of the transitions '%s' is available for state '%s'."
% (repr(transition), self.getState())) % (repr(transition), self.getState()))
@ -95,6 +98,12 @@ class StatefulAdapter(Stateful):
statesAttr[self.statesDefinition] = value statesAttr[self.statesDefinition] = value
state = property(getState, setState) state = property(getState, setState)
def doTransition(self, transition, historyInfo=None):
previousState = self.getState()
transition = super(StatefulAdapter, self).doTransition(transition, historyInfo)
transition = self.getStatesDefinition().transitions[transition]
notify(TransitionEvent(self.context, transition, previousState))
class IndexInfo(object): class IndexInfo(object):
@ -111,3 +120,16 @@ class IndexInfo(object):
stf = component.getAdapter(self.context, IStateful, name=std) stf = component.getAdapter(self.context, IStateful, name=std)
yield ':'.join((std, stf.state)) yield ':'.join((std, stf.state))
# event
class TransitionEvent(ObjectEvent):
implements(ITransitionEvent)
def __init__(self, obj, transition, previousState):
super(TransitionEvent, self).__init__(obj)
self.transition = transition
self.previousState = previousState

View file

@ -22,14 +22,11 @@ State definition implementation.
$Id$ $Id$
""" """
from zope.component.interfaces import ObjectEvent
from zope.event import notify
from zope.interface import implements from zope.interface import implements
from cybertools.util.jeep import Jeep from cybertools.util.jeep import Jeep
from cybertools.stateful.interfaces import IState, ITransition from cybertools.stateful.interfaces import IState, ITransition
from cybertools.stateful.interfaces import IStatesDefinition from cybertools.stateful.interfaces import IStatesDefinition
from cybertools.stateful.interfaces import ITransitionEvent
class State(object): class State(object):
@ -86,28 +83,13 @@ class StatesDefinition(object):
if transition not in [t.name for t in self.getAvailableTransitionsFor(obj)]: if transition not in [t.name for t in self.getAvailableTransitionsFor(obj)]:
raise ValueError("Transition '%s' is not reachable from state '%s'." raise ValueError("Transition '%s' is not reachable from state '%s'."
% (transition, obj.getState())) % (transition, obj.getState()))
transObject = self.transitions[transition] obj.state = self.transitions[transition].targetState
previousState = obj.state
obj.state = transObject.targetState
notify(TransitionEvent(obj, transObject, previousState))
def getAvailableTransitionsFor(self, obj): def getAvailableTransitionsFor(self, obj):
state = obj.getState() state = obj.getState()
return [self.transitions[t] for t in self.states[state].transitions] return [self.transitions[t] for t in self.states[state].transitions]
# event
class TransitionEvent(ObjectEvent):
implements(ITransitionEvent)
def __init__(self, obj, transition, previousState):
super(TransitionEvent, self).__init__(obj)
self.transition = transition
self.previousState = previousState
# dummy default states definition # dummy default states definition
defaultSD = StatesDefinition('default', defaultSD = StatesDefinition('default',