问题描述
使用 .NET 的无状态库我编写了一个状态机,可以做一些事情:
- 读取条形码票
- 做一些验证
- 检查更多验证
- 做一些数字 I/O(变成浅绿色并打开一扇门)
- 构建事务并提交
我的StateMachine代码如下:
public class MainStateMachine
{
public delegate void tvOnTransitioned(StateMachine<State,Trigger>.Transition otransition);
public delegate void tvUnhandledTrigger(State estate,Trigger etrigger);
public delegate void tvEntryExit();
public delegate bool bnGuardClause();
public delegate void vLogMsg(string sstring);
public delegate void tvOnTransition_Barcode(sbarcodeserial);
StateMachine<State,Trigger>.TriggerWithParameters<string> oBarcode_Trigger_With_Parameters;
public tvOnTransitioned OnTransitioned = null;
public tvUnhandledTrigger OnUnhandledTrigger = null;
#region SuperState
public tvEntryExit OnEntry_Input = null;
public tvEntryExit OnExit_Input = null;
#endregion
#region Substates_Entry_Exit
public tvEntryExit OnEntry_CSC_BarcodeValidation = null;
public tvEntryExit OnEntry_PaymentSatisfied = null;
public tvEntryExit OnEntry_FrameTransaction = null;
#endregion
#region Transitions
public tvEntryExit OnTransition_BarcodeValid = null;
public tvEntryExit OnTransition_OCR_Validation_OK = null;
public tvEntryExit OnTransition_LD_RisingEdge = null;
public tvEntryExit OnTransition_BarcodeError = null;
public tvEntryExit OnTransition_BarcodeInvalid = null;
public tvEntryExit OnTransition_OCR_ValidationNot_OK = null;
#endregion
public tvOnTransition_Barcode OnTransition_DO_CSCBarcodeValidation = null;
public enum State
{
//Super states
Input,//sub states
CSC_Barcode_Validation,OCR_BarcodeValidation,PaymentSatisfied,Transaction
}
public enum Trigger
{
OpenLane,Trg_CloseLane,Trg_BC,Trg_BarCodeRead,Trg_BarcodeError,Trg_BarcodeInvalid,Trg_BarcodeValid,Trg_OCR_ValidationNot_OK,Trg_OCR_Validation_OK,Trg_LDRisingEdge,Trg_LDFallingEdge
}
State _state = State.Input;
StateMachine<State,Trigger> _sMachine;
object oLock;
public MainStateMachine()
{
this.oLock = new object();
_sMachine = new StateMachine<State,Trigger>(() => _state,s => _state = s);
this._sMachine.OnTransitioned((otransition) => { if (this.OnTransitioned != null) this.OnTransitioned(otransition); });
this._sMachine.OnUnhandledTrigger((estate,etrigger) => { if (this.OnUnhandledTrigger != null) this.OnUnhandledTrigger(estate,etrigger); });
this.oBarcode_Trigger_With_Parameters = this._sMachine.SetTriggerParameters<string>(Trigger.Trg_BC);
//Tag/Barcode Input state
_sMachine.Configure(State.Input)
.Permit(Trigger.Trg_BC,State.CSC_Barcode_Validation)
.OnEntry(() => { if (this.OnEntry_Input != null) this.OnEntry_input(); })
.OnExit(() => { if (this.OnExit_Input != null) this.OnExit_input(); });
_sMachine.Configure(State.CSC_Barcode_Validation)
.SubstateOf(State.Input)
.OnEntryFrom(this.oBarcode_Trigger_With_Parameters,(sbarcodeserial) => { if (this.OnTransition_DO_CSCBarcodeValidation != null) this.OnTransition_DO_CSCBarcodeValidation( sbarcodeserial); })
.Permit(Trigger.Trg_BarcodeError,State.Transaction)
.Permit(Trigger.Trg_BarcodeValid,State.OCR_BarcodeValidation)
.OnEntry(() => { if (OnEntry_CSC_BarcodeValidation != null) OnEntry_CSC_BarcodeValidation(); });
_sMachine.Configure(State.OCR_BarcodeValidation)
.SubstateOf(State.Input)
.OnEntryFrom(Trigger.Trg_BarcodeValid,() =>
{
if(this.OnTransition_BarcodeValid != null) this.OnTransition_BarcodeValid();
})
.Permit(Trigger.Trg_OCR_ValidationNot_OK,State.Transaction)
.Permit(Trigger.Trg_OCR_Validation_OK,State.PaymentSatisfied);
_sMachine.Configure(State.PaymentSatisfied)
.Permit(Trigger.Trg_LDRisingEdge,State.Transaction)
.OnEntryFrom(Trigger.Trg_OCR_Validation_OK,() =>
{
if (this.OnTransition_OCR_Validation_OK != null) this.OnTransition_OCR_Validation_OK();
})
.OnEntry(() => { if (this.OnEntry_PaymentSatisfied != null) OnEntry_PaymentSatisfied(); }); //.OnExit(() => { if (this.OnExit_PaymentSatisfied != null) OnExit_PaymentSatisfied(); });
_sMachine.Configure(State.Transaction)
.OnEntryFrom(Trigger.Trg_LDRisingEdge,() =>
{
if (this.OnTransition_LD_RisingEdge != null) this.OnTransition_LD_RisingEdge();
})
.OnEntryFrom(Trigger.Trg_BarcodeError,() => { if (this.OnTransition_BarcodeError != null) this.OnTransition_BarcodeError(); })
.OnEntryFrom(Trigger.Trg_BarcodeInvalid,() => { if (this.OnTransition_BarcodeInvalid != null) this.OnTransition_BarcodeInvalid(); })
.OnEntryFrom(Trigger.Trg_OCR_ValidationNot_OK,() => { if (this.OnTransition_OCR_ValidationNot_OK != null) this.OnTransition_OCR_ValidationNot_OK(); })
.OnEntry(() => { if (this.OnEntry_FrameTransaction != null) OnEntry_FrameTransaction(); }); // on entry into this State,I have to frame a Transaction and commit it
}
public bool TryFireTrigger(Trigger etrigger)
{
bool bReturn = false;
lock (this.oLock)
{
if (this._sMachine.CanFire(etrigger))
{
try
{
this._sMachine.Fire(etrigger);
bReturn = true;
}
catch (Exception oException)
{
bReturn = false;
Console.WriteLine(oException.StackTrace);
}
}
}
return bReturn;
}
}
此状态机适用于车辆进入停车场中无人值守的摊位时的车辆。我不知道如何创建一个事务对象,因为它的属性随着状态的变化而变化。 我是否将 Transaction 对象传递给每个状态并将其修改后的状态返回并将其传递给下一个状态?我不知道该怎么做。任何帮助表示赞赏。
编辑:另一个问题。什么是子状态?
子状态继承其超状态的允许转换。当从超状态外部直接进入子状态时,将执行超状态的进入动作。同样,当从子状态离开到超状态外时,也会执行超状态的退出动作。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)