是BoUML';s状态机生成器正确运行时';在退出状态机之前调用doActivity?

是BoUML';s状态机生成器正确运行时';在退出状态机之前调用doActivity?,uml,state-machine,Uml,State Machine,考虑一个简单的状态机: 是由C++生成的一个C++代码片段: 请注意,\u do(stm)由Sample::Sample\u State::State1\u State::exit\u State1(Sample&stm)调用,即在退出状态1时,就在调用退出行为stm.\u Sample\u State1\u State.\u doexit(stm)之前 告诉我们: 14.2.3.4.3说明进入、退出和行动行为 一个状态也可能具有相关的doActivity行为。此行为在输入状态时开始执行(但

考虑一个简单的状态机:

是由C++生成的一个C++代码片段:

请注意,
\u do(stm)
Sample::Sample\u State::State1\u State::exit\u State1(Sample&stm)
调用,即在退出状态1时,就在调用退出行为
stm.\u Sample\u State1\u State.\u doexit(stm)之前

告诉我们:

14.2.3.4.3说明进入、退出和行动行为

一个状态也可能具有相关的doActivity行为。此行为在输入状态时开始执行(但仅在状态输入行为完成后),并与可能与状态关联的任何其他行为同时执行,直到:

  • 完成(在这种情况下生成完成事件)或
  • 状态已退出,在这种情况下,doActivity行为的执行将中止
状态的doActivity行为的执行不受该状态内部转换触发的影响


Sample::Sample\u State::State1\u State::create()
,在
\u doentry(stm)之后调用
\u do(stm)
不是更符合UML规范吗

事实上最糟糕的是,我在进入和退出案例之间交换了do行为的管理。考虑到状态机(从状态到自身的转换是内部的):

主要的

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();
}
因此,do行为是针对内部转换执行的,在退出状态时是错误的,而在进入状态时是缺失的

注意,状态机生成器是插件,它的定义是通过项目SmithGuiver实现的BouML交付的一部分,它是用C++实现的(不是java)。因此,您可以加载项目SMIGng生机,保存为您具有写权限的地方,改正它,生成C++代码,编译它并用新版本替换官方生成器,或者声明新的插件并将其关联到状态机中以使其在菜单中。


我修改了我的状态机生成器,上一次是在2011年

当退出状态(包括通过自外部转换)时不再执行do行为,它现在在可能的do条目之后执行。我也会在自我内部转换的可能转换行为之后,而不是之前,避免在转换有行为的情况下,在没有中间任何东西的情况下连续执行两次

注意,已经可以通过在与机器关联的类上定义的操作doActivity来执行当前状态的可能do行为。这样就可以在过渡发射之间完成

对以前的状态机稍作修改以添加自外部转换:

那条主线呢



您的结论似乎有道理。非常确定Bruno会插手并进行评论/回答。如果您无法编译自己的状态机生成器,请告诉我您在哪个操作系统上使用BoUML,我会为您做。这里可能值得一提的是,例如,在Fedora上,sm_项目位于/usr/lib64/BoUML/sm_生成器/文件夹中。@zer0hedge是的,这是我放置它们的地方,这就是为什么加载该项目后,您必须执行另存为,否则您无法修改它,除非是root用户(当然也可以使用sudo调用bouml)@zer0hedge我修改了我的状态机生成器(请参见编辑的答案)。我不知道什么时候我会发布一个新版本的BoUML,我可以为你使用BoUML的操作系统生成可执行文件,如果你想要的话,可以提前发布,尽管问我。谢谢。我会很感激Debian Buster的版本。我将很快迁移到Debian。@zer0hedge,然后将
/usr/lib/bouml/stmgen
替换为您可以通过
wget获得的新版本http://bouml.fr/buster64/stmgen
md5sum是3b60357c6974fb2575794aaba8c159e5,新的状态机生成器版本是5.0.1(在启动时编写)。我想你想要的是64b版本,而不是32b版本
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();
}
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 $ 
#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();
}
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 $