public ISerialiser GetSerialiser( string version, Type objectType) { IEnumerable <FormatVersionAttribute> matches = _versionSerialisers.Keys.Where(fva => fva.Version == version && fva.ObjectType == objectType); if (matches.Any()) { FormatVersionAttribute[] allMatches = matches.ToArray(); if (allMatches.Length == 1) { FormatVersionAttribute match = allMatches[0]; Type type = _versionSerialisers[match]; object instance = Activator.CreateInstance(type); return((ISerialiser)instance); } else { throw new MultipleVersionSerialiserMatchesException( version, objectType); } } else { throw new UnmatchedVersionSerialiserException( version, objectType); } }
public void SequentialUpgradeTest() { Vault testVault = VaultTests.CreateRandomVault(_rng); IEnumerable <FormatVersionAttribute> vaultSerialisers = FormatVersions.Instance.VersionSerialisers.Keys.Where(fva => fva.ObjectType == typeof(Vault)).OrderBy(fva => double.Parse(fva.Version)); FormatVersionAttribute[] filteredOrderedSerialisers = vaultSerialisers.ToArray(); object curSerialised = null; Vault curVault = null; string lastVersion = String.Empty; for (int curVersion = 0; curVersion < filteredOrderedSerialisers.Length; curVersion++) { if (curSerialised != null) { FormatVersionAttribute prevSerialiserAttrib = filteredOrderedSerialisers[curVersion - 1]; ISerialiser prevSerialiser = FormatVersions.Instance.GetSerialiser(prevSerialiserAttrib.Version, typeof(Vault)); curVault = (Vault)prevSerialiser.Read(curSerialised, String.Empty); } else { curVault = testVault; } FormatVersionAttribute nextSerialiserAttrib = filteredOrderedSerialisers[curVersion]; lastVersion = nextSerialiserAttrib.Version; ISerialiser nextSerialiser = FormatVersions.Instance.GetSerialiser(nextSerialiserAttrib.Version, typeof(Vault)); curSerialised = nextSerialiser.Write(curVault, String.Empty); } Assert.IsTrue(lastVersion == Framework.Serialisers.JSON.Common.LATEST_VAULT_VERSION); ISerialiser latestSerialiser = FormatVersions.GetLatestSerialiser(typeof(Vault)); curVault = (Vault)latestSerialiser.Read(curSerialised, String.Empty); Assert.IsTrue(curVault.CompareTo(testVault) == 0); }
public static T Deserialize(string json, out bool upgraded) { #if UNITY_2020 string version = JsonUtility.FromJson <T>(json).version; Type subclassType = null; string latestVersion = null; // Find which subclass to deserialize as, and what's the // latest format version. foreach (Attribute a in Attribute.GetCustomAttributes( typeof(T))) { if (!(a is FormatVersionAttribute)) { continue; } FormatVersionAttribute formatVersion = a as FormatVersionAttribute; if (formatVersion.version == version) { subclassType = formatVersion.subclassType; } if (formatVersion.isLatest) { latestVersion = formatVersion.version; } } if (subclassType == null) { throw new Exception($"Unknown version: {version}"); } if (latestVersion == null) { throw new Exception($"Latest version not defined."); } // Deserialize, upgrade if necessary, initialize if necessary. T t = JsonUtility.FromJson(json, subclassType) as T; upgraded = false; while (t.version != latestVersion) { t = t.Upgrade(); upgraded = true; } t.InitAfterDeserialize(); return(t); #else upgraded = false; return(null); #endif }
private FormatVersions() { Assembly thisAssembly = typeof(FormatVersions).Assembly; _versionSerialisers = new Dictionary <FormatVersionAttribute, Type>(); Type[] allTypes = thisAssembly.GetTypes(); foreach (Type type in allTypes) { try { if (FormatVersionAttribute.TypeHasAttribute(type)) { FormatVersionAttribute attribute = FormatVersionAttribute.GetAttributeFromType(type); _versionSerialisers.Add(attribute, type); } } catch (Exception) { //Do nothing } } }