2 次代码提交 fc1e35578b ... c9aebf88ae

作者 SHA1 备注 提交日期
  Eric Ramat c9aebf88ae Add event data in guard parameter list 1 年之前
  Eric Ramat 54b32b2413 Add macro 1 年之前
共有 2 个文件被更改,包括 82 次插入5 次删除
  1. 12 0
      src/utils/RootStateMachine.hpp
  2. 70 5
      src/utils/StateMachine.hpp

+ 12 - 0
src/utils/RootStateMachine.hpp

@@ -176,4 +176,16 @@ private:
 
 }
 
+#define DEFINE_ROOT_STATE_MACHINE(RootStateMachineClassName, StateMachineTypes) \
+  template<class Types, class Parameters>                                       \
+    class RootStateMachineClassName                                             \
+      : public artis::addons::utils::RootStateMachine<artis::common::DoubleTime, Types, Parameters, StateMachineTypes<Types, Parameters>> { \
+    public:                                                                     \
+      RootStateMachineClassName() = default;                                    \
+      ~RootStateMachineClassName() override = default;                          \
+      void build(const Parameters &parameters) override {                       \
+        this->template build_machines<typename Types::root_state_machine_type, std::tuple_size_v<StateMachineTypes<Types, Parameters>>>(parameters); \
+      }                                                                         \
+    };
+
 #endif //ARTIS_STAR_ADDONS_UTILS_ROOT_STATE_MACHINE_HPP

+ 70 - 5
src/utils/StateMachine.hpp

@@ -84,7 +84,8 @@ public:
 
     virtual bool event(const typename Time::type & /* t */, int  /* event */) = 0;
 
-    virtual bool guard(const typename Time::type & /* t */) const = 0;
+    virtual bool guard(const typename Time::type & /* t */,
+                       const artis::common::event::Value & /* value */) const = 0;
 
     virtual bool no_event() const = 0;
 
@@ -105,7 +106,8 @@ public:
     bool event(const typename Time::type & /* t */,
                int  /* event */) override { return false; }
 
-    bool guard(const typename Time::type & /* t */) const override { return true; }
+    bool guard(const typename Time::type & /* t */,
+               const artis::common::event::Value & /* value */) const override { return true; }
 
     bool no_event() const override { return false; }
 
