jp-embedded / scxmlcc

The SCXML state machine to C++ compiler
GNU General Public License v3.0
140 stars 34 forks source link

Parallel: Wrong transition executed #97

Closed sstiller closed 5 years ago

sstiller commented 5 years ago

If a parallel state and one of its descendants have a transition with the same event, the wrong transition is executed.

At least I understand the algorithm in this way:

Behavior of the state machine generated by scxmlcc:

The SCXML code:

<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="parallelevent">
    <parallel id="P1">
        <state id="P1S1">
            <state id="P1S1S1">
                <transition type="external" event="ev1" target="P1S1S2"/>
            </state>
            <state id="P1S1S2">
            </state>
        </state>
        <state id="P1S2">
            <state id="P1S2S1">
            </state>
        </state>
        <transition type="external" event="ev1" target="Final_1"/>
    </parallel>
    <final id="Final_1">
    </final>
</scxml>

Test program:

#include <iostream>
#include "parallelevent.h"

using namespace std;
typedef sc_parallelevent sc;

int main(int argc, char *argv[])
{
  sc sc;
  sc.init();
  std::clog << "event here\n";
  sc.dispatch("ev1");
  return 0;
}

scxmlcc command line: scxmlcc -d clog --cpp14 --stringevents -o parallelevent.h parallelevent.scxml

log:

$ ./parallelevent 
sc_parallelevent: transition [initial] sc_parallelevent::scxml -> sc_parallelevent::state_P1
sc_parallelevent: enter sc_parallelevent::state_P1
sc_parallelevent: transition [initial] sc_parallelevent::state_P1 -> sc_parallelevent::state_P1S1
sc_parallelevent: enter sc_parallelevent::state_P1S1
sc_parallelevent: enter sc_parallelevent::state_P1S2
sc_parallelevent: transition [initial] sc_parallelevent::state_P1S2 -> sc_parallelevent::state_P1S2S1
sc_parallelevent: enter sc_parallelevent::state_P1S2S1
sc_parallelevent: transition [initial] sc_parallelevent::state_P1S1 -> sc_parallelevent::state_P1S1S1
sc_parallelevent: enter sc_parallelevent::state_P1S1S1
event here
sc_parallelevent: transition [event_ev1] sc_parallelevent::state_P1 -> sc_parallelevent::state_Final_1
sc_parallelevent: exit sc_parallelevent::state_P1S1S1
sc_parallelevent: exit sc_parallelevent::state_P1S1
sc_parallelevent: exit sc_parallelevent::state_P1S2S1
sc_parallelevent: exit sc_parallelevent::state_P1S2
sc_parallelevent: exit sc_parallelevent::state_P1
sc_parallelevent: enter sc_parallelevent::state_Final_1
sstiller commented 5 years ago

If all children of P1 have transitions for the event, everything is fine:

<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="parallelevent">
    <parallel id="P1">
        <state id="P1S1">
            <state id="P1S1S1">
                <transition type="external" event="ev1" target="P1S1S2"/>
            </state>
            <state id="P1S1S2">
            </state>
        </state>
        <state id="P1S2">
            <state id="P1S2S1">
                <transition type="external" event="ev1" target="P1S2S2"/>
            </state>
            <state id="P1S2S2">
            </state>
        </state>
        <transition type="external" event="ev1" target="Final_1"/>
    </parallel>
    <final id="Final_1">
    </final>
</scxml>
jp-embedded commented 5 years ago

Thanks. Yes the wrong transition is taken. I will look into this.

jp-embedded commented 5 years ago

Just a minor update. I have been quite busy lately, but I think I will get some time in week 28 to solve this

jp-embedded commented 5 years ago

Work in progress...

jp-embedded commented 5 years ago

fixed in #105