|
ceStateCore.h
Go to the documentation of this file.
00001 00002 /* --- Source License 00003 * Author : FX Programmer. 00004 * Contact : CorEngine@gmail.com 00005 * 00006 * Copyright (c) 2010 by FX Programmer. 00007 * 00008 * This source code is free software; you can redistribute it and/or modify it 00009 * under the terms of the GNU Lesser General Public License as published by 00010 * the Free Software Foundation; either version 2.1 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This source code is distributed in the hope that it will be useful, but 00014 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 00015 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00016 * License for more details. 00017 * 00018 * Redistribution and use in source and binary forms, with or without 00019 * modification, are permitted provided that the following conditions are met: 00020 * 1. The origin of this software must not be misrepresented; you must not 00021 * claim that you wrote the original software. If you use this software 00022 * in a product, an acknowledgement in the product documentation would be 00023 * appreciated but is not required. 00024 * 2. Altered source versions must be clearly marked as such, and must not 00025 * be misrepresented as being the original software. 00026 * 3. Redistributions of source code must retain the above copyright 00027 * notice, this list of conditions and the following disclaimer. 00028 * 00029 * You should have received a copy of the GNU Lesser General Public License 00030 * along with this source code; if not, write to the Free Software Foundation, 00031 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 00032 */ 00033 00039 #ifndef _CE_STATECORE_H_ 00040 #define _CE_STATECORE_H_ 0x1 00042 #ifndef __cplusplus 00043 #error ceStateCore.h requires C++ compilation (use a .cpp suffix) 00044 #endif 00045 00046 #if __GNUC__ >= 0x3 00047 #pragma GCC system_header 00048 #endif 00049 00050 #if _MSC_VER > 1000 00051 #pragma once 00052 #pragma warning(disable: 4100) 00053 #endif 00054 00055 // #include <typeinfo> // typeid 00056 00058 #ifndef APICALL 00059 # if defined(__WIN32__) && !defined(__GNUC__) 00060 # define APICALL __cdecl 00061 # elif defined(__OS2__) 00062 # if defined (__GNUC__) && __GNUC__ < 4 00063 # /* Added support for GCC-EMX <v4.x */ 00064 # /* this is needed for XFree86/OS2 developement */ 00065 # /* F. Ambacher(anakor@snafu.de) 05.2008 */ 00066 # define APICALL _cdecl 00067 # else 00068 # /* On other compilers on OS/2, we use the _System calling convention */ 00069 # /* to be compatible with every compiler */ 00070 # define APICALL _System 00071 # endif 00072 # else 00073 # define APICALL 00074 # endif 00075 #endif // APICALL 00076 00078 #if !defined(__MACH__) 00079 #ifndef NULL 00080 #ifdef __cplusplus 00081 #define NULL 0 00082 #else 00083 #define NULL ((void *)0) 00084 #endif 00085 #endif // NULL 00086 #endif // ! Mac OS X - breaks precompiled headers 00087 00089 namespace ce { 00090 00091 // --- class IState --- */ 00092 00093 class IStateManager; 00094 00096 typedef class IState 00097 { 00098 public: 00099 00100 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00101 virtual ~IState(void) { }; 00102 #endif 00103 00107 virtual void APICALL 00108 OnEnter(const IStateManager *Owner) = 0; 00109 00113 virtual void APICALL 00114 OnExecute(const IStateManager *Owner) = 0; 00115 00119 virtual void APICALL 00120 OnExit(const IStateManager *Owner) = 0; 00121 00122 } IState; 00123 00124 // --- end class IState --- */ 00125 00126 // --- class CNullState --- */ 00127 00128 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00129 typedef class CNullState : public IState 00130 { 00131 public: 00132 00133 CNullState(void) { }; 00134 virtual ~CNullState(void) { }; 00135 00136 inline void APICALL 00137 OnEnter(const IStateManager *Owner) { }; 00138 00139 inline void APICALL 00140 OnExecute(const IStateManager *Owner) 00141 { 00142 // std::printf("\n NullState : %p \n", this); 00143 }; 00144 00145 inline void APICALL 00146 OnExit(const IStateManager *Owner) { }; 00147 00148 const CNullState* operator -> (void) const 00149 { return this; }; 00150 00151 private: 00152 00153 friend class IState; 00154 00155 CNullState(const CNullState&); 00156 void operator=(const CNullState&); 00157 00158 // DISALLOW_COPY_AND_ASSIGN(CNullState); 00159 } CNullState; 00160 #endif // DOXYGEN_SHOULD_SKIP_THIS 00161 00162 static class CNullState NullState; 00163 00164 // --- end class CNullState --- */ 00165 00166 // --- class IStateManager --- */ 00167 00168 // #define CE_WITHOUT_GLOBAL_STATE 0x1 00169 // #define CE_FSM_VERIFY 0x1 00170 00174 typedef class IStateManager 00175 { 00176 public: 00177 00178 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00179 IStateManager(void) : 00180 #ifndef CE_WITHOUT_GLOBAL_STATE 00181 GlobalState(&NullState), 00182 #endif 00183 CurrentState(&NullState), 00184 PreviousState(&NullState) { }; 00185 00186 virtual ~IStateManager(void) 00187 { 00188 this -> CurrentState -> OnExit(this); 00189 #ifndef CE_WITHOUT_GLOBAL_STATE 00190 this -> GlobalState -> OnExit(this); 00191 #endif 00192 }; 00193 #endif 00194 00195 // #ifdef CE_FSM_VERIFY 00200 inline const short APICALL 00201 VerifyStateManager(void) const 00202 { 00203 #ifndef CE_WITHOUT_GLOBAL_STATE 00204 if (!this -> GlobalState) return 0x0; 00205 #endif 00206 if (!this -> CurrentState) return 0x0; 00207 if (!this -> PreviousState) return 0x0; 00208 return 0x1; 00209 }; 00210 // #endif 00211 00212 #ifndef CE_WITHOUT_GLOBAL_STATE 00213 // --- Global State --- */ 00219 inline void APICALL 00220 SetGlobalState(IState *State) const 00221 { 00222 this -> GlobalState -> OnExit(this); 00223 this -> GlobalState = (State) ? State : &NullState; 00224 this -> GlobalState -> OnEnter(this); 00225 }; 00226 00230 inline IState* APICALL 00231 GetGlobalState(void) const 00232 { return this -> GlobalState; }; 00233 // -------------------- */ 00234 #endif // CE_WITHOUT_GLOBAL_STATE 00235 00236 // --- Current State --- */ 00242 inline void APICALL 00243 SetCurrentState(IState *State) const 00244 { 00245 this -> CurrentState -> OnExit(this); 00246 this -> CurrentState = (State) ? State : &NullState; 00247 this -> CurrentState -> OnEnter(this); 00248 }; 00249 00253 inline IState* APICALL 00254 GetCurrentState(void) const 00255 { return this -> CurrentState; }; 00256 // --------------------- */ 00257 00258 // --- Previous State --- */ 00263 inline void APICALL 00264 SetPreviousState(IState *State) const 00265 { this -> PreviousState = (State) ? State : &NullState; }; 00266 00270 inline IState* APICALL 00271 GetPreviousState(void) const 00272 { return this -> PreviousState; }; 00273 // ---------------------- */ 00274 00276 inline void APICALL 00277 Update(void) const 00278 { 00279 #ifndef CE_WITHOUT_GLOBAL_STATE 00280 this -> GlobalState -> OnExecute(this); 00281 #endif 00282 this -> CurrentState -> OnExecute(this); 00283 }; 00284 00289 inline void APICALL 00290 ChangeState(IState *State) const 00291 { 00292 this -> PreviousState = this -> CurrentState; 00293 00294 this -> CurrentState -> OnExit(this); 00295 this -> CurrentState = (State) ? State : &NullState; 00296 this -> CurrentState -> OnEnter(this); 00297 }; 00298 00300 inline void APICALL 00301 RevertToPreviousState(void) const 00302 { this -> ChangeState(this -> PreviousState); }; 00303 00310 inline short APICALL 00311 IsInState(const IState &State) const 00312 { 00313 #ifdef _TYPEINFO 00314 return (typeid(*this -> CurrentState) == typeid(State)); 00315 #else 00316 return (this -> CurrentState == ((IState *) &(State))); 00317 #endif 00318 }; 00319 00320 const IStateManager* operator -> (void) const 00321 { return this; }; 00322 00323 protected: 00324 00325 #ifndef CE_WITHOUT_GLOBAL_STATE 00326 00327 mutable IState *GlobalState; 00328 #endif 00329 00330 mutable IState *CurrentState; 00332 mutable IState *PreviousState; 00333 00334 private: 00335 00336 IStateManager(const IStateManager&); 00337 void operator=(const IStateManager&); 00338 00339 // DISALLOW_COPY_AND_ASSIGN(IStateManager); 00340 } IStateManager; 00341 00342 // --- end class IStateManager --- */ 00343 00344 // --- IStateManager Factory --- */ 00345 00350 inline IStateManager* APICALL 00351 CreateStateManager(void) 00352 { 00353 IStateManager *NewInstance = new IStateManager; 00354 if (!NewInstance) return NULL; 00355 00356 // #ifdef CE_FSM_VERIFY 00357 if (!NewInstance -> VerifyStateManager()) 00358 { 00359 delete NewInstance; 00360 NewInstance = NULL; return NULL; 00361 }; 00362 // #endif 00363 00364 return NewInstance; 00365 }; 00366 00370 inline void APICALL 00371 DestroyStateManager(IStateManager **Instance = NULL) 00372 { 00373 if (!Instance || !((IStateManager *) *(Instance))) return; 00374 delete *(Instance); 00375 *(Instance) = NULL; Instance = NULL; 00376 }; 00377 00378 // --- end IStateManager Factory --- */ 00379 00380 } // end namespace ce 00381 00382 #if _MSC_VER > 1000 00383 #pragma warning(default:4100) 00384 #endif 00385 00386 #endif // _CE_STATECORE_H_ 00387 |
|