状态机生成工具——SMC

一直觉得状态机是一个非常好玩的东西,以前用C++简单的写过状态机的简单实现,但是始终还是觉得麻烦(现在让我独立写状态机的话,我觉得我也已经写不出来了)。今天在好兄弟的指导下学会了使用一个状态机生成工具——SMC,感觉相当的有意思,于是就写下来吧。

首先简单说SMC是啥。SMC是用java开发的一个状态机软件代码生成工具,SMC支持多种开发语言:C、JavaScriptPython、C++、Lua、Ruby、C#、Objective-CScala、Groovy、Perl、TCL、JavaPHP、VB.NET等,而我们需要做的就是完成一个.sm的脚本和拥有这些状态的主体类。

下面设计这样一个简单状态机,程序初始化时,进入idle状态;当在idle状态收到信号时,进入busy状态;当在busy状态收到一个很special的信号时,进入idle状态。实现这个状态机的.sm脚本我们将它命名为Hello.sm,具体的脚本如下所示:

// 指定初始状态
%start HelloMap::Idle
// 实体对象
%class Hello
// 实体对象头文件
%header Hello.h
// 存放状态对象的类
%map HelloMap
%%
// State Transition End State Action(s)
Idle
//Entry { sayHello(); }
//Exit {}
{
receiveBuff(buff: char*) //填写到其它状态的逻辑
Busy
{ProcessReceive(buff);}
Default
nil
{ProcessDefault();}
}
Busy
//Entry {}
//Exit {}
{
receiveBuff(buff: char*) //填写到其它状态的逻辑
Busy
{}
receiveSpecial(buff: char*)
Idle
{Process(buff);}
Default
nil
{ProcessDefault();}
}
%%

以上脚本是什么意思详见注释即可,使用java -jar Smc.jar -c Hello.sm命令即可生成状态机代码:Hello_sm.c和Hello_sm.h。

下面完成拥有这些状态的主体类(C语言里就是完成一个.c和一个.h),我们将它命名为hello.c和hello.h。

首先是Hello.c:

然后是Hello.h:

由以上图片可以看出,实际上Transition和Action部分的代码,均是“结构体名字_sm文件中的函数名”的格式,其参数的第一个均是一个结构体指针*this,然后接上sm文件中指定的那些参数就可以了。然后,在Transition部分的函数中,最后一句一般都是固定写法,用于状态机执行对应的Action。因此整个状态机的实现,我们只需要完成Transition中的一部分和Action中的全部逻辑即可。是不是很方便?

下面完成main()函数:

一个很简单的main()函数,可以演示一下从idle状态跳到busy状态的全部打印。

尝试看了一下生成的Hello_sm.c和Hello_sm.h,说实话,要看懂还是要花点时间的。

个人觉得这个工具还是非常有用的,在网上搜资料学习时,居然不小心收到了李老师新浪博客的关于SMC的介绍,看到还可以生成状态转换图。表示不太会用,什么时候找个时间深入学习学习,哈哈。

共有 0 条评论

Top