RTC Toolkit 4.0.1
Loading...
Searching...
No Matches
stdComponent.hpp
Go to the documentation of this file.
1
13#ifndef RTCTK_COMPONENTFRAMEWORK_STDCOMPONENT_HPP
14#define RTCTK_COMPONENTFRAMEWORK_STDCOMPONENT_HPP
15
17#include <rtctk/componentFramework/events.rad.hpp>
27
28#include <mal/Cii.hpp>
29
30#include <memory>
31#include <string>
32
34
38class LogInfo : public stdif::LogInfo {
39public:
40 LogInfo() = default;
41
42 explicit LogInfo(std::string const& level, std::string const& logger = "")
43 : m_logger(logger), m_level(level) {
44 }
45
46 std::string getLogger() const override {
47 return m_logger;
48 }
49
50 void setLogger(std::string const& logger) override {
51 m_logger = logger;
52 }
53
54 std::string getLevel() const override {
55 return m_level;
56 }
57
58 void setLevel(std::string const& level) override {
59 m_level = level;
60 }
61
62 bool hasKey() const override {
63 return false;
64 }
65
66 bool keyEquals(stdif::LogInfo const& other) const override {
67 return false;
68 }
69
70 std::unique_ptr<stdif::LogInfo> clone() const override {
71 return std::make_unique<LogInfo>(m_logger, m_level);
72 }
73
74 std::unique_ptr<stdif::LogInfo> cloneKey() const override {
75 return std::make_unique<LogInfo>(m_logger, m_level);
76 }
77
78private:
79 std::string m_logger;
80 std::string m_level;
81};
82
84
85// this we reply over MAL for commands that succeeds
86inline const std::string STD_OK_REPLY = "OK";
87
89
90// High level exception types returned via MAL
91
96class StdIfRequestAborted : public stdif::ExceptionErr {
97public:
98 static constexpr int32_t ERROR_CODE = 11;
99 StdIfRequestAborted() : stdif::ExceptionErr("Request aborted.", ERROR_CODE) {
100 }
101};
102
107class StdIfRequestRejected : public stdif::ExceptionErr {
108public:
112 static constexpr int32_t ERROR_CODE = 10;
113 StdIfRequestRejected(std::string const& request_id, std::string const& state_id)
114 : stdif::ExceptionErr("Request " + request_id + " rejected in state " + state_id,
115 ERROR_CODE) {
116 }
117};
118
123class StdIfRequestFailed : public stdif::ExceptionErr {
124public:
128 static constexpr int32_t ERROR_CODE = 501;
129 explicit StdIfRequestFailed(std::string const& message)
130 : stdif::ExceptionErr(message, ERROR_CODE) {
131 }
132};
133
149 public:
150 virtual void ActivityStarting(StopToken st){};
154 };
155
160 public:
162 : m_replier(replier), m_engine(engine) {
163 }
164
165 virtual ~InputStage() = default;
166
167 virtual void Start() {
168 // exit event is used by SIGTERM, SIGINT and SIGHUP
169 m_engine.RegisterExitEvent(std::make_unique<events::Exit>());
170 // stdif MAL commands
173 }
174
175 protected:
178 };
179
184 public:
186 // Handlers ###################################################################
187
188 engine.RegisterRejectHandler<events::Init, StdIfRequestRejected>();
189 engine.RegisterRejectHandler<events::Stop, StdIfRequestRejected>();
190 engine.RegisterRejectHandler<events::Reset, StdIfRequestRejected>();
191 engine.RegisterRejectHandler<events::Enable, StdIfRequestRejected>();
192 engine.RegisterRejectHandler<events::Disable, StdIfRequestRejected>();
193 engine.RegisterRejectHandler<events::GetState, StdIfRequestRejected>();
194 engine.RegisterRejectHandler<events::Exit, StdIfRequestRejected>();
195
196 m_success_handler = [this] { m_engine.PostEvent(std::make_unique<events::Done>()); };
197
198 m_error_handler = [this](std::exception_ptr eptr) {
199 m_engine.PostEvent(std::make_unique<events::Error>(std::move(eptr)));
200 };
201
202 // Reset ######################################################################
203
204 engine.RegisterAction("ActionStartingEntry", [this](auto c) {
205 m_tmp_request = GetPayloadNothrow<events::Reset>(c);
206 });
207
208 engine.RegisterAction("ActionStartingDone", [this](auto c) {
209 if (m_tmp_request) {
210 m_tmp_request->SetReplyValue(STD_OK_REPLY);
211 m_tmp_request = nullptr;
212 }
213 });
214
215 // Init ######################################################################
216
217 engine.RegisterAction("ActionInitialisingEntry", [this](auto c) {
218 m_tmp_request = GetPayloadNothrow<events::Init>(c);
219 });
220
221 engine.RegisterAction("ActionInitialisingDone", [this](auto c) {
222 if (m_tmp_request) {
223 m_tmp_request->SetReplyValue(STD_OK_REPLY);
224 m_tmp_request = nullptr;
225 }
226 });
227
228 engine.RegisterAction("ActionInitialisingFailed", [this](auto c) {
229 if (auto eptr = GetPayloadNothrow<events::Error>(c); eptr) {
230 if (m_tmp_request) {
231 m_tmp_request->SetException(
233 m_tmp_request = nullptr;
234 }
235 }
236 });
237
238 engine.RegisterAction("ActionInitialisingStopped", [this](auto c) {
239 auto req = GetPayloadNothrow<events::Stop>(c);
240 if (req == nullptr) {
241 // no event or request
242 return;
243 }
244 if (m_tmp_request) {
245 m_tmp_request->SetException(StdIfRequestAborted());
246 m_tmp_request = nullptr;
247 }
248 req->SetReplyValue(STD_OK_REPLY);
249 });
250
251 engine.RegisterAction("ActionInitialisingRestarted", [this](auto c) {
252 auto req = GetPayloadNothrow<events::Init>(c);
253 if (req == nullptr) {
254 // no event or request
255 return;
256 }
257 if (m_tmp_request) {
258 m_tmp_request->SetException(StdIfRequestAborted());
259 m_tmp_request = nullptr;
260 }
261 m_tmp_request = req;
262 });
263
264 // Enable ######################################################################
265
266 engine.RegisterAction("ActionEnablingEntry", [this](auto c) {
267 m_tmp_request = GetPayloadNothrow<events::Enable>(c);
268 });
269
270 engine.RegisterAction("ActionEnablingDone", [this](auto c) {
271 if (m_tmp_request) {
272 m_tmp_request->SetReplyValue(STD_OK_REPLY);
273 m_tmp_request = nullptr;
274 }
275 });
276
277 engine.RegisterAction("ActionEnablingFailed", [this](auto c) {
278 if (auto eptr = GetPayloadNothrow<events::Error>(c); eptr) {
279 if (m_tmp_request) {
280 m_tmp_request->SetException(
282 m_tmp_request = nullptr;
283 }
284 }
285 });
286
287 // Disable #####################################################################
288
289 engine.RegisterAction("ActionDisablingEntry", [this](auto c) {
290 m_tmp_request = GetPayloadNothrow<events::Disable>(c);
291 });
292
293 engine.RegisterAction("ActionDisablingDone", [this](auto c) {
294 if (m_tmp_request) {
295 m_tmp_request->SetReplyValue(STD_OK_REPLY);
296 m_tmp_request = nullptr;
297 }
298 });
299
300 engine.RegisterAction("ActionDisablingFailed", [this](auto c) {
301 if (auto eptr = GetPayloadNothrow<events::Error>(c); eptr) {
302 if (m_tmp_request) {
303 m_tmp_request->SetException(
305 m_tmp_request = nullptr;
306 }
307 }
308 });
309
310 // Exit #####################################################################
311
312 engine.RegisterAction("ActionExit", [this](auto c) {
313 auto req = GetPayloadNothrow<events::Exit>(c);
314 if (req == nullptr) {
315 // no event or request
316 return;
317 }
318 req->SetReplyValue(STD_OK_REPLY);
319 m_engine.Stop();
320 });
321
322 // GetState #####################################################################
323
324 engine.RegisterAction("ActionGetState", [this](auto c) {
325 auto req = GetPayloadNothrow<events::GetState>(c);
326 if (req == nullptr) {
327 // no event or request
328 return;
329 }
330 req->SetReplyValue(m_engine.GetState());
331 });
332
333 // GetStatus #####################################################################
334
335 engine.RegisterAction("ActionGetStatus", [this](auto c) {
336 auto req = GetPayloadNothrow<events::GetStatus>(c);
337 if (req == nullptr) {
338 // no event or request
339 return;
340 }
341 req->SetReplyValue(m_engine.GetState());
342 });
343
344 // GetVersion #####################################################################
345
346 engine.RegisterAction("ActionGetVersion", [this](auto c) {
347 auto req = GetPayloadNothrow<events::GetVersion>(c);
348 if (req == nullptr) {
349 // no event or request
350 return;
351 }
352 req->SetReplyValue(VERSION);
353 });
354
355 // SetLogLevel #####################################################################
356
357 engine.RegisterAction("ActionSetLogLevel", [this](auto c) {
358 auto req = GetPayloadNothrow<events::SetLogLevel>(c);
359 if (req == nullptr) {
360 // no event or request
361 return;
362 }
363 auto loginfo = req->GetRequestPayload();
364 auto selected_logger = loginfo->getLogger();
365 auto& logger = GetLogger(selected_logger);
366 log4cplus::LogLevelManager llm;
367 auto selected_ll = llm.fromString(loginfo->getLevel());
368 if (selected_ll == log4cplus::NOT_SET_LOG_LEVEL) {
369 req->SetException(StdIfRequestFailed("Invalid LogLevel specified"));
370 } else {
371 logger.setLogLevel(selected_ll);
372 LOG4CPLUS_INFO(GetLogger("rtctk"),
373 "Log Level of logger '" << loginfo->getLogger() << "' set to '"
374 << llm.toString(logger.getLogLevel())
375 << "'");
376 req->SetReplyValue(STD_OK_REPLY);
377 }
378 });
379
380 // Activities #####################################################################
381
383 "ActivityStarting",
384 [this](StopToken stop_token) { m_logic.ActivityStarting(stop_token); },
387
389 "ActivityInitialising",
390 [this](StopToken stop_token) { m_logic.ActivityInitialising(stop_token); },
393
395 "ActivityEnabling",
396 [this](StopToken stop_token) { m_logic.ActivityEnabling(stop_token); },
399
401 "ActivityDisabling",
402 [this](StopToken stop_token) { m_logic.ActivityDisabling(stop_token); },
405 }
406
407 virtual ~OutputStage() = default;
408
409 protected:
412 std::shared_ptr<rad::cii::Request<std::string, void>> m_tmp_request;
413 std::function<void()> m_success_handler;
414 std::function<void(std::exception_ptr)> m_error_handler;
415 };
416
421 public:
423 // clang-format off
424 mm.AddState(Initial, "Initial");
425 mm.AddState(Parallel, "On");
426 mm.AddState(Final, "Off");
427
428 mm.AddState(Composite, "On:", "On");
429 mm.AddState(Initial, "On::Initial", "On:");
430 mm.AddState(Composite, "On::NotOperational", "On:");
431 mm.AddState(Simple, "On::Operational", "On:");
432
433 mm.AddState(Initial, "On::NotOperational::Initial", "On::NotOperational");
434 mm.AddState(Simple, "On::NotOperational::NotReady", "On::NotOperational");
435 mm.AddState(Simple, "On::NotOperational::Ready", "On::NotOperational");
436
437 mm.AddTrans("Initial" , "On");
438 mm.AddTrans("On" , "Off" , "events.Exit", "" ,"ActionExit");
439 mm.AddTrans("On" , "" , "events.GetState", "" ,"ActionGetState");
440 mm.AddTrans("On" , "" , "events.GetStatus", "" ,"ActionGetStatus");
441 mm.AddTrans("On" , "" , "events.GetVersion", "" ,"ActionGetVersion");
442 mm.AddTrans("On" , "" , "events.SetLogLevel","" ,"ActionSetLogLevel");
443 mm.AddTrans("On" , "On" , "events.Reset");
444 mm.AddTrans("On::Initial" , "On::NotOperational");
445
446 mm.AddState(Simple, "On::NotOperational::Starting", "On::NotOperational", "ActivityStarting" ,"ActionStartingEntry");
447
448 mm.AddTrans("On::NotOperational::Initial" , "On::NotOperational::Starting");
449 mm.AddTrans("On::NotOperational::Starting" , "On::NotOperational::NotReady" , "events.Done", "" ,"ActionStartingDone");
450
451 mm.AddState(Simple, "On::NotOperational::Initialising", "On::NotOperational", "ActivityInitialising" ,"ActionInitialisingEntry");
452
453 mm.AddTrans("On::NotOperational::NotReady" , "On::NotOperational::Initialising" , "events.Init");
454 mm.AddTrans("On::NotOperational::Initialising" , "On::NotOperational::Ready" , "events.Done", "" ,"ActionInitialisingDone");
455 mm.AddTrans("On::NotOperational::Initialising" , "On::NotOperational::NotReady" , "events.Error", "" ,"ActionInitialisingFailed");
456 mm.AddTrans("On::NotOperational::Initialising" , "On::NotOperational::NotReady" , "events.Stop", "" ,"ActionInitialisingStopped");
457 mm.AddTrans("On::NotOperational::Initialising" , "On::NotOperational::Initialising" , "events.Init", "" ,"ActionInitialisingRestarted");
458 mm.AddTrans("On::NotOperational::Ready" , "On::NotOperational::Initialising" , "events.Init");
459
460 mm.AddState(Simple, "On::NotOperational::Enabling", "On::NotOperational", "ActivityEnabling" ,"ActionEnablingEntry");
461
462 mm.AddTrans("On::NotOperational::Ready" , "On::NotOperational::Enabling" , "events.Enable");
463 mm.AddTrans("On::NotOperational::Enabling" , "On::Operational" , "events.Done", "" ,"ActionEnablingDone");
464 mm.AddTrans("On::NotOperational::Enabling" , "On::NotOperational::Ready" , "events.Error", "" ,"ActionEnablingFailed");
465 // TODO, do we want enabling to be stopable?
466 //mm.AddTrans("On::NotOperational::Enabling" , "On::NotOperational::Ready" , "events.Stop" );
467
468 mm.AddState(Simple, "On::NotOperational::Disabling", "On::NotOperational", "ActivityDisabling" ,"ActionDisablingEntry");
469 mm.AddTrans("On::Operational" , "On::NotOperational::Disabling" , "events.Disable");
470 mm.AddTrans("On::NotOperational::Disabling" , "On::NotOperational::Ready" , "events.Done", "" ,"ActionDisablingDone");
471 mm.AddTrans("On::NotOperational::Disabling" , "On::NotOperational::Ready" , "events.Error", "" ,"ActionDisablingFailed");
472 // clang-format on
473 }
474 };
475};
476
477} // namespace rtctk::componentFramework
478
479#endif // RTCTK_COMPONENTFRAMEWORK_STDCOMPONENT_HPP
Class that handles reception of commands using MAL.
Definition: commandReplier.hpp:29
static void Register(CommandReplier &replier, StateMachineEngine &engine)
Definition: introspectionImpl.hpp:39
Definition: stdComponent.hpp:38
std::string getLevel() const override
Definition: stdComponent.hpp:54
std::unique_ptr< stdif::LogInfo > cloneKey() const override
Definition: stdComponent.hpp:74
std::string getLogger() const override
Definition: stdComponent.hpp:46
bool hasKey() const override
Definition: stdComponent.hpp:62
std::unique_ptr< stdif::LogInfo > clone() const override
Definition: stdComponent.hpp:70
bool keyEquals(stdif::LogInfo const &other) const override
Definition: stdComponent.hpp:66
LogInfo(std::string const &level, std::string const &logger="")
Definition: stdComponent.hpp:42
void setLevel(std::string const &level) override
Definition: stdComponent.hpp:58
void setLogger(std::string const &logger) override
Definition: stdComponent.hpp:50
Base class of the ModelBuilder.
Definition: modelBuilderBase.hpp:35
ModelManipulator mm
Definition: modelBuilderBase.hpp:79
void AddTrans(std::string const &source_id, std::string const &target_id, std::string const &event_id="", std::string const &guard_id="", std::string const &action_id="")
Adds a new transition.
Definition: modelManipulator.cpp:229
void AddState(StateType type, std::string const &id, std::string const &parent_id="", std::string const &activity_id="", std::string const &entry_action_id="", std::string const &exit_action_id="")
Adds a new state.
Definition: modelManipulator.cpp:30
Adapter object intended to be used in contexts without direct access to the output-stream object.
Definition: exceptions.hpp:185
std::string Str() const
Convenience function for constructing a std::string from the exception.
Definition: exceptions.hpp:203
Definition: stateMachineEngine.hpp:35
void RegisterRejectHandler(std::string const &id, RejectMethod reject)
Register reject handler.
Definition: stateMachineEngine.cpp:131
void RegisterActivity(std::string const &id, ActivityMethod activity, SuccessMethod on_success, FailureMethod on_failure)
Register activity.
Definition: stateMachineEngine.cpp:123
void RegisterExitEvent(rad::UniqueEvent exit_event)
Register an exit event.
Definition: stateMachineEngine.cpp:69
std::string GetState()
Queries the current state.
Definition: stateMachineEngine.cpp:153
void RegisterAction(std::string const &id, ActionMethod action)
Register action.
Definition: stateMachineEngine.cpp:86
void Stop()
Stops execution of the state machine event loop.
Definition: stateMachineEngine.cpp:191
void PostEvent(rad::SharedEvent s)
Injects a new event into the state machine engine.
Definition: stateMachineEngine.cpp:148
static void Register(CommandReplier &replier, StateMachineEngine &engine)
Definition: stdCmdsImpl.hpp:37
virtual void ActivityInitialising(StopToken)
Definition: stdComponent.hpp:151
virtual void ActivityEnabling(StopToken)
Definition: stdComponent.hpp:152
virtual void ActivityStarting(StopToken st)
Definition: stdComponent.hpp:150
virtual void ActivityDisabling(StopToken)
Definition: stdComponent.hpp:153
CommandReplier & m_replier
Definition: stdComponent.hpp:176
virtual void Start()
Definition: stdComponent.hpp:167
StateMachineEngine & m_engine
Definition: stdComponent.hpp:177
InputStage(CommandReplier &replier, StateMachineEngine &engine)
Definition: stdComponent.hpp:161
ModelBuilder(StateMachineEngine &engine)
Definition: stdComponent.hpp:422
std::function< void()> m_success_handler
Definition: stdComponent.hpp:413
OutputStage(StateMachineEngine &engine, BizLogicIf &bl)
Definition: stdComponent.hpp:185
StateMachineEngine & m_engine
Definition: stdComponent.hpp:410
std::function< void(std::exception_ptr)> m_error_handler
Definition: stdComponent.hpp:414
BizLogicIf & m_logic
Definition: stdComponent.hpp:411
std::shared_ptr< rad::cii::Request< std::string, void > > m_tmp_request
Definition: stdComponent.hpp:412
Thrown if somebody sent a stop or abort command.
Definition: stdComponent.hpp:96
static constexpr int32_t ERROR_CODE
Definition: stdComponent.hpp:98
StdIfRequestAborted()
Definition: stdComponent.hpp:99
Thrown if the command was accepted but the task to run failed.
Definition: stdComponent.hpp:123
StdIfRequestFailed(std::string const &message)
Definition: stdComponent.hpp:129
static constexpr int32_t ERROR_CODE
Definition: stdComponent.hpp:128
Thrown if the command is not allowed in current state or guard.
Definition: stdComponent.hpp:107
StdIfRequestRejected(std::string const &request_id, std::string const &state_id)
Definition: stdComponent.hpp:113
static constexpr int32_t ERROR_CODE
Definition: stdComponent.hpp:112
Receive commands via MAL.
Provides macros and utilities for exception handling.
log4cplus::Logger & GetLogger(const std::string &name="app")
Get handle to a specific logger.
Definition: logger.cpp:180
Implementation of MAL commands for layer 'IntrospectionIf'.
Logging Support Library based on log4cplus.
Base class of the ModelBuilder.
Definition: commandReplier.cpp:22
const std::string STD_OK_REPLY
Definition: stdComponent.hpp:86
rad::StopToken StopToken
Definition: stopToken.hpp:20
@ Simple
Definition: model.hpp:22
@ Composite
Definition: model.hpp:22
@ Parallel
Definition: model.hpp:22
@ Final
Definition: model.hpp:22
@ Initial
Definition: model.hpp:22
Definition: statePublisher.hpp:25
A container that can hold any type of service.
Wrapper around the SCXML State Machine Engine.
Implementation of MAL commands for layer 'StdComponent'.
A simple Stop Token.
Basic life cycle for StdComponent.
Definition: stdComponent.hpp:144
Various utilities for Life Cycle Extension.