I am implementing a state machine in C# and i am running into a problem. I have an event log, containing events and timestamps. When processing this, i get output with the following format: Timestamp of transition, State transitioned to, Time in state
The trouble i have here is that i do not know the time in state yet until i run the eventlog and it finds a valid transition. In my implementation i make use of some functions to handle the trigger of an event, and i return a tuple containing a string with some data (time of transition and new state) but because i do not know what the time in this state is yet i cannot write it properly yet. After the processing of an event set (multiple ways to initiate this, step function, run to breakpoint function) the string in the tuple gets written to a list, which gets written to a file when the whole event log is processed.
Do not look at the extended use of tuples too much, this is because i was testing some stuff, that part can still be optimized, i am just looking for some good idea to solve my issue with the time in state part.
Function that triggers one event:
/// <summary>
/// Trigger an event in the event log on the state machine
/// </summary>
/// <param name="ev">Event to be triggered</param>
/// <param name="oldDate">Initial date</param>
/// <param name="oldMs">Initial milliseconds</param>
/// <returns>Tuple containing output string for event log, new date and new milliseconds belonging to the date</returns>
public Tuple<Tuple<string, string, string>, DateTime, int> TriggerEvent(Event ev, DateTime oldDate, int oldMs)
{
string outputString;
int newMs = oldMs;
DateTime newDate = oldDate;
Tuple<string, string, string> outPut;
if (this.Fire(ev.Trigger))
{
int outputMs = ev.Milliseconds - oldMs;
TimeSpan outputTs = ev.Timestamp - oldDate;
if (outputMs < 0)
{
outputMs = Math.Abs(outputMs);
outputTs = outputTs.Add(TimeSpan.FromSeconds(-1));
}
string firstPart = ev.Timestamp + "." + ev.Milliseconds.ToString();
string secondPart = this.fsm.State;
string thirdPart = outputTs + "." + outputMs.ToString().PadRight(6, '0');
outputString = firstPart + "," + secondPart;// +"," + thirdPart;
newDate = ev.Timestamp;
newMs = ev.Milliseconds;
this.activeState = this.GetStateByTag(this.fsm.State);
outPut = new Tuple<string, string, string>(firstPart, secondPart, thirdPart);
}
else
{
outputString = string.Empty;
outPut = new Tuple<string, string, string>(string.Empty, string.Empty, string.Empty);
}
this.lastEvent = ev;
return new Tuple<Tuple<string, string, string>, DateTime, int>(outPut, newDate, newMs);
}
Function that processes a list of events:
/// <summary>
/// Process an event log
/// </summary>
/// <param name="list">Event list to process</param>
/// <returns>List containing the output for storage</returns>
public Tuple<List<string>, Event> ProcessEventSet(List<Event> list)
{
List<string> tmpObj = new List<string>();
Tuple<string, string, string> outPut;
if (this.initialDate == DateTime.MinValue)
{
this.initialDate = list.First().Timestamp;
this.initialMs = list.First().Milliseconds;
}
foreach (Event ev in list)
{
Tuple<Tuple<string, string, string>, DateTime, int> newData = this.TriggerEvent(ev, this.initialDate, this.initialMs);
outPut = newData.Item1;
if (!string.IsNullOrEmpty(newData.Item1.Item1))
{
string output;
if (outPut.Item3 == "00:00:00.000000")
{
output = outPut.Item1 + "," + outPut.Item2;
}
else
{
output = outPut.Item1 + "," + outPut.Item2 + "," + outPut.Item3;
}
tmpObj.Add(output);
this.initialDate = newData.Item2;
this.initialMs = newData.Item3;
}
}
return new Tuple<List<string>, Event>(tmpObj, list.Last());
}
Output i am getting:
7-1-2013 0:00:06.193133,State B,00:00:00.000000
7-1-2013 0:00:06.227664,State C,00:00:00.345310
7-1-2013 0:00:07.391359,State D,00:00:01.163695
7-1-2013 0:06:22.693034,State A,00:06:15.301675
7-1-2013 1:10:43.770820,State B,01:04:21.777860
7-1-2013 1:10:43.808832,State A,00:00:00.380120
7-1-2013 4:59:16.704133,State B,03:48:32.104699
7-1-2013 4:59:16.742639,State C,00:00:00.385060
7-1-2013 5:01:57.975030,State A,00:02:41.232391
7-1-2013 6:50:03.577993,State B,01:48:05.397037
7-1-2013 6:50:03.613139,State C,00:00:00.351460
7-1-2013 6:50:03.680799,State D,00:00:00.676600
7-1-2013 6:51:10.399170,State A,00:01:06.281629
7-1-2013 8:51:02.344653,State B,01:59:51.545170
7-1-2013 8:51:02.383053,State A,00:00:00.384000
7-1-2013 10:11:46.822542,State B,01:20:44.439489
7-1-2013 10:11:46.871144,State A,00:00:00.486020
7-1-2013 10:22:29.117037,State B,00:10:42.754107
7-1-2013 10:22:29.153400,State A,00:00:00.363630
7-1-2013 10:39:08.495431,State B,00:16:39.342031
7-1-2013 10:39:08.537063,State A,00:00:00.416320
7-1-2013 11:29:54.932916,State B,00:50:46.395853
7-1-2013 11:29:54.971428,State A,00:00:00.385120
Output i want:
7-1-2013 0:00:06.193133,State B,00:00:00.345310
7-1-2013 0:00:06.227664,State C,00:00:01.163695
7-1-2013 0:00:07.391359,State D,00:06:15.301675
7-1-2013 0:06:22.693034,State A,01:04:21.777860
7-1-2013 1:10:43.770820,State B,00:00:00.380120
7-1-2013 1:10:43.808832,State A,03:48:32.104699
7-1-2013 4:59:16.704133,State B,00:00:00.385060
7-1-2013 4:59:16.742639,State C,00:02:41.232391
7-1-2013 5:01:57.975030,State A,01:48:05.397037
7-1-2013 6:50:03.577993,State B,00:00:00.351460
7-1-2013 6:50:03.613139,State C,00:00:00.676600
7-1-2013 6:50:03.680799,State D,00:01:06.281629
7-1-2013 6:51:10.399170,State A,01:59:51.545170
7-1-2013 8:51:02.344653,State B,00:00:00.384000
7-1-2013 8:51:02.383053,State A,01:20:44.439489
7-1-2013 10:11:46.822542,State B,00:00:00.486020
7-1-2013 10:11:46.871144,State A,00:10:42.754107
7-1-2013 10:22:29.117037,State B,00:00:00.363630
7-1-2013 10:22:29.153400,State A,00:16:39.342031
7-1-2013 10:39:08.495431,State B,00:00:00.416320
7-1-2013 10:39:08.537063,State A,00:50:46.395853
7-1-2013 11:29:54.932916,State B,00:00:00.385120
7-1-2013 11:29:54.971428,State A
I have solved this by post-processing the output instead of doing it every iteration. The logic for doing this in every iteration seems to be quite hard to implement.