【问题标题】:Is BoUML's State Machine Generator right when it's calling doActivity just before exit from a state of StateMachine?BoUML 的状态机生成器在退出 StateMachine 状态之前调用 doActivity 是否正确?
【发布时间】:2020-08-21 02:22:57
【问题描述】:

考虑一个简单的状态机:

下面是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 状态进入、退出和 doActivity 行为

。 . .

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

  • 完成(在这种情况下会生成完成事件)或
  • 状态已退出,在这种情况下 doActivity 行为的执行将中止。

State 的 doActivity 行为的执行不受该 State 的内部转换触发的影响。

_doentry(stm);之后从Sample::Sample_State::State1_State::create()调用_do(stm)不是更符合UML规范吗?

【问题讨论】:

  • 你的结论似乎有道理。很确定布鲁诺会加入并评论/回答。
  • 如果您无法编译自己的状态机生成器,请告诉我您在哪个操作系统上使用 BoUML,我会为您做的

标签: uml state-machine


【解决方案1】:

其实最糟糕的是,我在入口和出口案例之间交换了 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();
}

编译(没有定义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 行为 是为内部转换执行的,在退出状态时会出错,在进入状态时会丢失。

注意状态机生成器是插件,它的定义是通过项目sm_generator交付的BoUML的一部分,它被实现了在 C++ 中(不是在 Java 中)。所以你可以加载项目sm_generator,在你有写权限的地方保存,更正它,生成C++代码,编译它并用你的新版本替换官方生成器或声明你的新plug-out 并将其关联到 状态机 以使其出现在菜单中。


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

do 行为 在退出状态时不再执行,包括通过自身外部转换,它现在在可能的 do entry 之后执行。我也在自我内部转换的可能转换行为之后而不是之前这样做,以避免在转换有行为的情况下两次连续执行之间没有任何内容。

注意,已经可以通过在与机器关联的类上定义的操作doActivity 来执行当前状态可能的do 行为。这允许在转换触发之间进行。

与之前的状态机稍作修改,添加了一个self外部转换

还有那个

#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 可用并解决问题

【讨论】:

  • 这里可能值得一提的是,例如在 Fedora 上,sm_project 位于 /usr/lib64/bouml/sm_generator/ 文件夹中。
  • @zer0hedge 是的,这是我放置它们的地方,这就是为什么在加载该项目后您必须进行保存,否则您无法修改它,除非是 root(或调用 bouml i> 当然有 sudo
  • @zer0hedge 我修改了我的状态机生成器(见编辑后的答案)。我不知道什么时候会发布新版本的 BoUML,我可以为您使用 BoUML 的操作系统生成可执行文件,以便您提前拥有它,如果您愿意,请问我。跨度>
  • 谢谢。我会很感激 Debian Buster 版本。我很快就会迁移到 Debian。
  • @zer0hedge 所以install BoUML 然后将/usr/lib/bouml/stmgen 替换为您可以通过wget http://bouml.fr/buster64/stmgen 获得的新的md5sum 是3b60357c6974fb2575794aaba8c159e5 和新的状态机生成器 i> 版本是 5.0.1(在启动时编写)。我想你想要 64b 版本而不是 32b
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-09
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 2017-10-16
相关资源
最近更新 更多