Skip to content

Commit 798f512

Browse files
committed
Add READ_COUNT for explicit read counts, and to be able to get the read count of a variable divert target.
1 parent ded0c8c commit 798f512

7 files changed

Lines changed: 79 additions & 29 deletions

File tree

ink-engine-runtime/ControlCommand.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public enum CommandType
1919
NoOp,
2020
ChoiceCount,
2121
TurnsSince,
22+
ReadCount,
2223
Random,
2324
SeedRandom,
2425
VisitIndex,
@@ -104,6 +105,11 @@ public static ControlCommand TurnsSince() {
104105
return new ControlCommand(CommandType.TurnsSince);
105106
}
106107

108+
public static ControlCommand ReadCount ()
109+
{
110+
return new ControlCommand (CommandType.ReadCount);
111+
}
112+
107113
public static ControlCommand Random ()
108114
{
109115
return new ControlCommand (CommandType.Random);

ink-engine-runtime/JsonSerialisation.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,7 @@ static Json()
653653
_controlCommandNames [(int)ControlCommand.CommandType.NoOp] = "nop";
654654
_controlCommandNames [(int)ControlCommand.CommandType.ChoiceCount] = "choiceCnt";
655655
_controlCommandNames [(int)ControlCommand.CommandType.TurnsSince] = "turns";
656+
_controlCommandNames [(int)ControlCommand.CommandType.ReadCount] = "readc";
656657
_controlCommandNames [(int)ControlCommand.CommandType.Random] = "rnd";
657658
_controlCommandNames [(int)ControlCommand.CommandType.SeedRandom] = "srnd";
658659
_controlCommandNames [(int)ControlCommand.CommandType.VisitIndex] = "visit";

ink-engine-runtime/Story.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class Story : Runtime.Object
1515
/// <summary>
1616
/// The current version of the ink story file format.
1717
/// </summary>
18-
public const int inkVersionCurrent = 16;
18+
public const int inkVersionCurrent = 17;
1919

2020
// Version numbers are for engine itself and story file, rather
2121
// than the story state save format (which is um, currently nonexistant)
@@ -853,6 +853,7 @@ bool PerformLogicAndFlowControl(Runtime.Object contentObj)
853853
break;
854854

855855
case ControlCommand.CommandType.TurnsSince:
856+
case ControlCommand.CommandType.ReadCount:
856857
var target = state.PopEvaluationStack();
857858
if( !(target is DivertTargetValue) ) {
858859
string extraNote = "";
@@ -864,8 +865,14 @@ bool PerformLogicAndFlowControl(Runtime.Object contentObj)
864865

865866
var divertTarget = target as DivertTargetValue;
866867
var container = ContentAtPath (divertTarget.targetPath) as Container;
867-
int turnCount = TurnsSinceForContainer (container);
868-
state.PushEvaluationStack (new IntValue (turnCount));
868+
869+
int eitherCount;
870+
if (evalCommand.commandType == ControlCommand.CommandType.TurnsSince)
871+
eitherCount = TurnsSinceForContainer (container);
872+
else
873+
eitherCount = VisitCountForContainer (container);
874+
875+
state.PushEvaluationStack (new IntValue (eitherCount));
869876
break;
870877

871878
case ControlCommand.CommandType.Random:

ink-engine-runtime/StoryState.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class StoryState
1717
/// <summary>
1818
/// The current version of the state save file JSON-based format.
1919
/// </summary>
20-
public const int kInkSaveStateVersion = 6;
20+
public const int kInkSaveStateVersion = 7;
2121
const int kMinCompatibleLoadVersion = 6;
2222

2323
/// <summary>

inklecate/ParsedHierarchy/DivertTarget.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public override void ResolveReferences (Story context)
5050
}
5151
else if( usageParent is FunctionCall ) {
5252
var funcCall = usageParent as FunctionCall;
53-
if( !funcCall.isTurnsSince ) {
53+
if( !funcCall.isTurnsSince && !funcCall.isReadCount ) {
5454
badUsage = true;
5555
}
5656
foundUsage = true;

inklecate/ParsedHierarchy/FunctionCall.cs

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ internal class FunctionCall : Expression
1212
public bool isRandom { get { return name == "RANDOM"; } }
1313
public bool isSeedRandom { get { return name == "SEED_RANDOM"; } }
1414
public bool isListRange { get { return name == "LIST_RANGE"; } }
15+
public bool isReadCount { get { return name == "READ_COUNT"; } }
1516

1617
public bool shouldPopReturnedValue;
1718

@@ -33,34 +34,37 @@ public override void GenerateIntoContainer (Runtime.Container container)
3334

3435
container.AddContent (Runtime.ControlCommand.ChoiceCount ());
3536

36-
} else if (isTurnsSince) {
37+
} else if (isTurnsSince || isReadCount) {
3738

3839
var divertTarget = arguments [0] as DivertTarget;
3940
var variableDivertTarget = arguments [0] as VariableReference;
4041

4142
if (arguments.Count != 1 || (divertTarget == null && variableDivertTarget == null)) {
42-
Error ("The TURNS_SINCE() function should take one argument: a divert target to the target knot, stitch, gather or choice you want to check. e.g. TURNS_SINCE(-> myKnot)");
43+
Error ("The "+name+"() function should take one argument: a divert target to the target knot, stitch, gather or choice you want to check. e.g. TURNS_SINCE(-> myKnot)");
4344
return;
4445
}
4546

4647
if (divertTarget) {
47-
_turnCountDivertTarget = divertTarget;
48-
AddContent (_turnCountDivertTarget);
48+
_divertTargetToCount = divertTarget;
49+
AddContent (_divertTargetToCount);
4950

50-
_turnCountDivertTarget.GenerateIntoContainer (container);
51+
_divertTargetToCount.GenerateIntoContainer (container);
5152
} else {
52-
_turnCountVariableReference = variableDivertTarget;
53-
AddContent (_turnCountVariableReference);
53+
_variableReferenceToCount = variableDivertTarget;
54+
AddContent (_variableReferenceToCount);
5455

55-
_turnCountVariableReference.GenerateIntoContainer (container);
56+
_variableReferenceToCount.GenerateIntoContainer (container);
5657

5758
if (!story.countAllVisits) {
5859
Error ("Attempting to get TURNS_SINCE for a variable target without -c compiler option. You need the compiler switch turned on so that it can track turn counts for everything, not just those you directly reference.");
5960
}
6061
}
6162

62-
63-
container.AddContent (Runtime.ControlCommand.TurnsSince ());
63+
if (isTurnsSince)
64+
container.AddContent (Runtime.ControlCommand.TurnsSince ());
65+
else
66+
container.AddContent (Runtime.ControlCommand.ReadCount ());
67+
6468
} else if (isRandom) {
6569
if (arguments.Count != 2)
6670
Error ("RANDOM should take 2 parameters: a minimum and a maximum integer");
@@ -103,7 +107,7 @@ public override void GenerateIntoContainer (Runtime.Container container)
103107
// Don't attempt to resolve as a divert
104108
content.Remove (_proxyDivert);
105109

106-
} else if (Runtime.NativeFunctionCall.CallExistsWithName(name)) {
110+
} else if (Runtime.NativeFunctionCall.CallExistsWithName (name)) {
107111

108112
var nativeCall = Runtime.NativeFunctionCall.CallWithName (name);
109113

@@ -121,8 +125,7 @@ public override void GenerateIntoContainer (Runtime.Container container)
121125

122126
// Don't attempt to resolve as a divert
123127
content.Remove (_proxyDivert);
124-
}
125-
else if (foundList != null) {
128+
} else if (foundList != null) {
126129
if (arguments.Count > 1)
127130
Error ("Can currently only construct a list from one integer (or an empty list from a given list definition)");
128131

@@ -131,7 +134,7 @@ public override void GenerateIntoContainer (Runtime.Container container)
131134
container.AddContent (new Runtime.StringValue (name));
132135
arguments [0].GenerateIntoContainer (container);
133136
container.AddContent (Runtime.ControlCommand.ListFromInt ());
134-
}
137+
}
135138

136139
// Empty list with given origin.
137140
else {
@@ -144,8 +147,8 @@ public override void GenerateIntoContainer (Runtime.Container container)
144147
content.Remove (_proxyDivert);
145148
}
146149

147-
// Normal function call
148-
else {
150+
// Normal function call
151+
else {
149152
container.AddContent (_proxyDivert.runtimeObject);
150153
}
151154

@@ -170,8 +173,8 @@ public override void ResolveReferences (Story context)
170173
arg.ResolveReferences (context);
171174
}
172175

173-
if( _turnCountDivertTarget ) {
174-
var divert = _turnCountDivertTarget.divert;
176+
if( _divertTargetToCount ) {
177+
var divert = _divertTargetToCount.divert;
175178
var attemptingTurnCountOfVariableTarget = divert.runtimeDivert.variableDivertName != null;
176179

177180
if( attemptingTurnCountOfVariableTarget ) {
@@ -189,10 +192,10 @@ public override void ResolveReferences (Story context)
189192
}
190193
}
191194

192-
else if( _turnCountVariableReference ) {
193-
var runtimeVarRef = _turnCountVariableReference.runtimeVarRef;
195+
else if( _variableReferenceToCount ) {
196+
var runtimeVarRef = _variableReferenceToCount.runtimeVarRef;
194197
if( runtimeVarRef.pathForCount != null ) {
195-
Error("Should be TURNS_SINCE(-> "+_turnCountVariableReference.name+"). Without the '->' it expects a variable target");
198+
Error("Should be "+name+"(-> "+_variableReferenceToCount.name+"). Usage without the '->' only makes sense for variable targets.");
196199
}
197200
}
198201
}
@@ -202,7 +205,12 @@ public static bool IsBuiltIn(string name)
202205
if (Runtime.NativeFunctionCall.CallExistsWithName (name))
203206
return true;
204207

205-
return name == "CHOICE_COUNT" || name == "TURNS_SINCE" || name == "RANDOM" || name == "SEED_RANDOM" || name == "LIST_VALUE";
208+
return name == "CHOICE_COUNT"
209+
|| name == "TURNS_SINCE"
210+
|| name == "RANDOM"
211+
|| name == "SEED_RANDOM"
212+
|| name == "LIST_VALUE"
213+
|| name == "READ_COUNT";
206214
}
207215

208216
public override string ToString ()
@@ -212,8 +220,8 @@ public override string ToString ()
212220
}
213221

