SMACC
Loading...
Searching...
No Matches
smacc_orthogonal_impl.h
Go to the documentation of this file.
1/*****************************************************************************************************************
2 * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018
3 * Authors: Pablo Inigo Blasco, Brett Aldrich
4 *
5 ******************************************************************************************************************/
6
7#pragma once
10#include <cassert>
11
12namespace smacc
13{
14
15template <typename SmaccClientType>
16bool ISmaccOrthogonal::requiresClient(SmaccClientType *&storage)
17{
18 for (auto &client : clients_)
19 {
20 storage = dynamic_cast<SmaccClientType *>(client.get());
21 if (storage != nullptr)
22 return true;
23 }
24
25 auto requiredClientName = demangledTypeName<SmaccClientType>();
26 ROS_WARN_STREAM("Required client ["<< requiredClientName<< "] not found in current orthogonal. Searching in other orthogonals.");
27
28 for (auto &orthoentry : this->getStateMachine()->getOrthogonals())
29 {
30 for (auto &client : orthoentry.second->getClients())
31 {
32 storage = dynamic_cast<SmaccClientType *>(client.get());
33 if (storage != nullptr)
34 {
35 ROS_WARN_STREAM("Required client ["<< requiredClientName<<"] found in other orthogonal.");
36 return true;
37 }
38 }
39 }
40
41 ROS_ERROR_STREAM("Required client ["<< requiredClientName<< "] not found even in other orthogonals. Returning null pointer. If the requested client is used may result in a segmentation fault.");
42 return false;
43}
44
45template <typename SmaccComponentType>
46void ISmaccOrthogonal::requiresComponent(SmaccComponentType *&storage)
47{
48 if (stateMachine_ == nullptr)
49 {
50 ROS_ERROR("Cannot use the requiresComponent funcionality from an orthogonal before onInitialize");
51 }
52 else
53 {
55 }
56}
57
58template <typename TOrthogonal, typename TClient>
60{
61 client->setStateMachine(getStateMachine());
62 client->setOrthogonal(this);
63
64 client->template onOrthogonalAllocation<TOrthogonal, TClient>();
65}
66
67template <typename TClientBehavior>
69{
70 for (auto &cb : this->clientBehaviors_.back())
71 {
72 auto *ret = dynamic_cast<TClientBehavior *>(cb.get());
73 if (ret != nullptr)
74 {
75 return ret;
76 }
77 }
78
79 return nullptr;
80}
81
82inline const std::vector<std::shared_ptr<smacc::ISmaccClient>> &ISmaccOrthogonal::getClients()
83{
84 return clients_;
85}
86
87inline const std::vector<std::vector<std::shared_ptr<smacc::ISmaccClientBehavior>>> &ISmaccOrthogonal::getClientBehaviors() const
88{
89 return this->clientBehaviors_;
90}
91
92template <typename T>
93void ISmaccOrthogonal::setGlobalSMData(std::string name, T value)
94{
95 this->getStateMachine()->setGlobalSMData(name, value);
96}
97
98template <typename T>
99bool ISmaccOrthogonal::getGlobalSMData(std::string name, T &ret)
100{
101 return this->getStateMachine()->getGlobalSMData(name, ret);
102}
103
104//inline
106
107template <typename TOrthogonal, typename TClient>
108class ClientHandler : public TClient
109{
110public:
111 template <typename... TArgs>
112 ClientHandler(TArgs... args)
113 : TClient(args...)
114 {
115 }
116
118 : TClient()
119 {
120 }
121
122 template <typename SmaccComponentType, typename... TArgs>
123 SmaccComponentType *createComponent(TArgs... targs)
124 {
125 return ISmaccClient::createComponent<SmaccComponentType, TOrthogonal, TClient, TArgs...>(targs...);
126 }
127
128 template <typename SmaccComponentType, typename... TArgs>
129 SmaccComponentType *createNamedComponent(std::string name, TArgs... targs)
130 {
131 return ISmaccClient::createNamedComponent<SmaccComponentType, TOrthogonal, TClient, TArgs...>(name, targs...);
132 }
133
135 {
136 return smacc::introspection::TypeInfo::getTypeInfoFromType<TClient>();
137 }
138};
139
140template <typename TOrthogonal>
142{
143public:
144 template <typename TClient, typename... TArgs>
145 std::shared_ptr<ClientHandler<TOrthogonal, TClient>> createClient(TArgs... args)
146 {
147 //static_assert(std::is_base_of<ISmaccOrthogonal, TOrthogonal>::value, "The object Tag must be the orthogonal type where the client was created");
148 // if (typeid(*this) != typeid(TOrthogonal))
149 // {
150 // ROS_ERROR_STREAM("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");
151 // return nullptr;
152 // }
153
154 ROS_INFO("[%s] creates a client of type '%s' and object tag '%s'",
155 demangleType(typeid(*this)).c_str(),
156 demangledTypeName<TClient>().c_str(),
157 demangledTypeName<TOrthogonal>().c_str()
158 );
159
160 auto client = std::make_shared<ClientHandler<TOrthogonal, TClient>>(args...);
161 this->template assignClientToOrthogonal<TOrthogonal, TClient>(client.get());
162
163 // it is stored the client (not the client handler)
164 clients_.push_back(client);
165
166 return client;
167 }
168};
169}; // namespace smacc
virtual smacc::introspection::TypeInfo::Ptr getType() override
SmaccComponentType * createNamedComponent(std::string name, TArgs... targs)
SmaccComponentType * createComponent(TArgs... targs)
SmaccComponentType * createComponent(TArgs... targs)
SmaccComponentType * createNamedComponent(std::string name, TArgs... targs)
std::vector< std::shared_ptr< smacc::ISmaccClient > > clients_
void assignClientToOrthogonal(TClient *client)
void setGlobalSMData(std::string name, T value)
void requiresComponent(SmaccComponentType *&storage)
ISmaccStateMachine * stateMachine_
TClientBehavior * getClientBehavior()
bool requiresClient(SmaccClientType *&storage)
const std::vector< std::vector< std::shared_ptr< smacc::ISmaccClientBehavior > > > & getClientBehaviors() const
const std::vector< std::shared_ptr< smacc::ISmaccClient > > & getClients()
std::vector< std::vector< std::shared_ptr< smacc::ISmaccClientBehavior > > > clientBehaviors_
bool getGlobalSMData(std::string name, T &ret)
ISmaccStateMachine * getStateMachine()
void setGlobalSMData(std::string name, T value)
void requiresComponent(SmaccComponentType *&storage)
bool getGlobalSMData(std::string name, T &ret)
std::shared_ptr< ClientHandler< TOrthogonal, TClient > > createClient(TArgs... args)
std::shared_ptr< TypeInfo > Ptr
std::string demangleType(const std::type_info *tinfo)
Definition: introspection.h:86