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); }