示例#1
0
        public override void OnBeforeSerialize(Type storageType, object instance)
        {
            CompRef        cref = instance as CompRef;
            SavedComponent comp = cref.component;

            if (comp != null)
            {
                cref.isNull = false;
                if (blueprint)
                {
                    cref.entity_ID = comp.Entity.blueprintID;
                }
                else
                {
                    cref.entity_ID = comp.Entity.ID;
                }

                cref.component_ID = comp.componentID;
                cref.entityName   = comp.Entity.name;
            }
            else
            {
                cref.isNull = true;
            }
            cref.component = null;
        }
示例#2
0
        static void SetDataForComponent(SavedComponent comp, SaveData data)
        {
            Type t     = comp.GetType();
            var  field = findDataField(t);

            if (field != null)
            {
                field.SetValue(comp, data);
            }
        }
示例#3
0
        /// <summary>
        /// Attempts to deserialize a value from a serialized state.
        /// </summary>
        public fsResult TryDeserialize(fsData data, Type storageType, Type overrideConverterType, ref object result)
        {
            if (data.IsNull)
            {
                result = null;
                var processors = GetProcessors(storageType);
                Invoke_OnBeforeDeserialize(processors, storageType, ref data);
                Invoke_OnAfterDeserialize(processors, storageType, null);
                return(fsResult.Success);
            }

            // Convert legacy data into modern style data
            ConvertLegacyData(ref data);

            try
            {
                // We wrap the entire deserialize call in a reference group so
                // that we can properly deserialize a "parallel" set of
                // references, ie, a list of objects that are cyclic w.r.t. the
                // list
                _references.Enter();

                List <fsObjectProcessor> processors;
                var r = InternalDeserialize_1_CycleReference(overrideConverterType, data, storageType, ref result, out processors);
                if (r.Succeeded)
                {
                    Invoke_OnAfterDeserialize(processors, storageType, result);

                    if (result != null)
                    {
                        if (typeof(SavedComponent).IsAssignableFrom(storageType))
                        {
                            SavedComponent component = result as SavedComponent;
                            component.OnAfterLoad();
                        }
                        else
                        if (typeof(SavedScriptable).IsAssignableFrom(storageType))
                        {
                            SavedScriptable scriptable = result as SavedScriptable;
                            scriptable.OnAfterLoad();
                        }
                    }
                }
                return(r);
            }
            finally
            {
                _references.Exit();
            }
        }
示例#4
0
        static SaveData GetDataFromComponent(SavedComponent comp)
        {
            if (comp == null)
            {
                return(null);
            }
            Type t     = comp.GetType();
            var  field = findDataField(t);

            if (field != null)
            {
                var data = field.GetValue(comp) as SaveData;
                return(data);
            }
            else
            {
                return(null);
            }
        }
示例#5
0
        /// <summary>
        /// Serialize the given value.
        /// </summary>
        /// <param name="storageType">
        /// The type of field/property that stores the object instance. This is
        /// important particularly for inheritance, as a field storing an
        /// IInterface instance should have type information included.
        /// </param>
        /// <param name="overrideConverterType">
        /// An fsBaseConverter derived type that will be used to serialize the
        /// object instead of the converter found via the normal discovery
        /// mechanisms.
        /// </param>
        /// <param name="instance">
        /// The actual object instance to serialize.
        /// </param>
        /// <param name="data">The serialized state of the object.</param>
        /// <returns>If serialization was successful.</returns>
        public fsResult TrySerialize(Type storageType, Type overrideConverterType, object instance, out fsData data)
        {
            var processors = GetProcessors(instance == null ? storageType : instance.GetType());

            Invoke_OnBeforeSerialize(processors, storageType, instance);


            if (instance != null)
            {
                if (typeof(SavedComponent).IsAssignableFrom(storageType))
                {
                    SavedComponent component = instance as SavedComponent;
                    component.OnBeforeSave();
                }
                else
                if (typeof(SavedScriptable).IsAssignableFrom(storageType))
                {
                    SavedScriptable scriptable = instance as SavedScriptable;
                    scriptable.OnBeforeSave();
                }
            }

            // We always serialize null directly as null
            if (ReferenceEquals(instance, null))
            {
                data = new fsData();
                Invoke_OnAfterSerialize(processors, storageType, instance, ref data);
                return(fsResult.Success);
            }

            var result = InternalSerialize_1_ProcessCycles(storageType, overrideConverterType, instance, out data);

            Invoke_OnAfterSerialize(processors, storageType, instance, ref data);


            return(result);
        }
