public List <ReadStorageResult> Read(params string[] storageCapsuleIDs) { List <ReadStorageResult> storageDicts = new List <ReadStorageResult>(); RefreshCachedData(storageCapsuleIDs); foreach (var capsuleToStorage in _cachedStorageCapsules) { if (storageCapsuleIDs == null || storageCapsuleIDs.Length == 0 || Array.IndexOf(storageCapsuleIDs, capsuleToStorage.Key.ID) >= 0) { List <KeyValuePair <Type, IStorageDictionaryEditor> > refStorages = new List <KeyValuePair <Type, IStorageDictionaryEditor> >(); if (capsuleToStorage.Value.TryGetValue(ROOT_SAVE_DATA_CAPSULE_REFERENCE_ID, out StorageDictionary capsuleStorage)) { foreach (var storageItem in capsuleToStorage.Value) { if (storageItem.Key != ROOT_SAVE_DATA_CAPSULE_REFERENCE_ID) { Type referenceType = null; if (storageItem.Value.LoadValue(STORAGE_REFERENCE_TYPE_ID_ULONG_KEY, out ulong classTypeId)) { referenceType = _storageObjectFactory.GetTypeForId(classTypeId); } else if (storageItem.Value.LoadValue(STORAGE_REFERENCE_TYPE_STRING_KEY, out string referenceTypeString)) { referenceType = Type.GetType(referenceTypeString); } if (referenceType != null) { refStorages.Add(new KeyValuePair <Type, IStorageDictionaryEditor>(referenceType, storageItem.Value)); } } } } else { capsuleStorage = new StorageDictionary(capsuleToStorage.Key.ID, this); capsuleToStorage.Value.Add(ROOT_SAVE_DATA_CAPSULE_REFERENCE_ID, capsuleStorage); } storageDicts.Add(new ReadStorageResult(capsuleToStorage.Key.ID, capsuleStorage, refStorages)); } } return(storageDicts); }
public void Load(params string[] storageCapsuleIDs) { using (ActiveRefHandler = new SaveableReferenceIdHandler()) { RefreshCachedData(storageCapsuleIDs); foreach (var capsuleToStorage in _cachedStorageCapsules) { if (storageCapsuleIDs != null && storageCapsuleIDs.Length > 0 && Array.IndexOf(storageCapsuleIDs, capsuleToStorage.Key.ID) < 0) { continue; } List <ISaveable> _allLoadedReferences = new List <ISaveable>(); List <string> _allLoadedReferenceIds = new List <string>(); Action <string> referenceRequestedEventAction = (id) => { if (_allLoadedReferenceIds.Contains(id)) { return; } _allLoadedReferenceIds.Add(id); if (!capsuleToStorage.Value.TryGetValue(id, out StorageDictionary storage)) { storage = new StorageDictionary(capsuleToStorage.Key.ID, this); } if (id == ROOT_SAVE_DATA_CAPSULE_REFERENCE_ID) { capsuleToStorage.Key.Load(storage); _allLoadedReferences.Add(capsuleToStorage.Key); } else if (storage.LoadValue(STORAGE_REFERENCE_TYPE_ID_ULONG_KEY, out ulong classTypeId)) { ISaveable referenceInstance = _storageObjectFactory.LoadSaveableObject(classTypeId, storage); ActiveRefHandler.SetReferenceReady(referenceInstance, id); _allLoadedReferences.Add(referenceInstance); } else if (storage.LoadValue(STORAGE_REFERENCE_TYPE_STRING_KEY, out string classTypeFullName)) { Type referenceType = Type.GetType(classTypeFullName); bool methodLoadInterface = typeof(ISaveableLoad).IsAssignableFrom(referenceType); ISaveable referenceInstance = (methodLoadInterface ? Activator.CreateInstance(referenceType) : Activator.CreateInstance(referenceType, storage)) as ISaveable; ActiveRefHandler.SetReferenceReady(referenceInstance, id); if (methodLoadInterface) { ((ISaveableLoad)referenceInstance).Load(storage); } _allLoadedReferences.Add(referenceInstance); } else { Debug.LogErrorFormat("UNABLE TO LOAD REFERENCE ID {0}'s CLASS TYPE NAME", id); } }; ActiveRefHandler.ReferenceRequestedEvent += referenceRequestedEventAction; referenceRequestedEventAction(ROOT_SAVE_DATA_CAPSULE_REFERENCE_ID); ActiveRefHandler.LoadRemainingAsNull(); ActiveRefHandler.ReferenceRequestedEvent -= referenceRequestedEventAction; for (int i = _allLoadedReferences.Count - 1; i >= 0; i--) { _allLoadedReferences[i].LoadingCompleted(); } _allLoadedReferences = null; _allLoadedReferenceIds = null; } } }
public void Save(bool flushAfterSave, params string[] storageCapsuleIDs) { Dictionary <IStorageCapsule, Dictionary <string, StorageDictionary> > buffer = new Dictionary <IStorageCapsule, Dictionary <string, StorageDictionary> >(); Dictionary <string, IStorageCapsule> _alreadySavedReferencesToOriginCapsuleMap = new Dictionary <string, IStorageCapsule>(); using (ActiveRefHandler = new SaveableReferenceIdHandler()) { foreach (var pair in _cachedStorageCapsules) { if (storageCapsuleIDs != null && storageCapsuleIDs.Length > 0 && Array.IndexOf(storageCapsuleIDs, pair.Key.ID) < 0) { continue; } Dictionary <string, StorageDictionary> referencesSaved = new Dictionary <string, StorageDictionary>(); Action <string, ISaveable> refDetectedAction = (refID, referenceInstance) => { if (_alreadySavedReferencesToOriginCapsuleMap.TryGetValue(refID, out IStorageCapsule holdingCapsule)) { if (holdingCapsule != pair.Key) { throw new Exception(string.Format("Save aborted! Reference {0} saved in capsule {1} while capsule {2} is saving it now! Each capsule should not be saving cross references!", referenceInstance.ToString(), holdingCapsule.ID, pair.Key.ID)); } } if (!referencesSaved.ContainsKey(refID)) { StorageDictionary storageDictForRef = new StorageDictionary(pair.Key.ID, this); referencesSaved.Add(refID, storageDictForRef); storageDictForRef.SaveValue(STORAGE_REFERENCE_TYPE_STRING_KEY, referenceInstance.GetType().AssemblyQualifiedName); storageDictForRef.SaveValue(STORAGE_REFERENCE_TYPE_ID_ULONG_KEY, _storageObjectFactory.GetIdForSaveable(referenceInstance.GetType())); referenceInstance.Save(storageDictForRef); if (pair.Value.TryGetValue(refID, out StorageDictionary oldData)) { foreach (var valueKey in oldData.GetValueStorageKeys()) { if (oldData.ShouldKeepValueKey(valueKey) && !storageDictForRef.HasValueKey(valueKey)) { storageDictForRef.SetValue(valueKey, oldData.GetValueSection(valueKey).GetValue()); } } foreach (var refKey in oldData.GetRefStorageKeys()) { if (oldData.ShouldKeepRefKey(refKey) && !storageDictForRef.HasRefKey(refKey)) { storageDictForRef.SetValueRef(refKey, oldData.GetValueRef(refKey)); } } } if (refID != ROOT_SAVE_DATA_CAPSULE_REFERENCE_ID) { _alreadySavedReferencesToOriginCapsuleMap.Add(refID, pair.Key); } } }; ActiveRefHandler.IdForReferenceRequestedEvent += refDetectedAction; refDetectedAction(ROOT_SAVE_DATA_CAPSULE_REFERENCE_ID, pair.Key); ActiveRefHandler.IdForReferenceRequestedEvent -= refDetectedAction; buffer.Add(pair.Key, referencesSaved); } } foreach (var pair in buffer) { _cachedStorageCapsules[pair.Key] = pair.Value; } if (flushAfterSave) { Flush(); } }