Remove .gitignore do nothing is ignored.
[synfig.git] / ETL / trunk / ETL / _smach.h
index 24f6b5e..99a7320 100644 (file)
@@ -1,9 +1,10 @@
 /*! ========================================================================
 ** Extended Template and Library
 ** State Machine Abstraction Class Implementation
-** $Id: _smach.h,v 1.1.1.1 2005/01/04 01:31:48 darco Exp $
+** $Id$
 **
 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
+** Copyright (c) 2008 Chris Moore
 **
 ** This package is free software; you can redistribute it and/or
 ** modify it under the terms of the GNU General Public License as
@@ -38,7 +39,7 @@
 
 #ifdef _MSC_VER
 #pragma warning (disable:4786)
-#pragma warning (disable:4290) // MSVC6 doesnt like function declarations with exception specs
+#pragma warning (disable:4290) // MSVC6 doesn't like function declarations with exception specs
 #endif
 
 //#define ETL_MUTEX_LOCK()             _mutex::lock lock(mutex)
@@ -65,7 +66,7 @@ public:
        typedef M _mutex;
        typedef CON context_type;
 
-       
+
        struct egress_exception { };
        struct pop_exception { };
 
@@ -79,7 +80,7 @@ public:
                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
        };
 
@@ -89,16 +90,16 @@ public:
        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
+       class event_def_internal
        {
                // List our friends
                friend class smach;
@@ -116,15 +117,15 @@ public:
                funcptr handler;        //<! Pointer event handler
 
        public:
-               
+
                //! Less-than operator for sorting. Based on event_key value.
-               bool operator<(const event_def &rhs)const
+               bool operator<(const event_def_internal &rhs)const
                        { return id<rhs.id; }
 
                //! Equal-to operator. Based on event_key value.
-               bool operator==(const event_def &rhs)const
+               bool operator==(const event_def_internal &rhs)const
                        { return id==rhs.id; }
-       
+
                //! Less-than operator for finding.
                bool operator<(const event_key &rhs)const
                        { return id<rhs; }
@@ -132,50 +133,50 @@ public:
                //! Equal-to operator. Based on event_key value.
                bool operator==(const event_key &rhs)const
                        { return id==rhs; }
-                       
+
                //! Trivial Constructor
-               event_def() { }
+               event_def_internal() { }
 
-               //! Constructor for creating an event_def from the given key and function reference.
-               event_def(event_key a, funcptr b):id(a),handler(b) { }
+               //! Constructor for creating an event_def_internal from the given key and function reference.
+               event_def_internal(event_key a, funcptr b):id(a),handler(b) { }
 
                //! Copy constructor
-               event_def(const event_def &x):id(x.id),handler(x.handler) { }
+               event_def_internal(const event_def_internal &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 event_def_internal<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
@@ -187,9 +188,9 @@ public:
                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; }
@@ -199,19 +200,19 @@ public:
 
                //! 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())
@@ -227,29 +228,29 @@ public:
                        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)
                        {
@@ -257,27 +258,27 @@ public:
                                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:
@@ -291,14 +292,14 @@ public: // this really should be private
 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];
@@ -319,7 +320,7 @@ public:
                        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 */
@@ -338,14 +339,14 @@ public:
                const state_base *prev_state=default_state;
 
                // If we are already in a state, leave it and
-               // colapse the state stack
+               // 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)
                {
@@ -362,12 +363,12 @@ public:
                // 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
@@ -381,22 +382,22 @@ public:
                while(states_on_stack) pop_state();
 
                // If we are not in a state, then I guess
-               // we were succesful.
+               // 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 it's 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;
        }
 
@@ -416,14 +417,14 @@ public:
                const state_base *prev_state=curr_state;
 
                // If we are already in a state, leave it and
-               // colapse the state stack
+               // 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)
@@ -435,7 +436,7 @@ public:
                // 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;
@@ -499,13 +500,13 @@ public:
                {
                        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);                    
+                       old_state->leave_state(old_context);
                }
                else // If there are no states on stack, just egress
                        egress();
@@ -522,7 +523,7 @@ public:
                default_context(0),
                states_on_stack(0)
        { }
-       
+
        //! The destructor
        ~smach()
        {
@@ -531,7 +532,7 @@ public:
                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
@@ -544,7 +545,7 @@ public:
 #endif
                child=x;
        }
-       
+
        //! Returns the number states currently active
        int
        state_depth()
@@ -552,7 +553,7 @@ public:
 
        event_result
        process_event(const event_key& id) { return process_event(event(id)); }
-       
+
        //! Process an event
        event_result
        process_event(const event& id)
@@ -560,25 +561,25 @@ public:
 #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; }