add timeout transition

This commit is contained in:
2024-07-28 20:16:52 +03:00
parent abdba6d68b
commit f07c9cbce8
5 changed files with 75 additions and 6 deletions

View File

@@ -72,7 +72,10 @@ FunctionBase * makeFunction(std::function<Ret(Args...)> func) {
} // namespace PIStateMachineHelpers } // namespace PIStateMachineHelpers
class PITransitionBase; class PITransitionBase;
class PITransitionTimeout;
class PIStateBase; class PIStateBase;
class PIStateLambda;
class PIStateFinal;
class PIStateMachine; class PIStateMachine;

View File

@@ -23,8 +23,8 @@
PIStateBase::~PIStateBase() { PIStateBase::~PIStateBase() {
piDeleteAll(children);
piDeleteAll(transitions); piDeleteAll(transitions);
piDeleteAll(children);
} }
@@ -76,9 +76,21 @@ PITransitionBase * PIStateBase::addTransition(PIStateBase * target, int event_id
} }
PITransitionTimeout * PIStateBase::addTimeoutTransition(PIStateBase * target, PISystemTime timeout) {
PITransitionTimeout * ret = new PITransitionTimeout(this, target, timeout);
ret->root = root;
transitions << ret;
return ret;
}
void PIStateBase::print(PIString prefix) { void PIStateBase::print(PIString prefix) {
PICout(PICoutManipulators::AddNewLine) << prefix << "[" << (isActive() ? "*" : " ") << "] " << getName() << " active " auto ac = activeChildren();
<< activeChildren(); PICout(PICoutManipulators::AddNone) << prefix << "[" << (isActive() ? "*" : " ") << "] \"" << getName() << "\"";
if (ac.isNotEmpty())
piCout << ", active" << activeChildren();
else
piCout << "";
prefix += " "; prefix += " ";
for (auto * c: children) for (auto * c: children)
c->print(prefix); c->print(prefix);
@@ -86,6 +98,7 @@ void PIStateBase::print(PIString prefix) {
bool PIStateBase::start() { bool PIStateBase::start() {
if (isActive()) return true;
if (isAtomic()) { if (isAtomic()) {
setActive(true); setActive(true);
return true; return true;
@@ -94,8 +107,10 @@ bool PIStateBase::start() {
if (initial_state) { if (initial_state) {
setActive(true); setActive(true);
return initial_state->start(); return initial_state->start();
} else } else {
piCout << "error:" << getName() << "no initial state!"; piCout << "error:" << getName() << "no initial state!";
return false;
}
} else { } else {
setActive(true); setActive(true);
for (auto * s: children) { for (auto * s: children) {
@@ -114,12 +129,16 @@ void PIStateBase::setActive(bool yes) {
if (parent_state && yes) parent_state->childActived(this); if (parent_state && yes) parent_state->childActived(this);
if (!prev_active && is_active) { if (!prev_active && is_active) {
onEnter(); onEnter();
for (auto * t: transitions)
t->enabled();
// if (isParallel()) setChildrenActive(true); // if (isParallel()) setChildrenActive(true);
} }
if (prev_active && !is_active) { if (prev_active && !is_active) {
active_state = nullptr; active_state = nullptr;
if (isParallel()) setChildrenActiveRecursive(false); if (isParallel()) setChildrenActiveRecursive(false);
onExit(); onExit();
for (auto * t: transitions)
t->disabled();
} }
} }

View File

@@ -28,6 +28,7 @@
#include "pistatemachine_base.h" #include "pistatemachine_base.h"
#include "pistring.h" #include "pistring.h"
#include "pisystemtime.h"
//! \ingroup StateMachine //! \ingroup StateMachine
@@ -57,6 +58,7 @@ public:
void setInitialState(PIStateBase * s); void setInitialState(PIStateBase * s);
PITransitionBase * addTransition(PIStateBase * target, int event_id); PITransitionBase * addTransition(PIStateBase * target, int event_id);
PITransitionTimeout * addTimeoutTransition(PIStateBase * target, PISystemTime timeout);
void setParallel(bool yes) { is_parallel = yes; } void setParallel(bool yes) { is_parallel = yes; }
@@ -132,7 +134,7 @@ inline PICout operator<<(PICout c, PIStateBase * s) {
if (!s) if (!s)
c << "state(nullptr)"; c << "state(nullptr)";
else else
c << ("state(" + s->getName() + ")"); c << ("state(\"" + s->getName() + "\")");
return c; return c;
} }

View File

@@ -69,6 +69,7 @@ void PITransitionBase::trigger() {
// piCout << "common" << common_count; // piCout << "common" << common_count;
source_path.remove(source_path.size_s() - common_count, common_count); source_path.remove(source_path.size_s() - common_count, common_count);
target_path.remove(target_path.size_s() - common_count, common_count); target_path.remove(target_path.size_s() - common_count, common_count);
// piCout << "source_target_path" << source_target_path;
// piCout << "source_path" << source_path; // piCout << "source_path" << source_path;
// piCout << "target_path" << target_path; // piCout << "target_path" << target_path;
// piCout << "source_state before" << source_state; // piCout << "source_state before" << source_state;
@@ -92,3 +93,30 @@ void PITransitionBase::trigger() {
} }
if (target_state->isCompound()) target_state->start(); if (target_state->isCompound()) target_state->start();
} }
// PITransitionTimeout
PITransitionTimeout::PITransitionTimeout(PIStateBase * source, PIStateBase * target, PISystemTime timeout)
: PITransitionBase(source, target, 0) {
timer.setInterval(timeout);
timer.setSlot([this] {
trigger();
timer.stopLater();
});
}
PITransitionTimeout::~PITransitionTimeout() {
timer.stop();
}
void PITransitionTimeout::enabled() {
timer.start();
}
void PITransitionTimeout::disabled() {
timer.stopLater();
}

View File

@@ -27,6 +27,7 @@
#define pistatemachine_transition_H #define pistatemachine_transition_H
#include "pistatemachine_base.h" #include "pistatemachine_base.h"
#include "pitimer.h"
//! \ingroup StateMachine //! \ingroup StateMachine
@@ -39,7 +40,7 @@ class PIP_EXPORT PITransitionBase {
public: public:
PITransitionBase(PIStateBase * source, PIStateBase * target, int event_id); PITransitionBase(PIStateBase * source, PIStateBase * target, int event_id);
~PITransitionBase(); virtual ~PITransitionBase();
PIStateMachine * machine() const { return root; } PIStateMachine * machine() const { return root; }
PIStateBase * source() const { return source_state; } PIStateBase * source() const { return source_state; }
@@ -74,6 +75,9 @@ public:
void trigger(); void trigger();
protected: protected:
virtual void enabled() {}
virtual void disabled() {}
int eventID = 0; int eventID = 0;
PIStateBase *source_state = nullptr, *target_state = nullptr; PIStateBase *source_state = nullptr, *target_state = nullptr;
PIStateMachine * root = nullptr; PIStateMachine * root = nullptr;
@@ -81,4 +85,17 @@ protected:
std::function<void()> action; std::function<void()> action;
}; };
class PIP_EXPORT PITransitionTimeout: public PITransitionBase {
public:
PITransitionTimeout(PIStateBase * source, PIStateBase * target, PISystemTime timeout);
~PITransitionTimeout();
private:
void enabled() override;
void disabled() override;
PITimer timer;
};
#endif #endif