ステートレスを使用して、複数のクラスにFSMを実装しています。(http://code.google.com/p/stateless/)
トリガーの起動やロギングなどに基本クラスを使用したい。また、baseFSMクラスを継承するすべてのクラスが、独自のローカル状態とトリガーを使用してStateMachineを実装するように強制したい。
ただし、私の問題は、列挙型を抽象化したり、関数に渡したりできないことです。
ちなみに、Statelessは「任意の.NETタイプ(数値、文字列、列挙型など)の状態とトリガーの一般的なサポート」と言っているので、これについてもっと良い方法があれば教えてください。
理想的には、これが私が実装したいものです(または同じように機能するもの)。
BaseFSMクラス:
public abstract class BaseFSM : IStateMachine
{
#region Implementation of IStateMachine
public ICall LocalCall { get; set; }
#endregion
internal abstract enum State {}
internal abstract enum Trigger {}
internal abstract StateMachine<State, Trigger> fsm { get; set; }
public abstract void Fire(Enum trigger);
}
BaseFSMを実装するクラス:
class Incoming_Initial : BaseFSM
{
private enum State
{
WaitForCallToBeAnswered,
CallConnected,
CallNeverConnected,
CheckForCustomIntro,
PlayIntro,
PlayPleaseEnterPin,
ReadLanguageSettings,
ChooseLanguage,
ValidatePIN,
PINWasInvalid,
IdentifyUser
}
private enum Trigger
{
Yes,
No,
DigitPressed,
PromptDonePlaying,
PromptTimerElapse,
Done
}
public Incoming_Initial(ICall call)
{
LocalCall = call;
fsm = new StateMachine<this.State, this.Trigger>(State.WaitForCallToBeAnswered);
....
または私はこのようなものを取るでしょう:
public class myStateMachine
{
private enum State{}
private enum Trigger{}
private StateMachine<State, Trigger> stateMachine;
public myStateMachine (Enum _states, Enum _triggers, Enum _startState)
{
State = _states;
Trigger = _triggers;
stateMachine = new StateMachine<State, Trigger>(_startState);
}
}
これを実装する方法についての洞察をいただければ幸いです。
編集:私の最終的な目標は、ステートレスを使用して、最大40の異なるFSMを持つIVR( IVR )システムを実装することです。ステートマシンは、コールフローとユーザーがシステムと対話する方法を担当します。私はすでにデモステートマシンを動作させていますが、ステートとトリガーはそのクラスにローカルです。
ステートマシンを基本クラスにプルできるかどうかを確認しようとしているだけなので、ステートマシンをヘルパー関数に渡す必要はありません。
ステートマシンを基本クラスに入れることができれば、1セットのトリガー(CallConnected、UserPressedDigit、CallDisconnected、PromptDonePlayingなどの電話からのイベント)を使用でき、FSMごとに状態を実装するだけでよいと思います。 。
@phoogに感謝します(少なくとも私がこれをどのように使用しているか):
public abstract class BaseFSM <TState> : IStateMachine
{
#region Implementation of IStateMachine
public ICall LocalCall { get; set; }
#endregion
public enum Triggers
{
Yes = 0,
No,
DigitPressed,
PromptDonePlaying,
PromptTimerElapse,
Done
}
protected IList<TState> States { get; set; }
protected StateMachine<TState, Triggers> fsm { get; set; }
...
class Incoming_Initial : BaseFSM<Incoming_Initial.State>
{
internal enum State
{
WaitForCallToBeAnswered,
CallConnected,
CallNeverConnected,
CheckForCustomIntro,
PlayIntro,
PlayPleaseEnterPin,
ReadLanguageSettings,
ChooseLanguage,
ValidatePIN,
PINWasInvalid,
IdentifyUser
}
public Incoming_Initial(ICall call)
{
LocalCall = call;
LocalCall.CallEventHandler += new CallEventHandler(LocalCall_CallEventHandler);
States = (State[]) Enum.GetValues(typeof (State));
fsm = new StateMachine<State, Triggers>(State.WaitForCallToBeAnswered);