前页 后页

示例:模拟命令

此示例演示了如何使用“模拟”窗口观察跟踪消息或发送命令来控制StateMachine。通过示例,您可以检查:

  • 上下文的属性-类中定义的成员变量,它是StateMachine的上下文;这些属性在上下文中包含所有状态行为和过渡效果的值,以供访问和修改
  • 信号的每个属性-信号中定义的成员变量,由事件引用并且可以用作事件参数;每个信号事件发生可能具有不同的信号实例
  • 使用“ Eval”命令查询上下文属性的运行时值
  • 使用“转储”命令转储当前状态的活动计数;它还可以转储池中延迟的当前事件
此示例摘自EAExample模型:

示例模型。模型仿真。可执行状态机。仿真命令

访问

色带

  • 模拟>动态模拟>模拟器>打开模拟窗口)
  • 模拟>动态模拟>事件(用于“模拟事件”窗口)

这两个窗口在可执行状态机的仿真中经常一起使用。

创建上下文和状态机

在本节中,我们将创建一个名为TransactionServer的类,该类将StateMachine定义为其行为。然后,我们创建一个可执行状态机工件作为模拟环境。

创建StateMachine的上下文

Class as context for StateMachine simulation in Sparx Systems Enterprise Architect

  1. 创建一个名为TransactionServer的Class元素
  2. 在此类中,创建一个名为authorizeCnt的属性,其初始值为0。
  3. 在浏览器窗口中,右键单击TransactionServer,然后选择“添加| StateMachine'选项。

创建StateMachine

StateMachine for SysML Parametric simulation in Sparx Systems Enterprise Architect

  1. 创建一个称为Initial的Initial伪状态。
  2. 过渡到一个叫做闲置的国家。
  3. 使用触发器NEW_REQUEST转换到状态为busy的状态。
  4. 过渡:
    -使用触发器QUIT进入称为Final的Final伪状态
    -返回到空闲状态 ,触发已授权,效果为“ this.authorizeCnt ++;”

繁忙 的州创建一个延迟事件

  1. 画一个自我过渡的忙碌。
  2. 将过渡的“种类”更改为“内部”。
  3. 将触发器指定为要延迟的事件。
  4. 在“效果”字段中,键入“ defer();”。

创建信号和属性

  1. 创建一个称为RequestSignal的Signal元素
  2. 创建一个名为requestType的属性,类型为'int'。
  3. 配置事件NEW_REQUEST以引用RequestSignal。

创建可执行状态机器工件

