boost-ext / sml

C++14 State Machine library
https://boost-ext.github.io/sml
Boost Software License 1.0
1.14k stars 177 forks source link

process_event on user callback #242

Open segfault-magnet opened 5 years ago

segfault-magnet commented 5 years ago
#include <boost/sml.hpp>
#include <cassert>
#include <functional>
#include <iostream>
#include <queue>
#include <utility>

struct DoStuff {};
struct SomeEvent {};

template <typename func>
struct DelayedCall {
  void set_callback(func f) { f_ = std::move(f); }
  void invoke() { f_(); }
  func f_;
};

struct SomeTransitions {
  auto operator()() const noexcept {
    auto delayDoingStuff =
        [](boost::sml::back::process<DoStuff> processEvent,
           DelayedCall<std::function<void()>>& delayer) -> void {
      delayer.set_callback([processEvent{std::move(processEvent)}]() mutable {
        processEvent(DoStuff{});
      });
    };

    using namespace boost::sml;
    return make_transition_table(
        *"initial"_s + event<SomeEvent> / delayDoingStuff,
        "initial"_s + event<DoStuff> = X);
  }
};

int main(int argc, char* argv[]) {
  using namespace boost::sml;
  using namespace std;

  DelayedCall<std::function<void()>> delayer;
  sm<SomeTransitions, process_queue<queue>> machine{delayer};
  assert(machine.is("initial"_s));

  machine.process_event(SomeEvent{});
  delayer.invoke(); // Should send DoStuff to the state machine

  assert(machine.is(X)); // Doesn't work
  return 0;
}

Will SML support calling sml::back::process after a (here simulated) time delay?

almini commented 5 years ago

I have the same issue. It seems that it only works as long as the action is still ongoing. Calling processEvent after the action function call has finished does not work.