Rhapsody C ++状态图 - 事件(似乎工作)vs触发操作(似乎什么都不做)

时间:2018-02-27 13:15:52

标签: c++ state-machine rhapsody

我正在使用Rhapsody 8.2.1 - 只是学习一些基础知识。

我正在编译(使用MSVC 2012),生成代码并运行。首先,我有一个类counter,其中一个属性int m_count带有一个打印“hello”的构造函数和一个带有一个状态start的状态图表,默认转换为它 - 默认值交易集m_count = 3。执行start::stateEntry()的{​​{1}}行动。

所以,接下来我每秒都会从状态printf("start - stateEntry m_count = %d\r\n", m_count);添加一个计时器事件。这是start --> start

所以...正如你所料,当我跑步时,我得到:

m_count -= 1

现在我在start - stateEntry m_count = 3 start - stateEntry m_count = 2 start - stateEntry m_count = 1 start - stateEntry m_count = 0 start - stateEntry m_count = -1 etc... 时想要转换到新状态m_count == 0。因此,为了实现这一点,我添加了一个新状态,并加入了两个状态,状态转换从done开始。我将状态转换命名为start --> done(正如我在教程中看到的那样)并按ctrl + enter。这具有添加:

的效果
  • 名为evTrigger
  • 的新事件
  • 一个名为evTrigger的新触发操作(类计数器的成员)。

当我打开转换时,“触发器”显示counter::evTrigger() - 所以我猜它指的是事件,而不是触发的操作。

现在我尝试使用它,我将以下代码添加到状态evTrigger in Default的输入操作中:

start

在状态if (m_count <= 0) { GEN(evTrigger()); } 的条目中,我输入了代码:done

好的,这样可行 - 我明白了:

printf("stateEntry - Done!\r\n");

但是我不能使用为我做的被称为start - stateEntry m_count = 3 start - stateEntry m_count = 2 start - stateEntry m_count = 1 start - stateEntry m_count = 0 stateEntry - done! 的触发操作。为什么不? 如果我调用evTrigger()而不是GEN(evTrigger());它会编译,但事件转换不会触发(它会一直向下计数到零以下)。为什么呢?

然后我创建了两个新项目来分别测试事件和触发操作,并且我在从evTrigger()start的新过渡中使用每个项目,因此有3个具有不同触发器的过渡:

  • 新事件evTriggerEvent
  • 新触发的操作trTriggerOperation

所以状态图如下所示:

done

开始输入操作如下所示:

*
|  /m_count = 3;
|
|       +---------+      evTrigger              +---------+
+-----> |  start  |---------------------------->|  done   |
        |---------|                             |---------|
        |         |                             |         |
        |         |      trTriggerOperation     |         |
        |         |---------------------------->|         |
        |         |                             |         |
        |         |                             |         |
        |         |      evTriggerEvent         |         |
        |         |---------------------------->|         |
        +---------+                             +---------+
          |     ^
          |     | tm(1000)/m_count -=1;
          +-----+

然后我一次取消评论(确保其他两个被注释掉)并测试它们,我得到以下结果(结果也在上面评论过):

GEN(evTrigger()) - 作品:

if (m_count <= 0)
{
    //GEN(evTrigger());        <----- works
    //trTriggerOperation();    <----- appears to do nothing
    //GEN(evTriggerEvent());   <----- works
}

trTriggerOperation() - 不触发交易...

start - stateEntry m_count = 3
start - stateEntry m_count = 2
start - stateEntry m_count = 1
start - stateEntry m_count = 0
stateEntry - done!

GEN(evTriggerEvent()) - 作品:

start - stateEntry m_count = 3
start - stateEntry m_count = 2
start - stateEntry m_count = 1
start - stateEntry m_count = 0
start - stateEntry m_count = -1
start - stateEntry m_count = -2
      etc...

所以我的问题是:

  • 为什么ctrl +同时生成一个事件和一个触发操作 - 当简单和事件会做同样的工作时?
  • 触发动作的目的是什么(它不直观地应该做什么)?
  • 使用触发操作的正确方法是什么(如果我做错了)?

更新

我刚注意到 - 我可以自己创建一个事件。但是当我在转换触发器中使用事件时,会在类操作中自动创建触发操作...我无法删除它因为它正被使用 - 现在我更加困惑:(

主要问题是关于狂想曲的文档/示例非常差...大多数论坛都是风滚草,所以这提出了另一个问题:这是一个死亡/垂死的产品还是什么?!

1 个答案:

答案 0 :(得分:2)

Ctrl + 输入只需在转换/状态/任何其他图形元素的顶部键入文本时,即可让您退出编辑模式 - 它不应创建触发操作

触发操作是可以触发状态机转换的同步操作(如基本操作)。它与事件之间的区别在于,当您调用触发操作时,它会同步执行(调用者正在等待状态机中的转换/运行完成步骤完成)。当您生成/发送事件时,事件进入事件队列,调用者(进行GEN调用的人)没有等待。

您调用触发操作就像调用基本操作一样(例如myInstance-&gt; myTrigOp(myArgValue))。触发的操作可以有参数并且可以返回一个值,但是有一种特殊的方法来访问参数并从状态机操作设置返回值。

如果您想了解有关如何使用触发操作的更多信息,请参阅Rhapsody帮助系统中的已触发操作。