// Executes a node. Use this in a for-each construct; each time you iterate over it, // you'll get a line, command, or set of options. public IEnumerable<Yarn.Dialogue.RunnerResult> Run(string startNode = DEFAULT_START) { if (LogDebugMessage == null) { throw new YarnException ("LogDebugMessage must be set before running"); } if (LogErrorMessage == null) { throw new YarnException ("LogErrorMessage must be set before running"); } if (program == null) { LogErrorMessage ("Dialogue.Run was called, but no program was loaded. Stopping."); yield break; } vm = new VirtualMachine (this, program); RunnerResult latestResult; vm.lineHandler = delegate(LineResult result) { latestResult = result; }; vm.commandHandler = delegate(CommandResult result) { // Is it the special custom command "<<stop>>"? if (result is CommandResult && (result as CommandResult).command.text == "stop") { vm.Stop(); } latestResult = result; }; vm.nodeCompleteHandler = delegate(NodeCompleteResult result) { visitedNodeNames.Add (vm.currentNodeName); latestResult = result; }; vm.optionsHandler = delegate(OptionSetResult result) { latestResult = result; }; if (vm.SetNode (startNode) == false) { yield break; } // Run until the program stops, pausing to yield important // results do { latestResult = null; vm.RunNext (); if (latestResult != null) yield return latestResult; } while (vm.executionState != VirtualMachine.ExecutionState.Stopped); }