示例#6
0
        static void ProcessEntity(SaveObject file, SaveEntity ent, HashSet <int> bp_ids, Transform root)
        {
            EntityObject eobj        = new EntityObject();
            SaveEntity   entity      = ent;
            bool         isBlueprint = bp_ids != null;

            file.isBlueprint = isBlueprint;
            CompRefSerializationProcessor.blueprint = isBlueprint;
            if (isBlueprint && entity.blueprintID == 0)
            {
                entity.blueprintID = SaveSystemUtilities.GetUniqueID(bp_ids);
            }

            eobj.blueprint_ID = entity.blueprintID;
            Transform tr = entity.transform;

            eobj.database_ID = entity.entityID;
            eobj.instance_ID = entity.instanceID;
            eobj.prefabPath  = SaveEntityDatabase.GetPrefabPath(entity.entityID);
            eobj.Enabled     = ent.gameObject.activeSelf;

            if (isBlueprint)
            {
                eobj.position = root.InverseTransformPoint(tr.position);
                eobj.rotation = tr.localRotation.eulerAngles;
            }
            else
            {
                eobj.position = tr.position;
                eobj.rotation = tr.rotation.eulerAngles;
            }
            bool           hasParent  = tr.parent != null;
            SavedComponent parentComp = null;

            if (hasParent)
            {
                parentComp = tr.parent.GetComponent <SavedComponent>();
            }
            if (tr.parent != root && parentComp)
            {
                eobj.parentIsComponent = true;
                if (isBlueprint)
                {
                    eobj.parent_entity_ID = parentComp.Entity.blueprintID;
                }
                else
                {
                    eobj.parent_entity_ID = parentComp.Entity.ID;
                }
                eobj.parent_component_ID = parentComp.componentID;
            }
            else
            {
                SaveEntity parentEntity = null;
                if (hasParent)
                {
                    parentEntity = tr.parent.GetComponent <SaveEntity>();
                }
                if (tr.parent != root && parentEntity)
                {
                    eobj.parentIsEntity = true;
                    if (isBlueprint)
                    {
                        eobj.parent_entity_ID = parentEntity.blueprintID;
                    }
                    else
                    {
                        eobj.parent_entity_ID = parentEntity.ID;
                    }
                }
                else
                {
                    if (isBlueprint)
                    {
                        eobj.parentName = "null";
                    }
                    else
                    {
                        eobj.parentName = tr.parent == null ? "null" : tr.parent.name;
                    }
                }
            }
            eobj.gameObjectName = entity.name;

            file.entities.Add(eobj);

            getComponentsSwapList.Clear();

            entity.GetComponentsInChildren <SavedComponent>(true, getComponentsSwapList);

            foreach (var comp in getComponentsSwapList)
            {
                if (comp.componentID == 0)
                {
                    //Debug.Log("Skipping component without ID : " + comp.GetType(), entity.gameObject);
                    continue;
                }

                comp.SendMessage("OnBeforeSave", SendMessageOptions.DontRequireReceiver);

                ComponentObject cobj = new ComponentObject();

                cobj.component_ID = comp.componentID;
                cobj.data         = GetDataFromComponent(comp);
                cobj.initialized  = comp.Initialized;
                cobj.enabled      = comp.enabled;

                Dictionary <int, ComponentObject> entityComponents = null;
                if (isBlueprint)
                {
                    file.components.TryGetValue(entity.blueprintID, out entityComponents);
                }
                else
                {
                    file.components.TryGetValue(entity.instanceID, out entityComponents);
                }

                if (entityComponents == null)
                {
                    entityComponents = new Dictionary <int, ComponentObject>();
                    if (isBlueprint)
                    {
                        file.components.Add(entity.blueprintID, entityComponents);
                    }
                    else
                    {
                        file.components.Add(entity.instanceID, entityComponents);
                    }
                }

                if (entityComponents.ContainsKey(comp.componentID))
                {
                    Debug.LogError("Super fatal error with duplicate component id's on entity.", entity.gameObject);
                }
                entityComponents.Add(comp.componentID, cobj);
                if (cobj.data != null)
                {
                    Type t      = cobj.data.GetType();
                    var  fields = t.GetFields();
                    foreach (var f in fields)
                    {
                        if (f.FieldType == typeof(CompRef))
                        {
                            file.comprefs.Add(f.GetValue(cobj.data) as CompRef);
                        }
                    }
                }
            }
        }
