SMACC2
Loading...
Searching...
No Matches
smacc_state_impl.hpp
Go to the documentation of this file.
1// Copyright 2021 RobosoftAI Inc.
2//
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 *
17 * Authors: Pablo Inigo Blasco, Brett Aldrich
18 *
19 ******************************************************************************************************************/
20
21#pragma once
27//#include <smacc2/smacc_event_generator.hpp>
31
32namespace smacc2
33{
34using namespace smacc2::introspection;
35
36//-------------------------------------------------------------------------------------------------------
37#define THIS_STATE_NAME ((demangleSymbol(typeid(*this).name()).c_str()))
38template <typename TOrthogonal, typename TBehavior, typename... Args>
39std::shared_ptr<TBehavior> ISmaccState::configure(Args &&... args)
40{
41 std::string orthogonalkey = demangledTypeName<TOrthogonal>();
42 RCLCPP_INFO(
43 getLogger(), "[%s] Configuring orthogonal: %s", THIS_STATE_NAME, orthogonalkey.c_str());
44
45 TOrthogonal * orthogonal = this->getOrthogonal<TOrthogonal>();
46 if (orthogonal != nullptr)
47 {
48 auto clientBehavior = std::shared_ptr<TBehavior>(new TBehavior(args...));
49 clientBehavior->currentState = this;
50 orthogonal->addClientBehavior(clientBehavior);
51 clientBehavior->template onOrthogonalAllocation<TOrthogonal, TBehavior>();
52 return clientBehavior;
53 }
54 else
55 {
56 RCLCPP_ERROR(
57 getLogger(), "[%s] Skipping client behavior creation in orthogonal [%s]. It does not exist.",
58 THIS_STATE_NAME, orthogonalkey.c_str());
59 return nullptr;
60 }
61}
62//-------------------------------------------------------------------------------------------------------
63
64template <typename SmaccComponentType>
65void ISmaccState::requiresComponent(SmaccComponentType *& storage)
66{
67 this->getStateMachine().requiresComponent(storage);
68}
69//-------------------------------------------------------------------------------------------------------
70
71template <typename SmaccClientType>
72void ISmaccState::requiresClient(SmaccClientType *& storage)
73{
74 const char * sname = (demangleSymbol(typeid(*this).name()).c_str());
75 storage = nullptr;
76 auto & orthogonals = this->getStateMachine().getOrthogonals();
77 for (auto & ortho : orthogonals)
78 {
79 ortho.second->requiresClient(storage);
80 if (storage != nullptr) return;
81 }
82
83 RCLCPP_ERROR(
84 getLogger(),
85 "[%s] Client of type '%s' not found in any orthogonal of the current state machine. This may "
86 "produce a segmentation fault if the returned reference is used.",
87 sname, demangleSymbol<SmaccClientType>().c_str());
88}
89//-------------------------------------------------------------------------------------------------------
90
91template <typename T>
92bool ISmaccState::getGlobalSMData(std::string name, T & ret)
93{
94 return this->getStateMachine().getGlobalSMData(name, ret);
95}
96//-------------------------------------------------------------------------------------------------------
97
98// Store globally in this state machine. (By value parameter )
99template <typename T>
100void ISmaccState::setGlobalSMData(std::string name, T value)
101{
102 this->getStateMachine().setGlobalSMData(name, value);
103}
104//-------------------------------------------------------------------------------------------------------
105
106template <typename TStateReactor, typename... TEvArgs>
107std::shared_ptr<TStateReactor> ISmaccState::createStateReactor(TEvArgs... args)
108{
109 auto sr = std::make_shared<TStateReactor>(args...);
110 //sb->initialize(this, mock);
111 //sb->setOutputEvent(typelist<TTriggerEvent>());
112 stateReactors_.push_back(sr);
113 return sr;
114}
115
116template <typename TEventGenerator, typename... TEvArgs>
117std::shared_ptr<TEventGenerator> ISmaccState::createEventGenerator(TEvArgs... args)
118{
119 auto eg = std::make_shared<TEventGenerator>(args...);
120 eventGenerators_.push_back(eg);
121 return eg;
122}
123
124// used to iterate on the source events list and fill the information of the stateReactorInfo structure
125template <typename TEventList>
127{
130
131 template <typename T>
133 {
134 auto evinfo = std::make_shared<SmaccEventInfo>(TypeInfo::getTypeInfoFromType<T>());
135 srInfo_->sourceEventTypes.push_back(evinfo);
136 EventLabel<T>(evinfo->label);
137 }
138};
139
140// used to iterate on the source events list and fill the information of the stateReactorInfo structure
141// (is it required alreadyy having the AddTEventTypeStateReactorInfo?)
142template <typename TEventList>
144{
147
148 template <typename T>
150 {
151 sr_->addInputEvent<T>();
152 }
153};
154
155template <typename TStateReactor, typename TTriggerEvent, typename TEventList, typename... TEvArgs>
156std::shared_ptr<TStateReactor> ISmaccState::createStateReactor(TEvArgs... args)
157{
158 auto sr = std::make_shared<TStateReactor>(args...);
159 sr->initialize(this);
160 sr->template setOutputEvent<TTriggerEvent>();
161
162 using boost::mpl::_1;
163 using wrappedList = typename boost::mpl::transform<TEventList, _1>::type;
165 boost::mpl::for_each<wrappedList>(op);
166
167 stateReactors_.push_back(sr);
168 return sr;
169}
170
171template <typename TOrthogonal>
173{
174 return this->getStateMachine().getOrthogonal<TOrthogonal>();
175}
176
177template <typename TEventGenerator>
179{
180 TEventGenerator * ret = nullptr;
181 for (auto & evg : this->eventGenerators_)
182 {
183 ret = dynamic_cast<TEventGenerator *>(evg.get());
184 if (ret != nullptr) break;
185 }
186 return ret;
187}
188
189template <typename TStateReactor>
191{
192 TStateReactor * ret = nullptr;
193 for (auto & sr : this->eventGenerators_)
194 {
195 ret = dynamic_cast<TStateReactor *>(sr.get());
196 if (ret != nullptr) break;
197 }
198 return ret;
199}
200
201// template <typename TStateReactor, typename TTriggerEvent, typename... TEvArgs>
202// std::shared_ptr<TStateReactor> ISmaccState::createStateReactor(TEvArgs... args)
203// {
204// auto sb = std::make_shared<TStateReactor>(std::forward(args...));
205// sb->initialize(this, typelist<TEvArgs...>());
206// sb->setOutputEvent(typelist<TTriggerEvent>());
207// stateReactors_.push_back(sb);
208
209// return sb;
210// }
211//-------------------------------------------------------------------------------------------------------
212
213template <typename EventType>
214void ISmaccState::postEvent(const EventType & ev)
215{
217}
218
219template <typename EventType>
221{
222 getStateMachine().postEvent<EventType>();
223}
224//-------------------------------------------------------------------------------------------------------
225
226template <typename TransitionType>
228{
229 auto transitionType = TypeInfo::getTypeInfoFromType<TransitionType>();
230 this->notifyTransitionFromTransitionTypeInfo(transitionType);
231}
232
233//-------------------------------------------------------------------------------------------------------------------
234
235} // namespace smacc2
236
237// implementation depends on state definition
bool getGlobalSMData(std::string name, T &ret)
void setGlobalSMData(std::string name, T value)
const std::map< std::string, std::shared_ptr< smacc2::ISmaccOrthogonal > > & getOrthogonals() const
void postEvent(EventType *ev, EventLifeTime evlifetime=EventLifeTime::ABSOLUTE)
void requiresComponent(SmaccComponentType *&storage, bool throwsException=false)
rclcpp::Logger getLogger()
Definition: smacc_state.hpp:36
std::shared_ptr< TEventGenerator > createEventGenerator(TEvArgs... args)
std::vector< std::shared_ptr< StateReactor > > stateReactors_
Definition: smacc_state.hpp:99
bool getGlobalSMData(std::string name, T &ret)
std::shared_ptr< TBehavior > configure(Args &&... args)
void requiresClient(SmaccClientType *&storage)
std::shared_ptr< TStateReactor > createStateReactor(TEvArgs... args)
TOrthogonal * getOrthogonal()
void requiresComponent(SmaccComponentType *&storage)
TStateReactor * getStateReactor()
virtual ISmaccStateMachine & getStateMachine()=0
std::vector< std::shared_ptr< smacc2::SmaccEventGenerator > > eventGenerators_
void setGlobalSMData(std::string name, T value)
TEventGenerator * getEventGenerator()
void notifyTransitionFromTransitionTypeInfo(std::shared_ptr< smacc2::introspection::TypeInfo > &transitionTypeInfo)
Definition: smacc_state.cpp:28
std::string demangleSymbol()
#define THIS_STATE_NAME
smacc2::SmaccStateReactorInfo * srInfo_
AddTEventTypeStateReactorInfo(smacc2::SmaccStateReactorInfo *srInfo)
AddTEventTypeStateReactor(smacc2::StateReactor *sr)
std::vector< std::shared_ptr< SmaccEventInfo > > sourceEventTypes