================ Stateful Objects ================ ($Id$) >>> from cybertools.stateful.definition import StatesDefinition >>> from cybertools.stateful.definition import State, Transition >>> from cybertools.stateful.definition import registerStatesDefinition >>> from cybertools.stateful.base import Stateful We start with a simple demonstration class that provides stateful behaviour directly. >>> class Demo(Stateful): ... pass >>> demo = Demo() The default states definition has the `started` state has its initial state. >>> demo.getState() 'started' >>> demo.getStateObject().title 'Started' We can now execute the `finish` Transition. >>> demo.doTransition('finish') >>> demo.getState() 'finished' More complex states definitions ------------------------------- >>> registerStatesDefinition( ... StatesDefinition('publishing', ... State('private', 'private', ('show',)), ... State('visible', 'visible', ('publish', 'hide',)), ... State('published', 'published', ('retract',)), ... Transition('show', 'show', 'visible'), ... Transition('hide', 'hide', 'private'), ... Transition('publish', 'publish', 'published'), ... Transition('retract', 'retract', 'visible'), ... initialState='visible')) >>> demo = Demo() >>> demo.statesDefinition = 'publishing' >>> demo.getState() 'visible' If we try to execute a transition that is not an outgoing transition of the current state we get an error. >>> demo.doTransition('retract') Traceback (most recent call last): ... ValueError: Transition 'retract' is not reachable from state 'visible'. >>> demo.getState() 'visible' Stateful Adapters ================= Objects that show stateful behaviour need not be derived from the Stateful class, for persistent objects one can also provide a stateful adapter. >>> from persistent import Persistent >>> class Demo(Persistent): ... pass >>> demo = Demo() >>> from zope import component >>> from cybertools.stateful.base import StatefulAdapter >>> component.provideAdapter(StatefulAdapter) We can now retrieve a stateful adapter using the IStateful interface. >>> from cybertools.stateful.interfaces import IStateful >>> statefulDemo = IStateful(demo) >>> statefulDemo.getState() 'started' >>> statefulDemo.getStateObject().title 'Started' >>> statefulDemo.doTransition('finish') >>> statefulDemo.getState() 'finished' If we make a new adapter for the same persistent object we get back the state that is stored with the object. >>> statefulDemo = IStateful(demo) >>> statefulDemo.getState() 'finished'