00001 #ifndef STATE_MACHINE_CLASS
00002 #define STATE_MACHINE_CLASS
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mechanisms_dll.h"
00019
00020 #include <basis/object_base.h>
00021
00022
00023 class state_machine_override_array;
00024 class state_machine_state_array;
00025 class time_stamp;
00026
00028
00045 class MECHANISMS_CLASS_STYLE state_machine : public virtual object_base
00046 {
00047 public:
00048 state_machine();
00050
00051 state_machine(const state_machine &to_copy);
00053
00054 virtual ~state_machine();
00055
00056 IMPLEMENT_CLASS_NAME("state_machine");
00057
00058 state_machine &operator =(const state_machine &to_copy);
00060
00061 virtual int update();
00063
00080 inline int current() const { return _current; }
00082
00084 inline int last() const { return _last; }
00086
00087 inline int trigger() const { return _trig; }
00089
00092 enum transition_types { SIMPLE, RANGE, TIMED };
00094
00095 inline bool simple() const { return _type == SIMPLE; }
00097 inline bool ranged() const { return _type == RANGE; }
00099 inline bool timed() const { return _type == TIMED; }
00101
00102 inline void set_state(int new_current, int new_last, int trigger,
00103 transition_types type);
00105
00111 time_stamp start() const;
00113
00115 void set_name(const istring &name);
00117
00118 istring get_name() const;
00120
00121 void override_timing(int current, int next, int duration);
00123
00128 int duration_override(int current, int next) const;
00130
00135 private:
00136 friend class MECHANISMS_CLASS_STYLE transition_map;
00138 int _current;
00139 int _last;
00140 int _trig;
00141 transition_types _type;
00142 time_stamp *_start;
00143 istring *_name;
00144 state_machine_override_array *_overrides;
00145
00146 int duration_index(int current, int next) const;
00148
00151 };
00152
00154
00156
00191 class MECHANISMS_CLASS_STYLE transition_map : public virtual object_base
00192 {
00193 public:
00194 transition_map();
00195 virtual ~transition_map();
00196
00197
00198
00199 IMPLEMENT_CLASS_NAME("transition_map");
00200
00201 inline bool valid() const { return _valid; }
00203
00207 int states() const;
00209
00210
00211
00212 enum outcomes {
00213 OKAY = common::OKAY,
00214 DEFINE_OUTCOME(BAD_START, -43, "The start state has not been properly "
00215 "specified"),
00216 DEFINE_OUTCOME(OVERLAPPING_RANGES, -44, "The ranges overlap for two "
00217 "transitions from a state"),
00218 DEFINE_OUTCOME(UNREACHABLE, -45, "There is an unreachable state in the map")
00219 };
00220 outcome validate(int &examine);
00222
00230 void reconfigure();
00232
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 bool add_state(int state_number);
00247
00251 bool set_start(int starting_state);
00253
00256 bool add_simple_transition(int current, int next);
00258
00264 bool add_range_transition(int current, int next, int low, int high);
00266
00270 bool add_timed_transition(int current, int next, int duration);
00272
00281
00282
00283
00284
00285
00286 bool make_transition(state_machine &m, int next);
00288
00292 bool pulse(state_machine &m, int trigger);
00294
00301 bool time_slice(state_machine &m);
00302
00303
00304
00305
00306 bool reset(state_machine &m);
00307
00308
00309
00310
00311
00312 private:
00313 bool _valid;
00314 int _start_state;
00315 state_machine_state_array *_state_list;
00317
00318 bool check_overlapping(int &examine);
00320
00323 bool check_reachability(int &examine);
00325
00326 int state_index(int state_id) const;
00328
00329 int transition_index(int state_index, int next, int &start);
00331
00338 bool check_states();
00340
00341
00342 transition_map(const transition_map &);
00343 transition_map &operator =(const transition_map &);
00344 };
00345
00346 #endif
00347