public override IEnumerable <IEnumerable> GetContainers(IJsonDict source) { this.Validate(source); var result = new List <IEnumerable>(3); if (source.ContainsKey("data")) { result.Add((IJsonDict)source["data"]); } if (source.ContainsKey("keys")) { result.Add((IJsonList)source["keys"]); } if (source.ContainsKey("values")) { result.Add((IJsonList)source["values"]); } return(result); }
/// <summary> /// Helper function for resolving references. Updates the passed list of references. Returns a non-null value if the parent container should replace /// its current item with the returned item. /// </summary> /// <param name="references"></param> /// <param name="item"></param> /// <returns></returns> internal IJsonDict ResolveItem(IJsonDict item) { object typeId = GetTypeIdentifier(item); object objectId = item.GetValueOrDefault("ref"); // Debug.Log(string.Format("Identified object of type {0} -- object ID: {1}", typeId, objectId)); IJsonDict referenced = (objectId == null) ? null : deserializerState.references.GetValueOrDefault(objectId); if (typeId as string == "ref") // Found a reference { if (objectId == null) { throw new SerializationException("Found a missing or null reference ID."); } // This works because we don't want to replace if the item didn't exist (and thus would return NULL), // and we do want to replace if it did (and thus would return an actual value) if (referenced == null) { // Debug.Log(string.Format("Adding new pending reference to {0}", objectId)); deserializerState.references[objectId] = item; } else { // Debug.Log(string.Format("Replacing reference with actual object of type ", referenced["type"])); } return(referenced); } // Still here? Okay. // Nested container check. TypeHandler handler = registry.GetDeserializer(typeId).CreateHandler(this); if (handler is ICollectionHandler) { // FIXME: See if this code is actually needed. if (item.ContainsKey("_visited")) { Debug.LogWarning("*** WARNING ***: Container already visited."); } else { item["_visited"] = true; foreach (var container in ((ICollectionHandler)handler).GetContainers(item)) { deserializerState.pending.Push(container); } } } if (objectId == null) { return(null); // Unreferenced object, nothing to do. } if (referenced == null) { deserializerState.references[objectId] = item; // Debug.Log("Saving reference."); } else { // Already references something else. Let's hope it's a reference. if (GetTypeIdentifier(referenced) as string != "ref") { // ... nope. Complain loudly. throw new SerializationException(string.Format("Object reference '{0}' refers to multiple non-reference objects", objectId)); } // Everything we've previously seen up until now points to the old object. It's way too much of a hassle to replace it, so... // instead we clear it and copy all of our data to it. // Debug.Log(string.Format("Copying over to actual object of type ", referenced["type"])); referenced.Clear(); foreach (JsonKey kvp in item) { referenced[kvp.Key] = kvp.Value; // Resistance is futile. You will be assimilated. } // Debug.Log("Done copying over"); } return(referenced); }