1 /* 2 * Copyright (C) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef STATE_MACHINE_H 17 #define STATE_MACHINE_H 18 19 #include <array> 20 #include <map> 21 #include <string> 22 #include "base_def.h" 23 #include "message.h" 24 25 namespace utility { 26 class StateMachine { 27 public: 28 class State { 29 public: 30 /** 31 * @brief Construct a new State object. 32 * @param name State's name. 33 * @param statemachine State is owned by which StateMachine. 34 * @param parent State's parent state. 35 * @since 6 36 */ State(const std::string & name,StateMachine & statemachine)37 explicit State(const std::string &name, StateMachine &statemachine) 38 : name_(name), statemachine_(statemachine){}; 39 40 /** 41 * @brief Construct a new State object. 42 * @param name State's name. 43 * @param statemachine State is owned by which StateMachine. 44 * @param parent State's parent state. 45 * @since 6 46 */ State(const std::string & name,StateMachine & statemachine,State & parent)47 explicit State(const std::string &name, StateMachine &statemachine, State &parent) 48 : name_(name), statemachine_(statemachine), parent_(&parent){}; 49 50 /** 51 * @brief Destroy the State object 52 * @since 6 53 */ ~State()54 virtual ~State(){}; 55 56 /** 57 * @brief Get State's name. 58 * @return State's name. 59 * @since 6 60 */ Name()61 const std::string &Name() const 62 { 63 return name_; 64 }; 65 66 /** 67 * @brief Transition to another state. 68 * @param name Another state's name. 69 */ Transition(const std::string & name)70 void Transition(const std::string &name) 71 { 72 statemachine_.Transition(name); 73 }; 74 75 private: 76 State() = delete; 77 78 /** 79 * @brief Operation should be executed when Entry the state. 80 * @since 6 81 */ 82 virtual void Entry() = 0; 83 84 /** 85 * @brief Operation should be executed when Exit the state. 86 * @since 6 87 */ 88 virtual void Exit() = 0; 89 90 virtual bool Dispatch(const Message &msg) = 0; 91 92 std::string name_ {""}; 93 StateMachine &statemachine_; 94 State* parent_ {nullptr}; 95 96 friend class StateMachine; 97 BT_DISALLOW_COPY_AND_ASSIGN(State); 98 }; 99 100 /** 101 * @brief Construct a new State Machine object 102 * @since 6 103 */ StateMachine()104 StateMachine() {}; 105 106 /** 107 * @brief Destroy the State Machine object, type is virtual. 108 * @since 6 109 */ ~StateMachine()110 virtual ~StateMachine() {}; 111 112 /** 113 * @brief Move unique_ptr of state to StateMachine. 114 * @param state State pointer. 115 * @since 6 116 */ 117 void Move(std::unique_ptr<State> &state); 118 119 /** 120 * @brief Transation to init state. 121 * @param name Init state's name. 122 * @since 6 123 */ 124 void InitState(const std::string &name); 125 126 /** 127 * @brief StateMachine process message 128 * @param msg message reference. 129 * @since 6 130 */ 131 bool ProcessMessage(const Message &msg) const; 132 133 /** 134 * @brief Get the State object 135 * @return const State & 136 * @since 6 137 */ 138 const State *GetState() const; 139 140 private: 141 const static int STACK_DEPTH = 5; 142 void Transition(const std::string &name); 143 inline int GetStateDepth(State &state); 144 145 int top_ {0}; 146 State* current_ {nullptr}; 147 std::array<State*, STACK_DEPTH> stack_ {}; 148 std::map<std::string, std::unique_ptr<State>> states_ {}; 149 150 BT_DISALLOW_COPY_AND_ASSIGN(StateMachine); 151 }; 152 } // namespace utility 153 154 #endif // STATE_MACHINE_H