mirror of
https://github.com/Ratstail91/Mementos.git
synced 2025-11-29 10:34:27 +11:00
Committed everything
This commit is contained in:
@@ -0,0 +1,720 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ink.Runtime
|
||||
{
|
||||
public static class Json
|
||||
{
|
||||
public static List<T> JArrayToRuntimeObjList<T>(List<object> jArray, bool skipLast=false) where T : Runtime.Object
|
||||
{
|
||||
int count = jArray.Count;
|
||||
if (skipLast)
|
||||
count--;
|
||||
|
||||
var list = new List<T> (jArray.Count);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
var jTok = jArray [i];
|
||||
var runtimeObj = JTokenToRuntimeObject (jTok) as T;
|
||||
list.Add (runtimeObj);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<Runtime.Object> JArrayToRuntimeObjList(List<object> jArray, bool skipLast=false)
|
||||
{
|
||||
return JArrayToRuntimeObjList<Runtime.Object> (jArray, skipLast);
|
||||
}
|
||||
|
||||
public static void WriteDictionaryRuntimeObjs(SimpleJson.Writer writer, Dictionary<string, Runtime.Object> dictionary)
|
||||
{
|
||||
writer.WriteObjectStart();
|
||||
foreach(var keyVal in dictionary) {
|
||||
writer.WritePropertyStart(keyVal.Key);
|
||||
WriteRuntimeObject(writer, keyVal.Value);
|
||||
writer.WritePropertyEnd();
|
||||
}
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
|
||||
|
||||
public static void WriteListRuntimeObjs(SimpleJson.Writer writer, List<Runtime.Object> list)
|
||||
{
|
||||
writer.WriteArrayStart();
|
||||
foreach (var val in list)
|
||||
{
|
||||
WriteRuntimeObject(writer, val);
|
||||
}
|
||||
writer.WriteArrayEnd();
|
||||
}
|
||||
|
||||
public static void WriteIntDictionary(SimpleJson.Writer writer, Dictionary<string, int> dict)
|
||||
{
|
||||
writer.WriteObjectStart();
|
||||
foreach (var keyVal in dict)
|
||||
writer.WriteProperty(keyVal.Key, keyVal.Value);
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
|
||||
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 boolVal = obj as BoolValue;
|
||||
if (boolVal) {
|
||||
writer.Write(boolVal.value);
|
||||
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 static Dictionary<string, Runtime.Object> JObjectToDictionaryRuntimeObjs(Dictionary<string, object> jObject)
|
||||
{
|
||||
var dict = new Dictionary<string, Runtime.Object> (jObject.Count);
|
||||
|
||||
foreach (var keyVal in jObject) {
|
||||
dict [keyVal.Key] = JTokenToRuntimeObject(keyVal.Value);
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static Dictionary<string, int> JObjectToIntDictionary(Dictionary<string, object> jObject)
|
||||
{
|
||||
var dict = new Dictionary<string, int> (jObject.Count);
|
||||
foreach (var keyVal in jObject) {
|
||||
dict [keyVal.Key] = (int)keyVal.Value;
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
// ----------------------
|
||||
// JSON ENCODING SCHEME
|
||||
// ----------------------
|
||||
//
|
||||
// Glue: "<>", "G<", "G>"
|
||||
//
|
||||
// ControlCommand: "ev", "out", "/ev", "du" "pop", "->->", "~ret", "str", "/str", "nop",
|
||||
// "choiceCnt", "turns", "visit", "seq", "thread", "done", "end"
|
||||
//
|
||||
// NativeFunction: "+", "-", "/", "*", "%" "~", "==", ">", "<", ">=", "<=", "!=", "!"... etc
|
||||
//
|
||||
// Void: "void"
|
||||
//
|
||||
// Value: "^string value", "^^string value beginning with ^"
|
||||
// 5, 5.2
|
||||
// {"^->": "path.target"}
|
||||
// {"^var": "varname", "ci": 0}
|
||||
//
|
||||
// Container: [...]
|
||||
// [...,
|
||||
// {
|
||||
// "subContainerName": ...,
|
||||
// "#f": 5, // flags
|
||||
// "#n": "containerOwnName" // only if not redundant
|
||||
// }
|
||||
// ]
|
||||
//
|
||||
// Divert: {"->": "path.target", "c": true }
|
||||
// {"->": "path.target", "var": true}
|
||||
// {"f()": "path.func"}
|
||||
// {"->t->": "path.tunnel"}
|
||||
// {"x()": "externalFuncName", "exArgs": 5}
|
||||
//
|
||||
// Var Assign: {"VAR=": "varName", "re": true} // reassignment
|
||||
// {"temp=": "varName"}
|
||||
//
|
||||
// Var ref: {"VAR?": "varName"}
|
||||
// {"CNT?": "stitch name"}
|
||||
//
|
||||
// ChoicePoint: {"*": pathString,
|
||||
// "flg": 18 }
|
||||
//
|
||||
// Choice: Nothing too clever, it's only used in the save state,
|
||||
// there's not likely to be many of them.
|
||||
//
|
||||
// Tag: {"#": "the tag text"}
|
||||
public static Runtime.Object JTokenToRuntimeObject(object token)
|
||||
{
|
||||
if (token is int || token is float || token is bool) {
|
||||
return Value.Create (token);
|
||||
}
|
||||
|
||||
if (token is string) {
|
||||
string str = (string)token;
|
||||
|
||||
// String value
|
||||
char firstChar = str[0];
|
||||
if (firstChar == '^')
|
||||
return new StringValue (str.Substring (1));
|
||||
else if( firstChar == '\n' && str.Length == 1)
|
||||
return new StringValue ("\n");
|
||||
|
||||
// Glue
|
||||
if (str == "<>") return new Runtime.Glue ();
|
||||
|
||||
// Control commands (would looking up in a hash set be faster?)
|
||||
for (int i = 0; i < _controlCommandNames.Length; ++i) {
|
||||
string cmdName = _controlCommandNames [i];
|
||||
if (str == cmdName) {
|
||||
return new Runtime.ControlCommand ((ControlCommand.CommandType)i);
|
||||
}
|
||||
}
|
||||
|
||||
// Native functions
|
||||
// "^" conflicts with the way to identify strings, so now
|
||||
// we know it's not a string, we can convert back to the proper
|
||||
// symbol for the operator.
|
||||
if (str == "L^") str = "^";
|
||||
if( NativeFunctionCall.CallExistsWithName(str) )
|
||||
return NativeFunctionCall.CallWithName (str);
|
||||
|
||||
// Pop
|
||||
if (str == "->->")
|
||||
return Runtime.ControlCommand.PopTunnel ();
|
||||
else if (str == "~ret")
|
||||
return Runtime.ControlCommand.PopFunction ();
|
||||
|
||||
// Void
|
||||
if (str == "void")
|
||||
return new Runtime.Void ();
|
||||
}
|
||||
|
||||
if (token is Dictionary<string, object>) {
|
||||
|
||||
var obj = (Dictionary < string, object> )token;
|
||||
object propValue;
|
||||
|
||||
// Divert target value to path
|
||||
if (obj.TryGetValue ("^->", out propValue))
|
||||
return new DivertTargetValue (new Path ((string)propValue));
|
||||
|
||||
// VariablePointerValue
|
||||
if (obj.TryGetValue ("^var", out propValue)) {
|
||||
var varPtr = new VariablePointerValue ((string)propValue);
|
||||
if (obj.TryGetValue ("ci", out propValue))
|
||||
varPtr.contextIndex = (int)propValue;
|
||||
return varPtr;
|
||||
}
|
||||
|
||||
// Divert
|
||||
bool isDivert = false;
|
||||
bool pushesToStack = false;
|
||||
PushPopType divPushType = PushPopType.Function;
|
||||
bool external = false;
|
||||
if (obj.TryGetValue ("->", out propValue)) {
|
||||
isDivert = true;
|
||||
}
|
||||
else if (obj.TryGetValue ("f()", out propValue)) {
|
||||
isDivert = true;
|
||||
pushesToStack = true;
|
||||
divPushType = PushPopType.Function;
|
||||
}
|
||||
else if (obj.TryGetValue ("->t->", out propValue)) {
|
||||
isDivert = true;
|
||||
pushesToStack = true;
|
||||
divPushType = PushPopType.Tunnel;
|
||||
}
|
||||
else if (obj.TryGetValue ("x()", out propValue)) {
|
||||
isDivert = true;
|
||||
external = true;
|
||||
pushesToStack = false;
|
||||
divPushType = PushPopType.Function;
|
||||
}
|
||||
if (isDivert) {
|
||||
var divert = new Divert ();
|
||||
divert.pushesToStack = pushesToStack;
|
||||
divert.stackPushType = divPushType;
|
||||
divert.isExternal = external;
|
||||
|
||||
string target = propValue.ToString ();
|
||||
|
||||
if (obj.TryGetValue ("var", out propValue))
|
||||
divert.variableDivertName = target;
|
||||
else
|
||||
divert.targetPathString = target;
|
||||
|
||||
divert.isConditional = obj.TryGetValue("c", out propValue);
|
||||
|
||||
if (external) {
|
||||
if (obj.TryGetValue ("exArgs", out propValue))
|
||||
divert.externalArgs = (int)propValue;
|
||||
}
|
||||
|
||||
return divert;
|
||||
}
|
||||
|
||||
// Choice
|
||||
if (obj.TryGetValue ("*", out propValue)) {
|
||||
var choice = new ChoicePoint ();
|
||||
choice.pathStringOnChoice = propValue.ToString();
|
||||
|
||||
if (obj.TryGetValue ("flg", out propValue))
|
||||
choice.flags = (int)propValue;
|
||||
|
||||
return choice;
|
||||
}
|
||||
|
||||
// Variable reference
|
||||
if (obj.TryGetValue ("VAR?", out propValue)) {
|
||||
return new VariableReference (propValue.ToString ());
|
||||
} else if (obj.TryGetValue ("CNT?", out propValue)) {
|
||||
var readCountVarRef = new VariableReference ();
|
||||
readCountVarRef.pathStringForCount = propValue.ToString ();
|
||||
return readCountVarRef;
|
||||
}
|
||||
|
||||
// Variable assignment
|
||||
bool isVarAss = false;
|
||||
bool isGlobalVar = false;
|
||||
if (obj.TryGetValue ("VAR=", out propValue)) {
|
||||
isVarAss = true;
|
||||
isGlobalVar = true;
|
||||
} else if (obj.TryGetValue ("temp=", out propValue)) {
|
||||
isVarAss = true;
|
||||
isGlobalVar = false;
|
||||
}
|
||||
if (isVarAss) {
|
||||
var varName = propValue.ToString ();
|
||||
var isNewDecl = !obj.TryGetValue("re", out propValue);
|
||||
var varAss = new VariableAssignment (varName, isNewDecl);
|
||||
varAss.isGlobal = isGlobalVar;
|
||||
return varAss;
|
||||
}
|
||||
|
||||
// Tag
|
||||
if (obj.TryGetValue ("#", out propValue)) {
|
||||
return new Runtime.Tag ((string)propValue);
|
||||
}
|
||||
|
||||
// List value
|
||||
if (obj.TryGetValue ("list", out propValue)) {
|
||||
var listContent = (Dictionary<string, object>)propValue;
|
||||
var rawList = new InkList ();
|
||||
if (obj.TryGetValue ("origins", out propValue)) {
|
||||
var namesAsObjs = (List<object>)propValue;
|
||||
rawList.SetInitialOriginNames (namesAsObjs.Cast<string>().ToList());
|
||||
}
|
||||
foreach (var nameToVal in listContent) {
|
||||
var item = new InkListItem (nameToVal.Key);
|
||||
var val = (int)nameToVal.Value;
|
||||
rawList.Add (item, val);
|
||||
}
|
||||
return new ListValue (rawList);
|
||||
}
|
||||
|
||||
// Used when serialising save state only
|
||||
if (obj ["originalChoicePath"] != null)
|
||||
return JObjectToChoice (obj);
|
||||
}
|
||||
|
||||
// Array is always a Runtime.Container
|
||||
if (token is List<object>) {
|
||||
return JArrayToContainer((List<object>)token);
|
||||
}
|
||||
|
||||
if (token == null)
|
||||
return null;
|
||||
|
||||
throw new System.Exception ("Failed to convert token to runtime object: " + token);
|
||||
}
|
||||
|
||||
public static void WriteRuntimeContainer(SimpleJson.Writer writer, Container container, bool withoutName = false)
|
||||
{
|
||||
writer.WriteArrayStart();
|
||||
|
||||
foreach (var c in container.content)
|
||||
WriteRuntimeObject(writer, c);
|
||||
|
||||
// Container is always an array [...]
|
||||
// But the final element is always either:
|
||||
// - a dictionary containing the named content, as well as possibly
|
||||
// the key "#" with the count flags
|
||||
// - null, if neither of the above
|
||||
var namedOnlyContent = container.namedOnlyContent;
|
||||
var countFlags = container.countFlags;
|
||||
var hasNameProperty = container.name != null && !withoutName;
|
||||
|
||||
bool hasTerminator = namedOnlyContent != null || countFlags > 0 || hasNameProperty;
|
||||
|
||||
if( hasTerminator )
|
||||
writer.WriteObjectStart();
|
||||
|
||||
if ( namedOnlyContent != null ) {
|
||||
foreach(var namedContent in namedOnlyContent) {
|
||||
var name = namedContent.Key;
|
||||
var namedContainer = namedContent.Value as Container;
|
||||
writer.WritePropertyStart(name);
|
||||
WriteRuntimeContainer(writer, namedContainer, withoutName:true);
|
||||
writer.WritePropertyEnd();
|
||||
}
|
||||
}
|
||||
|
||||
if (countFlags > 0)
|
||||
writer.WriteProperty("#f", countFlags);
|
||||
|
||||
if (hasNameProperty)
|
||||
writer.WriteProperty("#n", container.name);
|
||||
|
||||
if (hasTerminator)
|
||||
writer.WriteObjectEnd();
|
||||
else
|
||||
writer.WriteNull();
|
||||
|
||||
writer.WriteArrayEnd();
|
||||
}
|
||||
|
||||
static Container JArrayToContainer(List<object> jArray)
|
||||
{
|
||||
var container = new Container ();
|
||||
container.content = JArrayToRuntimeObjList (jArray, skipLast:true);
|
||||
|
||||
// Final object in the array is always a combination of
|
||||
// - named content
|
||||
// - a "#f" key with the countFlags
|
||||
// (if either exists at all, otherwise null)
|
||||
var terminatingObj = jArray [jArray.Count - 1] as Dictionary<string, object>;
|
||||
if (terminatingObj != null) {
|
||||
|
||||
var namedOnlyContent = new Dictionary<string, Runtime.Object> (terminatingObj.Count);
|
||||
|
||||
foreach (var keyVal in terminatingObj) {
|
||||
if (keyVal.Key == "#f") {
|
||||
container.countFlags = (int)keyVal.Value;
|
||||
} else if (keyVal.Key == "#n") {
|
||||
container.name = keyVal.Value.ToString ();
|
||||
} else {
|
||||
var namedContentItem = JTokenToRuntimeObject(keyVal.Value);
|
||||
var namedSubContainer = namedContentItem as Container;
|
||||
if (namedSubContainer)
|
||||
namedSubContainer.name = keyVal.Key;
|
||||
namedOnlyContent [keyVal.Key] = namedContentItem;
|
||||
}
|
||||
}
|
||||
|
||||
container.namedOnlyContent = namedOnlyContent;
|
||||
}
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
static Choice JObjectToChoice(Dictionary<string, object> jObj)
|
||||
{
|
||||
var choice = new Choice();
|
||||
choice.text = jObj ["text"].ToString();
|
||||
choice.index = (int)jObj ["index"];
|
||||
choice.sourcePath = jObj ["originalChoicePath"].ToString();
|
||||
choice.originalThreadIndex = (int)jObj ["originalThreadIndex"];
|
||||
choice.pathStringOnChoice = jObj ["targetPath"].ToString();
|
||||
return choice;
|
||||
}
|
||||
public static void WriteChoice(SimpleJson.Writer writer, Choice choice)
|
||||
{
|
||||
writer.WriteObjectStart();
|
||||
writer.WriteProperty("text", choice.text);
|
||||
writer.WriteProperty("index", choice.index);
|
||||
writer.WriteProperty("originalChoicePath", choice.sourcePath);
|
||||
writer.WriteProperty("originalThreadIndex", choice.originalThreadIndex);
|
||||
writer.WriteProperty("targetPath", choice.pathStringOnChoice);
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
public static ListDefinitionsOrigin JTokenToListDefinitions (object obj)
|
||||
{
|
||||
var defsObj = (Dictionary<string, object>)obj;
|
||||
|
||||
var allDefs = new List<ListDefinition> ();
|
||||
|
||||
foreach (var kv in defsObj) {
|
||||
var name = (string) kv.Key;
|
||||
var listDefJson = (Dictionary<string, object>)kv.Value;
|
||||
|
||||
// Cast (string, object) to (string, int) for items
|
||||
var items = new Dictionary<string, int> ();
|
||||
foreach (var nameValue in listDefJson)
|
||||
items.Add(nameValue.Key, (int)nameValue.Value);
|
||||
|
||||
var def = new ListDefinition (name, items);
|
||||
allDefs.Add (def);
|
||||
}
|
||||
|
||||
return new ListDefinitionsOrigin (allDefs);
|
||||
}
|
||||
|
||||
static Json()
|
||||
{
|
||||
_controlCommandNames = new string[(int)ControlCommand.CommandType.TOTAL_VALUES];
|
||||
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.EvalStart] = "ev";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.EvalOutput] = "out";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.EvalEnd] = "/ev";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.Duplicate] = "du";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.PopEvaluatedValue] = "pop";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.PopFunction] = "~ret";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.PopTunnel] = "->->";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.BeginString] = "str";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.EndString] = "/str";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.NoOp] = "nop";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.ChoiceCount] = "choiceCnt";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.Turns] = "turn";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.TurnsSince] = "turns";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.ReadCount] = "readc";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.Random] = "rnd";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.SeedRandom] = "srnd";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.VisitIndex] = "visit";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.SequenceShuffleIndex] = "seq";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.StartThread] = "thread";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.Done] = "done";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.End] = "end";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.ListFromInt] = "listInt";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.ListRange] = "range";
|
||||
_controlCommandNames [(int)ControlCommand.CommandType.ListRandom] = "lrnd";
|
||||
|
||||
for (int i = 0; i < (int)ControlCommand.CommandType.TOTAL_VALUES; ++i) {
|
||||
if (_controlCommandNames [i] == null)
|
||||
throw new System.Exception ("Control command not accounted for in serialisation");
|
||||
}
|
||||
}
|
||||
|
||||
static string[] _controlCommandNames;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user