@@ -187,7 +189,7 @@ public:
       std::for_each(it->second.cbegin(), it->second.cend(),
                     [t, &unique, &select, &stateID](
                       const std::pair<std::unique_ptr<AbstractTransition>, int> &e) {
-                      if (e.first->no_event() and e.first->guard(t)) {
+                      if (e.first->no_event() and e.first->guard(t, {})) {
                         select = e.first.get();
                         stateID = e.second;
                         ++unique;
@@ -221,7 +223,7 @@ public:
       std::for_each(it->second.cbegin(), it->second.cend(),
                     [t, event, &unique, &select, &stateID](
                       const std::pair<std::unique_ptr<AbstractTransition>, int> &e) {
-                      if (e.first->guard(t) and e.first->event(t, event.id)) {
+                      if (e.first->guard(t, event.data) and e.first->event(t, event.id)) {
                         select = e.first.get();
                         stateID = e.second;
                         ++unique;
@@ -255,7 +257,7 @@ public:
       std::for_each(it->second.cbegin(), it->second.cend(),
                     [t, event, &unique, &select, &stateID](
                       const std::pair<std::unique_ptr<AbstractTransition>, int> &e) {
-                      if (e.first->guard(t) and e.first->event(t, event.id)) {
+                      if (e.first->guard(t, event.data) and e.first->event(t, event.id)) {
                         select = e.first.get();
                         stateID = e.second;
                         ++unique;
@@ -316,4 +318,67 @@ protected:
 };
 
 }
+
+#define DECLARE_STATE_TRANSITION_TYPES(StateMachineClassName) \
+  typedef typename StateMachineClassName<Types, Parameters, StateType>::template State<StateMachineClassName<Types, Parameters, StateType>> State_t; \
+  typedef typename StateMachineClassName<Types, Parameters, StateType>::template Transition<StateMachineClassName<Types, Parameters, StateType>> Transition_t;
+
+#define DEFINE_STATE_MACHINE_STATE(StateClassName, StateID, StateMachineClassName) \
+  template<class Types, class Parameters, class StateType>                         \
+    struct StateClassName : StateMachineClassName<Types, Parameters, StateType>::State_t { \
+      StateClassName(const std::shared_ptr<StateMachineClassName<Types, Parameters, StateType>> &machine) : \
+      StateMachineClassName<Types, Parameters, StateType>::State_t(StateID, machine) {}    \
+    };
+
+#define DEFINE_STATE_MACHINE_STATE_WITH_NULL_TA(StateClassName, StateID, StateMachineClassName) \
+  template<class Types, class Parameters, class StateType>                                      \
+    struct StateClassName : StateMachineClassName<Types, Parameters, StateType>::State_t {      \
+      StateClassName(const std::shared_ptr<StateMachineClassName<Types, Parameters, StateType>> &machine) : \
+      StateMachineClassName<Types, Parameters, StateType>::State_t(StateID, machine) {}         \
+      artis::traffic::core::Time ta(const artis::traffic::core::Time & /* t */) const override { return 0; }\
+    };
+
+#define DEFINE_STATE_MACHINE_STATE_WITH_TA(StateClassName, StateID, StateMachineClassName) \
+  template<class Types, class Parameters, class StateType>                                      \
+    struct StateClassName : StateMachineClassName<Types, Parameters, StateType>::State_t {      \
+      StateClassName(const std::shared_ptr<StateMachineClassName<Types, Parameters, StateType>> &machine) : \
+      StateMachineClassName<Types, Parameters, StateType>::State_t(StateID, machine) {}         \
+      artis::traffic::core::Time ta(const artis::traffic::core::Time & /* t */) const override; \
+    };
+
+#define DEFINE_STATE_MACHINE_TRANSITION_HEADER(TransitionClassName, StateMachineClassName) \
+  template<class Types, class Parameters, class StateType>                                 \
+    struct TransitionClassName : StateMachineClassName<Types, Parameters, StateType>::Transition_t { \
+     TransitionClassName(                                                                  \
+        const std::shared_ptr<StateMachineClassName<Types, Parameters, StateType>> &machine) :       \
+        StateMachineClassName<Types, Parameters, StateType>::Transition_t(machine) {}
+
+#define ATTRIBUTE(Type, Var) Type Var;
+
+#define NO_ATTRIBUTE
+
+#define DEFINE_STATE_MACHINE_TRANSITION_FOOTER(Attribute) \
+  Attribute                                               \
+  };
+
+#define DEFINE_STATE_MACHINE_TRANSITION_ACTION_true void action(const artis::traffic::core::Time & /* t */, const artis::common::event::Value & /* value */) override;
+#define DEFINE_STATE_MACHINE_TRANSITION_ACTION_false
+#define DEFINE_STATE_MACHINE_TRANSITION_EVENT_true bool event(const artis::traffic::core::Time & /* t */, int event) override;
+#define DEFINE_STATE_MACHINE_TRANSITION_EVENT_false
+#define DEFINE_STATE_MACHINE_TRANSITION_GUARD_true bool guard(const artis::traffic::core::Time & /* t */) const override;
+#define DEFINE_STATE_MACHINE_TRANSITION_GUARD_false
+#define DEFINE_STATE_MACHINE_TRANSITION_NO_EVENT_true bool no_event() const override { return true; }
+#define DEFINE_STATE_MACHINE_TRANSITION_NO_EVENT_false
+#define DEFINE_STATE_MACHINE_TRANSITION_OUTPUT_true(StateMachineClassName) typename StateMachineClassName<Types, Parameters, StateType>::Events output(const artis::traffic::core::Time & /* t */) const override;
+#define DEFINE_STATE_MACHINE_TRANSITION_OUTPUT_false(StateMachineClassName)
+
+#define DEFINE_STATE_MACHINE_TRANSITION(TransitionClassName, StateMachineClassName, Attribute, ActionMethod, EventMethod, GuardMethod, NoEventMethod, OutputMethod) \
+  DEFINE_STATE_MACHINE_TRANSITION_HEADER(TransitionClassName, StateMachineClassName)                                                                    \
+  DEFINE_STATE_MACHINE_TRANSITION_ACTION_##ActionMethod                                                                                                 \
+  DEFINE_STATE_MACHINE_TRANSITION_EVENT_##EventMethod                                                                                                   \
+  DEFINE_STATE_MACHINE_TRANSITION_GUARD_##GuardMethod                                                                                                   \
+  DEFINE_STATE_MACHINE_TRANSITION_NO_EVENT_##NoEventMethod                                                                                              \
+  DEFINE_STATE_MACHINE_TRANSITION_OUTPUT_##OutputMethod(StateMachineClassName)                                                                          \
+  DEFINE_STATE_MACHINE_TRANSITION_FOOTER(Attribute)
+
 #endif //ARTIS_STAR_ADDONS_UTILS_STATE_MACHINE_HPP