![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /******************************************************************************* 00002 * This file is part of openWNS (open Wireless Network Simulator) 00003 * _____________________________________________________________________________ 00004 * 00005 * Copyright (C) 2004-2007 00006 * Chair of Communication Networks (ComNets) 00007 * Kopernikusstr. 5, D-52074 Aachen, Germany 00008 * phone: ++49-241-80-27910, 00009 * fax: ++49-241-80-22242 00010 * email: info@openwns.org 00011 * www: http://www.openwns.org 00012 * _____________________________________________________________________________ 00013 * 00014 * openWNS is free software; you can redistribute it and/or modify it under the 00015 * terms of the GNU Lesser General Public License version 2 as published by the 00016 * Free Software Foundation; 00017 * 00018 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00019 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00020 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00021 * details. 00022 * 00023 * You should have received a copy of the GNU Lesser General Public License 00024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00025 * 00026 ******************************************************************************/ 00027 00028 #ifndef WNS_FSM_FSM_HPP 00029 #define WNS_FSM_FSM_HPP 00030 00031 #include "FSMConfigCreator.hpp" 00032 00033 #include <WNS/StaticFactory.hpp> 00034 #include <WNS/TypeInfo.hpp> 00035 #include <WNS/Assure.hpp> 00036 #include <WNS/SmartPtr.hpp> 00037 #include <WNS/logger/Logger.hpp> 00038 #include <WNS/pyconfig/Parser.hpp> 00039 00040 #include <string> 00041 00042 #include <iostream> 00043 00044 namespace wns { namespace fsm { 00065 template <typename SIGNALS, typename VARIABLES> 00066 class FSM 00067 { 00068 public: 00072 typedef VARIABLES VariablesType; 00073 00077 class StateInterface : 00078 virtual public SIGNALS 00079 { 00080 private: 00081 template <class> friend class wns::fsm::FSMConfigCreator; 00082 00086 typedef FSM<SIGNALS, VARIABLES> FSMType; 00087 00088 public: 00092 explicit 00093 StateInterface(FSMType* _fsm, const std::string& _stateName) : 00094 fsm(_fsm), 00095 stateName(_stateName) 00096 {} 00097 00101 virtual void 00102 initState() 00103 {} 00104 00108 virtual void 00109 exitState() 00110 {} 00111 00115 std::string 00116 getStateName() const 00117 { 00118 return stateName; 00119 } 00120 00126 VariablesType& 00127 vars() 00128 { 00129 return getFSM()->getVariables(); 00130 } 00131 00132 protected: 00136 virtual FSMType* 00137 getFSM() const 00138 { 00139 return fsm; 00140 } 00141 00142 private: 00146 FSMType* fsm; 00147 00151 std::string stateName; 00152 }; 00153 00159 explicit 00160 FSM(const VariablesType& v) : 00161 currentState(NULL), 00162 variables(v), 00163 logger("WNS", TypeInfo::create(*this).toString()), 00164 stateCreated(false) 00165 {} 00166 00173 virtual 00174 ~FSM() 00175 { 00176 } 00177 00178 public: 00182 template <typename NEWSTATE> 00183 StateInterface* 00184 createState() 00185 { 00186 assure(!stateCreated, "A new state has been created already."); 00187 00188 stateCreated = true; 00189 return new NEWSTATE(this); 00190 } 00191 00192 private: 00196 typedef FSMConfigCreator<StateInterface> StateCreator; 00197 typedef wns::StaticFactory<StateCreator> StateFactory; 00198 00199 public: 00203 StateInterface* 00204 createState(const std::string& stateName) 00205 { 00206 if (currentState && currentState->getStateName() == stateName) 00207 return currentState; 00208 00209 assure(!stateCreated, "A new state has been created already."); 00210 00211 stateCreated = true; 00212 return StateFactory::creator(stateName) 00213 ->create(this); 00214 } 00215 00222 VariablesType& 00223 getVariables() 00224 { 00225 return variables; 00226 } 00227 00233 std::string 00234 getStateName() const 00235 { 00236 return getState()->getStateName(); 00237 } 00238 00242 void 00243 replaceState(SIGNALS* newState) 00244 { 00245 assureType(newState, StateInterface*); 00246 StateInterface* si = dynamic_cast<StateInterface*>(newState); 00247 00248 if (si == currentState) 00249 throw wns::Exception("replaceState(...) called with current state."); 00250 00251 if (currentState) 00252 { 00253 MESSAGE_BEGIN(NORMAL, logger, m, "State replacement: "); 00254 m << wns::TypeInfo::create(*currentState) 00255 << " -> " 00256 << wns::TypeInfo::create(*si); 00257 MESSAGE_END(); 00258 00259 delete currentState; 00260 } 00261 00262 stateCreated = false; 00263 00264 currentState = si; 00265 currentState->initState(); 00266 } 00267 00268 protected: 00272 StateInterface* 00273 getState() const 00274 { 00275 assure(currentState, "FSM not initialized. Please set state berfore sending signals."); 00276 return currentState; 00277 } 00278 00282 void 00283 changeState(SIGNALS* newState) 00284 { 00285 assureType(newState, StateInterface*); 00286 StateInterface* si = dynamic_cast<StateInterface*>(newState); 00287 00288 if (si == currentState) 00289 return; 00290 00291 if (currentState) 00292 { 00293 currentState->exitState(); 00294 00295 MESSAGE_BEGIN(NORMAL, logger, m, "State transition: "); 00296 m << wns::TypeInfo::create(*currentState) 00297 << " -> " 00298 << wns::TypeInfo::create(*si); 00299 MESSAGE_END(); 00300 00301 delete currentState; 00302 } 00303 00304 stateCreated = false; 00305 00306 currentState = si; 00307 currentState->initState(); 00308 } 00309 00310 private: 00314 StateInterface* currentState; 00315 00319 VariablesType variables; 00320 00324 logger::Logger logger; 00325 00329 bool stateCreated; 00330 00331 }; // FSM 00332 00333 } // fsm 00334 } // wns 00335 00336 #endif // WNS_FSM_FSM_HPP 00337
1.5.5