wow. that was easy: git mv core nucleus
[feisty_meow.git] / core / library / processes / state_machine.h
diff --git a/core/library/processes/state_machine.h b/core/library/processes/state_machine.h
deleted file mode 100644 (file)
index 3d2761e..0000000
+++ /dev/null
@@ -1,348 +0,0 @@
-#ifndef STATE_MACHINE_CLASS
-#define STATE_MACHINE_CLASS
-
-/*****************************************************************************\
-*                                                                             *
-*  Name   : state_machine                                                     *
-*  Author : Chris Koeritz                                                     *
-*                                                                             *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author.  This program 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 is online at:      *
-*     http://www.fsf.org/copyleft/gpl.html                                    *
-* Please send any updates to: fred@gruntose.com                               *
-\*****************************************************************************/
-
-#include <basis/contracts.h>
-#include <timely/time_stamp.h>
-
-namespace processes {
-
-class state_machine_override_array;
-class state_machine_state_array;
-
-//! Monitors objects with multiple states and the transitions between states.
-/*!
-  A state machine is a computational abstraction for any control process
-  that has discrete states and transitions between the states.
-  As used here, the "state_machine" is a base class for objects that can be
-  manipulated by the "transition_map" class.  Your transition map must be
-  validated and you must use it to reset() your state_machine object before
-  any activity can occur.  (One aspect of validation is that all states must be
-  reachable from the user-specified starting state.  The other requirements
-  are documented below for transition_map.) Once validation is done, the
-  transition map manages the machine through the various states that are
-  defined and applies trigger values to modify the current state when asked
-  to do so.  It also applies any defined timed transitions automatically.
-  This implementation of state machines is configured once (by defining the
-  transition_map object), but then the machines can be run repeatedly (via
-  the state_machine object).
-*/
-
-class state_machine : public virtual basis::root_object
-{
-public:
-  state_machine();
-    //!< sets up the machine in a blank state.
-
-  state_machine(const state_machine &to_copy);
-    //!< copies the machine provided in "to_copy".
-
-  virtual ~state_machine();
-
-  DEFINE_CLASS_NAME("state_machine");
-
-  state_machine &operator =(const state_machine &to_copy);
-    //!< assigns this to a copy of the machine provided in "to_copy".
-
-  virtual int update();
-    //!< this is the main implementation function provided by derived classes.
-    /*!< this is implemented by derived classes that want to perform an action
-    when the state machine is pulsed (see below in transition_map), which is
-    why it is not pure virtual; a state machine might still be useful as a
-    state tracking object rather than needing to implement extended
-    functionality.  this function is invoked whenever the state changes due to
-    a timed, range based or simple transition.  one must be careful when
-    servicing this transition not to enmesh oneself in a snarled invocation
-    situation; if make_transition or time_slice or pulse are invoked from this
-    update function and conditions are right for another transition, then the
-    update function will be re-entered recursively.  if the value returned
-    from update is non-zero, it is used to pulse the state machine again as a
-    new trigger value (this is safer than explicitly calling one of the
-    transition causing functions).  note that this assumes that zero is an
-    invalid trigger.  if your triggers include zero as a valid value, don't
-    try returning it through update; use pulse to force the triggering to
-    accept the invalid trigger instead. */
-
-  int current() const { return _current; }
-    //!< returns the current state.
-    /*!< NOTE: a zero value for a state means that it is uninitialized. */
-
-  int last() const { return _last; }
-    //!< returns the last active state.
-
-  int trigger() const { return _trig; }
-    //!< returns the trigger that caused this state.
-    /*!< this is only meaningful when the transition was caused by a range
-    transition.  if it was, then ranged() will return true. */
-
-  enum transition_types { SIMPLE, RANGE, TIMED };
-    //!< the three types of transitions supported.
-
-  bool simple() const { return _type == SIMPLE; }
-    //!< returns true if the last transition was a simple type.
-  bool ranged() const { return _type == RANGE; }
-    //!< returns true if the last transition was a ranged type.
-  bool timed() const { return _type == TIMED; }
-    //!< returns true if the last transition was a timed type.
-
-  void set_state(int new_current, int new_last, int trigger,
-          transition_types type);
-    //!< sets the current state to "new_current" and the previous state to "new_last".
-    /*!< the "trigger" causing the transition, if any, will be stored also.
-    the "type" of transition is stored also.  the time stamp for time spent in
-    the current state is reset.  be very careful with this; if the two states
-    do not conform to the legal transitions in your map, then the state
-    machine will not behave properly. */
-
-  timely::time_stamp start() const;
-    //!< start time for the current state.
-    /*!< this records how long we've been in this state. */
-
-  void set_name(const basis::astring &name);
-    //!< sets the name to be printed in any debugging information for "this".
-
-  basis::astring get_name() const;
-    //!< retrieves the object's current name.
-
-  void override_timing(int current, int next, int duration);
-    //!< modifies the recorded timing for timed transitions.
-    /*!< this overrides the transition_map's time-out value for the transition
-    between the states "current" and "next".  a time-out of "duration"
-    will be used instead of whatever was specified when the map was set
-    up.  to erase an override, use zero as the "duration". */
-
-  int duration_override(int current, int next) const;
-    //!< reports if there's a duration override for a timed transition.
-    /*!< this returns the amount of time that this particular state_machine is
-    allowed to exist in the "current" state before progressing to the "next"
-    state.  this has nothing to do with the transition_map; it is valid only
-    for this state_machine object.  zero is returned if no override exists. */
-
-private:
-  friend class transition_map;
-    //!< manager buddy object.
-  int _current;  //!< the current state of the state machine.
-  int _last;  //!< the previous state for the state machine.
-  int _trig;  //!< the last trigger value, if _ranged is true.
-  transition_types _type;  //!< what kind of transition just occurred.
-  timely::time_stamp *_start;  //!< the time this state started.
-  basis::astring *_name;  //!< the name this state_machine reports itself as.
-  state_machine_override_array *_overrides;  //!< the timing overrides.
-
-  int duration_index(int current, int next) const;
-    //!< finds the index of a duration override in our list.
-    /*!< this locates the duration override specified for the transition
-    between "current" and "next".  it returns the index of that override, or
-    a negative number if the override is not found. */
-};
-
-//////////////
-
-//! The transition_map manages state machines and causes state changes to occur.
-/*!
-  The transition_map is a heavyweight class that is a repository for all
-  information about transitions and which manages pushing the state machines
-  through the proper states.
-
-  The transition_map guarantees these characteristics:
-
-    0) the below characteristics are checked (in validate) and no state
-       machine object is allowed to operate until they are satisfied,
-
-    1) the machine starts in the specified starting state,
-
-    2) the current state is always one that has been added and approved,
-
-    3) transitions are allowed between states only if the transition has
-       been added and approved,
-
-    4) the update() function is invoked every time the machine hits a
-       transition between states (even if it is a transition to the same
-       state),
-
-    5) range transitions are non-intersecting within one state,
-*** 5 is unimplemented ***
-
-    6) all states are reachable from the starting state by some valid
-       transition, and
-
-    7) each state has no more than one timed transition.
-
-  if any of these conditions are violated, then validate() will fail.
-  the machine will also not operate properly (at all) until the conditions
-  are satisfied by validate().  the states and transitions should
-  thus be carefully examined before turning them into a state machine....
-*/
-
-class transition_map : public virtual basis::root_object
-{
-public:
-  transition_map();
-  virtual ~transition_map();
-
-  // informational functions...
-
-  DEFINE_CLASS_NAME("transition_map");
-
-  bool valid() const { return _valid; }
-    //!< returns true if the transition_map is valid and ready for operation.
-    /*!< once the validate() call has succeeded and valid() is true, no more
-    configuration functions (see below) may be called until the reconfigure()
-    function is invoked. */
-
-  int states() const;
-    //!< returns the current number of states.
-
-  // validation functions...
-
-  enum outcomes {
-    OKAY = basis::common::OKAY,
-    DEFINE_OUTCOME(BAD_START, -49, "The start state has not been properly "
-        "specified"),
-    DEFINE_OUTCOME(OVERLAPPING_RANGES, -50, "The ranges overlap for two "
-        "transitions from a state"),
-    DEFINE_OUTCOME(UNREACHABLE, -51, "There is an unreachable state in the map")
-  };
-  basis::outcome validate(int &examine);
-    //!< checks to that all required transition conditions are satisfied.
-    /*!< OKAY is returned if they are and the map is then ready to operate.
-    other outcomes are returned if one or more of the conditions are not met:
-    BAD_START means that the starting state is badly specified.
-    OVERLAPPING_RANGES means that one state has two transitions that do not
-    have mutually exclusive ranges.  UNREACHABLE means that a state is not
-    reachable from the starting state.  for all of these cases, the "examine"
-    parameter is set to a state related to the problem. */
-
-  void reconfigure();
-    //!< puts the transition_map back into an unvalidated state.
-    /*!< this allows the characteristics of the map to be changed.  validate()
-    must be called again before resuming operation using this map. */
-
-  // configuration functions...
-
-  // NOTE: all of the functions below will fail if the transition_map has
-  // already been validated previously and reconfigure() has not been called.
-
-  // NOTE: a zero value for a state means that it is uninitialized.  thus, zero
-  // is never allowed as a value for a state or a transition endpoint.  zero is
-  // grudgingly allowed as a trigger value, although that interferes with the
-  // state_machine object's update() method.
-
-  bool add_state(int state_number);
-    //!< registers a legal state in the transition_map.
-    /*!< no action will be taken for any state until it is registered.  the
-    operation returns true for successful registration and false for errors
-    (such as when a state is already registered or is invalid). */
-
-  bool set_start(int starting_state);
-    //!< assigns a state as the first state.
-    /*!< if the "starting_state" does not already exist, it is an error and
-    false is returned. */
-
-  bool add_simple_transition(int current, int next);
-    //!< adds a transition between "current" and "next".
-    /*!< it is an error to use either an invalid "current" state or an invalid
-    "next" state.  these errors are detected during the validate() function.
-    this type of transition is unspecialized--it does not respond to triggers
-    and does not occur due to timing.  to make a state_machine undergo this
-    transition, make_transition() must be used. */
-    
-  bool add_range_transition(int current, int next, int low, int high);
-    //!< adds a transition that listens to triggers in the pulse() method.
-    /*!< this uses "low" and "high" as the inclusive range of triggers that
-    will cause a transition to the "next" state when a state_machine is pulsed
-    in the "current" state.  it is erroneous for these trigger values to
-    intersect with other values in the same "current" state. */
-  bool add_timed_transition(int current, int next, int duration);
-    //!< adds a transition that occurs after a timeout with no other activity.
-    /*!< adds a timed transition to the "next" state when the "current" state
-    has lasted "duration" milliseconds.  this relies on the time_slice function
-    being called periodically, with appropriate regularity for the specified
-    "duration" (e.g., if one's time-out is 100 ms, then one might want to call
-    time_slice() every 20 ms or so to ensure that the transition is at most 20
-    ms late in firing.  NOTE: this is not an argument for calling time_slice()
-    as fast as possible; it is an argument for realizing that the "duration"
-    must be carefully considered to meet one's timing deadlines). */
-
-  // transition functions...
-
-  // NOTE: all of these actions will fail if the transition_map has not been
-  // validated yet.
-
-  bool make_transition(state_machine &m, int next);
-    //!< changes the state to the "next" listed for "m" given the current state.
-    /*!< it is an error to make a transition that has not been specified
-    through an add_X() transition function (false is returned).  if the
-    transition succeeds, then the current_state will be "next". */
-
-  bool pulse(state_machine &m, int trigger);
-    //!< applies a "trigger" to possibly cause a range transition.
-    /*!< this causes the state_machine to accept the "trigger" as input and
-    perform at least one traversal of the transition_map.  if the trigger
-    value is found in one of the range transitions for the current state, then
-    the next state specified in that transition becomes the current state and
-    the update() function is invoked (and true is returned).  if the trigger
-    is not found in any range transition, then false is returned. */
-
-  bool time_slice(state_machine &m);
-    // allows the transition_map to process any timed transitions that may be
-    // required for the state_machine "m".  the return value is true if such
-    // a transition was found.
-
-  bool reset(state_machine &m);
-    // resets the state_machine to the starting state in the transition_map.
-    // the update function is NOT invoked at the time of the reset.  true is
-    // returned if the reset was successful; it would fail if the transition
-    // map has not been validated yet.
-
-private:
-  bool _valid;  //!< records whether we've been validated or not.
-  int _start_state;  //!< remembers the default starting state.
-  state_machine_state_array *_state_list;
-    //!< the list of transitions between states.
-
-  bool check_overlapping(int &examine);
-    //!< a validation function that looks for erroneous range transitions.
-    /*!< this returns true if there are no overlapping ranges found in the
-    range transitions for each state. */
-
-  bool check_reachability(int &examine);
-    //!< returns true if all states are reachable from the starting state.
-
-  int state_index(int state_id) const;
-    //!< returns the index of "state_id" in states, if it exists.
-
-  int transition_index(int state_index, int next, int &start);
-    //!< locates a transition into "next" for a state in our list.
-    /*!< returns the index of a transition between the state at "state_index"
-    and the "next" state by starting the search at index "start".  if there
-    is no matching transition from the "start" index on in the transition
-    list, then a negative number is returned.  "start" is updated to point
-    to the index just after a found transition, or to some random number if
-    the index is not found. */
-
-  bool check_states();
-    //!< returns false if the current machine is hosed up.
-
-  // disallowed functions for now:
-  transition_map(const transition_map &);
-  transition_map &operator =(const transition_map &);
-};
-
-} //namespace.
-
-#endif
-