SMC - 状态机代码生成工具
一、介绍
1.1 smc简介
smc官网地址: smc官方网站.
SMC是用java开发的一个状态机软件代码生成工具,SMC支持多种开发语言:C、JavaScript、Python、C++、Lua、Ruby、C#、Objective-C、Scala、Groovy、Perl、TCL、Java、PHP、VB.NET等,而我们需要做的就是完成一个.sm的脚本和拥有这些状态的主体类。
利用有限状态机来控制对象的行为,其原理就是利用多态,常常我们自己写代码,需要很大篇幅,万一需要再加一个或者几个状态,自己维护时就会很麻烦,SMC这个工具可以帮助我们解决这个问题。
SMC可以通过一个配置文件,生成有限状态机所需的所有状态类以及状态机类,同时还包括了所有的状态间的转换逻辑。
1.2 环境准备
我们这里以java语言为例来进行说明。
使用这个工具之前我们需要jdk环境,最新版的SMC支持jdk1.7,之前版本的SMC支持jdk1.6,要想中间没有问题,一定要将电脑上的jdk版本与SMC的jdk版本对应起来。
smc下载地址: http://sourceforge.net/projects/smc/files/.
二、 smc文件格式说明
%class 状态机所作用的类
%package 类所在的包
%access 生成类的可访问级别
%start 指定状态机的开始状态
%map 状态机的名字
%%...%%:这一对%%中间定义了各个状态类以及状态的各种行为。格式说明如下:
注意:sm文件名称需要与.sm文件中指定的%class 类名称 相同
Start --状态1(名称可自定义)
{
DoStart --Do状态名:执行状态1
State2–执行完状态1之后,跳转到该状态(状态2)
{method1();}–执行状态1时,需要实现的功能
}
State2-状态2
{
DoState2
[ctxt.isSuccessState2()== true] – ctxt:上下文,实体类CoreSchMatch 中isSuccessState2()函数返回值为true时,执行该功能
State3
{
notifyClientState2Ok();
}
DoState2
[ctxt.isSuccessState2()==== false] – ctxt:上下文,实体类CoreSchMatch 中isSuccessState2()函数返回值为false时,执行该功能
State2Fail{notifyClientState2Fail();}
}
State3
{
DoState3
nil{method3();releaseStm();}–表示清空资源;nli-结束状态
}
State2Fail
{
DoState2Fail
nil{releaseStm();}–表示清空资源;nli-结束状态
Default -- 默认状态转换:被放置在一个状态中,用于备份所有转换。
{
nil{ process();}
}
}
Default –默认状态,如果状态机接收到未在该状态机中定义的转换时,定义该状态下的动作或转换
{
DoStart
nil
{}
DoState2
nil
{}
DoState3
nil
{}
DoState2Fail
nil
{}
}
三、java - smc 代码生成过程
3.1 java环境
1、创建java工程;
2、引入jar包:Smc.jar
3、创建:SchMatchState.sm文件
3.2 编写smc文件
下面设计这样一个简单状态机,程序初始化时,进入"start"初始状态;当在”"start"初始状态收到信号时,进入”busy“状态;当在"busy"状态收到一个"special"的信号时,进入"idle"状态,当在"busy"状态收到一个"exception"的信号时,进入"stop"退出状态。
实现这个状态机的.sm脚本我们将它命名为SchMatchState.sm,
具体的脚本如下所示:
%{
%}
%class SchMatchState
%package com.math.sch
%start SchMatchStateMap::Start
%map SchMatchStateMap
%%
Start
{
DoStart
Busy{state2Busy();}
}
Busy
{
DoBusy [ctxt.isSpecialState() == true] Idle{idleProcess();}
DoBusy [ctxt.isSpecialState() == false] Stop{stopProcess();}
}
Idle{
DoIdle
nil {release();}
}
Stop{
DoStop
nil {release();}
}
Default
{
DoStart
nil
{}
DoBusy
nil
{}
DoIdle
nil
{}
DoStop
nil
{}
}
%%
3.3 执行.sm文件
执行.sm文件,生成对应的类和方法,有两种方法:
1、通过命令行执行生成;
2、通过ant自动化编译工具生成;
3.3.1 命令行方式
1、命令行内容:
java -jar Smc.jar -java -g -d ./ 需要处理的状态机.sm文件名
示例:
java -jar Smc.jar -java -g -d ./ SchMatchState.sm
2、执行命令:
(1)Window+R,打开cmd命令行窗口;
(2)在命令行中进入smc.jar包的位置:
(3)执行命令:
注意:sm文件名称需要与.sm文件中指定的%class 类名称 相同,我这边因为名称不相同导致生成异常: