Diag-Client-Lib
state.h
Go to the documentation of this file.
1 /* Diagnostic Client library
2  * Copyright (C) 2024 Avijit Dey
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  */
8 #ifndef DIAGNOSTIC_CLIENT_LIB_LIB_UTILITY_UTILITY_STATE_H
9 #define DIAGNOSTIC_CLIENT_LIB_LIB_UTILITY_UTILITY_STATE_H
10 
11 #include <atomic>
12 #include <cstdint>
13 #include <map>
14 #include <memory>
15 #include <mutex>
16 #include <string>
17 #include <utility>
18 
19 namespace utility {
20 namespace state {
21 template<typename EnumState>
22 class State {
23  public:
24  // ctor
25  explicit State(EnumState state) : state_{state} {}
26 
27  // dtor
28  virtual ~State() = default;
29 
30  // start the state
31  virtual void Start() = 0;
32 
33  // Update the state
34  virtual void Stop() = 0;
35 
36  // Handle invoked asynchronously
37  // Todo:: Delete this methods, no used anywhere
38  virtual void HandleMessage() {}
39 
40  // Get the State index
41  auto GetState() const noexcept -> EnumState { return state_; }
42 
43  protected:
44  // state index number
45  EnumState state_;
46 };
47 
48 template<typename EnumState>
49 class StateContext {
50  public:
51  // ctor
53 
54  // dtor
55  ~StateContext() = default;
56 
57  // Add the needed state
58  void AddState(EnumState state, std::unique_ptr<State<EnumState>> state_ptr) {
59  state_map_.insert(std::pair<EnumState, std::unique_ptr<State<EnumState>>>(state, std::move(state_ptr)));
60  }
61 
62  // Get the current state
63  auto GetActiveState() noexcept -> State<EnumState> & {
64  std::lock_guard<std::mutex> const lck{state_lock};
65  return *current_state_;
66  }
67 
68  // Function to transition state to provided state
69  void TransitionTo(EnumState state) {
70  // stop the current state
71  Stop();
72  // Update to new state
73  Update(state);
74  // Start new state
75  Start();
76  }
77 
78  // Get Context
79  auto GetContext() noexcept -> StateContext * { return this; }
80 
81  private:
82  // Start the current state
83  void Start() {
84  if (this->current_state_ != nullptr) { this->current_state_->Start(); }
85  }
86 
87  // Stop the current state
88  void Stop() {
89  if (this->current_state_ != nullptr) { this->current_state_->Stop(); }
90  }
91 
92  // Update to new state
93  void Update(EnumState state) {
94  std::lock_guard<std::mutex> const lck{state_lock};
95  auto it = state_map_.find(state);
96  if (it != state_map_.end()) {
97  this->current_state_ = it->second.get();
98  } else {
99  // failure condition
100  }
101  }
102 
103  // mutex to protect transition
104  std::mutex state_lock;
105 
106  // pointer to store the active state
108  // mapping of state to state ref
109  std::map<EnumState, std::unique_ptr<State<EnumState>>> state_map_;
110 };
111 } // namespace state
112 } // namespace utility
113 #endif // DIAGNOSTIC_CLIENT_LIB_LIB_UTILITY_UTILITY_STATE_H
auto GetActiveState() noexcept -> State< EnumState > &
Definition: state.h:63
std::map< EnumState, std::unique_ptr< State< EnumState > > > state_map_
Definition: state.h:109
auto GetContext() noexcept -> StateContext *
Definition: state.h:79
State< EnumState > * current_state_
Definition: state.h:107
void Update(EnumState state)
Definition: state.h:93
void TransitionTo(EnumState state)
Definition: state.h:69
void AddState(EnumState state, std::unique_ptr< State< EnumState >> state_ptr)
Definition: state.h:58
auto GetState() const noexcept -> EnumState
Definition: state.h:41
State(EnumState state)
Definition: state.h:25
EnumState state_
Definition: state.h:45
virtual ~State()=default
virtual void Stop()=0
virtual void HandleMessage()
Definition: state.h:38
virtual void Start()=0