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