Delete svn tags. We don't need them in git
[synfig.git] / ETL / tags / ETL_0_04_10_rc2 / ETL / _smach.h
diff --git a/ETL/tags/ETL_0_04_10_rc2/ETL/_smach.h b/ETL/tags/ETL_0_04_10_rc2/ETL/_smach.h
deleted file mode 100644 (file)
index 992d09b..0000000
+++ /dev/null
@@ -1,597 +0,0 @@
-/*! ========================================================================
-** Extended Template and Library
-** State Machine Abstraction Class Implementation
-** $Id$
-**
-** Copyright (c) 2002 Robert B. Quattlebaum Jr.
-**
-** This package is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License as
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-** General Public License for more details.
-**
-** === N O T E S ===========================================================
-**
-** ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __ETL__SMACH_H_
-#define __ETL__SMACH_H_
-
-/* === H E A D E R S ======================================================= */
-
-#include <vector>
-#include <algorithm>
-#include <stdexcept>
-#include "_mutex_null.h"
-#include "_misc.h"
-
-/* === M A C R O S ========================================================= */
-
-#define SMACH_STATE_STACK_SIZE         (32)
-
-#ifdef _MSC_VER
-#pragma warning (disable:4786)
-#pragma warning (disable:4290) // MSVC6 doesn't like function declarations with exception specs
-#endif
-
-//#define ETL_MUTEX_LOCK()             _mutex::lock lock(mutex)
-#define ETL_MUTEX_LOCK()
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-_ETL_BEGIN_NAMESPACE
-
-/*! ========================================================================
-** \class      smach
-** \brief      Templatized State Machine
-**
-** A more detailed description needs to be written.
-*/
-template <typename CON, typename K=int, typename M=mutex_null>
-class smach
-{
-public:
-
-       typedef K event_key;
-       typedef M _mutex;
-       typedef CON context_type;
-
-
-       struct egress_exception { };
-       struct pop_exception { };
-
-
-       //! Result type for event processing
-       enum event_result
-       {
-               // These values are returned by the event
-               // handlers cast to state pointers.
-               RESULT_ERROR,           //!< General error or malfunction
-               RESULT_OK,                      //!< Event has been processed
-               RESULT_ACCEPT,          //!< The event has been explicitly accepted.
-               RESULT_REJECT,          //!< The event has been explicitly rejected.
-
-               RESULT_END                      //!< Not a valid result
-       };
-
-       //template<typename T> class state;
-
-       //! Event base class
-       struct event
-       {
-               event_key key;
-
-               event() { }
-               event(const event_key& key):key(key) { }
-
-               operator event_key()const { return key; }
-       };
-
-       //! Event definition class
-       template<typename T>
-       class event_def
-       {
-               // List our friends
-               friend class smach;
-               //friend class state<T>;
-
-       public:
-               typedef T state_context_type;
-
-               //! Event function type
-               typedef event_result (T::*funcptr)(const event&);
-
-       //private:
-
-               event_key id;           //<! Event ID
-               funcptr handler;        //<! Pointer event handler
-
-       public:
-
-               //! Less-than operator for sorting. Based on event_key value.
-               bool operator<(const event_def &rhs)const
-                       { return id<rhs.id; }
-
-               //! Equal-to operator. Based on event_key value.
-               bool operator==(const event_def &rhs)const
-                       { return id==rhs.id; }
-
-               //! Less-than operator for finding.
-               bool operator<(const event_key &rhs)const
-                       { return id<rhs; }
-
-               //! Equal-to operator. Based on event_key value.
-               bool operator==(const event_key &rhs)const
-                       { return id==rhs; }
-
-               //! Trivial Constructor
-               event_def() { }
-
-               //! Constructor for creating an event_def from the given key and function reference.
-               event_def(event_key a, funcptr b):id(a),handler(b) { }
-
-               //! Copy constructor
-               event_def(const event_def &x):id(x.id),handler(x.handler) { }
-
-       };
-
-       class state_base
-       {
-               // Our parent is our friend
-               friend class smach;
-       public:
-               virtual ~state_base() { }
-
-               virtual void* enter_state(context_type* machine_context)const=0;
-
-               virtual bool leave_state(void* state_context)const=0;
-
-               virtual event_result process_event(void* state_context,const event& id)const=0;
-
-               virtual const char *get_name() const=0;
-       };
-
-       //! State class
-       template<typename T>
-       class state : public state_base
-       {
-               // Our parent is our friend
-               friend class smach;
-
-       public:
-               typedef event_def<T> event_def;
-               typedef T state_context_type;
-
-
-       private:
-
-               std::vector<event_def> event_list;
-
-               smach *nested;          //! Nested machine
-               event_key low,high;     //! Lowest and Highest event values
-               const char *name;       //! Name of the state
-               typename event_def::funcptr default_handler;    //! Default handler for unknown key
-
-       public:
-
-               //! Constructor
-               state(const char *n, smach* nest=0):
-                       nested(nest),name(n),default_handler(NULL)
-               { }
-
-               virtual ~state() { }
-
-               //! Setup a nested state machine
-               /*! A more detailed explanation needs to be written */
-               void set_nested_machine(smach *sm) { nested=sm; }
-
-               //! Sets the default handler
-               void set_default_handler(const typename event_def::funcptr &x) { default_handler=x; }
-
-               //! Returns given the name of the state
-               virtual const char *get_name() const { return name; }
-
-               state_context_type& get_context(smach& machine)
-               {
-                       state_context_type *context(dynamic_cast<state_context_type*>(machine.state_context));
-                       if(context)
-                               return context;
-
-               }
-
-               //! Adds an event_def onto the list and then make sure it is sorted correctly.
-               void
-               insert(const event_def &x)
-               {
-                       // If this is our first event_def,
-                       // setup the high and low values.
-                       if(!event_list.size())
-                               low=high=x.id;
-
-                       // Sort the event_def onto the list
-                       event_list.push_back(x);
-                       sort(event_list.begin(),event_list.end());
-
-                       // Update the low and high markers
-                       if(x.id<low)
-                               low=x.id;
-                       if(high<x.id)
-                               high=x.id;
-               }
-
-               typename std::vector<event_def>::iterator find(const event_key &x) { return binary_find(event_list.begin(),event_list.end(),x); }
-               typename std::vector<event_def>::const_iterator find(const event_key &x)const { return binary_find(event_list.begin(),event_list.end(),x); }
-
-       protected:
-
-               virtual void* enter_state(context_type* machine_context)const
-               {
-                       return new state_context_type(machine_context);
-               }
-
-               virtual bool leave_state(void* x)const
-               {
-                       state_context_type* state_context(reinterpret_cast<state_context_type*>(x));
-                       delete state_context;
-                       return true;
-               }
-
-               virtual event_result
-               process_event(void* x,const event& id)const
-               {
-                       state_context_type* state_context(reinterpret_cast<state_context_type*>(x));
-
-                       // Check for nested machine in state
-                       if(nested)
-                       {
-                               const event_result ret(nested->process_event(id));
-                               if(ret!=RESULT_OK)
-                                       return ret;
-                       }
-
-                       // Quick test to make sure that the
-                       // given event is in the state
-                       if(id.key<low || high<id.key)
-                               return RESULT_OK;
-
-                       // Look for the event
-                       typename std::vector<event_def>::const_iterator iter(find(id.key));
-
-                       // If search results were negative, fail.
-                       if(iter->id!=id.key)
-                               return RESULT_OK;
-
-                       // Execute event function
-                       event_result ret((state_context->*(iter->handler))(id));
-
-                       if(ret==RESULT_OK && default_handler)
-                               ret=(state_context->*(default_handler))(id);
-
-                       return ret;
-               }
-       };
-
-private:
-
-       // Machine data
-       const state_base* curr_state;   //!< Current state of the machine
-       smach* child;                              //!< Child machine
-
-public: // this really should be private
-       void* state_context;            //!< State Context
-private:
-
-       context_type* machine_context;          //!< Machine Context
-
-       const state_base* default_state;
-       void*   default_context;
-
-#ifdef ETL_MUTEX_LOCK
-       _mutex mutex;
-#endif
-
-       //! State stack data
-       const state_base*       state_stack[SMACH_STATE_STACK_SIZE];
-       void*                           state_context_stack[SMACH_STATE_STACK_SIZE];
-       int                             states_on_stack;
-
-public:
-
-       //! Gets the name of the currently active state
-       const char *
-       get_state_name()const
-       {
-#ifdef ETL_MUTEX_LOCK
-               ETL_MUTEX_LOCK();
-#endif
-               if(curr_state)
-                       return curr_state->get_name();
-               if(default_state)
-                       return default_state->get_name();
-               return 0;
-       }
-
-       //! Determines if a given event result is an error
-       /*! This function allows us to quickly see
-               if an event_result contained an error */
-       static bool
-       event_error(const event_result &rhs)
-               { return rhs<=RESULT_ERROR; }
-
-       bool
-       set_default_state(const state_base *nextstate)
-       {
-#ifdef ETL_MUTEX_LOCK
-               ETL_MUTEX_LOCK();
-#endif
-               // Keep track of the current state unless
-               // the state switch fails
-               const state_base *prev_state=default_state;
-
-               // If we are already in a state, leave it and
-               // collapse the state stack
-               if(default_state)
-                       default_state->leave_state(default_context);
-
-               // Set this as our current state
-               default_state=nextstate;
-               default_context=0;
-
-               // Attempt to enter the state
-               if(default_state)
-               {
-                       default_context=default_state->enter_state(machine_context);
-                       if(default_context)
-                               return true;
-               }
-               else
-                       return true;
-
-               // We failed, so attempt to return to previous state
-               default_state=prev_state;
-
-               // If we had a previous state, enter it
-               if(default_state)
-                       default_context=default_state->enter_state(machine_context);
-
-               // At this point we are not in the
-               // requested state, so return failure
-               return false;
-       }
-
-       //! Leaves the current state
-       /*! Effectively makes the state_depth() function return zero. */
-       bool
-       egress()
-       {
-#ifdef ETL_MUTEX_LOCK
-               ETL_MUTEX_LOCK();
-#endif
-
-               // Pop all states off the state stack
-               while(states_on_stack) pop_state();
-
-               // If we are not in a state, then I guess
-               // we were successful.
-               if(!curr_state)
-                       return true;
-
-               // Grab the return value from the exit function
-               bool ret=true;
-
-               const state_base* old_state=curr_state;
-               void *old_context=state_context;
-
-               // Clear out the current state and its state_context
-               curr_state=0;state_context=0;
-
-               // Leave the state
-               return old_state->leave_state(old_context);
-
-               return ret;
-       }
-
-       //! State entry function
-       /*! Attempts to enter the given state,
-               popping off all states on the stack
-               in the process. */
-       bool
-       enter(const state_base *nextstate)
-       {
-#ifdef ETL_MUTEX_LOCK
-               ETL_MUTEX_LOCK();
-#endif
-
-               // Keep track of the current state unless
-               // the state switch fails
-               const state_base *prev_state=curr_state;
-
-               // If we are already in a state, leave it and
-               // collapse the state stack
-               if(curr_state)
-                       egress();
-
-               // Set this as our current state
-               curr_state=nextstate;
-               state_context=0;
-
-               // Attempt to enter the state
-               state_context=curr_state->enter_state(machine_context);
-               if(state_context)
-                       return true;
-
-               // We failed, so attempt to return to previous state
-               curr_state=prev_state;
-
-               // If we had a previous state, enter it
-               if(curr_state)
-                       state_context=curr_state->enter_state(machine_context);
-
-               // At this point we are not in the
-               // requested state, so return failure
-               return false;
-       }
-
-       //! Pushes state onto state stack
-       /*! This allows you to enter a state without
-               leaving your current state.
-               \param   nextstate Pointer to the state to enter
-               \sa      pop_state()
-       */
-       bool
-       push_state(const state_base *nextstate)
-       {
-#ifdef ETL_MUTEX_LOCK
-               ETL_MUTEX_LOCK();
-#endif
-
-               // If there are not enough slots, then throw something.
-               if(states_on_stack==SMACH_STATE_STACK_SIZE)
-                       throw(std::overflow_error("smach<>::push_state(): state stack overflow!"));
-
-               // If there is no current state, nor anything on stack,
-               // just go ahead and enter the given state.
-               if(!curr_state && !states_on_stack)
-                       return enter(nextstate);
-
-               // Push the current state onto the stack
-               state_stack[states_on_stack]=curr_state;
-               state_context_stack[states_on_stack++]=state_context;
-
-               // Make the next state the current state
-               curr_state=nextstate;
-
-               // Try to enter the next state
-               state_context=curr_state->enter_state(machine_context);
-               if(state_context)
-                       return true;
-
-               // Unable to push state, return to old one
-               curr_state=state_stack[--states_on_stack];
-               state_context=state_context_stack[states_on_stack];
-               return false;
-       }
-
-       //! Pops state off of state stack
-       /*! Decreases state depth */
-       void
-       pop_state()
-       {
-#ifdef ETL_MUTEX_LOCK
-               ETL_MUTEX_LOCK();
-#endif
-
-               // If we aren't in a state, then there is nothing
-               // to do.
-               if(!curr_state)
-                       throw(std::underflow_error("smach<>::pop_state(): stack is empty!"));
-
-               if(states_on_stack)
-               {
-                       const state_base* old_state=curr_state;
-                       void *old_context=state_context;
-
-                       // Pop previous state off of stack
-                       --states_on_stack;
-                       curr_state=state_stack[states_on_stack];
-                       state_context=state_context_stack[states_on_stack];
-
-                       old_state->leave_state(old_context);
-               }
-               else // If there are no states on stack, just egress
-                       egress();
-       }
-
-       //! State Machine Constructor
-       /*! A more detailed description needs to be written */
-       smach(context_type* machine_context=0):
-               curr_state(0),
-               child(0),
-               state_context(0),
-               machine_context(machine_context),
-               default_state(0),
-               default_context(0),
-               states_on_stack(0)
-       { }
-
-       //! The destructor
-       ~smach()
-       {
-               egress();
-
-               if(default_state)
-                       default_state->leave_state(default_context);
-       }
-
-       //! Sets up a child state machine
-       /*! A child state machine runs in parallel with
-               its parent, and gets event priority. This
-               mechanism is useful in cases where an inherited
-               object has its own state machine. */
-       void set_child(smach *x)
-       {
-#ifdef ETL_MUTEX_LOCK
-               ETL_MUTEX_LOCK();
-#endif
-               child=x;
-       }
-
-       //! Returns the number states currently active
-       int
-       state_depth()
-               { return curr_state?states_on_stack+1:0; }
-
-       event_result
-       process_event(const event_key& id) { return process_event(event(id)); }
-
-       //! Process an event
-       event_result
-       process_event(const event& id)
-       {
-#ifdef ETL_MUTEX_LOCK
-               ETL_MUTEX_LOCK();
-#endif
-
-               event_result ret(RESULT_OK);
-
-               // Check for child machine
-               if(child)
-               {
-                       ret=child->process_event(id);
-                       if(ret!=RESULT_OK)
-                               return ret;
-               }
-
-               try
-               {
-                       if(curr_state)
-                               ret=curr_state->process_event(state_context,id);
-
-                       if(ret==RESULT_OK)
-                               return default_state->process_event(default_context,id);
-
-                       return ret;
-               }
-               catch(egress_exception) { return egress()?RESULT_ACCEPT:RESULT_ERROR; }
-               catch(pop_exception) { pop_state(); return RESULT_ACCEPT; }
-               catch(const state_base* state) { return enter(state)?RESULT_ACCEPT:RESULT_ERROR; }
-       }
-
-}; // END of template class smach
-
-_ETL_END_NAMESPACE
-
-/* === E X T E R N S ======================================================= */
-
-/* === E N D =============================================================== */
-
-#endif