X-Git-Url: http://git.maemo.org/git/?p=theonering;a=blobdiff_plain;f=src%2Fgvoice%2Fstate_machine.py;h=1403ebca4e756552704fa3df9b12e29976951501;hp=71f68ce421330ad223f7b3e2e042e5efdefc30a0;hb=b58a60f57eb97bfc4fb3008b3edb4618d60ad045;hpb=53b0ea74d8264243da3d047582071396d7eece1c diff --git a/src/gvoice/state_machine.py b/src/gvoice/state_machine.py index 71f68ce..1403ebc 100644 --- a/src/gvoice/state_machine.py +++ b/src/gvoice/state_machine.py @@ -1,9 +1,5 @@ #!/usr/bin/env python -""" -@todo Look into supporting more states -""" - import logging import gobject @@ -48,6 +44,9 @@ class NopStateStrategy(object): def initialize_state(self): pass + def reinitialize_state(self): + pass + def increment_state(self): pass @@ -55,6 +54,9 @@ class NopStateStrategy(object): def timeout(self): return UpdateStateMachine.INFINITE_PERIOD + def __repr__(self): + return "NopStateStrategy()" + class ConstantStateStrategy(object): @@ -65,6 +67,9 @@ class ConstantStateStrategy(object): def initialize_state(self): pass + def reinitialize_state(self): + pass + def increment_state(self): pass @@ -72,12 +77,15 @@ class ConstantStateStrategy(object): def timeout(self): return self._timeout + def __repr__(self): + return "ConstantStateStrategy(timeout=%r)" % self._timeout + class GeometricStateStrategy(object): def __init__(self, init, min, max): - assert 0 < init and init < max and init != UpdateStateMachine.INFINITE_PERIOD - assert 0 < min and min != UpdateStateMachine.INFINITE_PERIOD + assert 0 < init and init < max or init == UpdateStateMachine.INFINITE_PERIOD + assert 0 < min or min == UpdateStateMachine.INFINITE_PERIOD assert min < max or max == UpdateStateMachine.INFINITE_PERIOD self._min = min self._max = max @@ -85,19 +93,34 @@ class GeometricStateStrategy(object): self._current = 0 def initialize_state(self): + self._current = self._max + + def reinitialize_state(self): self._current = self._min def increment_state(self): - if self._max == UpdateStateMachine.INFINITE_PERIOD: + if self._current == UpdateStateMachine.INFINITE_PERIOD: + pass + if self._init == UpdateStateMachine.INFINITE_PERIOD: + self._current = UpdateStateMachine.INFINITE_PERIOD + elif self._max == UpdateStateMachine.INFINITE_PERIOD: self._current *= 2 else: self._current = min(2 * self._current, self._max - self._init) @property def timeout(self): - timeout = self._init + self._current + if UpdateStateMachine.INFINITE_PERIOD in (self._init, self._current): + timeout = UpdateStateMachine.INFINITE_PERIOD + else: + timeout = self._init + self._current return timeout + def __repr__(self): + return "GeometricStateStrategy(init=%r, min=%r, max=%r)" % ( + self._init, self._min, self._max + ) + class StateMachine(object): @@ -160,12 +183,14 @@ class UpdateStateMachine(StateMachine): # Making sure the it is initialized is finicky, be careful INFINITE_PERIOD = -1 + DEFAULT_MAX_TIMEOUT = to_seconds(hours=24) _IS_DAEMON = True - def __init__(self, updateItems, name=""): + def __init__(self, updateItems, name="", maxTime = DEFAULT_MAX_TIMEOUT): self._name = name self._updateItems = updateItems + self._maxTime = maxTime self._state = self.STATE_ACTIVE self._timeoutId = None @@ -177,6 +202,12 @@ class UpdateStateMachine(StateMachine): ) ) + def __repr__(self): + return """UpdateStateMachine( + name=%r, + strategie=%r, +)""" % (self._name, self._strategies) + def set_state_strategy(self, state, strategy): self._strategies[state] = strategy @@ -203,14 +234,13 @@ class UpdateStateMachine(StateMachine): _moduleLogger.info("%s Transitioning from %s to %s" % (self._name, oldState, newState)) self._state = newState - self._reset_timers() + self._reset_timers(initialize=True) @property def state(self): return self._state def reset_timers(self): - _moduleLogger.info("%s Resetting State Machine" % (self._name, )) self._reset_timers() @property @@ -225,13 +255,16 @@ class UpdateStateMachine(StateMachine): def _request_reset_timers(self, *args): self._reset_timers() - def _schedule_update(self): - assert self._timeoutId is None - self._strategy.increment_state() - nextTimeout = self._strategy.timeout - if nextTimeout != self.INFINITE_PERIOD: - self._timeoutId = gobject_utils.timeout_add_seconds(nextTimeout, self._on_timeout) - _moduleLogger.info("%s Next update in %s seconds" % (self._name, nextTimeout, )) + def _reset_timers(self, initialize=False): + if self._timeoutId is None: + return # not started yet + _moduleLogger.info("%s Resetting State Machine" % (self._name, )) + self._stop_update() + if initialize: + self._strategy.initialize_state() + else: + self._strategy.reinitialize_state() + self._schedule_update() def _stop_update(self): if self._timeoutId is None: @@ -239,12 +272,16 @@ class UpdateStateMachine(StateMachine): gobject.source_remove(self._timeoutId) self._timeoutId = None - def _reset_timers(self): - if self._timeoutId is None: - return # not started yet - self._stop_update() - self._strategy.initialize_state() - self._schedule_update() + def _schedule_update(self): + assert self._timeoutId is None + self._strategy.increment_state() + nextTimeout = self._strategy.timeout + if nextTimeout != self.INFINITE_PERIOD and nextTimeout < self._maxTime: + assert 0 < nextTimeout + self._timeoutId = gobject_utils.timeout_add_seconds(nextTimeout, self._on_timeout) + _moduleLogger.info("%s Next update in %s seconds" % (self._name, nextTimeout, )) + else: + _moduleLogger.info("%s No further updates (timeout is %s seconds)" % (self._name, nextTimeout, )) @gtk_toolbox.log_exception(_moduleLogger) def _on_timeout(self):