SMACC2
Loading...
Searching...
No Matches
smacc_orthogonal_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
22#include <cassert>
26
27namespace smacc2
28{
29template <typename SmaccClientType>
30bool ISmaccOrthogonal::requiresClient(SmaccClientType *& storage)
31{
32 for (auto & client : clients_)
33 {
34 storage = dynamic_cast<SmaccClientType *>(client.get());
35 if (storage != nullptr) return true;
36 }
37
38 auto requiredClientName = demangledTypeName<SmaccClientType>();
39 RCLCPP_WARN_STREAM(
40 getLogger(), "Required client ["
41 << requiredClientName
42 << "] not found in current orthogonal. Searching in other orthogonals.");
43
44 for (auto & orthoentry : this->getStateMachine()->getOrthogonals())
45 {
46 for (auto & client : orthoentry.second->getClients())
47 {
48 storage = dynamic_cast<SmaccClientType *>(client.get());
49 if (storage != nullptr)
50 {
51 RCLCPP_WARN_STREAM(
52 getLogger(),
53 "Required client [" << requiredClientName << "] found in other orthogonal.");
54 return true;
55 }
56 }
57 }
58
59 RCLCPP_ERROR_STREAM(
60 getLogger(), "Required client ["
61 << requiredClientName
62 << "] not found even in other orthogonals. Returning null pointer. If the "
63 "requested client is used may result in a segmentation fault.");
64 return false;
65}
66
67template <typename SmaccComponentType>
68void ISmaccOrthogonal::requiresComponent(SmaccComponentType *& storage)
69{
70 if (stateMachine_ == nullptr)
71 {
72 RCLCPP_ERROR(
73 getLogger(),
74 "Cannot use the requiresComponent funcionality from an orthogonal before onInitialize");
75 }
76 else
77 {
79 }
80}
81
82template <typename TOrthogonal, typename TClient>
84{
85 client->setStateMachine(getStateMachine());
86 client->setOrthogonal(this);
87
88 client->template onOrthogonalAllocation<TOrthogonal, TClient>();
89 client->template onStateOrthogonalAllocation<TOrthogonal, TClient>();
90}
91
92template <typename TClientBehavior>
93TClientBehavior * ISmaccOrthogonal::getClientBehavior(int index)
94{
95 int i = 0;
96 for (auto & cb : this->clientBehaviors_.back())
97 {
98 auto * ret = dynamic_cast<TClientBehavior *>(cb.get());
99 if (ret != nullptr)
100 {
101 if (i == index)
102 return ret;
103 else
104 i++;
105 }
106 }
107
108 return nullptr;
109}
110inline const std::vector<std::shared_ptr<smacc2::ISmaccClient>> & ISmaccOrthogonal::getClients()
111{
112 return clients_;
113}
114
115inline const std::vector<std::vector<std::shared_ptr<smacc2::ISmaccClientBehavior>>> &
117{
118 return this->clientBehaviors_;
119}
120
121template <typename T>
122void ISmaccOrthogonal::setGlobalSMData(std::string name, T value)
123{
124 this->getStateMachine()->setGlobalSMData(name, value);
125}
126
127template <typename T>
128bool ISmaccOrthogonal::getGlobalSMData(std::string name, T & ret)
129{
130 return this->getStateMachine()->getGlobalSMData(name, ret);
131}
132
133//inline
135
136template <typename TOrthogonal, typename TClient>
137class ClientHandler : public TClient
138{
139public:
140 template <typename... TArgs>
141 ClientHandler(TArgs... args) : TClient(args...)
142 {
143 }
144
146
147 template <typename SmaccComponentType, typename... TArgs>
148 SmaccComponentType * createComponent(TArgs... targs)
149 {
150 return ISmaccClient::createComponent<SmaccComponentType, TOrthogonal, TClient, TArgs...>(
151 targs...);
152 }
153
154 template <typename SmaccComponentType, typename... TArgs>
155 SmaccComponentType * createNamedComponent(std::string name, TArgs... targs)
156 {
157 return ISmaccClient::createNamedComponent<SmaccComponentType, TOrthogonal, TClient, TArgs...>(
158 name, targs...);
159 }
160
165};
166
167template <typename TOrthogonal>
169{
170public:
171 template <typename TClient, typename... TArgs>
172 std::shared_ptr<ClientHandler<TOrthogonal, TClient>> createClient(TArgs... args)
173 {
174 //static_assert(std::is_base_of<ISmaccOrthogonal, TOrthogonal>::value, "The object Tag must be the orthogonal type where the client was created");
175 // if (typeid(*this) != typeid(TOrthogonal))
176 // {
177 // RCLCPP_ERROR_STREAM(getLogger(),"Error creating client. The object Tag must be the type of the orthogonal where the client was created:" << demangleType(typeid(*this)) << ". The object creation was skipped and a nullptr was returned");
178 // return nullptr;
179 // }
180
181 RCLCPP_INFO(
182 getLogger(), "[%s] Creating client object, type:'%s' object tag: '%s'",
183 demangleType(typeid(*this)).c_str(), demangledTypeName<TClient>().c_str(),
185
186 auto client = std::make_shared<ClientHandler<TOrthogonal, TClient>>(args...);
187 this->template assignClientToOrthogonal<TOrthogonal, TClient>(client.get());
188
189 // Call the component initialization hook
190 TClient * clientPtr = static_cast<TClient *>(client.get());
191 clientPtr->template onComponentInitialization<TOrthogonal, TClient>();
192
193 // it is stored the client (not the client handler)
194 this->clients_.push_back(client);
195
196 return client;
197 }
198};
199} // namespace smacc2
smacc2::introspection::TypeInfo::Ptr getType() override
SmaccComponentType * createComponent(TArgs... targs)
SmaccComponentType * createNamedComponent(std::string name, TArgs... targs)
SmaccComponentType * createNamedComponent(std::string name, TArgs... targs)
SmaccComponentType * createComponent(TArgs... targs)
ISmaccStateMachine * getStateMachine()
void setGlobalSMData(std::string name, T value)
bool getGlobalSMData(std::string name, T &ret)
void requiresComponent(SmaccComponentType *&storage)
std::vector< std::shared_ptr< smacc2::ISmaccClient > > clients_
ISmaccStateMachine * stateMachine_
bool requiresClient(SmaccClientType *&storage)
void assignClientToOrthogonal(TClient *client)
std::vector< std::vector< std::shared_ptr< smacc2::ISmaccClientBehavior > > > clientBehaviors_
const std::vector< std::vector< std::shared_ptr< smacc2::ISmaccClientBehavior > > > & getClientBehaviors() const
TClientBehavior * getClientBehavior(int index=0)
const std::vector< std::shared_ptr< smacc2::ISmaccClient > > & getClients()
bool getGlobalSMData(std::string name, T &ret)
void setGlobalSMData(std::string name, T value)
void requiresComponent(SmaccComponentType *&storage, bool throwsExceptionIfNotExist=false)
std::shared_ptr< ClientHandler< TOrthogonal, TClient > > createClient(TArgs... args)
static TypeInfo::Ptr getTypeInfoFromType()
std::shared_ptr< TypeInfo > Ptr
std::string demangledTypeName()
std::string demangleType(const std::type_info *tinfo)