public void Load(GameobjectSaveData fullSave)
 {
     foreach (var save in fullSave.saves)
     {
         try
         {
             Type      type = save.GetSaveType();
             Component comp = GetComponent(type);
             if (comp == null)
             {
                 throw new Exception("No component of type " + type.ToString() + " on gameobject " + gameObject.name);
             }
             ISaveableComponent saveable = (ISaveableComponent)comp;
             if (saveable == null)
             {
                 throw new Exception("Component of type " + type.ToString() + " on gameobject " + gameObject.name + " is not a ISaveable");
             }
             saveable.Load(save);
         }
         catch (Exception e)
         {
             Debug.LogError("Error when loading component due to " + e.ToString());
         }
     }
 }
예제 #2
0
        /// <summary>
        /// Returns default not unique id for specified saveable component.
        /// Returns Id specified in <see cref="SaveableComponentIdAttribute"/>. If there is no attribute then returns class name.
        /// </summary>
        /// <param name="saveableComponent">Saveable component.</param>
        /// <returns>Default not unique id for specified saveable component.</returns>
        private static string GetBaseIdForSaveableComponent(ISaveableComponent saveableComponent)
        {
            var type        = saveableComponent.GetType();
            var idAttribute = (SaveableComponentIdAttribute)type
                              .GetCustomAttributes(typeof(SaveableComponentIdAttribute), true).FirstOrDefault();
            var identifier = idAttribute != null ? idAttribute.Id : type.Name;

            return(identifier);
        }
    public static void restoreData(Dictionary <string, object> source,
                                   ISaveableComponent target, Type lastSerializedType)
    {
        FieldInfo[] fields = getFieldsFromType(target.GetType(), lastSerializedType);

        foreach (KeyValuePair <string, object> entry in source)
        {
            fields.Where(field => field.Name == entry.Key).First().
            setValue(target, getValue(entry.Value));
        }
    }
예제 #4
0
        /// <summary>
        /// Useful if you want to dynamically add a saveable component. To ensure it
        /// gets registered.
        /// </summary>
        /// <param name="identifier">The identifier for the component, this is the adress the data will be loaded from </param>
        /// <param name="iSaveableComponent">The interface reference on the component. </param>
        /// <param name="reloadData">Do you want to reload the data on all the components?
        /// Only call this if you add one component. Else call SaveMaster.ReloadListener(saveable). </param>
        public void AddSaveableComponent(string identifier, ISaveableComponent iSaveableComponent,
                                         bool reloadData = false)
        {
            _saveableComponents.Add(identifier, iSaveableComponent);

            if (reloadData)
            {
                // Load it again, to ensure all ISaveableComponent interface are updated.
                SaveSystemSingleton.Instance.GameStateManager.LoadSaveable(this);
            }
        }
예제 #5
0
        /// <summary>
        /// Returns unique id for specified saveable component.
        /// </summary>
        /// <param name="saveableComponent"></param>
        /// <returns></returns>
        private string GenerateIdForSaveableComponent(ISaveableComponent saveableComponent)
        {
            var identifier = GetBaseIdForSaveableComponent(saveableComponent);

            while (!IsIdentifierUnique(identifier))
            {
                int    guidLength = SaveSettings.Get().componentGuidLength;
                string guidString = Guid.NewGuid().ToString().Substring(0, guidLength);
                identifier = string.Format("{0}-{1}", identifier, guidString);
            }

            return(identifier);
        }
    List <ISaveableComponent> GetSaveableComponents()
    {
        List <ISaveableComponent> saveables = new List <ISaveableComponent>();
        var comps = GetComponents <Component>();

        foreach (Component c in comps)
        {
            ISaveableComponent saveable = c as ISaveableComponent;
            if (saveable != null)
            {
                saveables.Add(saveable);
            }
        }
        return(saveables);
    }
예제 #7
0
        /// <inheritdoc/>
        public void Load(JObject state)
        {
            if (loadOnce && _hasLoaded)
            {
                return;
            }

            // Ensure it loads only once with the loadOnce parameter set to true
            _hasLoaded = true;

            if (_container == null)
            {
                _container = new SaveableContainerJObject("Saveable GameObject Container");
            }
            _container.Load(state);

            foreach (var pair in _saveableComponents)
            {
                string             saveableComponentId = pair.Key;
                ISaveableComponent saveableComponent   = pair.Value;

                if (saveableComponent == null)
                {
                    Debug.LogError(
                        $"Failed to load component with id: {saveableComponentId}. Component is potentially destroyed.");
                }
                else
                {
                    if (_container.TryGetValue(saveableComponentId, out var data, saveableComponent.SaveDataType))
                    {
                        saveableComponent.Load(data);
                    }
                }
            }

            // clear empty records if any
            foreach (var emptyKey in _saveableComponents.Where(pair => pair.Value == null).Select(pair => pair.Key)
                     .ToArray())
            {
                _saveableComponents.Remove(emptyKey);
            }
        }
