- using System.Collections.Generic;
- namespace Ink.Parsed
- {
- [System.Flags]
- public enum SequenceType
- {
- Stopping = 1,
- Cycle = 2,
- Shuffle = 4,
- Once = 8
- }
- public class Sequence : Parsed.Object
- {
- public List<Parsed.Object> sequenceElements;
- public SequenceType sequenceType;
- public Sequence (List<ContentList> elementContentLists, SequenceType sequenceType)
- {
- this.sequenceType = sequenceType;
- this.sequenceElements = new List<Parsed.Object> ();
- foreach (var elementContentList in elementContentLists) {
- var contentObjs = elementContentList.content;
- Parsed.Object seqElObject = null;
-
-
- if (contentObjs == null || contentObjs.Count == 0)
- seqElObject = elementContentList;
- else
- seqElObject = new Weave (contentObjs);
-
- this.sequenceElements.Add (seqElObject);
- AddContent (seqElObject);
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public override Runtime.Object GenerateRuntimeObject ()
- {
- var container = new Runtime.Container ();
- container.visitsShouldBeCounted = true;
- container.countingAtStartOnly = true;
- _sequenceDivertsToResove = new List<SequenceDivertToResolve> ();
-
- container.AddContent (Runtime.ControlCommand.EvalStart ());
- container.AddContent (Runtime.ControlCommand.VisitIndex ());
- bool once = (sequenceType & SequenceType.Once) > 0;
- bool cycle = (sequenceType & SequenceType.Cycle) > 0;
- bool stopping = (sequenceType & SequenceType.Stopping) > 0;
- bool shuffle = (sequenceType & SequenceType.Shuffle) > 0;
- var seqBranchCount = sequenceElements.Count;
- if (once) seqBranchCount++;
-
-
-
-
- if (stopping || once) {
-
- container.AddContent (new Runtime.IntValue (seqBranchCount-1));
- container.AddContent (Runtime.NativeFunctionCall.CallWithName ("MIN"));
- }
-
- else if (cycle) {
- container.AddContent (new Runtime.IntValue (sequenceElements.Count));
- container.AddContent (Runtime.NativeFunctionCall.CallWithName ("%"));
- }
-
- if (shuffle) {
-
- var postShuffleNoOp = Runtime.ControlCommand.NoOp();
-
- if ( once || stopping )
- {
-
- int lastIdx = stopping ? sequenceElements.Count - 1 : sequenceElements.Count;
- container.AddContent(Runtime.ControlCommand.Duplicate());
- container.AddContent(new Runtime.IntValue(lastIdx));
- container.AddContent(Runtime.NativeFunctionCall.CallWithName("=="));
- var skipShuffleDivert = new Runtime.Divert();
- skipShuffleDivert.isConditional = true;
- container.AddContent(skipShuffleDivert);
- AddDivertToResolve(skipShuffleDivert, postShuffleNoOp);
- }
-
- var elementCountToShuffle = sequenceElements.Count;
- if (stopping) elementCountToShuffle--;
- container.AddContent (new Runtime.IntValue (elementCountToShuffle));
- container.AddContent (Runtime.ControlCommand.SequenceShuffleIndex ());
- if (once || stopping) container.AddContent(postShuffleNoOp);
- }
- container.AddContent (Runtime.ControlCommand.EvalEnd ());
-
- var postSequenceNoOp = Runtime.ControlCommand.NoOp();
-
-
- for (var elIndex=0; elIndex<seqBranchCount; elIndex++) {
-
-
-
- container.AddContent (Runtime.ControlCommand.EvalStart ());
- container.AddContent (Runtime.ControlCommand.Duplicate ());
- container.AddContent (new Runtime.IntValue (elIndex));
- container.AddContent (Runtime.NativeFunctionCall.CallWithName ("=="));
- container.AddContent (Runtime.ControlCommand.EvalEnd ());
-
- var sequenceDivert = new Runtime.Divert ();
- sequenceDivert.isConditional = true;
- container.AddContent (sequenceDivert);
- Runtime.Container contentContainerForSequenceBranch;
-
- if ( elIndex < sequenceElements.Count ) {
- var el = sequenceElements[elIndex];
- contentContainerForSequenceBranch = (Runtime.Container)el.runtimeObject;
- }
-
- else {
- contentContainerForSequenceBranch = new Runtime.Container();
- }
- contentContainerForSequenceBranch.name = "s" + elIndex;
- contentContainerForSequenceBranch.InsertContent(Runtime.ControlCommand.PopEvaluatedValue(), 0);
-
- var seqBranchCompleteDivert = new Runtime.Divert ();
- contentContainerForSequenceBranch.AddContent (seqBranchCompleteDivert);
- container.AddToNamedContentOnly (contentContainerForSequenceBranch);
-
- AddDivertToResolve (sequenceDivert, contentContainerForSequenceBranch);
- AddDivertToResolve (seqBranchCompleteDivert, postSequenceNoOp);
- }
- container.AddContent (postSequenceNoOp);
- return container;
- }
- void AddDivertToResolve(Runtime.Divert divert, Runtime.Object targetContent)
- {
- _sequenceDivertsToResove.Add( new SequenceDivertToResolve() {
- divert = divert,
- targetContent = targetContent
- });
- }
- public override void ResolveReferences(Story context)
- {
- base.ResolveReferences (context);
- foreach (var toResolve in _sequenceDivertsToResove) {
- toResolve.divert.targetPath = toResolve.targetContent.path;
- }
- }
- class SequenceDivertToResolve
- {
- public Runtime.Divert divert;
- public Runtime.Object targetContent;
- }
- List<SequenceDivertToResolve> _sequenceDivertsToResove;
- }
- }