You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

214 lines
4.5 KiB

import threading
import Queue as queue
class IllegalEventError(Exception):
pass
class AbstractState(object):
def __init__(self, controller):
pass
def on_registration_in_progress(self):
raise IllegalEventError()
def on_registration_successful(self):
raise IllegalEventError()
def on_gabelschalter_up(self):
raise IllegalEventError()
def on_gabelschalter_down(self):
raise IllegalEventError()
def on_incoming_call(self):
raise IllegalEventError()
def on_call_ended(self):
raise IllegalEventError()
def on_call_accepted(self):
raise IllegalEventError()
def on_call_ringing(self):
raise IllegalEventError()
def on_nummernschalter_input(self, num):
raise IllegalEventError()
def on_timeout(self):
raise IllegalEventError()
class InitState(AbstractState):
def on_registration_in_progress(self):
print('registration in progress')
return RegisteringState
class RegisteringState(AbstractState):
def on_registration_successful(self):
print('registration successfull')
return IdleState
class IdleState(AbstractState):
def on_incoming_call(self):
print('incomfing call')
def on_gabelschalter_up(self):
print('gabel up')
return DailingState
def on_gabelschalter_down(self):
pass
def on_nummernschalter_input(self, x):
pass
class SchelltState(AbstractState):
def on_gabelschalter_up(self):
return AcceptingState
def on_call_ended(self):
return IdleState
class AcceptingState(AbstractState):
def on_call_accepted(self):
return CallRunningState
class CallTerminatingState(AbstractState):
def on_call_ended(self):
return IdleState
def on_call_accepted(self):
return None
class ForgottenState(AbstractState):
def on_gabelschalter_down(self):
return IdleState
class BusyBeepingState(AbstractState):
def on_timeout(self):
return ForgottenState
def on_gabelschalter_down(self):
return IdleState
class CallRunningState(AbstractState):
def on_gabelschalter_down(self):
return CallTerminatingState
def on_call_ended(self):
return BusyBeepingState
class WecktState(AbstractState):
def on_gabelschalter_down(self):
return CallTerminatingState
def on_call_ended(self):
return BusyBeepingState
def on_call_accepted(self):
return CallRunningState
class ConnectingState(AbstractState):
def on_gabelschalter_down(self):
return CallTerminatingState
def on_call_ringing(self):
return WecktState
class DailingState(AbstractState):
def on_gabelschalter_down(self):
return IdleState
def on_nummernschalter_input(self, num):
print('nummernschalter: %d' % (num))
def on_timeout(self):
return ConnectingState
class TelefonapparatUserInterface(object):
def __init__(self):
pass
def add_gabelschalter_callback(self, cb):
pass
def add_nummernschalter_callback(self, cb):
pass
def set_wecker(self, enabled):
pass
def set_schauzeichen(self, enabled):
pass
class StateMachineController(object):
def __init__(self):
self.__state = InitState(self)
self.__running = True
self.__evqueue = queue.Queue()
self.__evthread = threading.Thread(target=self.__event_dispatcher)
self.__evthread.start()
def __event_dispatcher(self):
while self.__running:
(evname, evargs, evkwargs) = self.__evqueue.get()
if not evname:
return
print('!!! event: %s' % (evname))
handler = getattr(self.__state, 'on_%s' % (evname))
try:
newstate = handler(*evargs, **evkwargs)
except IllegalEventError:
print('illegal event occured!!!!!!!!!!!!!!!!!!!!')
if not newstate:
continue
oldstate = self.__state.__class__
print('%s -> %s' % (oldstate.__name__, newstate.__name__))
self.__state = newstate(self)
def queue_event(self, evname, *evargs, **evkwargs):
if not hasattr(AbstractState, 'on_%s' % (evname)):
raise ValueError('Illegal event name: %s' % (evname))
self.__evqueue.put((evname, evargs, evkwargs))
def stop(self, hard=False):
if hard:
self.__running = False
self.__evqueue.put((None, None, None))
if __name__ == '__main__':
c = StateMachineController()
c.queue_event('registration_in_progress')
c.queue_event('registration_successful')
c.queue_event('gabelschalter_up')
c.queue_event('nummernschalter_input', 4)
c.queue_event('nummernschalter_input', 2)
#c.queue_event('gabelschalter_down')
#c.queue_event('call_accepted')
c.queue_event('timeout')
c.queue_event('call_ringing')
#c.queue_event('gabelschalter_down')
c.queue_event('call_accepted')
c.queue_event('call_ended')
c.queue_event('timeout')
c.queue_event('gabelschalter_down')
c.stop()