214222
Parsed.Divert _proxyDivert;
215-
Parsed.DivertTarget _turnCountDivertTarget;
216-
Parsed.VariableReference _turnCountVariableReference;
223+
Parsed.DivertTarget _divertTargetToCount;
224+
Parsed.VariableReference _variableReferenceToCount;
217225
}
218226
}
219227

tests/Tests.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2889,6 +2889,34 @@ public void TestTunnelOnwardsWithParamDefaultChoice ()
28892889
Assert.AreEqual ("8\n", story.ContinueMaximally ());
28902890
}
28912891

2892+
2893+
[Test ()]
2894+
public void TestReadCountVariableTarget ()
2895+
{
2896+
var storyStr =
2897+
@"
2898+
VAR x = ->knot
2899+
2900+
Count start: {READ_COUNT (x)} {READ_COUNT (-> knot)} {knot}
2901+
2902+
-> x (1) ->
2903+
-> x (2) ->
2904+
-> x (3) ->
2905+
2906+
Count end: {READ_COUNT (x)} {READ_COUNT (-> knot)} {knot}
2907+
-> END
2908+
2909+
2910+
== knot (a) ==
2911+
{a}
2912+
->->
2913+
";
2914+
2915+
var story = CompileString (storyStr, countAllVisits:true);
2916+
Assert.AreEqual ("Count start: 0 0 0\n1\n2\n3\nCount end: 3 3 3\n", story.ContinueMaximally ());
2917+
}
2918+
2919+
28922920
[Test ()]
28932921
public void TestDivertTargetsWithParameters ()
28942922
{

0 commit comments

Comments
 (0)