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 clientBehavior->template onStateOrthogonalAllocation<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 TOrthogonal, typename TClientBehavior>
178TClientBehavior * ISmaccState::getClientBehavior(int index)
179{
180 return this->getStateMachine().getClientBehavior<TOrthogonal, TClientBehavior>(index);
181}
182
183template <typename TEventGenerator>
185{
186 TEventGenerator * ret = nullptr;
187 for (auto & evg : this->eventGenerators_)
188 {
189 ret = dynamic_cast<TEventGenerator *>(evg.get());
190 if (ret != nullptr) break;
191 }
192 return ret;
193}
194
195template <typename TStateReactor>
197{
198 TStateReactor * ret = nullptr;
199 for (auto & sr : this->eventGenerators_)
200 {
201 ret = dynamic_cast<TStateReactor *>(sr.get());
202 if (ret != nullptr) break;
203 }
204 return ret;
205}
206
207// template <typename TStateReactor, typename TTriggerEvent, typename... TEvArgs>
208// std::shared_ptr<TStateReactor> ISmaccState::createStateReactor(TEvArgs... args)
209// {
210// auto sb = std::make_shared<TStateReactor>(std::forward(args...));
211// sb->initialize(this, typelist<TEvArgs...>());
212// sb->setOutputEvent(typelist<TTriggerEvent>());
213// stateReactors_.push_back(sb);
214
215// return sb;
216// }
217//-------------------------------------------------------------------------------------------------------
218
219template <typename EventType>
220void ISmaccState::postEvent(const EventType & ev)
221{
223}
224
225template <typename EventType>
227{
228 getStateMachine().postEvent<EventType>();
229}
230//-------------------------------------------------------------------------------------------------------
231
232template <typename TransitionType>
238
239//-------------------------------------------------------------------------------------------------------------------
240
241} // namespace smacc2
242
243// 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()
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)
static TypeInfo::Ptr getTypeInfoFromType()
std::enable_if< HasEventLabel< T >::value, void >::type EventLabel(std::string &label)
std::string demangleSymbol()
std::string demangledTypeName()
#define THIS_STATE_NAME
smacc2::SmaccStateReactorInfo * srInfo_
AddTEventTypeStateReactorInfo(smacc2::SmaccStateReactorInfo *srInfo)
AddTEventTypeStateReactor(smacc2::StateReactor *sr)
std::vector< std::shared_ptr< SmaccEventInfo > > sourceEventTypes