put tags in choices
This commit is contained in:
@@ -2,10 +2,9 @@ package hank;
|
||||
|
||||
import haxe.ds.Option;
|
||||
|
||||
typedef Choice = {id:Int, onceOnly:Bool, label:Option<String>, condition:Option<String>, depth:Int, output:Output, divertTarget:Option<String>};
|
||||
typedef ChoiceInfo = {choice: Choice, tags: Array<String>};
|
||||
typedef ChoicePointInfo = {choices:Array<ChoiceInfo>, fallbackIndex:Int};
|
||||
typedef FallbackChoiceInfo = {choiceInfo:ChoiceInfo, index:Int};
|
||||
typedef Choice = {id:Int, onceOnly:Bool, label:Option<String>, condition:Option<String>, depth:Int, output:Output, divertTarget:Option<String>, tags:Array<String>};
|
||||
typedef ChoicePointInfo = {choices:Array<Choice>, fallbackIndex:Int};
|
||||
typedef FallbackChoiceInfo = {choiceInfo:Choice, index:Int};
|
||||
|
||||
class ChoiceExtension {
|
||||
public static function toString(choice:Choice):String {
|
||||
|
||||
@@ -2,7 +2,6 @@ package hank;
|
||||
|
||||
import haxe.ds.Option;
|
||||
import hank.Alt.AltInstance;
|
||||
import hank.Choice.ChoiceInfo;
|
||||
import hank.Choice.ChoicePointInfo;
|
||||
|
||||
enum ExprType {
|
||||
@@ -19,8 +18,6 @@ enum ExprType {
|
||||
EGather(label:Option<String>, depth:Int, expr:ExprType);
|
||||
// Hank pre-tag-implementation: Choices are the most complicated expressions
|
||||
EChoice(c:Choice);
|
||||
// Tags: Hold my beer
|
||||
ETagged(e: ExprType, tags:Array<String>);
|
||||
}
|
||||
|
||||
typedef HankExpr = {
|
||||
@@ -56,9 +53,9 @@ class ASTExtension {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static function tryAddFunc(choices: Array<ChoiceInfo>, expectedDepth: Int, c: Choice, tags: Array<String>) {
|
||||
static function tryAddFunc(choices: Array<Choice>, expectedDepth: Int, c: Choice, tags: Array<String>) {
|
||||
var valid = (c.depth == expectedDepth);
|
||||
if (valid) choices.push({choice:c,tags:tags});
|
||||
if (valid) choices.push(c);
|
||||
return valid;
|
||||
}
|
||||
|
||||
@@ -66,7 +63,7 @@ class ASTExtension {
|
||||
Collect every choice in the choice point starting at the given index.
|
||||
**/
|
||||
public static function collectChoices(ast:HankAST, startingIndex:Int, depth:Int):ChoicePointInfo {
|
||||
var choices = new Array<ChoiceInfo>();
|
||||
var choices = new Array<Choice>();
|
||||
var lastChoiceIndex = 0;
|
||||
var tryAdd = tryAddFunc.bind(choices, depth);
|
||||
if (startingIndex > ast.length || startingIndex < 0) {
|
||||
@@ -79,8 +76,6 @@ class ASTExtension {
|
||||
// Gather choices of the current depth
|
||||
case EChoice(choice) if (tryAdd(choice, [])):
|
||||
lastChoiceIndex = i;
|
||||
case ETagged(EChoice(choice), tags) if (tryAdd(choice, tags)):
|
||||
lastChoiceIndex = i;
|
||||
// Stop at the next gather of this depth
|
||||
case EGather(_, d, _) if (d == depth):
|
||||
break;
|
||||
@@ -97,7 +92,7 @@ class ASTExtension {
|
||||
public static function findNextGather(ast:HankAST, path:String, startingIndex:Int, maxDepth:Int):Int {
|
||||
for (i in startingIndex...findEOF(ast, path)) {
|
||||
switch (ast[i].expr) {
|
||||
case EGather(_, depth, _) | ETagged(EGather(_, depth, _), _):
|
||||
case EGather(_, depth, _):
|
||||
if (depth <= maxDepth)
|
||||
return i;
|
||||
default:
|
||||
@@ -111,7 +106,7 @@ class ASTExtension {
|
||||
for (i in 0...ast.length) {
|
||||
var expr = ast[i].expr;
|
||||
switch (expr) {
|
||||
case EChoice(c) | ETagged(EChoice(c), _) | EGather(_, _, EChoice(c)):
|
||||
case EChoice(c):
|
||||
if (c.id == id)
|
||||
return i;
|
||||
default:
|
||||
|
||||
@@ -216,7 +216,8 @@ class Parser {
|
||||
condition: condition,
|
||||
depth: depth,
|
||||
output: output,
|
||||
divertTarget: divertTarget
|
||||
divertTarget: divertTarget,
|
||||
tags: []
|
||||
});
|
||||
}
|
||||
|
||||
@@ -224,7 +225,14 @@ class Parser {
|
||||
buffer.drop('#');
|
||||
var tagLine = buffer.takeLine('lr').unwrap();
|
||||
var tags = tagLine.tokenize();
|
||||
return ETagged(parseExpr(buffer, position), tags);
|
||||
var expr = parseExpr(buffer, position);
|
||||
switch (expr) {
|
||||
case EChoice(c):
|
||||
c.tags = tags;
|
||||
default:
|
||||
trace("Warning! Can't apply tags to " + expr);
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
static function haxeBlock(buffer:HankBuffer, position:HankBuffer.Position):ExprType {
|
||||
|
||||
@@ -12,7 +12,6 @@ using hank.Extensions;
|
||||
using HankAST.ASTExtension;
|
||||
|
||||
import hank.Choice;
|
||||
import hank.Choice.ChoiceInfo;
|
||||
import hank.Choice.FallbackChoiceInfo;
|
||||
using Choice.ChoiceExtension;
|
||||
|
||||
@@ -239,12 +238,12 @@ class Story {
|
||||
nextExpr = ast[nextIdx].expr;
|
||||
// trace(nextExpr);
|
||||
switch (nextExpr) {
|
||||
case EGather(_, _, exp) | ETagged(EGather(_,_,exp), _):
|
||||
case EGather(_, _, exp):
|
||||
nextExpr = exp;
|
||||
default:
|
||||
}
|
||||
switch (nextExpr) {
|
||||
case EOutput(output) | ETagged(EOutput(output), _):
|
||||
case EOutput(output):
|
||||
if (output.startsWithGlue())
|
||||
text = Output.appendNextText(this, text + " ", Output.GLUE_ERROR);
|
||||
default:
|
||||
@@ -322,7 +321,7 @@ class Story {
|
||||
++exprIndex;
|
||||
return nextFrame();
|
||||
|
||||
case EChoice(choice) | ETagged(EChoice(choice), _):
|
||||
case EChoice(choice):
|
||||
if (choice.depth > weaveDepth) {
|
||||
weaveDepth = choice.depth;
|
||||
} else if (choice.depth < weaveDepth) {
|
||||
@@ -343,7 +342,7 @@ class Story {
|
||||
var choices = availableChoices();
|
||||
var optionsText = [
|
||||
for (choiceInfo in choices)
|
||||
choiceInfo.choice.output.format(this, hInterface, random, altInstances, nodeScopes, false)
|
||||
choiceInfo.output.format(this, hInterface, random, altInstances, nodeScopes, false)
|
||||
];
|
||||
var tags = [
|
||||
for (choiceInfo in choices)
|
||||
@@ -353,30 +352,30 @@ class Story {
|
||||
return finalChoiceProcessing(optionsText, tags);
|
||||
} else {
|
||||
var fallback = fallbackChoice();
|
||||
switch (fallback.choiceInfo.choice.divertTarget) {
|
||||
switch (fallback.choiceInfo.divertTarget) {
|
||||
case Some(t) if (t.length > 0):
|
||||
var fallbackText = evaluateChoice(fallback.choiceInfo.choice);
|
||||
var fallbackText = evaluateChoice(fallback.choiceInfo);
|
||||
if (fallbackText.length > 0) {
|
||||
throw 'For some reason a fallback choice evaluated to text!';
|
||||
}
|
||||
return nextFrame();
|
||||
default:
|
||||
exprIndex = fallback.index + 1;
|
||||
weaveDepth = fallback.choiceInfo.choice.depth + 1;
|
||||
weaveDepth = fallback.choiceInfo.depth + 1;
|
||||
return nextFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function traceChoiceArray(choices:Array<ChoiceInfo>) {
|
||||
private function traceChoiceArray(choices:Array<Choice>) {
|
||||
for (choiceInfo in choices) {
|
||||
trace('${choiceInfo.choice.toString()}: #${choiceInfo.tags.join(" #")}');
|
||||
trace('${choiceInfo.toString()}: #${choiceInfo.tags.join(" #")}');
|
||||
}
|
||||
trace('---');
|
||||
}
|
||||
|
||||
private function availableChoices():Array<ChoiceInfo> {
|
||||
var choices = new Array<ChoiceInfo>();
|
||||
private function availableChoices():Array<Choice> {
|
||||
var choices = new Array<Choice>();
|
||||
|
||||
// If we're threading, collect all the childrens' choices, too.
|
||||
if (embedMode == Thread) {
|
||||
@@ -389,20 +388,18 @@ class Story {
|
||||
}
|
||||
}
|
||||
|
||||
if (exprIndex < ast.length &&
|
||||
(ast[exprIndex].expr.match(EChoice(_))
|
||||
|| ast[exprIndex].expr.match(ETagged(EChoice(_), _)))) {
|
||||
if (exprIndex < ast.length && ast[exprIndex].expr.match(EChoice(_))) {
|
||||
var allChoiceInfo = ast.collectChoices(exprIndex, weaveDepth).choices;
|
||||
for (choiceInfo in allChoiceInfo) {
|
||||
if (choicesTaken.indexOf(choiceInfo.choice.id) == -1 || !choiceInfo.choice.onceOnly) {
|
||||
switch (choiceInfo.choice.condition) {
|
||||
if (choicesTaken.indexOf(choiceInfo.id) == -1 || !choiceInfo.onceOnly) {
|
||||
switch (choiceInfo.condition) {
|
||||
case Some(expr):
|
||||
if (!hInterface.cond(expr, nodeScopes)) {
|
||||
continue;
|
||||
}
|
||||
case None:
|
||||
}
|
||||
if (!choiceInfo.choice.output.isEmpty()) {
|
||||
if (!choiceInfo.output.isEmpty()) {
|
||||
choices.push(choiceInfo);
|
||||
}
|
||||
}
|
||||
@@ -418,7 +415,7 @@ class Story {
|
||||
private function fallbackChoice():FallbackChoiceInfo {
|
||||
var choiceInfo = ast.collectChoices(exprIndex, weaveDepth);
|
||||
var lastChoice = choiceInfo.choices[choiceInfo.choices.length - 1];
|
||||
if (lastChoice.choice.output.isEmpty()) {
|
||||
if (lastChoice.output.isEmpty()) {
|
||||
return {choiceInfo: lastChoice, index: choiceInfo.fallbackIndex};
|
||||
} else {
|
||||
throw 'there is no fallback choice!';
|
||||
@@ -574,7 +571,7 @@ class Story {
|
||||
return embeddedBlocks[0].choose(choiceIndex);
|
||||
} else {
|
||||
// if not embedded, actually make the choice. availableChoices() accounts for aggregating threaded choices
|
||||
var output = evaluateChoice(availableChoices()[choiceIndex].choice);
|
||||
var output = evaluateChoice(availableChoices()[choiceIndex]);
|
||||
if (embedMode == Thread) {
|
||||
embedMode = Tunnel;
|
||||
embeddedBlocks = [];
|
||||
|
||||
Reference in New Issue
Block a user