Пример #1
0
        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);
        }
Пример #2
0
        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;
                }
            }
        }
Пример #3
0
        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();
            }
        }