Executable StateMachine deferred event simulation in Sparx Systems Enterprise Architect

  1. 从图工具箱的“工件”页面中,将一个可执行的StateMachine图标拖到图上,并调用元素Simulation with Deferred Event。
  2. Ctrl +从浏览器窗口中拖动TransactionServer元素,并将其作为属性(带有名称服务器)拖放到Artifact 上。
  3. 将Artifact的语言设置为JavaScript,不需要编译器(例如;在生产中,您还可以使用C,C ++,C#或Java,它们也支持可执行StateMachines)。
  4. 单击工件,然后选择“模拟>可执行状态>状态机>生成,构建和运行”功能区选项。

仿真窗口和命令

模拟开始时, 空闲是当前状态。

“模拟”窗口显示,对于状态空闲 ,“过渡效果”,“进入”和“执行”行为已完成,并且StateMachine正在等待触发。

通过信号属性值的事件数据

对于触发信号事件NEW_REQUEST,将显示“触发器参数输入”对话框,以提示输入在NEW_REQUEST引用的Signal RequestSignal中定义的列出属性的值。

输入值“ 2”,然后单击“确定”按钮。然后将Signal属性值传递给调用的方法,例如State的行为和Transition的效果。

这些消息将输出到“模拟”窗口:

[03612562]等待触发

[03611358]命令: 广播NEW_REQUEST.RequestSignal(2)

[03611362] [server:TransactionServer]事件已排队:NEW_REQUEST.RequestSignal(requestType:2)

[03611367] [服务器:TransactionServer]已调度事件:NEW_REQUEST.RequestSignal(requestType:2)

[03611371] [server:TransactionServer]退出行为:ServerStateMachine_idle

[03611381] [server:TransactionServer]过渡效果:idle__TO__busy_61772

[03611390] [server:TransactionServer]条目行为:ServerStateMachine_busy

[03611398] [server:TransactionServer]行为:ServerStateMachine_busy

[03612544] [server:TransactionServer]完成:TransactionServer_ServerStateMachine_busy

[03612562]等待触发

我们可以通过双击“模拟事件”窗口中列出的项目来广播事件。或者,我们可以在“模拟”窗口的文本字段中(在工具栏下方)键入命令字符串。

[03612562]等待触发

[04460226]命令: 广播NEW_REQUEST.RequestSignal(3)

[04460233] [server:TransactionServer]事件已排队:NEW_REQUEST.RequestSignal(requestType:3)

[04461081]等待触发

模拟消息指示事件发生被推迟(事件已排队,但未调度)。我们可以使用文本字段运行其他命令:

[04655441]等待触发

[04664057]命令: 广播NEW_REQUEST.RequestSignal(6)

[04664066] [server:TransactionServer]事件已排队:NEW_REQUEST.RequestSignal(requestType:6)

[04664803]等待触发器

[04669659]命令: 广播NEW_REQUEST.RequestSignal(5)

[04669667] [server:TransactionServer]事件已排队:NEW_REQUEST.RequestSignal(requestType:5)

[04670312]等待触发

[04674196]命令: 广播NEW_REQUEST.RequestSignal(8)

[04674204] [server:TransactionServer]事件已排队:NEW_REQUEST.RequestSignal(requestType:8)

[04674838]等待触发器

dump:查询状态和事件池的“活动计数”

在文本字段中输入dump ;这些结果显示:

从“活动计数”部分,我们可以看到繁忙是活动状态(活动计数为1)。

提示 :对于复合状态,活动计数为1(本身) 加上活动区域的数量。

从“事件池”部分,我们可以看到事件队列中有四个事件发生。信号的每个实例都携带不同的数据。

池中事件的顺序是广播事件的顺序。

eval:查询上下文的运行时值

触发授权

[04817341]等待触发

[05494672]命令:已广播授权

[05494678] [server:TransactionServer]事件已排队:已授权

[05494680] [server:TransactionServer]已调度事件:已授权

[05494686] [server:TransactionServer]退出行为:ServerStateMachine_busy

[05494686] [server:TransactionServer] 过渡效果:busy__TO__idle_61769

[05494687] [server:TransactionServer]条目行为:ServerStateMachine_idle

[05494688] [server:TransactionServer]的行为:ServerStateMachine_idle

[05495835] [server:TransactionServer]完成:TransactionServer_ServerStateMachine_idle

[05495842] [server:TransactionServer]已调度事件:NEW_REQUEST.RequestSignal(requestType:3)

[05495844] [server:TransactionServer]退出行为:ServerStateMachine_idle

[05495846] [server:TransactionServer]过渡效果:idle__TO__busy_61772

[05495847] [server:TransactionServer]条目行为:ServerStateMachine_busy

[05495850] [server:TransactionServer]的行为:ServerStateMachine_busy

[05496349] [server:TransactionServer]完成:TransactionServer_ServerStateMachine_busy

[05496367]等待触发器

  • 繁忙空闲的转变而成,因此我们预计将要执行的效果
  • 空闲完成后,将从池中调出一个事件并调度该事件,从而使繁忙状态变为活动状态
  • 键入dump,并注意池中还剩下三个事件。第一个被召回并发送

[05693348]事件池:[

[05693349] NEW_REQUEST.RequestSignal(requestType:6),

[05693351] NEW_REQUEST.RequestSignal(requestType:5),

[05693352] NEW_REQUEST.RequestSignal(requestType:8),

[05693354]]

在文本字段中输入eval server.authorizeCnt 。该图表明“ server.authorizeCnt”的运行时值为1。

再次触发AUTHORIZED。当StateMachine在繁忙时稳定时,池中将剩下两个事件。再次运行eval server.suthorizeCnt ;该值为2。

从状态行为和过渡效应访问上下文的成员变量

Enterprise Architect的可执行StateMachine支持C,C ++,C#,Java和JavaScript的仿真。

对于C和C ++,其语法与C#,Java和JavaScript的区别在于访问上下文的成员变量。 C和C ++使用指针“->”,而其他仅使用“。”;但是,您始终可以使用this.variableName来访问变量。 Enterprise Architect会将其转换为C和C ++的this-> variableName。

因此,对于所有语言,只需使用以下格式进行模拟即可:

this.variableName

例子:

在过渡效果中:

this.authorizeCnt ++;

在某些状态下的进入,执行或退出行为:

this.foo + = this.bar;

注意:对于C和C ++,默认情况下, Enterprise Architect仅将'this->'替换为'this'。例如:

this.foo = this.bar + myObject.iCount + myPointer-> iCount;

将被翻译成:

this-> foo = this-> bar + myObject.iCount + myPointer-> iCount;

支持的命令的完整列表

由于Executable StateMachine Artifact可以一起模拟多个上下文,因此某些命令可以指定实例名称。

运行状态机:

由于每个上下文可以具有多个StateMachines,因此“运行”命令可以指定一个StateMachine开头。

  • 运行instance.statemachine
  • 全部运行
  • 运行实例
  • 全部运行
例如:

全部运行

运行服务器

运行server.myMainStatemachine

广播和发送事件:

  • 广播EventString
  • 发送EventString到实例
  • 发送EventString(相当于广播的EventString)
例如:

广播Event1

发送事件1给客户端

转储命令:

  • 倾倒
  • 转储实例
例如:

倾倒

转储服务器

转储客户端

eval命令:

  • 评估instance.variableName
例如:

评估client.requestCnt

评估server.responseCnt

退出命令:

  • 出口

EventString的格式:

  • EventName.SignalName(参数列表)
注意:参数列表应与order中的signal中定义的属性匹配。

例如,如果信号定义了两个属性:

  • 酒吧

那么这些EventString是有效的:

  • Event1.Signal1(10,5)--------- foo = 10;酒吧= 5
  • Event1.Signal1(10,)--------- foo = 10;栏未定义
  • Event1.Signal1(,5)--------- bar = 10; foo是未定义的
  • Event1.Signal1(,)--------- foo和bar均未定义

如果Signal不包含任何属性,我们可以将EventString简化为:

  • 事件名称