Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entry (exit) actions aren't called on substates of a composite state that has no entry (exit) actions of its own #53

Closed
Ulenspiegel opened this issue Jul 5, 2016 · 2 comments

Comments

@Ulenspiegel
Copy link

Ulenspiegel commented Jul 5, 2016

It appears that, if an enclosing composite state does not have entry or exit actions of its own (on any arbitrary state, even if it's not actually visited), then inside its substates' entry and exit actions aren't called either.

#include <cstdio>
#include <boost/msm-lite.hpp>

namespace msm = boost::msm::lite;

using msm::state;
using msm::event;
using msm::sm;
using msm::make_transition_table;

struct e1 {};
struct e2 {};
struct e3 {};

struct A {
  auto configure() const noexcept {
    using namespace msm;
    using msm::on_exit;
    state<class A1> a1;
    state<class A2> a2;
    return make_transition_table(
        *a1 + event<e2> = a2,
        a1 + on_entry / [] { printf("Entering A1\n"); },
        a1 + on_exit / [] { printf("Leaving A1\n"); }
    );
  }
};

struct B {
  auto configure() const noexcept {
    using namespace msm;
    using msm::on_exit;
    state<class B1> b1;
    state<class B2> b2;
    return make_transition_table(
        *b1 + event<e2> = b2,
        b1 + on_entry / [] { printf("Entering B1\n"); },
        b1 + on_exit / [] { printf("Leaving B1\n"); }
    );
  }
};

state<sm<A>> a;
state<sm<B>> b;
state<class C> c;

struct SM {
  auto configure() const noexcept {
    using namespace msm;
    using msm::on_exit;
    state<class Init> init;
    return make_transition_table(
        *init = a,
        a + event<e1> = b,
        b + event<e3> = c
        //, c + on_entry / [] {}   // (1)
        //, c + on_exit / [] {}    // (2)
    );
  }
};

int main(int argc, char** argv) {
  sm<SM> m;
  printf("Processing E1\n");
  m.process_event(e1{});
  return 0;
}

yields following output:

Processing E1

E.g. entry/exit actions on a(a1) and b(b1) during a -> b transition are not called. Uncommenting (1) yields:

Entering A1
Processing E1
Entering B1

Introducing dummy entry action on c enabled entry actions on a1 and b1. Uncommenting (2) gives

Processing E1
Leaving A1

And uncommenting both enables all actions:

Entering A1
Processing E1
Leaving A1
Entering B1
@feltech
Copy link
Contributor

feltech commented Aug 21, 2016

Aha! This dodgy workaround also enables entry/exit actions on sub-states with history. This then allows me to save/restore wider application state when moving out of/in to the sub-state, and to encapsulate that logic within the sub-state itself. Thanks!

@krzysztof-jusiak
Copy link
Collaborator

Fixed by 97965f0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants