static void WriteInkList(SimpleJson.Writer writer, ListValue listVal) { var rawList = listVal.value; writer.WriteObjectStart(); writer.WritePropertyStart("list"); writer.WriteObjectStart(); foreach (var itemAndValue in rawList) { var item = itemAndValue.Key; int itemVal = itemAndValue.Value; writer.WritePropertyNameStart(); writer.WritePropertyNameInner(item.originName ?? "?"); writer.WritePropertyNameInner("."); writer.WritePropertyNameInner(item.itemName); writer.WritePropertyNameEnd(); writer.Write(itemVal); writer.WritePropertyEnd(); } writer.WriteObjectEnd(); writer.WritePropertyEnd(); if (rawList.Count == 0 && rawList.originNames != null && rawList.originNames.Count > 0) { writer.WritePropertyStart("origins"); writer.WriteArrayStart(); foreach (var name in rawList.originNames) { writer.Write(name); } writer.WriteArrayEnd(); writer.WritePropertyEnd(); } writer.WriteObjectEnd(); }
void PrintAllMessages() { // { "issues": ["ERROR: blah", "WARNING: blah"] } if (opts.jsonOutput) { var writer = new Runtime.SimpleJson.Writer(); writer.WriteObjectStart(); writer.WritePropertyStart("issues"); writer.WriteArrayStart(); foreach (string msg in _authorMessages) { writer.Write(msg); } foreach (string msg in _warnings) { writer.Write(msg); } foreach (string msg in _errors) { writer.Write(msg); } writer.WriteArrayEnd(); writer.WritePropertyEnd(); writer.WriteObjectEnd(); Console.Write(writer.ToString()); } // Human consumption else { PrintIssues(_authorMessages, ConsoleColor.Green); PrintIssues(_warnings, ConsoleColor.Blue); PrintIssues(_errors, ConsoleColor.Red); } _authorMessages.Clear(); _warnings.Clear(); _errors.Clear(); }
public static void WriteRuntimeObject(SimpleJson.Writer writer, Runtime.Object obj) { var container = obj as Container; if (container) { WriteRuntimeContainer(writer, container); return; } var divert = obj as Divert; if (divert) { string divTypeKey = "->"; if (divert.isExternal) { divTypeKey = "x()"; } else if (divert.pushesToStack) { if (divert.stackPushType == PushPopType.Function) { divTypeKey = "f()"; } else if (divert.stackPushType == PushPopType.Tunnel) { divTypeKey = "->t->"; } } string targetStr; if (divert.hasVariableTarget) { targetStr = divert.variableDivertName; } else { targetStr = divert.targetPathString; } writer.WriteObjectStart(); writer.WriteProperty(divTypeKey, targetStr); if (divert.hasVariableTarget) { writer.WriteProperty("var", true); } if (divert.isConditional) { writer.WriteProperty("c", true); } if (divert.externalArgs > 0) { writer.WriteProperty("exArgs", divert.externalArgs); } writer.WriteObjectEnd(); return; } var choicePoint = obj as ChoicePoint; if (choicePoint) { writer.WriteObjectStart(); writer.WriteProperty("*", choicePoint.pathStringOnChoice); writer.WriteProperty("flg", choicePoint.flags); writer.WriteObjectEnd(); return; } var intVal = obj as IntValue; if (intVal) { writer.Write(intVal.value); return; } var floatVal = obj as FloatValue; if (floatVal) { writer.Write(floatVal.value); return; } var strVal = obj as StringValue; if (strVal) { if (strVal.isNewline) { writer.Write("\\n", escape: false); } else { writer.WriteStringStart(); writer.WriteStringInner("^"); writer.WriteStringInner(strVal.value); writer.WriteStringEnd(); } return; } var listVal = obj as ListValue; if (listVal) { WriteInkList(writer, listVal); return; } var divTargetVal = obj as DivertTargetValue; if (divTargetVal) { writer.WriteObjectStart(); writer.WriteProperty("^->", divTargetVal.value.componentsString); writer.WriteObjectEnd(); return; } var varPtrVal = obj as VariablePointerValue; if (varPtrVal) { writer.WriteObjectStart(); writer.WriteProperty("^var", varPtrVal.value); writer.WriteProperty("ci", varPtrVal.contextIndex); writer.WriteObjectEnd(); return; } var glue = obj as Runtime.Glue; if (glue) { writer.Write("<>"); return; } var controlCmd = obj as ControlCommand; if (controlCmd) { writer.Write(_controlCommandNames[(int)controlCmd.commandType]); return; } var nativeFunc = obj as Runtime.NativeFunctionCall; if (nativeFunc) { var name = nativeFunc.name; // Avoid collision with ^ used to indicate a string if (name == "^") { name = "L^"; } writer.Write(name); return; } // Variable reference var varRef = obj as VariableReference; if (varRef) { writer.WriteObjectStart(); string readCountPath = varRef.pathStringForCount; if (readCountPath != null) { writer.WriteProperty("CNT?", readCountPath); } else { writer.WriteProperty("VAR?", varRef.name); } writer.WriteObjectEnd(); return; } // Variable assignment var varAss = obj as VariableAssignment; if (varAss) { writer.WriteObjectStart(); string key = varAss.isGlobal ? "VAR=" : "temp="; writer.WriteProperty(key, varAss.variableName); // Reassignment? if (!varAss.isNewDeclaration) { writer.WriteProperty("re", true); } writer.WriteObjectEnd(); return; } // Void var voidObj = obj as Void; if (voidObj) { writer.Write("void"); return; } // Tag var tag = obj as Tag; if (tag) { writer.WriteObjectStart(); writer.WriteProperty("#", tag.text); writer.WriteObjectEnd(); return; } // Used when serialising save state only var choice = obj as Choice; if (choice) { WriteChoice(writer, choice); return; } throw new System.Exception("Failed to write runtime object to JSON: " + obj); }
public void Begin() { EvaluateStory(); var rand = new Random(); while (story.currentChoices.Count > 0 || this.keepOpenAfterStoryFinish) { var choices = story.currentChoices; var choiceIdx = 0; bool choiceIsValid = false; string userDivertedPath = null; // autoPlay: Pick random choice if (autoPlay) { choiceIdx = rand.Next() % choices.Count; } // Normal: Ask user for choice number else { if (!_jsonOutput) { Console.ForegroundColor = ConsoleColor.Blue; // Add extra newline to ensure that the choice is // on a separate line. Console.WriteLine(); int i = 1; foreach (Choice choice in choices) { Console.WriteLine("{0}: {1}", i, choice.text); i++; } } else { var writer = new Runtime.SimpleJson.Writer(); writer.WriteObjectStart(); writer.WritePropertyStart("choices"); writer.WriteArrayStart(); foreach (var choice in choices) { writer.Write(choice.text); } writer.WriteArrayEnd(); writer.WritePropertyEnd(); writer.WriteObjectEnd(); Console.WriteLine(writer.ToString()); } do { if (!_jsonOutput) { // Prompt Console.Write("?> "); } else { // Johnny Five, he's alive! Console.Write("{\"needInput\": true}"); } string userInput = Console.ReadLine(); // If we have null user input, it means that we're // "at the end of the stream", or in other words, the input // stream has closed, so there's nothing more we can do. // We return immediately, since otherwise we get into a busy // loop waiting for user input. if (userInput == null) { if (_jsonOutput) { Console.WriteLine("{\"close\": true}"); } else { Console.WriteLine("<User input stream closed.>"); } return; } var result = _compiler.ReadCommandLineInput(userInput); if (result.output != null) { if (_jsonOutput) { var writer = new Runtime.SimpleJson.Writer(); writer.WriteObjectStart(); writer.WriteProperty("cmdOutput", result.output); writer.WriteObjectEnd(); Console.WriteLine(writer.ToString()); } else { Console.WriteLine(result.output); } } if (result.requestsExit) { return; } if (result.divertedPath != null) { userDivertedPath = result.divertedPath; } if (result.choiceIdx >= 0) { if (result.choiceIdx >= choices.Count) { if (!_jsonOutput) // fail silently in json mode { Console.WriteLine("Choice out of range"); } } else { choiceIdx = result.choiceIdx; choiceIsValid = true; } } } while(!choiceIsValid && userDivertedPath == null); } Console.ResetColor(); if (choiceIsValid) { story.ChooseChoiceIndex(choiceIdx); } else if (userDivertedPath != null) { story.ChoosePathString(userDivertedPath); userDivertedPath = null; } EvaluateStory(); } }
void EvaluateStory() { while (story.canContinue) { story.Continue(); _compiler.RetrieveDebugSourceForLatestContent(); if (_jsonOutput) { var writer = new Runtime.SimpleJson.Writer(); writer.WriteObjectStart(); writer.WriteProperty("text", story.currentText); writer.WriteObjectEnd(); Console.WriteLine(writer.ToString()); } else { Console.Write(story.currentText); } var tags = story.currentTags; if (tags.Count > 0) { if (_jsonOutput) { var writer = new Runtime.SimpleJson.Writer(); writer.WriteObjectStart(); writer.WritePropertyStart("tags"); writer.WriteArrayStart(); foreach (var tag in tags) { writer.Write(tag); } writer.WriteArrayEnd(); writer.WritePropertyEnd(); writer.WriteObjectEnd(); Console.WriteLine(writer.ToString()); } else { Console.WriteLine("# tags: " + string.Join(", ", tags)); } } Runtime.SimpleJson.Writer issueWriter = null; if (_jsonOutput && (_errors.Count > 0 || _warnings.Count > 0)) { issueWriter = new Runtime.SimpleJson.Writer(); issueWriter.WriteObjectStart(); issueWriter.WritePropertyStart("issues"); issueWriter.WriteArrayStart(); if (_errors.Count > 0) { foreach (var errorMsg in _errors) { issueWriter.Write(errorMsg); } } if (_warnings.Count > 0) { foreach (var warningMsg in _warnings) { issueWriter.Write(warningMsg); } } issueWriter.WriteArrayEnd(); issueWriter.WritePropertyEnd(); issueWriter.WriteObjectEnd(); Console.WriteLine(issueWriter.ToString()); } if (_errors.Count > 0 && !_jsonOutput) { foreach (var errorMsg in _errors) { Console.WriteLine(errorMsg, ConsoleColor.Red); } } if (_warnings.Count > 0 && !_jsonOutput) { foreach (var warningMsg in _warnings) { Console.WriteLine(warningMsg, ConsoleColor.Blue); } } _errors.Clear(); _warnings.Clear(); } if (story.currentChoices.Count == 0 && keepOpenAfterStoryFinish) { if (_jsonOutput) { Console.WriteLine("{\"end\": true}"); } else { Console.WriteLine("--- End of story ---"); } } }
public string RequestExternalFunctionResult(string functionName, object[] args) { var arguments = ""; for (var i = 0; i < args.Length; i++) { if (args[i] is string) { args[i] = "\"" + args[i] + "\""; } arguments += args[i]; if (i + 1 < args.Length) { arguments += ", "; } } if (!_jsonOutput) { Console.ForegroundColor = ConsoleColor.Blue; Console.Write("Enter result for " + functionName + "(" + arguments + ") > "); Console.ResetColor(); } else { var writer = new Runtime.SimpleJson.Writer(); writer.WriteObjectStart(); writer.WriteProperty("external-function", functionName); if (arguments != "") { writer.WritePropertyStart("arguments"); writer.WriteArrayStart(); writer.Write(arguments); writer.WriteArrayEnd(); writer.WritePropertyEnd(); } writer.WriteObjectEnd(); Console.WriteLine(writer.ToString()); } string userInput = Console.ReadLine(); // If we have null user input, it means that we're // "at the end of the stream", or in other words, the input // stream has closed, so there's nothing more we can do. // We return immediately, since otherwise we get into a busy // loop waiting for user input. if (userInput == null) { if (_jsonOutput) { Console.WriteLine("{\"close\": true}"); } else { Console.WriteLine("<User input stream closed.>"); } } return(userInput); }