Skip to content

Commit

Permalink
Fix for mismatched left/right glue. I had assumed that only the most …
Browse files Browse the repository at this point in the history
…recent left/right glue pairs are important (therefore I was attempting to cache only the most recent right glue instance), but I was wrong. When you have an empty function, the glues end up getting mismatched, giving the wrong results. This approach requires more glue searching, but hopefully (!) isn't a major performance problem. Added test case.
  • Loading branch information
joethephish committed Sep 14, 2016
1 parent d9f7f51 commit 488a3e0
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 32 deletions.
51 changes: 19 additions & 32 deletions ink-engine-runtime/StoryState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class StoryState
/// <summary>
/// The current version of the state save file JSON-based format.
/// </summary>
public const int kInkSaveStateVersion = 4;
public const int kInkSaveStateVersion = 5;
const int kMinCompatibleLoadVersion = 4;

/// <summary>
Expand Down Expand Up @@ -200,8 +200,6 @@ internal StoryState Copy()

copy.callStack = new CallStack (callStack);

copy._currentRightGlue = _currentRightGlue;

copy.variablesState = new VariablesState (copy.callStack);
copy.variablesState.CopyFrom (variablesState);

Expand Down Expand Up @@ -260,13 +258,6 @@ public Dictionary<string, object> jsonToken

obj ["currentChoices"] = Json.ListToJArray (currentChoices);

if (_currentRightGlue) {
int rightGluePos = _outputStream.IndexOf (_currentRightGlue);
if( rightGluePos != -1 ) {
obj ["currRightGlue"] = _outputStream.IndexOf (_currentRightGlue);
}
}

if( divertedTargetObject != null )
obj ["currentDivertTarget"] = divertedTargetObject.path.componentsString;

Expand Down Expand Up @@ -304,14 +295,6 @@ public Dictionary<string, object> jsonToken

currentChoices = Json.JArrayToRuntimeObjList<Choice>((List<object>)jObject ["currentChoices"]);

object propValue;
if( jObject.TryGetValue("currRightGlue", out propValue ) ) {
int gluePos = (int)propValue;
if( gluePos >= 0 ) {
_currentRightGlue = _outputStream [gluePos] as Glue;
}
}

object currentDivertTargetPath;
if (jObject.TryGetValue("currentDivertTarget", out currentDivertTargetPath)) {
var divertPath = new Path (currentDivertTargetPath.ToString ());
Expand Down Expand Up @@ -463,12 +446,10 @@ void PushToOutputStreamIndividual(Runtime.Object obj)
bool includeInOutput = true;

if (glue) {

// Found matching left-glue for right-glue? Close it.
bool foundMatchingLeftGlue = glue.isLeft && _currentRightGlue && glue.parent == _currentRightGlue.parent;
if (foundMatchingLeftGlue) {
_currentRightGlue = null;
}
var existingRightGlue = currentRightGlue;
bool foundMatchingLeftGlue = glue.isLeft && existingRightGlue && glue.parent == existingRightGlue.parent;

// Left/Right glue is auto-generated for inline expressions
// where we want to absorb newlines but only in a certain direction.
Expand All @@ -477,13 +458,7 @@ void PushToOutputStreamIndividual(Runtime.Object obj)
TrimNewlinesFromOutputStream(stopAndRemoveRightGlue:foundMatchingLeftGlue);
}

// New right-glue
bool isNewRightGlue = glue.isRight && _currentRightGlue == null;
if (isNewRightGlue) {
_currentRightGlue = glue;
}

includeInOutput = glue.isBi || isNewRightGlue;
includeInOutput = glue.isBi || glue.isRight;
}

else if( text ) {
Expand All @@ -501,7 +476,6 @@ void PushToOutputStreamIndividual(Runtime.Object obj)
// Able to completely reset when
else if (text.isNonWhitespace) {
RemoveExistingGlue ();
_currentRightGlue = null;
}
} else if (text.isNewline) {
if (outputStreamEndsInNewline || !outputStreamContainsContent)
Expand Down Expand Up @@ -603,6 +577,20 @@ int currentGlueIndex {
}
}

Runtime.Glue currentRightGlue {
get {
for (int i = _outputStream.Count - 1; i >= 0; i--) {
var c = _outputStream [i];
var glue = c as Glue;
if (glue && glue.isRight)
return glue;
else if (c is ControlCommand) // e.g. BeginString
break;
}
return null;
}
}

internal bool outputStreamEndsInNewline {
get {
if (_outputStream.Count > 0) {
Expand Down Expand Up @@ -720,7 +708,6 @@ internal void AddError(string message)
// REMEMBER! REMEMBER! REMEMBER!

List<Runtime.Object> _outputStream;
Runtime.Glue _currentRightGlue;
}
}

21 changes: 21 additions & 0 deletions tests/Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2405,6 +2405,27 @@ Should be able to get here!
Assert.IsTrue (HadError ("it shouldn't be preceded by '->'"));
}

[Test ()]
public void TestLeftRightGlueMatching ()
{
var storyStr =
@"
A line.
{ f():
Another line.
}
== function f ==
{false:nothing}
~ return true
";
var story = CompileString (storyStr);

Assert.AreEqual ("A line.\nAnother line.\n", story.ContinueMaximally ());
}


// Helper compile function
protected Story CompileString(string str, bool countAllVisits = false, bool testingErrors = false)
{
Expand Down

0 comments on commit 488a3e0

Please sign in to comment.