BoUML 的状态机生成器在退出 StateMachine 状态之前调用 doActivity 时是否正确?
Is BoUML's State Machine Generator right when it's calling doActivity just before exit from a state of StateMachine?
考虑一个简单的状态机:
下面是 BoUML 从中生成的一段 C++ 代码:
// to manage the event create
void Sample::Sample_State::State1_State::create(Sample & stm) {
_doentry(stm);
}
// perform the 'entry behavior'
void Sample::Sample_State::State1_State::_doentry(Sample & stm) {
stm.enter_state1();
}
// perform the 'exit behavior'
void Sample::Sample_State::State1_State::_doexit(Sample & stm) {
stm.exit_state1();
}
// perform the 'do activity'
void Sample::Sample_State::State1_State::_do(Sample & stm) {
stm.do_state1();
}
// to manage the event exit_state1
void Sample::Sample_State::State1_State::exit_state1(Sample & stm) {
_do(stm);
{
stm._sample_state._state1_state._doexit(stm);
stm._set_currentState(stm._sample_state);
stm._final();
}
}
请注意 _do(stm)
由 Sample::Sample_State::State1_State::exit_state1(Sample & stm)
调用,即在退出状态 1 时,就在调用退出行为之前 stm._sample_state._state1_state._doexit(stm);
The UML Specification 告诉我们:
14.2.3.4.3 State entry, exit, and doActivity Behaviors
. . .
A State may also have an associated doActivity Behavior. This Behavior commences execution when the State is entered (but only after the State entry Behavior has completed) and executes concurrently with any other Behaviors that may be associated with the State, until:
- it completes (in which case a completion event is generated) or
- the State is exited, in which case execution of the doActivity Behavior is aborted.
The execution of a doActivity Behavior of a State is not affected by the firing of an internal transition of that State.
在 _doentry(stm);
之后从 Sample::Sample_State::State1_State::create()
调用 _do(stm)
不是更符合 UML 规范吗?
实际上是最糟糕的,我交换了进入和退出案例之间行为的管理。考虑到状态机(从状态到自身的转换是内部的):
和主要
int main()
{
MM mm;
mm.create();
cout << endl << "fire taa" << endl;
mm.taa();
cout << endl << "fire tab" << endl;
mm.tab();
cout << endl << "fire tbb" << endl;
mm.tbb();
cout << endl << "fire tba" << endl;
mm.tba();
cout << endl << "fire tdone" << endl;
mm.tdone();
}
编译(不定义VERBOSE_STATE_MACHINE)并执行:
pi@raspberrypi:~/sm/src $ g++ -Wall -g MM.cpp mmain.cpp
pi@raspberrypi:~/sm/src $ ./a.out
a entry
fire taa
a do
taa
fire tab
a do
a exit
tab expr
b entry
fire tbb
b do
tbb
fire tba
b do
b exit
tba expr
a entry
fire tdone
a do
a exit
tdone
pi@raspberrypi:~/sm/src $
因此 do 行为 为内部转换执行,在退出状态时错误,在进入状态时丢失。
注意状态机生成器是插件,它的定义是通过项目[=43=交付的BoUML的一部分]sm_generator,它是用C++实现的(不是Java)。所以你可以加载项目sm_generator,在你有写入权限的地方另存为,修改它,生成C++代码,编译它并用你的替换官方生成器新版本或声明您的新 插件 并将其关联到 状态机 以将其显示在菜单中。
我修改了我的状态机生成器,上次是2011年!
do 行为 在退出状态时不再执行,包括通过自我外部转换,它现在在可能的 do 进入[=63] 之后执行=].我也在自内部转换的可能转换行为之后而不是之前这样做,这避免了两次连续执行而中间没有任何内容,以防转换有行为。
请注意,已经可以通过在 class 关联到机器。这允许在转换触发之间进行。
对之前的状态机稍作修改,添加一个自外部转换:
和 main
#include "MM.h"
#include <iostream>
using namespace std;
int main()
{
MM mm;
mm.create();
cout << endl << "fire taa" << endl;
mm.taa();
cout << endl << "fire ta_a" << endl;
mm.ta_a();
cout << endl << "fire tab" << endl;
mm.tab();
cout << endl << "fire tbb" << endl;
mm.tbb();
cout << endl << "fire tba" << endl;
mm.tba();
cout << endl << "fire tdone" << endl;
mm.tdone();
}
编译(不定义VERBOSE_STATE_MACHINE)并执行:
pi@raspberrypi:~/sm/src $ g++ -Wall MM.cpp mmain.cpp
pi@raspberrypi:~/sm/src $ ./a.out
a entry
a do
fire taa
taa expr
a do
fire ta_a
a exit
ta_a expr
a entry
a do
fire tab
a exit
tab expr
b entry
b do
fire tbb
tbb expr
b do
fire tba
b exit
tba expr
a entry
a do
fire tdone
a exit
tdone expr
pi@raspberrypi:~/sm/src $
BoUML 7.10 可用并解决问题
考虑一个简单的状态机:
下面是 BoUML 从中生成的一段 C++ 代码:
// to manage the event create
void Sample::Sample_State::State1_State::create(Sample & stm) {
_doentry(stm);
}
// perform the 'entry behavior'
void Sample::Sample_State::State1_State::_doentry(Sample & stm) {
stm.enter_state1();
}
// perform the 'exit behavior'
void Sample::Sample_State::State1_State::_doexit(Sample & stm) {
stm.exit_state1();
}
// perform the 'do activity'
void Sample::Sample_State::State1_State::_do(Sample & stm) {
stm.do_state1();
}
// to manage the event exit_state1
void Sample::Sample_State::State1_State::exit_state1(Sample & stm) {
_do(stm);
{
stm._sample_state._state1_state._doexit(stm);
stm._set_currentState(stm._sample_state);
stm._final();
}
}
请注意 _do(stm)
由 Sample::Sample_State::State1_State::exit_state1(Sample & stm)
调用,即在退出状态 1 时,就在调用退出行为之前 stm._sample_state._state1_state._doexit(stm);
The UML Specification 告诉我们:
14.2.3.4.3 State entry, exit, and doActivity Behaviors
. . .
A State may also have an associated doActivity Behavior. This Behavior commences execution when the State is entered (but only after the State entry Behavior has completed) and executes concurrently with any other Behaviors that may be associated with the State, until:
- it completes (in which case a completion event is generated) or
- the State is exited, in which case execution of the doActivity Behavior is aborted.
The execution of a doActivity Behavior of a State is not affected by the firing of an internal transition of that State.
在 _doentry(stm);
之后从 Sample::Sample_State::State1_State::create()
调用 _do(stm)
不是更符合 UML 规范吗?
实际上是最糟糕的,我交换了进入和退出案例之间行为的管理。考虑到状态机(从状态到自身的转换是内部的):
和主要
int main()
{
MM mm;
mm.create();
cout << endl << "fire taa" << endl;
mm.taa();
cout << endl << "fire tab" << endl;
mm.tab();
cout << endl << "fire tbb" << endl;
mm.tbb();
cout << endl << "fire tba" << endl;
mm.tba();
cout << endl << "fire tdone" << endl;
mm.tdone();
}
编译(不定义VERBOSE_STATE_MACHINE)并执行:
pi@raspberrypi:~/sm/src $ g++ -Wall -g MM.cpp mmain.cpp
pi@raspberrypi:~/sm/src $ ./a.out
a entry
fire taa
a do
taa
fire tab
a do
a exit
tab expr
b entry
fire tbb
b do
tbb
fire tba
b do
b exit
tba expr
a entry
fire tdone
a do
a exit
tdone
pi@raspberrypi:~/sm/src $
因此 do 行为 为内部转换执行,在退出状态时错误,在进入状态时丢失。
注意状态机生成器是插件,它的定义是通过项目[=43=交付的BoUML的一部分]sm_generator,它是用C++实现的(不是Java)。所以你可以加载项目sm_generator,在你有写入权限的地方另存为,修改它,生成C++代码,编译它并用你的替换官方生成器新版本或声明您的新 插件 并将其关联到 状态机 以将其显示在菜单中。
我修改了我的状态机生成器,上次是2011年!
do 行为 在退出状态时不再执行,包括通过自我外部转换,它现在在可能的 do 进入[=63] 之后执行=].我也在自内部转换的可能转换行为之后而不是之前这样做,这避免了两次连续执行而中间没有任何内容,以防转换有行为。
请注意,已经可以通过在 class 关联到机器。这允许在转换触发之间进行。
对之前的状态机稍作修改,添加一个自外部转换:
和 main
#include "MM.h"
#include <iostream>
using namespace std;
int main()
{
MM mm;
mm.create();
cout << endl << "fire taa" << endl;
mm.taa();
cout << endl << "fire ta_a" << endl;
mm.ta_a();
cout << endl << "fire tab" << endl;
mm.tab();
cout << endl << "fire tbb" << endl;
mm.tbb();
cout << endl << "fire tba" << endl;
mm.tba();
cout << endl << "fire tdone" << endl;
mm.tdone();
}
编译(不定义VERBOSE_STATE_MACHINE)并执行:
pi@raspberrypi:~/sm/src $ g++ -Wall MM.cpp mmain.cpp
pi@raspberrypi:~/sm/src $ ./a.out
a entry
a do
fire taa
taa expr
a do
fire ta_a
a exit
ta_a expr
a entry
a do
fire tab
a exit
tab expr
b entry
b do
fire tbb
tbb expr
b do
fire tba
b exit
tba expr
a entry
a do
fire tdone
a exit
tdone expr
pi@raspberrypi:~/sm/src $
BoUML 7.10 可用并解决问题