/// <summary> /// Invokes and bubbles up output of embedded fragments and passages. /// </summary> IStoryThread CollapseThread(IStoryThread thread) { foreach (StoryOutput output in thread) { //foreach (TwineOutput scopeTag in ScopeOutputTags()) // yield return scopeTag; if (output is Embed) { var embed = (Embed)output; IStoryThread embeddedThread; if (embed is EmbedPassage) { var embedInfo = (EmbedPassage)embed; StoryPassage passage = GetPassage(embedInfo.Name); embeddedThread = passage.MainThread(); } else if (embed is EmbedFragment) { var embedInfo = (EmbedFragment)embed; embeddedThread = embedInfo.GetThread(); } else { continue; } // First yield the embed yield return(embed); // Output the content foreach (StoryOutput innerOutput in CollapseThread(embeddedThread)) { if (innerOutput != null) { innerOutput.EmbedInfo = embed; } yield return(innerOutput); } } else { yield return(output); } } //foreach (TwineOutput scopeTag in ScopeOutputTags()) // yield return scopeTag; }
void Enter(string passageName) { _passageWaitingToEnter = null; _passageEnterCueInvoked = false; _timeAccumulated = 0; _timeChangedToPlay = Time.time; this.InsertStack.Clear(); this.Output.Clear(); _groupStack.Clear(); _passageUpdateCues = null; StoryPassage passage = GetPassage(passageName); this.Tags = (string[])passage.Tags.Clone(); this.CurrentPassageName = passage.Name; PassageHistory.Add(passageName); // Prepare the thread enumerator _currentThread = CollapseThread(GetPassageThread(passage).Invoke()).GetEnumerator(); CurrentLinkInAction = null; this.State = StoryState.Playing; // Invoke the general passage enter event if (this.OnPassageEnter != null) { this.OnPassageEnter(passage); } // Story was paused, wait for it to resume if (this.State == StoryState.Paused) { return; } else { CuesInvoke(CuesGet(passage.Name, "Enter")); _passageEnterCueInvoked = true; ExecuteCurrentThread(); } }
protected virtual Func <IStoryThread> GetPassageThread(StoryPassage passage) { return(passage.MainThread); }