Click here to Skip to main content
15,889,595 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I'm looking at creating a state machine for a project. The project will have many algorithms each having a state machine in it. Returning an enumeration for the next state would pollute a base class enumeration, so not really thrilled about that.

Below is working code that I came up with. Not crazy about the return type of object but don't really see a way around it.

Anyone have any thoughts?

What I have tried:

C#
using System;

namespace StateMachine
{
	/// 
	public class StateMachine2BaseClass
	{
		protected void RunAlgorithm(Func<object> nextState)
		{
			while (nextState != null)
			{
				var currentState = nextState;
				nextState = (Func<object>)currentState();
			}
		}

		protected Func<object> End()
		{
			return null;
		}
	}

	/// 
	public class StateMachine2 : StateMachine2BaseClass
	{
		private int count;

		public void Run()
		{
			RunAlgorithm(Start);
		}

		private Func<object> Start()
		{
			Console.WriteLine("Start");
			return Step_1;
		}

		private Func<object> Step_1()
		{
			if (++count > 5)
				return Step_2;

			Console.WriteLine("Step 1");

			return Step_1;
		}

		private Func<object> Step_2()
		{
			Console.WriteLine("Step 2");
			return End;
		}
	}
}
Posted
Updated 7-Oct-16 4:09am
Comments
F-ES Sitecore 7-Oct-16 9:35am    
Rather than using functions to define your state you're better using classes. It might mean more coding but it'll be more flexible and type safe.

http://www.codeproject.com/Articles/43356/A-Simple-State-Machine

If you google "c# state machine" you'll find other examples too.

1 solution

As F-ES Sitecore suggests, a class - based approach would work better.
Define an abstract State class which declares an abstract DoWork method, taking as a parameter the "machine info" class which describes the information the states will operate on, if any and returning a State instance.

Then for each state you need, define a new class derived from the State class and implement the DoWork method for each.

All you have to do then is:
C#
protected void RunAlgorithm(Func<object> nextState)
    {
    State currentState = new FirstState();
    while (currentState != null)
        {
        currentState = currentState.DoWork(machineInfo);
        }
    }
The system will sort out which DoWork method it needs to call each time.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900