Python库用户手册
Step 1. 下载仓库,将仓库中的src_python/SMLite/
文件夹下的Python包拷贝进自己的解决方案项目,并引用
from SMLite import SMLite
from SMLiteAsync import SMLiteAsync
from SMLiteBuilder import SMLiteBuilder
from SMLiteBuilderAsync import SMLiteBuilderAsync
Step 2. 定义两个强枚举类,分别代表所有的状态与所有的触发器
from enum import IntEnum
class MyState (IntEnum):
Rest = 0
Ready = 1
Reading = 2
Writing = 3
class MyTrigger (IntEnum):
Run = 0
Close = 1
Read = 2
FinishRead = 3
Write = 4
FinishWrite = 5
Step 3. 定义状态机生成器
_smb = SMLiteBuilder ()
Step 4. 定义状态机的规则,指定具体的某个状态允许触发什么事件
# 备注:实际使用时删掉注释与空行,使得python的续行符正常使用
# 如果当状态机的当前状态是 MyState.Rest
_smb.Configure (MyState.Rest)\
# 如果状态由其他状态变成 MyState.Rest 状态,那么触发此方法,初始化状态机时指定的初始值不触发此方法
.OnEntry (lambda : print ("entry Rest"))\
# 如果状态由 MyState.Rest 状态变成其他状态,那么触发此方法
.OnLeave (lambda : print ("leave Rest"))\
# 如果触发 MyTrigger.Run,则将状态改为 MyState.Ready
.WhenChangeTo (MyTrigger.Run, MyState.Ready)\
# 如果触发 MyTrigger.Close,忽略
.WhenIgnore (MyTrigger.Close)\
# 如果触发 MyTrigger.Read,则调用回调函数,并将状态调整为返回值
# def _rest_read (_state, _trigger):
# print ("call WhenFunc callback")
# return MyState.Ready
.WhenFunc (MyTrigger.Read, _rest_read)\
# 如果触发 MyTrigger.FinishRead,则调用回调函数,并将状态调整为返回值
# 需注意,触发时候需传入参数,数量与类型必须完全匹配,否则抛异常
# def _rest_finishread (_state, _trigger, _param):
# print ("call WhenFunc callback with param [%s]", _param)
# return MyState.Ready
.WhenFunc (MyTrigger.FinishRead, _rest_finishread)\
# 如果触发 MyTrigger.Write,则调用回调函数(触发此方法回调不调整返回值)
# def _rest_write (_state, _trigger):
# print ("call WhenAction callback")
.WhenAction (MyTrigger.Write, _rest_write)\
# 如果触发 MyTrigger.FinishWrite,则调用回调函数(触发此方法回调不调整返回值)
# 需注意,触发时候需传入参数,数量与类型必须完全匹配,否则抛异常
# def _rest_finishwrite (_state, _trigger, _param):
# print ("call WhenAction callback with param [%s]", _param)
.WhenAction (MyTrigger.FinishWrite, _rest_finishwrite)
同一个状态下,如果遇到同样的触发器,最多只允许定义一种处理方式,上面代码对定义的触发事件有详细解释。如果不定义触发事件但遇到触发,那么抛异常。
Step 5. 下面开始真正使用到状态机
# 生成状态机
_sm = _smb.Build (MyState.Rest)
# 获取当前状态
Assert.AreEqual (_sm.GetState (), MyState.Rest)
# 判断是否允许触发某一个事件
Assert.IsTrue (_sm.AllowTriggering (MyTrigger.Run))
# 触发一个事件
_sm.Triggering (MyTrigger.Run)
# 触发一个事件,并传入指定参数
_sm.Triggering (MyTrigger.Run, "hello")
# 强行修改当前状态,此操作将不会触发OnEntry、OnLeave事件
_sm.SetState (MyState.Ready)
Step 6. 如果用到异步
使用与上面非常相似,下面是指定异步触发回调函数
_smb = SMLiteBuilderAsync ()
_smb.Configure (MyState.Ready)\
# 与 OnEntry 效果一致,不过这函数指定异步方法,并且不能与 OnEntry 同时调用
# async def _ready_entry ():
# await asyncio.sleep (0.01)
# print ("entry Ready")
.OnEntryAsync (_ready_entry)\
# 与 OnLeave 效果一致,不过这函数指定异步方法,并且不能与 OnLeave 同时调用
# async def _ready_leave ():
# await asyncio.sleep (0.01)
# print ("leave Ready")
.OnLeaveAsync (_ready_leave)\
# 效果与 WhenFunc 一致,不过这函数指定异步方法
# async def _ready_read (_state, _trigger):
# await asyncio.sleep (0.01)
# print ("call WhenFuncAsync callback")
# return MyState.Ready
.WhenFuncAsync (MyTrigger.Read, _ready_read)\
# 效果与 WhenFunc 一致,不过这函数指定异步方法
# async def _ready_finishread (_state, _trigger, _param):
# await asyncio.sleep (0.01)
# print ("call WhenFuncAsync callback with param %s", _param)
# return MyState.Ready
.WhenFuncAsync (MyTrigger.FinishRead, _ready_finishread)\
# 效果与 WhenAction 一致,不过这函数指定异步方法
# async def _ready_write (_state, _trigger):
# await asyncio.sleep (0.01)
# print ("call WhenActionAsync callback")
.WhenActionAsync (MyTrigger.Write, _ready_write)\
# 效果与 WhenAction 一致,不过这函数指定异步方法
# async def _ready_finishwrite (_state, _trigger, _param):
# await asyncio.sleep (0.01)
# print ("call WhenActionAsync callback with param %s", _param)
.WhenActionAsync (MyTrigger.FinishWrite, _ready_finishwrite)\
然后是触发一个事件:
# 异步触发一个事件,并传入指定参数
await _sm.TriggeringAsync (MyTrigger.Run, "hello")
await异步触发的事件将在所有函数执行完毕之后返回。另外需要注意,同步与异步最好不要混用,使用的不好就很容易导致死锁,最佳实践是统一同步或统一异步。