OSDN Git Service

Merge "Common: remove GD related stuff from common" am: 98695adc1c
[android-x86/system-bt.git] / common / state_machine.h
1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #pragma once
18
19 #include <map>
20 #include <utility>
21
22 #include <base/logging.h>
23
24 namespace bluetooth {
25
26 namespace common {
27
28 /**
29  * State machine used by Bluetooth native stack.
30  */
31 class StateMachine {
32  public:
33   enum { kStateInvalid = -1 };
34
35   /**
36    * A class to represent the state in the State Machine.
37    */
38   class State {
39     friend class StateMachine;
40
41    public:
42     /**
43      * Constructor.
44      *
45      * @param sm the State Machine to use
46      * @param state_id the unique State ID. It should be a non-negative number.
47      */
48     State(StateMachine& sm, int state_id) : sm_(sm), state_id_(state_id) {}
49
50     virtual ~State() = default;
51
52     /**
53      * Process an event.
54      * TODO: The arguments are wrong - used for backward compatibility.
55      * Will be replaced later.
56      *
57      * @param event the event type
58      * @param p_data the event data
59      * @return true if the processing was completed, otherwise false
60      */
61     virtual bool ProcessEvent(uint32_t event, void* p_data) = 0;
62
63     /**
64      * Get the State ID.
65      *
66      * @return the State ID
67      */
68     int StateId() const { return state_id_; }
69
70    protected:
71     /**
72      * Called when a state is entered.
73      */
74     virtual void OnEnter() {}
75
76     /**
77      * Called when a state is exited.
78      */
79     virtual void OnExit() {}
80
81     /**
82      * Transition the State Machine to a new state.
83      *
84      * @param dest_state_id the state ID to transition to. It must be one
85      * of the unique state IDs when the corresponding state was created.
86      */
87     void TransitionTo(int dest_state_id) { sm_.TransitionTo(dest_state_id); }
88
89     /**
90      * Transition the State Machine to a new state.
91      *
92      * @param dest_state the state to transition to. It cannot be nullptr.
93      */
94     void TransitionTo(StateMachine::State* dest_state) {
95       sm_.TransitionTo(dest_state);
96     }
97
98    private:
99     StateMachine& sm_;
100     int state_id_;
101   };
102
103   StateMachine()
104       : initial_state_(nullptr),
105         previous_state_(nullptr),
106         current_state_(nullptr) {}
107   ~StateMachine() {
108     for (auto& kv : states_) delete kv.second;
109   }
110
111   /**
112    * Start the State Machine operation.
113    */
114   void Start() { TransitionTo(initial_state_); }
115
116   /**
117    * Quit the State Machine operation.
118    */
119   void Quit() { previous_state_ = current_state_ = nullptr; }
120
121   /**
122    * Get the current State ID.
123    *
124    * @return the current State ID
125    */
126   int StateId() const {
127     if (current_state_ != nullptr) {
128       return current_state_->StateId();
129     }
130     return kStateInvalid;
131   }
132
133   /**
134    * Get the previous current State ID.
135    *
136    * @return the previous State ID
137    */
138   int PreviousStateId() const {
139     if (previous_state_ != nullptr) {
140       return previous_state_->StateId();
141     }
142     return kStateInvalid;
143   }
144
145   /**
146    * Process an event.
147    * TODO: The arguments are wrong - used for backward compatibility.
148    * Will be replaced later.
149    *
150    * @param event the event type
151    * @param p_data the event data
152    * @return true if the processing was completed, otherwise false
153    */
154   bool ProcessEvent(uint32_t event, void* p_data) {
155     if (current_state_ == nullptr) return false;
156     return current_state_->ProcessEvent(event, p_data);
157   }
158
159   /**
160    * Transition the State Machine to a new state.
161    *
162    * @param dest_state_id the state ID to transition to. It must be one
163    * of the unique state IDs when the corresponding state was created.
164    */
165   void TransitionTo(int dest_state_id) {
166     auto it = states_.find(dest_state_id);
167
168     CHECK(it != states_.end()) << "Unknown State ID: " << dest_state_id;
169     State* dest_state = it->second;
170     TransitionTo(dest_state);
171   }
172
173   /**
174    * Transition the State Machine to a new state.
175    *
176    * @param dest_state the state to transition to. It cannot be nullptr.
177    */
178   void TransitionTo(StateMachine::State* dest_state) {
179     if (current_state_ != nullptr) {
180       current_state_->OnExit();
181     }
182     previous_state_ = current_state_;
183     current_state_ = dest_state;
184     current_state_->OnEnter();
185   }
186
187   /**
188    * Add a state to the State Machine.
189    * The state machine takes ownership on the state - i.e., the state will
190    * be deleted by the State Machine itself.
191    *
192    * @param state the state to add
193    */
194   void AddState(State* state) {
195     states_.insert(std::make_pair(state->StateId(), state));
196   }
197
198   /**
199    * Set the initial state of the State Machine.
200    *
201    * @param initial_state the initial state
202    */
203   void SetInitialState(State* initial_state) { initial_state_ = initial_state; }
204
205  private:
206   State* initial_state_;
207   State* previous_state_;
208   State* current_state_;
209   std::map<int, State*> states_;
210 };
211
212 }  // namespace common
213
214 }  // namespace bluetooth