前页 | 后页 |
示例:仿真命令
这个例子演示了我们如何使用仿真窗口来观察跟踪消息或发送命令来控制状态机。通过示例,您可以检查:
- 一个上下文的属性——类中定义的成员变量,即状态机的上下文;这些属性在上下文范围内携带值,用于所有状态行为和过渡效果,以访问和修改
- 一个信号的每个属性——信号中定义的成员变量,被一个事件引用,可以作为一个事件参数;每个信号事件出现可能有一个信号的不同实例
- 使用'Eval'命令查询上下文属性的运行时值
- 使用“转储”命令转储当前状态的活动计数;它还可以转储池中延迟的当前事件
示例模型.模型仿真.可执行状态机.仿真命令
访问
功能区 |
这两个窗口在可执行状态机的模拟中经常一起使用。 |
创建上下文和状态机
在本节中,我们将创建一个称为 TransactionServer 的类,它将状态机定义为其行为。然后我们创建一个可执行状态机工件模拟环境。
创建状态机的Context
- 创建一个名为TransactionServer的类元素。
- 在这个类中,创建一个名为authorizeCnt的属性,初始值为 0。
- 在浏览器窗口中,右键单击TransactionServer并选择“添加|状态机”选项。
创建状态机
- 创建一个名为Initial的 Initial 伪状态。
- 转移
到了一种状态空闲的状态。 - 转移
到一个称为忙的状态,触发状态。 - 转移
:
- 到一个称为终点的终点伪状态,使用触发器 QUIT
- 回到空闲状态,触发 AUTHORIZED,影响'影响++;'
为忙状态创建一个延迟事件
- 为忙碌划自我过渡。
- 更改向“内部”过渡的“种类”。
- 简单地触发器要延迟的事件。
- 在“影响”字段中,输入“defer();”。
创建信号和属性
- 创建一个称为RequestSignal的信号元素。
- 创建一个名为requestType的属性,类型为“ int ”。
- 配置事件配置以引用RequestSignal。
创造可执行状态机工件
- 在工具箱的页面中,将“元素仿真可执行状态机”图标图表图表上,并调用仿真事件。
- 从浏览器窗口拖动事务元素并将其工件到作为属性服务器的名称服务器上。
- 将设备的JavaScript工件例如;在生产中,您还可以使用 C、C++、C# 或Java ,它们也支持可执行状态机)。
- 点击工件仿真> 执行状态 > 执行状态 > 状态机生成,编译和运行功能区选项
仿真窗口和命令
模拟开始时, idle是当前状态。
仿真窗口显示,转移
状态空闲的影响、进入和执行行为已完成,状态机正在等待触发。
通过信号属性值的事件数据
对于简单的信号事件触发器,“触发器参数Entry”对话框将显示用于提示在信号请求信号中定义的列出的属性的值,由信号引用。
类型值“2”并单击确定按钮。然后将信号属性值传递给调用的方法,例如状态的行为和转移
的影响。
这些消息输出到仿真窗口:
[触发器] 等待简单
[03611358] 命令:广播 NEW_REQUEST.RequestSignal(2)
[03611362] [服务器:TransactionServer]事件排队:NEW_REQUEST.RequestSignal(requestType:2)
[03611367] [服务器:TransactionServer]事件调度:NEW_REQUEST.RequestSignal(requestType:2)
[03611371] [server:TransactionServer] 退出行为:ServerStateMachine_idle
[03611381] [服务器:TransactionServer]转移
影响:影响
[03611390] [server:TransactionServer] 入口行为:ServerStateMachine_busy
[03611398] [server:TransactionServer]行为:ServerStateMachine_busy
[03612544] [服务器:TransactionServer] 完成:TransactionServer_ServerStateMachine_busy
[触发器] 等待简单
我们可以通过双击仿真事件窗口中列出的项目来播放事件。或者,我们可以在仿真窗口(工具栏下方)的文本字段中键入命令string 。
[触发器] 等待简单
[04460226] 命令:广播 NEW_REQUEST.RequestSignal(3)
[04460233] [服务器:TransactionServer]事件排队:NEW_REQUEST.RequestSignal(requestType:3)
[触发器] 等待简单
仿真事件消息表明事件发生被推迟(排队,但未调度)。我们可以使用文本字段运行更多命令:
[触发器] 等待简单
[04664057] 命令:广播 NEW_REQUEST.RequestSignal(6)
[04664066] [服务器:TransactionServer]事件排队:NEW_REQUEST.RequestSignal(requestType:6)
[触发器] 等待简单
[04669659] 命令:广播 NEW_REQUEST.RequestSignal(5)
[04669667] [服务器:TransactionServer]事件排队:NEW_REQUEST.RequestSignal(requestType:5)
[触发器] 等待简单
[04674196] 命令:广播 NEW_REQUEST.RequestSignal(8)
[04674204] [服务器:TransactionServer]事件排队:NEW_REQUEST.RequestSignal(requestType:8)
[触发器] 等待简单
dump:查询状态和事件的“活动泳池”
文本字段中的类型转储;这些结果显示:
从“活动计数”部分,我们可以看到忙碌是活动状态(活动计数为1 )。
提示:对于复合状态,活动计数为1 (对自身)加上活动区域的数量。
从“事件泳池”部分,我们可以看到事件队列中有四个事件发生。信号的每个实例都携带不同的数据。
池中事件的顺序是它们被广播的顺序。
eval:查询运行时间Context的值
触发器授权,
[触发器] 等待简单
[05494672] 命令:广播已授权
[05494678] [服务器:TransactionServer]事件排队:已授权
[05494680] [服务器:TransactionServer]事件调度:授权
[05494686] [server:TransactionServer] 退出行为:ServerStateMachine_busy
[05494686] [服务器:TransactionServer]转移
影响:忙影响
[05494687] [server:TransactionServer] 入口行为:ServerStateMachine_idle
[05494688] [server:TransactionServer]行为:ServerStateMachine_idle
[05495835] [服务器:TransactionServer] 完成:TransactionServer_ServerStateMachine_idle
[05495842] [服务器:TransactionServer]事件调度:NEW_REQUEST.RequestSignal(requestType:3)
[05495844] [server:TransactionServer] 退出行为:ServerStateMachine_idle
[05495846] [服务器:TransactionServer]转移
影响:影响
[05495847] [server:TransactionServer] 入口行为:ServerStateMachine_busy
[05495850] [server:TransactionServer]行为:ServerStateMachine_busy
[05496349] [服务器:TransactionServer] 完成:TransactionServer_ServerStateMachine_busy
[触发器] 等待简单
- 从忙到空闲的转换已经完成,所以我们期望执行效果
- 空闲完成时从池中回调一个事件并调度,使忙碌状态变为活动状态
- 类型转储,注意池中还剩下三个事件;第一个被召回和发送
[泳池]事件泳池:[
[05693349] NEW_REQUEST.RequestSignal(requestType:6),
[05693351] NEW_REQUEST.RequestSignal(requestType:5),
[05693352] NEW_REQUEST.RequestSignal(requestType:8),
[05693354] ]
文本字段中的类型eval server.authorizeCnt 。该图表示 '运行' 的运行时间值为1 。
触发器再次授权。当状态机稳定在busy时,池中会剩下两个事件。再次运行eval server.suthorizeCnt ;该值为 2。
从状态行为和转移
访问上下文的成员变量转移
影响
Enterprise Architect的可执行状态机,支持模拟C、C++、C# Java和JavaScript 。
对于 C 和 C++,访问上下文的成员变量的语法与 C#、 Java和JavaScript不同。 C 和 C++ 使用指针 '->' 而其他的只是使用 '.';但是,您始终可以使用this.variableName来访问变量。 Enterprise Architect将把它翻译成 this->variableName 用于 C 和 C++。
因此,对于所有语言,只需使用以下格式进行模拟:
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;
支持的命令A完全列表
由于多个可执行状态机工件一起模拟一些上下文,因此可以指定一个实例名称。
运行状态机:
由于每个上下文可以有多个状态机,“运行”命令可以指定一个状态机的机器。
- 运行instance.statemachine
- 运行
- 运行实例
- 运行
- 运行
运行
运行
运行服务器
运行
广播和发送事件:
- 广播事件字符串
- 将 EventString 发送到实例
- 发送EventString(相当于广播EventString)
广播事件1
将 Event1 发送给客户端
转储命令:
- 倾倒
- 转储实例
倾倒
转储服务器
转储客户端
评估命令:
- eval instance.variableName
评估 client.requestCnt
评估 server.responseCnt
退出命令:
- 出口
EventString 的格式:
- EventName.SignalName(参数列表)
例如,如果信号定义了两个属性:
- 富
- 酒吧
那么这些 EventStrings 是有效的:
- Event1.Signal1(10, 5) --------- foo = 10;酒吧 = 5
- Event1.Signal1(10,) --------- foo = 10;酒吧未定义
- Event1.Signal1(,5) --------- bar = 10; foo未定义
- Event1.Signal1(,) --------- foo 和 bar 都没有定义
如果信号不包含任何属性,我们可以将 EventString 简化为:
- 事件名称