static void Main(string[] args) { string command = ""; // Get application folder. string path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); // Setup a state machine by reading the external domain specific language program. Parser parser = new Parser(); StateMachine machine = parser.GetStateMachine(path + "\\dungeon.txt"); Console.WriteLine("Loading of External DSL completed.\n"); // Setup controller to run state machine. Controller controller = new Controller(machine); // Display some help. Console.WriteLine("> Q = Quit, ? = Available Commands"); Console.WriteLine("> Entering the dungeon."); // Execute the starting state. controller.CurrentState.Execute(); // Read commands from user to activate state machine. while (command.ToLower() != "q") { Console.Write("> "); // Read a command. command = Console.ReadLine(); // Send the command to our state machine. HandleCommand(controller, command); } }
/// <summary> /// Sends the command to the controller to handle. /// </summary> /// <param name="command">string</param> /// <param name="controller">state machine controller</param> private static void HandleCommand(Controller controller, string command) { if (!controller.Handle(command)) { if (command == "?") { // Display available commands for the given state. foreach (string eventCode in controller.CurrentState.GetEventCodes()) { Console.WriteLine(eventCode); } } else if (command.ToLower() != "q") { Console.WriteLine("Huh?"); } } }
public Parser() { // Setup a state machine with an internal DSL to handle parsing our code file. // You could actually create an external DSL code file to program the Parser itself, but for this example, we'll just utilize the code with an internal DSL. #region Setup Parser State Machine // States State idle = new State("idle"); State waitingForCommand = new State("waitingForCommand"); State waitingForCommandCode = new State("waitingForCommandCode"); State waitingForEvent = new State("waitingForEvent"); State waitingForEventCode = new State("waitingForEventCode"); State waitingForState = new State("waitingForState"); State waitingForAction = new State("waitingForAction"); State waitingForTransition = new State("waitingForTransition"); State waitingForTransitionState = new State("waitingForTransitionState"); // Events Event readCommandStart = new Event("readCommandStart", _commandsToken); Event readCommandCodeStart = new Event("readCommandCodeStart", _startCode); Event readCommandCodeEnd = new Event("readCommandCodeEnd", _endCode); Event readEventStart = new Event("readEventStart", _eventsToken); Event readEventCodeStart = new Event("readEventCodeStart", _startCode); Event readEventCodeEnd = new Event("readEventCodeEnd", _endCode); Event readActionStart = new Event("readActionStart", _actionsToken); Event readActionEnd = new Event("readActionEnd", _endCode); Event readStateStart = new Event("readStateStart", _stateToken); Event readTransitionStart = new Event("readTransitionEvent", _transitionsToken); Event readTransitionState = new Event("readTransitionState", "=>"); Event readTransitionStateEnd = new Event("readTransitionStateEnd", _endCode); Event endTransition = new Event("endTransition", "."); Event resetEvent = new Event("resetEvent", _resetToken); // Transitions idle.AddTransition(readCommandStart, waitingForCommand); idle.AddTransition(readEventStart, waitingForEvent); idle.AddTransition(readStateStart, waitingForState); waitingForCommand.AddTransition(readCommandCodeStart, waitingForCommandCode); waitingForCommandCode.AddTransition(readCommandCodeEnd, waitingForCommand); waitingForEvent.AddTransition(readEventCodeStart, waitingForEventCode); waitingForEventCode.AddTransition(readEventCodeEnd, waitingForEvent); waitingForState.AddTransition(readActionStart, waitingForAction); waitingForState.AddTransition(readTransitionStart, waitingForTransition); waitingForAction.AddTransition(readActionEnd, waitingForState); waitingForTransition.AddTransition(readTransitionState, waitingForTransitionState); waitingForTransition.AddTransition(endTransition, waitingForState); waitingForTransitionState.AddTransition(readTransitionStateEnd, waitingForTransition); // Setup state machine. _stateMachine = new StateMachine(idle); _stateMachine.AddResetEvent(resetEvent); // Setup controller. _controller = new Controller(_stateMachine); #endregion }