diff --git a/Unity/Assets/Yarn Spinner/Code/DialogueRunner.cs b/Unity/Assets/Yarn Spinner/Code/DialogueRunner.cs index a32b555d7..8f89ba469 100644 --- a/Unity/Assets/Yarn Spinner/Code/DialogueRunner.cs +++ b/Unity/Assets/Yarn Spinner/Code/DialogueRunner.cs @@ -129,7 +129,7 @@ public void StartDialogue (string startNode) StartCoroutine (RunDialogue (startNode)); } - IEnumerator RunDialogue (string startNode) + IEnumerator RunDialogue (string startNode = "Start") { // Mark that we're in conversation. isDialogueRunning = true; @@ -173,6 +173,24 @@ IEnumerator RunDialogue (string startNode) // out of a conversation (ie letterboxing going away, etc) isDialogueRunning = false; } + + public void Clear() { + + if (isDialogueRunning) { + throw new System.InvalidOperationException("You cannot clear the dialogue system while a dialogue is running."); + } + + dialogue.UnloadAll(); + } + + public void Stop() { + dialogue.Stop(); + } + + public bool NodeExists(string nodeName) { + return dialogue.NodeExists(nodeName); + } + } // Scripts that can act as the UI for the conversation should subclass this diff --git a/YarnSpinner/Dialogue.cs b/YarnSpinner/Dialogue.cs index 8e2cac73b..dfc2a1f09 100644 --- a/YarnSpinner/Dialogue.cs +++ b/YarnSpinner/Dialogue.cs @@ -186,7 +186,7 @@ public int LoadString(string text, bool showTokens=false, bool showParseTree=fal throw new InvalidOperationException ("Attempted to load a Yarn program, but no nodes were loaded"); } - program = loader.Compile (); + return nodesLoaded; } @@ -195,7 +195,6 @@ public int LoadString(string text, bool showTokens=false, bool showParseTree=fal // you'll get a line, command, or set of options. public IEnumerable Run(string startNode = DEFAULT_START) { - stopExecuting = false; if (LogDebugMessage == null) { throw new YarnException ("LogDebugMessage must be set before running"); @@ -205,6 +204,18 @@ public int LoadString(string text, bool showTokens=false, bool showParseTree=fal throw new YarnException ("LogErrorMessage must be set before running"); } + if (program == null && loader.nodes.Count > 0) { + program = loader.Compile(); + } + + if (program == null) { + LogErrorMessage ("Dialogue.Run was called, but no program was loaded. Stopping."); + yield break; + } + + stopExecuting = false; + + var vm = new VirtualMachine (this, program); vm.SetNode (startNode); @@ -245,12 +256,36 @@ public int LoadString(string text, bool showTokens=false, bool showParseTree=fal + } + + public void Stop() { + stopExecuting = true; + } + + public IEnumerable visitedNodes { + get { + return visitedNodeNames; + } + } + + // Unloads ALL nodes. + public void UnloadAll(bool clearVisitedNodes = true) { + if (clearVisitedNodes) + visitedNodeNames.Clear(); + + program = null; + loader.Clear (); + } public String Compile() { - var program = loader.Compile(); + program = loader.Compile(); return program.DumpCode (library); } + + public bool NodeExists(string nodeName) { + return program.nodes.ContainsKey(nodeName); + } // The standard, built-in library of functions and operators. diff --git a/YarnSpinnerTests/Test.cs b/YarnSpinnerTests/Test.cs index 10c70bbe0..6cfca431d 100644 --- a/YarnSpinnerTests/Test.cs +++ b/YarnSpinnerTests/Test.cs @@ -8,6 +8,7 @@ public class Test { Yarn.MemoryVariableStore storage = new Yarn.MemoryVariableStore(); + Yarn.Dialogue dialogue; [SetUp()] public void Init() @@ -15,13 +16,45 @@ public void Init() var newWorkingDir = System.IO.Path.Combine (Environment.CurrentDirectory, "Tests"); Environment.CurrentDirectory = newWorkingDir; + + dialogue = new Yarn.Dialogue (storage); + + dialogue.LogDebugMessage = delegate(string message) { + + Console.WriteLine (message); + + }; + + dialogue.LogErrorMessage = delegate(string message) { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine (message); + Console.ResetColor (); + }; + + dialogue.library.RegisterFunction ("assert", 1, delegate(Yarn.Value[] parameters) { + if (parameters[0].AsBool == false) + Assert.Fail ("Assertion failed"); + }); } [Test ()] - public void TestCase () + public void TestNodeExists () { + + dialogue.LoadFile ("Ship.json"); + + dialogue.Compile (); + + Assert.True (dialogue.NodeExists ("Sally")); + + // Test clearing everything + dialogue.UnloadAll (); + + // Load an empty node + dialogue.LoadString("// Test, this is empty"); + dialogue.Compile (); - var d = new Yarn.Dialogue (storage); + Assert.False (dialogue.NodeExists ("Sally")); }