diff options
author | Nathan Fritz <nathan@andyet.net> | 2010-10-13 18:15:21 -0700 |
---|---|---|
committer | Nathan Fritz <nathan@andyet.net> | 2010-10-13 18:15:21 -0700 |
commit | 7ad7a29a8f08ff815164731eec50ff1cba46b07a (patch) | |
tree | 444a2d89993072a377155d8f131899a19d18dffa /sleekxmpp/xmlstream/statemanager.py | |
parent | b0e036d03c5e850af3a3c1589af7333becf54a86 (diff) | |
download | slixmpp-7ad7a29a8f08ff815164731eec50ff1cba46b07a.tar.gz slixmpp-7ad7a29a8f08ff815164731eec50ff1cba46b07a.tar.bz2 slixmpp-7ad7a29a8f08ff815164731eec50ff1cba46b07a.tar.xz slixmpp-7ad7a29a8f08ff815164731eec50ff1cba46b07a.zip |
new state machine in place
Diffstat (limited to 'sleekxmpp/xmlstream/statemanager.py')
-rw-r--r-- | sleekxmpp/xmlstream/statemanager.py | 139 |
1 files changed, 0 insertions, 139 deletions
diff --git a/sleekxmpp/xmlstream/statemanager.py b/sleekxmpp/xmlstream/statemanager.py deleted file mode 100644 index c7f76e75..00000000 --- a/sleekxmpp/xmlstream/statemanager.py +++ /dev/null @@ -1,139 +0,0 @@ -""" - SleekXMPP: The Sleek XMPP Library - Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout - This file is part of SleekXMPP. - - See the file LICENSE for copying permission. -""" - -from __future__ import with_statement -import threading - - -class StateError(Exception): - """Raised whenever a state transition was attempted but failed.""" - - -class StateManager(object): - """ - At the very core of SleekXMPP there is a need to track various - library configuration settings, XML stream features, and the - network connection status. The state manager is responsible for - tracking this information in a thread-safe manner. - - State 'variables' store the current state of these items as simple - string values or booleans. Changing those values must be done - according to transitions defined when creating the state variable. - - If a state variable is given a value that is not allowed according - to the transition definitions, a StateError is raised. When a - valid value is assigned an event is raised named: - - _state_changed_nameofthestatevariable - - The event carries a dictionary containing the previous and the new - state values. - """ - - def __init__(self, event_func=None): - """ - Initialize the state manager. The parameter event_func should be - the event() method of a SleekXMPP object in order to enable - _state_changed_* events. - """ - self.main_lock = threading.Lock() - self.locks = {} - self.state_variables = {} - - if event_func is not None: - self.event = event_func - else: - self.event = lambda name, data: None - - def add(self, name, default=False, values=None, transitions=None): - """ - Create a new state variable. - - When transitions is specified, only those defined state change - transitions will be allowed. - - When values is specified (and not transitions), any state changes - between those values are allowed. - - If neither values nor transitions are defined, then the state variable - will be a binary switch between True and False. - """ - if name in self.state_variables: - raise IndexError("State variable %s already exists" % name) - - self.locks[name] = threading.Lock() - with self.locks[name]: - var = {'value': default, - 'default': default, - 'transitions': {}} - - if transitions is not None: - for start in transitions: - var['transitions'][start] = set(transitions[start]) - elif values is not None: - values = set(values) - for value in values: - var['transitions'][value] = values - elif values is None: - var['transitions'] = {True: [False], - False: [True]} - - self.state_variables[name] = var - - def addStates(self, var_defs): - """ - Create multiple state variables at once. - """ - for var, data in var_defs: - self.add(var, - default=data.get('default', False), - values=data.get('values', None), - transitions=data.get('transitions', None)) - - def force_set(self, name, val): - """ - Force setting a state variable's value by overriding transition checks. - """ - with self.locks[name]: - self.state_variables[name]['value'] = val - - def reset(self, name): - """ - Reset a state variable to its default value. - """ - with self.locks[name]: - default = self.state_variables[name]['default'] - self.state_variables[name]['value'] = default - - def __getitem__(self, name): - """ - Get the value of a state variable if it exists. - """ - with self.locks[name]: - if name not in self.state_variables: - raise IndexError("State variable %s does not exist" % name) - return self.state_variables[name]['value'] - - def __setitem__(self, name, val): - """ - Attempt to set the value of a state variable, but raise StateError - if the transition is undefined. - - A _state_changed_* event is triggered after a successful transition. - """ - with self.locks[name]: - if name not in self.state_variables: - raise IndexError("State variable %s does not exist" % name) - current = self.state_variables[name]['value'] - if current == val: - return - if val in self.state_variables[name]['transitions'][current]: - self.state_variables[name]['value'] = val - self.event('_state_changed_%s' % name, {'from': current, 'to': val}) - else: - raise StateError("Can not transition from '%s' to '%s'" % (str(current), str(val))) |