public static Vector2 GetPos(FullSerializer.fsData jsData) { if (!jsData.IsDictionary) { return(Vector2.zero); } var data = jsData.AsDictionary; return(new Vector2((float)data["x"].AsDouble, (float)data["y"].AsDouble)); }
public bool Load(FullSerializer.fsData jsIsland) { var jsIslandData = jsIsland.AsDictionary; Id = (int)jsIslandData["id"].AsInt64; var islandPos = GameLevelJsonLoader.GetPos(jsIslandData["pos"]); var size = GameLevelJsonLoader.GetSize(jsIslandData["size"]); var resIndex = jsIslandData["res"].AsInt64; Pos = islandPos; Size = size; // back var sprite = _gameLevel.spriteLevelBack[(int)resIndex]; var backObj = EGHelpers.CreateSprite(Pos, sprite, "back_" + Id, _parentTransform, false); DebugLogger.WriteInfo("Island.Load sprite.rect = " + sprite.rect.ToString()); backObj.transform.localScale = new Vector3(Size.x * 100f / sprite.rect.width, Size.y * 100f / sprite.rect.height, 1f); var sprRender = backObj.GetComponent <SpriteRenderer>(); sprRender.sortingOrder = -2; if (jsIslandData.ContainsKey("backMesgColor")) { var sBackMesgColor = jsIslandData["backMesgColor"].AsString; float[] colors = sBackMesgColor.Split <float>(','); sprRender.color = new Color(colors[0], colors[1], colors[2]); } if (jsIslandData.ContainsKey("trees")) { var jsTreeList = jsIslandData["trees"].AsList; foreach (var jsTree in jsTreeList) { var jsTreeData = jsTree.AsDictionary; var treePos = GameLevelJsonLoader.GetPos(jsTreeData["pos"]); var treeObj = EGHelpers.CreateSpriteByScript <Tree>(islandPos + treePos, _gameLevel.spriteTree, "tree", _parentTransform, GameLevel.TerrainTagName); } } return(true); }
/// <summary> /// Writes the pretty JSON output data to the given stream. /// </summary> /// <param name="data">The data to print.</param> /// <param name="outputStream">Where to write the printed data.</param> public static void PrettyJson(fsData data, TextWriter outputStream) { BuildPrettyString(data, outputStream, 0); }
public void LoadLevel(string levelParams) { _player.Reset(); FullSerializer.fsData jsData = null; FullSerializer.fsResult res = FullSerializer.fsJsonParser.Parse(levelParams, out jsData); DebugLogger.WriteInfo("GameLevel.LoadLevel res.Failed = {0}", res.Failed.ToInt()); if (res.Failed) { DebugLogger.WriteError("GameLevel.LoadLevel error = {0}", res.FormattedMessages); return; } DebugLogger.WriteInfo("GameLevel.LoadLevel data.IsDictionary = {0}", jsData.IsDictionary.ToInt()); if (!jsData.IsDictionary) { DebugLogger.WriteError("GameLevel.LoadLevel json data is incorrect format"); return; } var isDict = jsData.IsDictionary; if (!isDict) { DebugLogger.WriteError("GameLevel.LoadLevel json data must be have node 'level'"); return; } jsData = jsData.AsDictionary["level"]; DebugLogger.WriteInfo("GameLevel.LoadLevel data.AsDictionary = {0}", jsData.IsDictionary.ToInt()); if (!jsData.IsDictionary) { DebugLogger.WriteError("GameLevel.LoadLevel level data is not dictionary"); return; } var jsLevelParams = jsData.AsDictionary; var jsTerrain = jsLevelParams["terrain"]; if (!jsTerrain.IsDictionary) { DebugLogger.WriteError("GameLevel.LoadLevel terrain data is not dictionary"); return; } _levelAllSprites = new GameObject("GameLevel"); var jsIslands = jsTerrain.AsDictionary["islands"]; var jsIslandList = jsIslands.AsList; var islandList = new List <Island>(); foreach (var jsIsland in jsIslandList) { var island = new Island(this, _levelAllSprites.transform); island.Load(jsIsland); islandList.Add(island); } if (islandList.Count == 1) { var island = islandList[0]; Field = new Rect(new Vector2(island.Pos.x - 0.5f * island.Size.x, island.Pos.y - 0.5f * island.Size.y), new Vector2(island.Size.x, island.Size.y)); } else { var minPosX = float.MaxValue; var maxPosX = float.MinValue; var minPosY = float.MaxValue; var maxPosY = float.MinValue; foreach (var island in islandList) { if (minPosX > island.Pos.x - 0.5f * island.Size.x) { minPosX = island.Pos.x - 0.5f * island.Size.x; } if (maxPosX < island.Pos.x + 0.5f * island.Size.x) { maxPosX = island.Pos.x + 0.5f * island.Size.x; } if (minPosY > island.Pos.y - 0.5f * island.Size.y) { minPosY = island.Pos.y - 0.5f * island.Size.y; } if (maxPosY < island.Pos.y + 0.5f * island.Size.y) { maxPosY = island.Pos.y + 0.5f * island.Size.y; } } Field = new Rect(new Vector2(minPosX, minPosY), new Vector2(maxPosX - minPosX, maxPosY - minPosX)); } if (jsTerrain.AsDictionary.ContainsKey("bridges")) { var jsBrigdeList = jsTerrain.AsDictionary["bridges"].AsList; foreach (var jsBrigde in jsBrigdeList) { var bridge = new Bridge(this, _levelAllSprites.transform, islandList); if (!bridge.Load(jsBrigde)) { DebugLogger.WriteError("GameLevel.LoadLevel load bridge is failed"); } } } foreach (var island in islandList) { island.CreateBorders(); } if (jsLevelParams.ContainsKey("enemy")) { var jsEnemy = jsLevelParams["enemy"]; if (jsEnemy.AsDictionary.ContainsKey("portals")) { var jsPortalList = jsEnemy.AsDictionary["portals"].AsList; foreach (var jsPortal in jsPortalList) { var jsPortalData = jsPortal.AsDictionary; int portalLevel = jsPortalData.ContainsKey("level") ? (int)jsPortalData["level"].AsInt64 : 0; var portalPos = GameLevelJsonLoader.GetPos(jsPortalData["pos"]); int islandId = jsPortalData.ContainsKey("islandId") ? (int)jsPortalData["islandId"].AsInt64 : -1; var portal = EGHelpers.CreateObjectByPrefab <Portal>((islandId == -1 ? portalPos : (portalPos + islandList.Find(it => it.Id == islandId).Pos)), prefabPortal, _levelAllSprites.transform); portal.Level = portalLevel; portal.AddObserver(_DiedObject); _enemyManager.AddEnemy(portal); } } } var jsBonus = jsLevelParams["bonus"]; var jsBonusData = jsBonus.AsDictionary; var jsGoodBonus = jsBonusData["player"].AsDictionary; PlayerUpgrade.SleepTime = (float)jsGoodBonus["sleepTime"].AsDouble; PlayerUpgrade.SpeedTime = (float)jsGoodBonus["speedTime"].AsDouble; PlayerUpgrade.ShieldTime = (float)jsGoodBonus["shieldTime"].AsDouble; PlayerUpgrade.ChildrenShieldTime = (float)jsGoodBonus["childrenShieldTime"].AsDouble; PlayerUpgrade.Health = (float)jsGoodBonus["health"].AsDouble; var jsEnemyBonus = jsBonusData["enemy"].AsDictionary; EnemyUpgrade.SleepTime = (float)jsEnemyBonus["sleepTime"].AsDouble; EnemyUpgrade.SpeedTime = (float)jsEnemyBonus["speedTime"].AsDouble; EnemyUpgrade.ShieldTime = (float)jsEnemyBonus["shieldTime"].AsDouble; EnemyUpgrade.Health = (float)jsEnemyBonus["health(%)"].AsDouble; _enemyCountText.text = String.Format("E: {0}", _enemyManager.Count.ToString()); }
/// <summary> /// Called before deserialization. /// </summary> /// <param name="storageType"> /// The field/property type that is storing the instance. /// </param> /// <param name="data"> /// The data that will be used for deserialization. /// </param> public virtual void OnBeforeDeserialize(Type storageType, ref fsData data) { }
private fsResult RunParse(out fsData data) { SkipSpace(); if (HasValue() == false) { data = default(fsData); return(MakeFailure("Unexpected end of input")); } switch (Character()) { case 'I': // Infinity case 'N': // NaN case '.': case '+': case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return(TryParseNumber(out data)); case '"': { string str; fsResult fail = TryParseString(out str); if (fail.Failed) { data = null; return(fail); } data = new fsData(str); return(fsResult.Success); } case '[': return(TryParseArray(out data)); case '{': return(TryParseObject(out data)); case 't': return(TryParseTrue(out data)); case 'f': return(TryParseFalse(out data)); case 'n': return(TryParseNull(out data)); default: data = null; return(MakeFailure("unable to parse; invalid token \"" + Character() + "\"")); } }
private fsResult InternalDeserialize_1_CycleReference(Type overrideConverterType, fsData data, Type storageType, ref object result, out List <fsObjectProcessor> processors) { // We handle object references first because we could be // deserializing a cyclic type that is inherited. If that is the // case, then if we handle references after inheritances we will try // to create an object instance for an abstract/interface type. // While object construction should technically be two-pass, we can // do it in one pass because of how serialization happens. We // traverse the serialization graph in the same order during // serialization and deserialization, so the first time we encounter // an object it'll always be the definition. Any times after that it // will be a reference. Because of this, if we encounter a reference // then we will have *always* already encountered the definition for // it. World.saveLog.takeLine("Deserial 5b"); if (IsObjectReference(data)) { int refId = int.Parse(data.AsDictionary[Key_ObjectReference].AsString); World.saveLog.takeLine("Deserial 5c"); result = _references.GetReferenceObject(refId); World.saveLog.takeLine("Deserial 5d"); processors = GetProcessors(result.GetType()); World.saveLog.takeLine("Deserial 5e"); return(fsResult.Success); } World.saveLog.takeLine("Deserial 5f"); return(InternalDeserialize_2_Version(overrideConverterType, data, storageType, ref result, out processors)); }
private fsResult InternalSerialize_4_Converter(Type overrideConverterType, object instance, out fsData data) { var instanceType = instance.GetType(); return(GetConverter(instanceType, overrideConverterType).TrySerialize(instance, out data, instanceType)); }
private fsResult InternalDeserialize_3_Inheritance(Type overrideConverterType, fsData data, Type storageType, ref object result, out List <fsObjectProcessor> processors) { var deserializeResult = fsResult.Success; Type objectType = storageType; // If the serialized state contains type information, then we need to // make sure to update our objectType and data to the proper values // so that when we construct an object instance later and run // deserialization we run it on the proper type. if (IsTypeSpecified(data)) { fsData typeNameData = data.AsDictionary[Key_InstanceType]; // we wrap everything in a do while false loop so we can break // out it do { if (typeNameData.IsString == false) { deserializeResult.AddMessage(Key_InstanceType + " value must be a string (in " + data + ")"); break; } string typeName = typeNameData.AsString; Type type = fsTypeCache.GetType(typeName); if (type == null) { deserializeResult += fsResult.Fail("Unable to locate specified type \"" + typeName + "\""); break; } if (storageType.IsAssignableFrom(type) == false) { deserializeResult.AddMessage("Ignoring type specifier; a field/property of type " + storageType + " cannot hold an instance of " + type); break; } objectType = type; } while (false); } RemapAbstractStorageTypeToDefaultType(ref objectType); // We wait until here to actually Invoke_OnBeforeDeserialize because // we do not have the correct set of processors to invoke until // *after* we have resolved the proper type to use for // deserialization. processors = GetProcessors(objectType); if (deserializeResult.Failed) { return(deserializeResult); } Invoke_OnBeforeDeserialize(processors, storageType, ref data); // Construct an object instance if we don't have one already. We also // need to construct an instance if the result type is of the wrong // type, which may be the case when we have a versioned import graph. if (ReferenceEquals(result, null) || result.GetType() != objectType) { result = GetConverter(objectType, overrideConverterType).CreateInstance(data, objectType); } // We call OnBeforeDeserializeAfterInstanceCreation here because we // still want to invoke the method even if the user passed in an // existing instance. Invoke_OnBeforeDeserializeAfterInstanceCreation(processors, storageType, result, ref data); // NOTE: It is critically important that we pass the actual // objectType down instead of using result.GetType() because it // is not guaranteed that result.GetType() will equal // objectType, especially because some converters are known to // return dummy values for CreateInstance() (for example, the // default behavior for structs is to just return the type of // the struct). return(deserializeResult += InternalDeserialize_4_Cycles(overrideConverterType, data, objectType, ref result)); }
/// <summary> /// Serialize the given value. /// </summary> /// <param name="storageType">The type of field/property that stores the object instance. This is /// important particularly for inheritance, as a field storing an IInterface instance /// should have type information included.</param> /// <param name="overrideConverterType">An fsBaseConverter derived type that will be used to serialize /// the object instead of the converter found via the normal discovery mechanisms.</param> /// <param name="instance">The actual object instance to serialize.</param> /// <param name="data">The serialized state of the object.</param> /// <returns>If serialization was successful.</returns> public fsResult TrySerialize(Type storageType, Type overrideConverterType, object instance, out fsData data) { var processors = GetProcessors(instance == null ? storageType : instance.GetType()); Invoke_OnBeforeSerialize(processors, storageType, instance); // We always serialize null directly as null if (ReferenceEquals(instance, null)) { data = new fsData(); Invoke_OnAfterSerialize(processors, storageType, instance, ref data); return(fsResult.Success); } var result = InternalSerialize_1_ProcessCycles(storageType, overrideConverterType, instance, out data); Invoke_OnAfterSerialize(processors, storageType, instance, ref data); return(result); }
protected fsResult CheckKey(fsData data, string key, out fsData subitem) { return(CheckKey(data.AsDictionary, key, out subitem)); }
protected fsResult FailExpectedType(fsData data, params fsDataType[] types) { return(fsResult.Fail(GetType().Name + " expected one of " + string.Join(", ", types.Select(t => t.ToString()).ToArray()) + " but got " + data.Type + " in " + data)); }
/// <summary> /// Deserialize data into the object instance. /// </summary> /// <param name="data">Serialization data to deserialize from.</param> /// <param name="instance">The object instance to deserialize into.</param> /// <param name="storageType">The field/property type that is storing the instance.</param> /// <returns>True if serialization was successful, false otherwise.</returns> public abstract fsResult TryDeserialize(fsData data, ref object instance, Type storageType);
/// <summary> /// Serialize the actual object into the given data storage. /// </summary> /// <param name="instance">The object instance to serialize. This will never be null.</param> /// <param name="serialized">The serialized state.</param> /// <param name="storageType">The field/property type that is storing this instance.</param> /// <returns>If serialization was successful.</returns> public abstract fsResult TrySerialize(object instance, out fsData serialized, Type storageType);
/// <summary> /// Writes the compressed JSON output data to the given stream. /// </summary> /// <param name="data">The data to print.</param> /// <param name="outputStream">Where to write the printed data.</param> public static void CompressedJson(fsData data, StreamWriter outputStream) { BuildCompressedString(data, outputStream); }
private fsResult InternalSerialize_2_Inheritance(Type storageType, Type overrideConverterType, object instance, out fsData data) { // Serialize the actual object with the field type being the same as // the object type so that we won't go into an infinite loop. var serializeResult = InternalSerialize_3_ProcessVersioning(overrideConverterType, instance, out data); if (serializeResult.Failed) { return(serializeResult); } // Do we need to add type information? If the field type and the // instance type are different then we will not be able to recover // the correct instance type from the field type when we deserialize // the object. // // Note: We allow converters to request that we do *not* add type // information. if (storageType != instance.GetType() && GetConverter(storageType, overrideConverterType).RequestInheritanceSupport(storageType)) { // Add the inheritance metadata EnsureDictionary(data); data.AsDictionary[Key_InstanceType] = new fsData(instance.GetType().FullName); } return(serializeResult); }
private fsResult InternalSerialize_3_ProcessVersioning(Type overrideConverterType, object instance, out fsData data) { // note: We do not have to take a Type parameter here, since at this // point in the serialization algorithm inheritance has // *always* been handled. If we took a type parameter, it will // *always* be equal to instance.GetType(), so why bother taking the // parameter? // Check to see if there is versioning information for this type. If // so, then we need to serialize it. fsOption <fsVersionedType> optionalVersionedType = fsVersionManager.GetVersionedType(instance.GetType()); if (optionalVersionedType.HasValue) { fsVersionedType versionedType = optionalVersionedType.Value; // Serialize the actual object content; we'll just wrap it with // versioning metadata here. var result = InternalSerialize_4_Converter(overrideConverterType, instance, out data); if (result.Failed) { return(result); } // Add the versioning information EnsureDictionary(data); data.AsDictionary[Key_Version] = new fsData(versionedType.VersionString); return(result); } // This type has no versioning information -- directly serialize it // using the selected converter. return(InternalSerialize_4_Converter(overrideConverterType, instance, out data)); }
private static void Invoke_OnAfterSerialize(List <fsObjectProcessor> processors, Type storageType, object instance, ref fsData data) { // We run the after calls in reverse order; this significantly // reduces the interaction burden between multiple processors - it // makes each one much more independent and ignorant of the other // ones. for (int i = processors.Count - 1; i >= 0; --i) { processors[i].OnAfterSerialize(storageType, instance, ref data); } }
/// <summary> /// Attempts to deserialize a value from a serialized state. /// </summary> public fsResult TryDeserialize(fsData data, Type storageType, ref object result) { return(TryDeserialize(data, storageType, null, ref result)); }
private static void Invoke_OnBeforeDeserialize(List <fsObjectProcessor> processors, Type storageType, ref fsData data) { for (int i = 0; i < processors.Count; ++i) { processors[i].OnBeforeDeserialize(storageType, ref data); } }
private fsResult TryParseObject(out fsData obj) { if (Character() != '{') { obj = null; return(MakeFailure("Expected initial { when parsing an object")); } // skip '{' if (TryMoveNext() == false) { obj = null; return(MakeFailure("Unexpected end of input when parsing an object")); } SkipSpace(); Dictionary <string, fsData> result = new Dictionary <string, fsData>( fsGlobalConfig.IsCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase); while (HasValue() && Character() != '}') { fsResult failure; // parse the key SkipSpace(); string key; failure = TryParseString(out key); if (failure.Failed) { obj = null; return(failure); } SkipSpace(); // parse the ':' after the key if (HasValue() == false || Character() != ':' || TryMoveNext() == false) { obj = null; return(MakeFailure("Expected : after key \"" + key + "\"")); } SkipSpace(); // parse the value fsData value; failure = RunParse(out value); if (failure.Failed) { obj = null; return(failure); } result.Add(key, value); // parse the comma SkipSpace(); if (HasValue() && Character() == ',') { if (TryMoveNext() == false) { break; } SkipSpace(); } } // skip the final } if (HasValue() == false || Character() != '}' || TryMoveNext() == false) { obj = null; return(MakeFailure("No closing } for object")); } obj = new fsData(result); return(fsResult.Success); }
private static void Invoke_OnBeforeDeserializeAfterInstanceCreation(List <fsObjectProcessor> processors, Type storageType, object instance, ref fsData data) { for (int i = 0; i < processors.Count; ++i) { processors[i].OnBeforeDeserializeAfterInstanceCreation(storageType, instance, ref data); } }
/// <summary> /// Called after serialization. /// </summary> /// <param name="storageType"> /// The field/property type that is storing the instance. /// </param> /// <param name="instance">The type of the instance.</param> /// <param name="data">The data that was serialized.</param> public virtual void OnAfterSerialize(Type storageType, object instance, ref fsData data) { }
/// <summary> /// Helper method that simply forwards the call to /// TrySerialize(typeof(T), instance, out data); /// </summary> public fsResult TrySerialize <T>(T instance, out fsData data) { return(TrySerialize(typeof(T), instance, out data)); }
/// <summary> /// Called before deserialization has begun but *after* the object /// instance has been created. This will get invoked even if the user /// passed in an existing instance. /// </summary> /// <remarks> /// **IMPORTANT**: The actual instance that gets passed here is *not* /// guaranteed to be an a subtype of storageType, since the value for /// instance is whatever the active converter returned for /// CreateInstance() - ie, some converters will return dummy types in /// CreateInstance() if instance creation cannot be separated from /// deserialization (ie, KeyValuePair). /// </remarks> /// <param name="storageType"> /// The field/property type that is storing the instance. /// </param> /// <param name="instance"> /// The created object instance. No deserialization has been applied to /// it. /// </param> /// <param name="data"> /// The data that will be used for deserialization. /// </param> public virtual void OnBeforeDeserializeAfterInstanceCreation(Type storageType, object instance, ref fsData data) { }
/// <summary> /// Serialize the given value. /// </summary> /// <param name="storageType"> /// The type of field/property that stores the object instance. This is /// important particularly for inheritance, as a field storing an /// IInterface instance should have type information included. /// </param> /// <param name="instance"> /// The actual object instance to serialize. /// </param> /// <param name="data">The serialized state of the object.</param> /// <returns>If serialization was successful.</returns> public fsResult TrySerialize(Type storageType, object instance, out fsData data) { return(TrySerialize(storageType, null, instance, out data)); }
/// <summary> /// Serialize the given value. /// </summary> /// <param name="storageType"> /// The type of field/property that stores the object instance. This is /// important particularly for inheritance, as a field storing an /// IInterface instance should have type information included. /// </param> /// <param name="overrideConverterType"> /// An fsBaseConverter derived type that will be used to serialize the /// object instead of the converter found via the normal discovery /// mechanisms. /// </param> /// <param name="instance"> /// The actual object instance to serialize. /// </param> /// <param name="data">The serialized state of the object.</param> /// <returns>If serialization was successful.</returns> public fsResult TrySerialize(Type storageType, Type overrideConverterType, object instance, out fsData data) { World.saveLog.takeLine("First step"); var processors = GetProcessors(instance == null ? storageType : instance.GetType()); World.saveLog.takeLine("Second step"); Invoke_OnBeforeSerialize(processors, storageType, instance); World.saveLog.takeLine("Third step"); // We always serialize null directly as null if (ReferenceEquals(instance, null)) { data = new fsData(); Invoke_OnAfterSerialize(processors, storageType, instance, ref data); return(fsResult.Success); } World.saveLog.takeLine("Forth step"); var result = InternalSerialize_1_ProcessCycles(storageType, overrideConverterType, instance, out data); World.saveLog.takeLine("Fifth step"); Invoke_OnAfterSerialize(processors, storageType, instance, ref data); World.saveLog.takeLine("Sixth step"); return(result); }
private fsResult InternalSerialize_1_ProcessCycles(Type storageType, Type overrideConverterType, object instance, out fsData data) { // We have an object definition to serialize. try { // Note that we enter the reference group at the beginning of // serialization so that we support references that are at equal // serialization levels, not just nested serialization levels, // within the given subobject. A prime example is serialization a // list of references. World.saveLog.takeLine("Internal serial 1: A. Instance " + instance); _references.Enter(); World.saveLog.takeLine("Internal serial 1: B"); // This type does not need cycle support. var converter = GetConverter(instance.GetType(), overrideConverterType); if (converter.RequestCycleSupport(instance.GetType()) == false) { return(InternalSerialize_2_Inheritance(storageType, overrideConverterType, instance, out data)); } World.saveLog.takeLine("Internal serial 1: C"); // We've already serialized this object instance (or it is // pending higher up on the call stack). Just serialize a // reference to it to escape the cycle. // // note: We serialize the int as a string to so that we don't // lose any information in a conversion to/from double. if (_references.IsReference(instance)) { data = fsData.CreateDictionary(); _lazyReferenceWriter.WriteReference(_references.GetReferenceId(instance), data.AsDictionary); return(fsResult.Success); } World.saveLog.takeLine("Internal serial 1: D"); // Mark inside the object graph that we've serialized the // instance. We do this *before* serialization so that if we get // back into this function recursively, it'll already be marked // and we can handle the cycle properly without going into an // infinite loop. _references.MarkSerialized(instance); World.saveLog.takeLine("Internal serial 1: E"); // We've created the cycle metadata, so we can now serialize the // actual object. InternalSerialize will handle inheritance // correctly for us. var result = InternalSerialize_2_Inheritance(storageType, overrideConverterType, instance, out data); if (result.Failed) { return(result); } World.saveLog.takeLine("Internal serial 1: F"); _lazyReferenceWriter.WriteDefinition(_references.GetReferenceId(instance), data); World.saveLog.takeLine("Internal serial 1: G"); return(result); } finally { if (_references.Exit()) { _lazyReferenceWriter.Clear(); } } }
public bool Load(FullSerializer.fsData jsBridge) { var jsBridgeData = jsBridge.AsDictionary; int beginId = (int)jsBridgeData["begin"].AsInt64; int endId = (int)jsBridgeData["end"].AsInt64; var resIndex = jsBridgeData["res"].AsInt64; if (!jsBridgeData.ContainsKey("orientation")) { return(false); } int orientation = (int)jsBridgeData["orientation"].AsInt64; if (!jsBridgeData.ContainsKey("pos")) { return(false); } //Pos = GameLevelJsonLoader.GetPos(jsBridgeData["pos"]); float width = (float)jsBridgeData["w"].AsDouble; var beginIsland = _islandList.Find(it => it.Id == beginId); var endIsland = _islandList.Find(it => it.Id == endId); if (beginIsland == null || endIsland == null) { DebugLogger.WriteError("Bridge.LoadLevel island is not found"); return(false); } Pos = Vector2.zero; if (orientation == 0) { // мост будет горизонтально Rectangle rect = beginIsland.IslandRect; Rectangle rect2 = endIsland.IslandRect; if (rect.IntersectsWith(rect2)) { DebugLogger.WriteError("Bridge.LoadLevel islands is intersects"); return(false); } Pos.y = (float)jsBridgeData["pos"].AsDouble; Rectangle leftIslandRect; Rectangle rightIslandRect; Island leftIsland; Island rightIsland; if (rect.X < rect2.X) { leftIslandRect = rect; leftIsland = beginIsland; rightIslandRect = rect2; rightIsland = endIsland; } else { leftIslandRect = rect2; leftIsland = endIsland; rightIslandRect = rect; rightIsland = beginIsland; } Pos.x = (leftIsland.Pos.x + rightIsland.Pos.x) / 2; /*if (Pos.x > rightIsland.Pos.x || Pos.x < leftIsland.Pos.x) { * DebugLogger.WriteError("Bridge.LoadLevel horizontal bridge of islands is impossible create"); * return false; * }*/ leftIsland.Bridges.AddBridge(Island.Side.Right, this); rightIsland.Bridges.AddBridge(Island.Side.Left, this); Size = new Vector2(rightIslandRect.Left - leftIslandRect.Right, width); CreateVBorders(Pos, new Vector2(Size.x, Thickness)); } else { // мост будет вертикально Rectangle rect = beginIsland.IslandRect; Rectangle rect2 = endIsland.IslandRect; if (rect.IntersectsWith(rect2)) { DebugLogger.WriteError("Bridge.LoadLevel islands is intersects"); return(false); } Pos.x = (float)jsBridgeData["pos"].AsDouble; Rectangle topIslandRect; Rectangle bottomIslandRect; Island topIsland; Island bottomIsland; if (rect.Y > rect2.Y) { topIslandRect = rect; topIsland = beginIsland; bottomIslandRect = rect2; bottomIsland = endIsland; } else { topIslandRect = rect2; topIsland = endIsland; bottomIslandRect = rect; bottomIsland = beginIsland; } Pos.y = (topIsland.Pos.y + bottomIsland.Pos.y) / 2; /*if (Pos.y < bottomIsland.Pos.y || Pos.y > topIsland.Pos.y) { * DebugLogger.WriteError("Bridge.LoadLevel vertical bridge of islands is impossible create"); * return false; * }*/ topIsland.Bridges.AddBridge(Island.Side.Bottom, this); bottomIsland.Bridges.AddBridge(Island.Side.Top, this); Size = new Vector2(width, topIslandRect.Bottom - bottomIslandRect.Top); CreateHBorders(Pos, new Vector2(Thickness, Size.y)); } // back var sprite = _gameLevel.spriteLevelBack[(int)resIndex]; DebugLogger.WriteInfo("Bridge.LoadLevel Pos = {0}; Size = {1}", Pos.ToString(), Size.ToString()); var backObj = EGHelpers.CreateSprite(Pos, sprite, "bridgeback_" + Id, _parentTransform, false); backObj.transform.localScale = new Vector3(Size.x * 100f / sprite.rect.width, Size.y * 100f / sprite.rect.height, 1f); var sprRender = backObj.GetComponent <SpriteRenderer>(); sprRender.sortingOrder = -1; return(true); }
/// <summary> /// Formats this data into the given builder. /// </summary> private static void BuildPrettyString(fsData data, TextWriter stream, int depth) { switch (data.Type) { case fsDataType.Null: stream.Write("null"); break; case fsDataType.Boolean: if (data.AsBool) { stream.Write("true"); } else { stream.Write("false"); } break; case fsDataType.Double: stream.Write(ConvertDoubleToString(data.AsDouble)); break; case fsDataType.Int64: stream.Write(data.AsInt64); break; case fsDataType.String: stream.Write('"'); stream.Write(EscapeString(data.AsString)); stream.Write('"'); break; case fsDataType.Object: { stream.Write('{'); stream.WriteLine(); bool comma = false; foreach (var entry in data.AsDictionary) { if (comma) { stream.Write(','); stream.WriteLine(); } comma = true; InsertSpacing(stream, depth + 1); stream.Write('"'); stream.Write(entry.Key); stream.Write('"'); stream.Write(": "); BuildPrettyString(entry.Value, stream, depth + 1); } stream.WriteLine(); InsertSpacing(stream, depth); stream.Write('}'); break; } case fsDataType.Array: // special case for empty lists; we don't put an empty line // between the brackets if (data.AsList.Count == 0) { stream.Write("[]"); } else { bool comma = false; stream.Write('['); stream.WriteLine(); foreach (var entry in data.AsList) { if (comma) { stream.Write(','); stream.WriteLine(); } comma = true; InsertSpacing(stream, depth + 1); BuildPrettyString(entry, stream, depth + 1); } stream.WriteLine(); InsertSpacing(stream, depth); stream.Write(']'); } break; } }