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#define THIS_STATE_NAME ((demangleSymbol(typeid(*this).name()).c_str()))
36template <typename TOrthogonal, typename TBehavior, typename... Args>
37std::shared_ptr<TBehavior> ISmaccState::configure(Args &&... args)
38{
39 std::string orthogonalkey = demangledTypeName<TOrthogonal>();
40 RCLCPP_INFO(
41 getLogger(), "[%s] Configuring orthogonal: %s", THIS_STATE_NAME, orthogonalkey.c_str());
42
43 TOrthogonal * orthogonal = this->getOrthogonal<TOrthogonal>();
44 if (orthogonal != nullptr)
45 {
46 auto clientBehavior =
47 std::shared_ptr<TBehavior>(new TBehavior(args...)); // is there an error here? are the
48 // behavior constructor parameters right?
49 orthogonal->addClientBehavior(clientBehavior);
50 clientBehavior->template onOrthogonalAllocation<TOrthogonal, TBehavior>();
51 return clientBehavior;
52 }
53 else
54 {
55 RCLCPP_ERROR(
56 getLogger(), "[%s] Skipping client behavior creation in orthogonal [%s]. It does not exist.",
57 THIS_STATE_NAME, orthogonalkey.c_str());
58 return nullptr;
59 }
60}
61//-------------------------------------------------------------------------------------------------------
62
63template <typename SmaccComponentType>
64void ISmaccState::requiresComponent(SmaccComponentType *& storage)
65{
66 this->getStateMachine().requiresComponent(storage);
67}
68//-------------------------------------------------------------------------------------------------------
69
70template <typename SmaccClientType>
71void ISmaccState::requiresClient(SmaccClientType *& storage)
72{
73 const char * sname = (demangleSymbol(typeid(*this).name()).c_str());
74 storage = nullptr;
75 auto & orthogonals = this->getStateMachine().getOrthogonals();
76 for (auto & ortho : orthogonals)
77 {
78 ortho.second->requiresClient(storage);
79 if (storage != nullptr) return;
80 }
81
82 RCLCPP_ERROR(
83 getLogger(),
84 "[%s] Client of type '%s' not found in any orthogonal of the current state machine. This may "
85 "produce a segmentation fault if the returned reference is used.",
86 sname, demangleSymbol<SmaccClientType>().c_str());
87}
88//-------------------------------------------------------------------------------------------------------
89
90template <typename T>
91bool ISmaccState::getGlobalSMData(std::string name, T & ret)
92{
93 return this->getStateMachine().getGlobalSMData(name, ret);
94}
95//-------------------------------------------------------------------------------------------------------
96
97// Store globally in this state machine. (By value parameter )
98template <typename T>
99void ISmaccState::setGlobalSMData(std::string name, T value)
100{
101 this->getStateMachine().setGlobalSMData(name, value);
102}
103//-------------------------------------------------------------------------------------------------------
104
105template <typename TStateReactor, typename... TEvArgs>
106std::shared_ptr<TStateReactor> ISmaccState::createStateReactor(TEvArgs... args)
107{
108 auto sr = std::make_shared<TStateReactor>(args...);
109 // sb->initialize(this, mock);
110 // sb->setOutputEvent(typelist<TTriggerEvent>());
111 stateReactors_.push_back(sr);
112 return sr;
113}
114
115template <typename TEventGenerator, typename... TEvArgs>
116std::shared_ptr<TEventGenerator> ISmaccState::createEventGenerator(TEvArgs... args)
117{
118 auto eg = std::make_shared<TEventGenerator>(args...);
119 eventGenerators_.push_back(eg);
120 return eg;
121}
122
123// used to iterate on the source events list and fill the information of the stateReactorInfo structure
124template <typename TEventList>
126{
129
130 template <typename T>
132 {
133 auto evinfo = std::make_shared<SmaccEventInfo>(TypeInfo::getTypeInfoFromType<T>());
134 srInfo_->sourceEventTypes.push_back(evinfo);
135 EventLabel<T>(evinfo->label);
136 }
137};
138
139// used to iterate on the source events list and fill the information of the stateReactorInfo structure
140// (is it required alreadyy having the AddTEventTypeStateReactorInfo?)
141template <typename TEventList>
143{
146
147 template <typename T>
149 {
150 sr_->addInputEvent<T>();
151 }
152};
153
154template <typename TStateReactor, typename TTriggerEvent, typename TEventList, typename... TEvArgs>
155std::shared_ptr<TStateReactor> ISmaccState::createStateReactor(TEvArgs... args)
156{
157 auto sr = std::make_shared<TStateReactor>(args...);
158 sr->initialize(this);
159 sr->template setOutputEvent<TTriggerEvent>();
160
161 using boost::mpl::_1;
162 using wrappedList = typename boost::mpl::transform<TEventList, _1>::type;
164 boost::mpl::for_each<wrappedList>(op);
165
166 stateReactors_.push_back(sr);
167 return sr;
168}
169
170template <typename TOrthogonal>
172{
173 return this->getStateMachine().getOrthogonal<TOrthogonal>();
174}
175
176template <typename TOrthogonal, typename TClientBehavior>
177TClientBehavior * ISmaccState::getClientBehavior(int index)
178{
179 return this->getStateMachine().getClientBehavior<TOrthogonal, TClientBehavior>(index);
180}
181
182template <typename TEventGenerator>
184{
185 TEventGenerator * ret = nullptr;
186 for (auto & evg : this->eventGenerators_)
187 {
188 ret = dynamic_cast<TEventGenerator *>(evg.get());
189 if (ret != nullptr) break;
190 }
191 return ret;
192}
193
194template <typename TStateReactor>
196{
197 TStateReactor * ret = nullptr;
198 for (auto & sr : this->eventGenerators_)
199 {
200 ret = dynamic_cast<TStateReactor *>(sr.get());
201 if (ret != nullptr) break;
202 }
203 return ret;
204}
205
206// template <typename TStateReactor, typename TTriggerEvent, typename... TEvArgs>
207// std::shared_ptr<TStateReactor> ISmaccState::createStateReactor(TEvArgs... args)
208// {
209// auto sb = std::make_shared<TStateReactor>(std::forward(args...));
210// sb->initialize(this, typelist<TEvArgs...>());
211// sb->setOutputEvent(typelist<TTriggerEvent>());
212// stateReactors_.push_back(sb);
213
214// return sb;
215// }
216//-------------------------------------------------------------------------------------------------------
217
218template <typename EventType>
219void ISmaccState::postEvent(const EventType & ev)
220{
222}
223
224template <typename EventType>
226{
227 getStateMachine().postEvent<EventType>();
228}
229//-------------------------------------------------------------------------------------------------------
230
231template <typename TransitionType>
233{
234 auto transitionType = TypeInfo::getTypeInfoFromType<TransitionType>();
235 this->notifyTransitionFromTransitionTypeInfo(transitionType);
236}
237
238//-------------------------------------------------------------------------------------------------------------------
239
240} // namespace smacc2
241
242// implementation depends on state definition
bool getGlobalSMData(std::string name, T &ret)
TClientBehavior * getClientBehavior(int index=0)
void setGlobalSMData(std::string name, T value)
const std::map< std::string, std::shared_ptr< smacc2::ISmaccOrthogonal > > & getOrthogonals() const
void requiresComponent(SmaccComponentType *&storage, bool throwsExceptionIfNotExist=false)
void postEvent(EventType *ev, EventLifeTime evlifetime=EventLifeTime::ABSOLUTE)
rclcpp::Logger getLogger()
Definition: smacc_state.hpp:36
TClientBehavior * getClientBehavior(int index=0)
std::shared_ptr< TEventGenerator > createEventGenerator(TEvArgs... args)
std::vector< std::shared_ptr< StateReactor > > stateReactors_
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