|
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
namespace FSA
{
/// <summary>
/// Extends standard FSA functionality by adding event notifications.
/// </summary>
public class EventedAutomaton : FiniteStateAutomaton
{
private readonly FiniteStateAutomaton fsa;
private int lastOutput;
private int outputTime; // how long the same output was produced
private int stateTime; // how long the machine remained in the same state
private readonly List<int> outputInput = new List<int>(); // What input sent to the machine since last output change
private readonly List<int> outputStates = new List<int>(); // What is the state transition history since last output change
private readonly List<int> stateInput = new List<int>(); // What input sent to the machine since last state change
private readonly List<int> stateOutput = new List<int>(); // What output was produced since last state change
//private readonly List<int> prevOutputInput = new List<int>(); // What input sent to the machine since last output change
//private readonly List<int> prevOutputStates = new List<int>(); // What is the state transition history since last output change
//private readonly List<int> prevStateInput = new List<int>(); // What input sent to the machine since last state change
//private readonly List<int> prevStateOutput = new List<int>(); // What output was produced since last state change
public event EventHandler<FsaEventArgs> StateChanged;
public event EventHandler<FsaEventArgs> OutputChange;
public event EventHandler<FsaEventArgs> Moved;
public EventedAutomaton(FiniteStateAutomaton fsa)
{
this.fsa = fsa;
}
public IEnumerable<int> OutputInput
{
get { return outputInput; }
}
public IEnumerable<int> OutputStates
{
get { return outputStates; }
}
public IEnumerable<int> StateOutput
{
get { return stateOutput; }
}
public IEnumerable<int> StateInput
{
get { return stateInput; }
}
public FiniteStateAutomaton Fsa
{
get { return fsa; }
}
private void InvokeMoved(FsaEventArgs e)
{
EventHandler<FsaEventArgs> movedHandler = Moved;
if (movedHandler != null) movedHandler(this, e);
}
private void InvokeStateChanged(FsaEventArgs e)
{
EventHandler<FsaEventArgs> stateLeavedHandler = StateChanged;
if (stateLeavedHandler != null) stateLeavedHandler(this, e);
}
private void InvokeOutputChange(FsaEventArgs e)
{
EventHandler<FsaEventArgs> outputChangeHandler = OutputChange;
if (outputChangeHandler != null) outputChangeHandler(this, e);
}
public override void Reset()
{
lastOutput = 0;
outputTime = stateTime = 0;
outputStates.Clear();
outputInput.Clear();
stateOutput.Clear();
stateInput.Clear();
Fsa.Reset();
}
public override int Send(int input)
{
int prevState = Fsa.CurrentState;
int output = Fsa.Send(input);
FsaEventArgs e;
e = new FsaEventArgs {
CurrentState = Fsa.CurrentState,
Output = output,
What = FsaEvents.OutputChanged,
PreviousOutput = lastOutput,
State = prevState,
Automaton = this
};
if (output != lastOutput) {
InvokeOutputChange(e);
outputTime = 0;
outputStates.Clear();
outputInput.Clear();
}
lastOutput = output;
outputTime++;
outputStates.Add(Fsa.CurrentState);
outputInput.Add(input);
if (prevState != Fsa.CurrentState) {
InvokeStateChanged(e);
stateOutput.Clear();
stateInput.Clear();
stateTime = 0;
}
stateTime++;
stateOutput.Add(output);
stateInput.Add(input);
InvokeMoved(e);
return output;
}
public override FiniteStateAutomaton ShallowCopy()
{
EventedAutomaton clone = new EventedAutomaton(Fsa.ShallowCopy());
clone.Moved = Moved;
clone.OutputChange = OutputChange;
clone.StateChanged = StateChanged;
return clone;
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
My name is Jacek. Currently, I am a Java/kotlin developer. I like C# and Monthy Python's sense of humour.