示例#7
0
        public static void UnboxSaveObject(SaveObject save, Transform root)
        {
            if (save == null)
            {
                Debug.LogError("Save object is null");
                return;
            }

            var initializedfield = typeof(SavedComponent).GetField("m_initialized", BindingFlags.NonPublic | BindingFlags.Instance);

            Dictionary <int, SaveEntity> bp_entity = null;
            Dictionary <int, Dictionary <int, SavedComponent> > bp_parent_component = null;
            Dictionary <int, Dictionary <int, SavedComponent> > bp_all_comp         = new Dictionary <int, Dictionary <int, SavedComponent> >();

            if (save.isBlueprint)
            {
                bp_entity           = new Dictionary <int, SaveEntity>();
                bp_parent_component = new Dictionary <int, Dictionary <int, SavedComponent> >();
                bp_all_comp         = new Dictionary <int, Dictionary <int, SavedComponent> >();
            }

            bool blueprintEditorMode = save.isBlueprint && !Application.isPlaying;

            Dictionary <int, ComponentObject> cobjects = null;
            Dictionary <int, Dictionary <int, SavedComponent> > allComps = new Dictionary <int, Dictionary <int, SavedComponent> >();
            Dictionary <int, SaveEntity>          allEntities            = new Dictionary <int, SaveEntity>();
            Dictionary <EntityObject, SaveEntity> toParent = new Dictionary <EntityObject, SaveEntity>();
            List <SavedComponent> allComponents            = new List <SavedComponent>();

            foreach (var eobj in save.entities)
            {
                var prefab = SaveEntityDatabase.GetPrefab(eobj.database_ID);

                if (!prefab)
                {
                    Debug.LogError("When loading, database entity: " + eobj.database_ID + " was not found, this probably means you saved an entity that is not registered in database. Make it a prefab in Entity folder and run database scan.");
                    continue;
                }
                bool prefabState = prefab.activeSelf;
                prefab.SetActive(false);
                GameObject gameobj = null;
#if UNITY_EDITOR
                if (blueprintEditorMode)
                {
                    gameobj = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
                }
                else
                {
                    gameobj = GameObject.Instantiate(prefab);
                }
#else
                gameobj = GameObject.Instantiate(prefab);
#endif
                gameobj.name = eobj.gameObjectName;
                var tr = gameobj.transform;

                GameObject parentGo = null;
                if (eobj.parentName != "null")
                {
                    parentGo = GameObject.Find(eobj.parentName);
                }

                if (save.isBlueprint)
                {
                    tr.parent        = root;
                    tr.localPosition = eobj.position;
                    tr.localRotation = Quaternion.Euler(eobj.rotation);
                }
                else
                {
                    tr.position = eobj.position;
                    tr.rotation = Quaternion.Euler(eobj.rotation);
                    tr.parent   = eobj.parentName == "null" ? root : parentGo == null ? root : parentGo.transform;
                }

                var entity = gameobj.GetComponent <SaveEntity>();
                Dictionary <int, SavedComponent> ecomps  = null;
                Dictionary <int, SavedComponent> bpcomps = null;

                if (save.isBlueprint)
                {
                    bp_entity.Add(eobj.blueprint_ID, entity);
                    bp_all_comp.TryGetValue(eobj.blueprint_ID, out bpcomps);
                    if (bpcomps == null)
                    {
                        bpcomps = new Dictionary <int, SavedComponent>();
                        bp_parent_component.Add(eobj.blueprint_ID, bpcomps);
                    }
                    bp_parent_component.TryGetValue(eobj.blueprint_ID, out ecomps);
                    if (ecomps == null)
                    {
                        ecomps = new Dictionary <int, SavedComponent>();
                        bp_parent_component.Add(eobj.blueprint_ID, ecomps);
                    }
                }
                else
                {
                    allEntities.Add(eobj.instance_ID, entity);
                }

                entity.instanceID  = eobj.instance_ID;
                entity.blueprintID = eobj.blueprint_ID;

                if (eobj.parentIsComponent || eobj.parentIsEntity)
                {
                    toParent.Add(eobj, entity);
                }

                var comps = gameobj.GetComponentsInChildren <SavedComponent>(true);
                if (comps.Length != 0)
                {
                    if (save.isBlueprint)
                    {
                        save.components.TryGetValue(entity.blueprintID, out cobjects);
                    }
                    else
                    {
                        save.components.TryGetValue(entity.instanceID, out cobjects);
                    }

                    if (cobjects != null)
                    {
                        foreach (var component in comps)
                        {
                            if (save.isBlueprint)
                            {
                                ecomps.Add(component.componentID, component);
                            }

                            ComponentObject cobj = null;
                            cobjects.TryGetValue(component.componentID, out cobj);
                            if (cobj != null)
                            {
                                SetDataForComponent(component, cobj.data);
                                initializedfield.SetValue(component, cobj.initialized);
                                component.enabled = cobj.enabled;
                            }

                            //Storing for later reference injection
                            Dictionary <int, SavedComponent> injectionDict = null;
                            allComps.TryGetValue(entity.ID, out injectionDict);
                            if (injectionDict == null)
                            {
                                injectionDict = new Dictionary <int, SavedComponent>();
                                allComps.Add(entity.ID, injectionDict);
                            }
                            injectionDict.Add(component.componentID, component);

                            allComponents.Add(component);
                        }
                    }
                }

                if (save.isBlueprint)
                {
                    entity.instanceID = 0;
                }



                prefab.SetActive(prefabState);

                if (eobj.Enabled)
                {
                    entity.gameObject.SetActive(true);
                }
                else
                {
                    entity.InitializeDisabled();
                }
                //HACK change this to something like interface.
                //entity.gameObject.BroadcastMessage("OnAfterLoad", SendMessageOptions.DontRequireReceiver);
            }

            if (CompRefSerializationProcessor.refs != null && CompRefSerializationProcessor.refs.Count > 0)
            {
                foreach (var compref in CompRefSerializationProcessor.refs)
                {
                    if (!compref.isNull)
                    {
                        Dictionary <int, SavedComponent> comps = null;
                        SavedComponent cbase = null;

                        if (save.isBlueprint)
                        {
                            bp_parent_component.TryGetValue(compref.entity_ID, out comps);
                        }
                        else
                        {
                            allComps.TryGetValue(compref.entity_ID, out comps);
                        }

                        if (comps != null)
                        {
                            if (save.isBlueprint)
                            {
                                bp_parent_component[compref.entity_ID].TryGetValue(compref.component_ID, out cbase);
                            }
                            else
                            {
                                comps.TryGetValue(compref.component_ID, out cbase);
                            }
                            if (cbase != null)
                            {
                                compref.component = cbase;
                            }
                            else
                            {
                                Debug.LogError("CompRef linker could not find component with id: " + compref.component_ID + " on entity: " + compref.entityName);
                            }
                        }
                        else
                        {
                            Debug.LogError("CompRef linker could not find entity with id: " + compref.entity_ID + " on entity: " + compref.entityName);
                        }
                    }
                }
            }
#if UNITY_EDITOR
            if (blueprintEditorMode)
            {
                foreach (var e in bp_entity)
                {
                    var go = PrefabUtility.FindPrefabRoot(e.Value.gameObject);
                    PrefabUtility.DisconnectPrefabInstance(go);
                    PrefabUtility.ReconnectToLastPrefab(go);
                }
            }
#endif
            if (save.isBlueprint)
            {
                if (blueprintEditorMode)
                {
#if UNITY_EDITOR
                    foreach (var pair in toParent)
                    {
                        SaveEntity e  = pair.Value;
                        var        go = PrefabUtility.FindPrefabRoot(e.gameObject);
                        PrefabUtility.DisconnectPrefabInstance(go);

                        EntityObject eobj   = pair.Key;
                        Transform    parent = null;
                        if (eobj.parentIsComponent)
                        {
                            parent = bp_parent_component[eobj.parent_entity_ID][eobj.parent_component_ID].transform;
                        }
                        else if (eobj.parentIsEntity)
                        {
                            parent = bp_entity[eobj.parent_entity_ID].transform;
                        }
                        e.transform.SetParent(parent);
                        PrefabUtility.ReconnectToLastPrefab(go);
                    }
#endif
                }
                else
                {
                    foreach (var pair in toParent)
                    {
                        SaveEntity   e      = pair.Value;
                        EntityObject eobj   = pair.Key;
                        Transform    parent = null;
                        if (eobj.parentIsComponent)
                        {
                            parent = bp_parent_component[eobj.parent_entity_ID][eobj.parent_component_ID].transform;
                        }
                        else if (eobj.parentIsEntity)
                        {
                            parent = bp_entity[eobj.parent_entity_ID].transform;
                        }
                        e.transform.SetParent(parent);
                    }
                }
            }
            else
            {
                foreach (var pair in toParent)
                {
                    SaveEntity   e      = pair.Value;
                    EntityObject eobj   = pair.Key;
                    Transform    parent = null;
                    if (eobj.parentIsComponent)
                    {
                        parent = allComps[eobj.parent_entity_ID][eobj.parent_component_ID].transform;
                    }
                    else if (eobj.parentIsEntity)
                    {
                        parent = allEntities[eobj.parent_entity_ID].transform;
                    }
                    e.transform.SetParent(parent);
                }
            }

            foreach (var comp in allComponents)
            {
                comp.SendMessage("OnAfterLoad", SendMessageOptions.DontRequireReceiver);
            }
        }