예제 #8
0
        public string Context => gameObject.scene.name; // todo cache?

        /// <inheritdoc/>
        public JObject Save()
        {
            foreach (var saveableComponent in _saveableComponents)
            {
                string             getIdentification    = saveableComponent.Key;
                ISaveableComponent getSaveableComponent = saveableComponent.Value;

                if (getSaveableComponent == null)
                {
                    Debug.LogError(string.Format("Failed to save component: {0}. Component is potentially destroyed.",
                                                 getIdentification));
                }
                else
                {
                    if (!_hasStateReset && !getSaveableComponent.OnSaveCondition())
                    {
                        continue;
                    }

                    var data = getSaveableComponent.Save();
                    if (data == null)
                    {
                        Debug.LogError($"Saveable component returned null data. Id: {getIdentification}", gameObject);
                    }
                    else
                    {
                        _container.Set(getIdentification, data);
                    }
                }
            }

            // clear empty records if any
            foreach (var emptyKey in _saveableComponents.Where(pair => pair.Value == null).Select(pair => pair.Key)
                     .ToArray())
            {
                _saveableComponents.Remove(emptyKey);
            }

            _hasStateReset = false;
            return(_container.Save());
        }
 protected virtual void componentRestored(ISaveableComponent c, IComponentAssigner assigner)
 {
 }
 protected virtual void componentAdded(ISaveableComponent c)
 {
 }
 public ISaveableComponent addComponent(GameObject gameObject, IComponentRecycler recycler)
 {
     createdComponent = (ISaveableComponent)recycler.getNextComponent(savedComponentType);
     componentAdded(createdComponent);
     return(createdComponent);
 }
예제 #12
0
 protected override void componentRestored(ISaveableComponent c, IComponentAssigner assigner)
 {
     ((IHybridComponent)c).restoreComponent(assigner);
 }
 protected override void componentRestored(ISaveableComponent c, IComponentAssigner assigner)
 {
     ((BaseSaveableMonoBehaviour)c).onBehaviourLoaded();
 }
 protected override void componentAdded(ISaveableComponent c)
 {
     ((BaseSaveableMonoBehaviour)c).WasCreated = true;
 }
예제 #15
0
        public void OnValidate()
        {
            if (Application.isPlaying)
            {
                return;
            }

            if (GetComponent <IGuidProvider>() == null)
            {
                Undo.AddComponent <GuidComponent>(gameObject);
            }

            List <ISaveableComponent> obtainSaveables = new List <ISaveableComponent>();

            GetComponentsInChildren(true, obtainSaveables);
            for (int i = 0; i < externalListeners.Count; i++)
            {
                if (externalListeners[i] != null)
                {
                    obtainSaveables.AddRange(externalListeners[i].GetComponentsInChildren <ISaveableComponent>(true)
                                             .ToList());
                }
            }

            for (int i = serializedSaveableComponents.Count - 1; i >= 0; i--)
            {
                if (serializedSaveableComponents[i].component == null)
                {
                    serializedSaveableComponents.RemoveAt(i);
                }
            }

            if (obtainSaveables.Count != serializedSaveableComponents.Count)
            {
                if (serializedSaveableComponents.Count > obtainSaveables.Count)
                {
                    for (int i = serializedSaveableComponents.Count - 1; i >= obtainSaveables.Count; i--)
                    {
                        serializedSaveableComponents.RemoveAt(i);
                    }
                }

                int saveableComponentCount = serializedSaveableComponents.Count;
                for (int i = saveableComponentCount - 1; i >= 0; i--)
                {
                    if (serializedSaveableComponents[i] == null)
                    {
                        serializedSaveableComponents.RemoveAt(i);
                    }
                }

                ISaveableComponent[] cachedSaveables = new ISaveableComponent[serializedSaveableComponents.Count];
                for (int i = 0; i < cachedSaveables.Length; i++)
                {
                    cachedSaveables[i] = serializedSaveableComponents[i].component as ISaveableComponent;
                }

                ISaveableComponent[] missingElements = obtainSaveables.Except(cachedSaveables).ToArray();

                for (int i = 0; i < missingElements.Length; i++)
                {
                    CachedSaveableComponent newSaveableComponent = new CachedSaveableComponent()
                    {
                        identifier = GenerateIdForSaveableComponent(missingElements[i]),
                        component  = missingElements[i] as Component
                    };

                    serializedSaveableComponents.Add(newSaveableComponent);
                }

                UnityEditor.EditorUtility.SetDirty(this);
                UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(gameObject.scene);
            }
        }
예제 #16
0
    public ISaveableComponent addComponent(GameObject gameObject, IComponentRecycler recycler)
    {
        ISaveableComponent result = (ISaveableComponent)recycler.getNextComponent(getGenericType());

        return(result);
    }