protected override void ReadFromImpl(object obj)
        {
            ClearReferencesCache();

            Scene scene = (Scene)obj;

            GameObject[] rootGameObjects;
            if (scene.IsValid())
            {
                rootGameObjects = scene.GetRootGameObjects();
            }
            else
            {
                rootGameObjects = new GameObject[0];
            }

            List <PersistentObject>     data            = new List <PersistentObject>();
            List <long>                 identifiers     = new List <long>();
            List <PersistentDescriptor> descriptors     = new List <PersistentDescriptor>(rootGameObjects.Length);
            GetDepsFromContext          getSceneDepsCtx = new GetDepsFromContext();

            for (int i = 0; i < rootGameObjects.Length; ++i)
            {
                GameObject           rootGO     = rootGameObjects[i];
                PersistentDescriptor descriptor = CreateDescriptorAndData(rootGO, data, identifiers, getSceneDepsCtx);
                if (descriptor != null)
                {
                    descriptors.Add(descriptor);
                }
            }

            HashSet <object> allDeps = getSceneDepsCtx.Dependencies;

            Queue <UnityObject> depsQueue = new Queue <UnityObject>(allDeps.OfType <UnityObject>());

            List <PersistentObject> assets = new List <PersistentObject>();
            List <int> assetIdentifiers    = new List <int>();

            GetDepsFromContext getDepsCtx = new GetDepsFromContext();

            while (depsQueue.Count > 0)
            {
                UnityObject uo = depsQueue.Dequeue();
                if (!uo)
                {
                    continue;
                }


                Type persistentType = m_typeMap.ToPersistentType(uo.GetType());
                if (persistentType != null)
                {
                    getDepsCtx.Clear();

                    try
                    {
                        PersistentObject persistentObject = (PersistentObject)Activator.CreateInstance(persistentType);
                        if (!(uo is GameObject) && !(uo is Component))
                        {
                            if (!m_assetDB.IsMapped(uo))
                            {
                                if (uo is Texture2D)
                                {
                                    Texture2D texture = (Texture2D)uo;
                                    if (texture.isReadable)  //
                                    {
                                        persistentObject.ReadFrom(uo);
                                        assets.Add(persistentObject);
                                        assetIdentifiers.Add(uo.GetInstanceID());
                                        persistentObject.GetDepsFrom(uo, getDepsCtx);
                                    }
                                }
                                else
                                {
                                    persistentObject.ReadFrom(uo);
                                    assets.Add(persistentObject);
                                    assetIdentifiers.Add(uo.GetInstanceID());
                                    persistentObject.GetDepsFrom(uo, getDepsCtx);
                                }
                            }
                            else
                            {
                                persistentObject.GetDepsFrom(uo, getDepsCtx);
                            }
                        }
                        else
                        {
                            persistentObject.GetDepsFrom(uo, getDepsCtx);
                        }
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(e.ToString());
                    }

                    foreach (UnityObject dep in getDepsCtx.Dependencies)
                    {
                        if (!allDeps.Contains(dep))
                        {
                            allDeps.Add(dep);
                            depsQueue.Enqueue(dep);
                        }
                    }
                }
            }

            List <UnityObject> externalDeps = new List <UnityObject>(allDeps.OfType <UnityObject>());

            for (int i = externalDeps.Count - 1; i >= 0; i--)
            {
                if (!m_assetDB.IsMapped(externalDeps[i]))
                {
                    externalDeps.RemoveAt(i);
                }
            }

            Descriptors  = descriptors.ToArray();
            Identifiers  = identifiers.ToArray();
            Data         = data.ToArray();
            Dependencies = externalDeps.Select(uo => m_assetDB.ToID(uo)).ToArray();

            Assets           = assets.ToArray();
            AssetIdentifiers = assetIdentifiers.ToArray();

            ClearReferencesCache();
        }
        protected virtual PersistentDescriptor CreateDescriptorAndData(GameObject go, List <PersistentObject> persistentData, List <long> persistentIdentifiers, /*HashSet<int> usings,*/ GetDepsFromContext getDepsFromCtx, PersistentDescriptor parentDescriptor = null)
        {
            if (go.GetComponent <RTSLIgnore>())
            {
                //Do not save persistent ignore objects
                return(null);
            }
            Type persistentType = m_typeMap.ToPersistentType(go.GetType());

            if (persistentType == null)
            {
                return(null);
            }

            long persistentID = ToID(go);
            //if(m_assetDB.IsResourceID(persistentID))
            //{
            //    int ordinal = m_assetDB.ToOrdinal(persistentID);
            //    usings.Add(ordinal);
            //}

            PersistentDescriptor descriptor = new PersistentDescriptor(m_typeMap.ToGuid(persistentType), persistentID, go.name);

            descriptor.Parent = parentDescriptor;

            PersistentObject goData = (PersistentObject)Activator.CreateInstance(persistentType);

            goData.ReadFrom(go);
            goData.GetDepsFrom(go, getDepsFromCtx);
            persistentData.Add(goData);
            persistentIdentifiers.Add(persistentID);

            Component[] components = go.GetComponents <Component>().Where(c => c != null).ToArray();
            if (components.Length > 0)
            {
                List <PersistentDescriptor> componentDescriptors = new List <PersistentDescriptor>();
                for (int i = 0; i < components.Length; ++i)
                {
                    Component component = components[i];
                    Type      persistentComponentType = m_typeMap.ToPersistentType(component.GetType());
                    if (persistentComponentType == null)
                    {
                        continue;
                    }

                    long componentID = ToID(component);
                    //if (m_assetDB.IsResourceID(componentID))
                    //{
                    //    int ordinal = m_assetDB.ToOrdinal(componentID);
                    //    usings.Add(ordinal);
                    //}
                    PersistentDescriptor componentDescriptor = new PersistentDescriptor(m_typeMap.ToGuid(persistentComponentType), componentID, component.name);
                    componentDescriptor.Parent = descriptor;
                    componentDescriptors.Add(componentDescriptor);

                    PersistentObject componentData = (PersistentObject)Activator.CreateInstance(persistentComponentType);
                    componentData.ReadFrom(component);
                    componentData.GetDepsFrom(component, getDepsFromCtx);
                    persistentData.Add(componentData);
                    persistentIdentifiers.Add(componentID);
                }

                if (componentDescriptors.Count > 0)
                {
                    descriptor.Components = componentDescriptors.ToArray();
                }
            }

            Transform transform = go.transform;

            if (transform.childCount > 0)
            {
                List <PersistentDescriptor> children = new List <PersistentDescriptor>();
                foreach (Transform child in transform)
                {
                    PersistentDescriptor childDescriptor = CreateDescriptorAndData(child.gameObject, persistentData, persistentIdentifiers, /*usings,*/ getDepsFromCtx, descriptor);
                    if (childDescriptor != null)
                    {
                        children.Add(childDescriptor);
                    }
                }

                descriptor.Children = children.ToArray();
            }

            return(descriptor);
        }
        protected override object WriteToImpl(object obj)
        {
            ClearReferencesCache();

            Scene scene = (Scene)obj;

            if (Descriptors == null && Data == null)
            {
                DestroyGameObjects(scene);
                return(obj);
            }

            if (Descriptors == null && Data != null || Data != null && Descriptors == null)
            {
                throw new ArgumentException("data is corrupted", "scene");
            }

            if (Descriptors.Length == 0)
            {
                DestroyGameObjects(scene);
                return(obj);
            }

            if (Identifiers == null || Identifiers.Length != Data.Length)
            {
                throw new ArgumentException("data is corrupted", "scene");
            }

            DestroyGameObjects(scene);
            Dictionary <int, UnityObject> idToUnityObj = new Dictionary <int, UnityObject>();

            for (int i = 0; i < Descriptors.Length; ++i)
            {
                PersistentDescriptor descriptor = Descriptors[i];
                if (descriptor != null)
                {
                    CreateGameObjectWithComponents(m_typeMap, descriptor, idToUnityObj, null);
                }
            }


            UnityObject[] assetInstances = null;
            if (AssetIdentifiers != null)
            {
                IUnityObjectFactory factory = IOC.Resolve <IUnityObjectFactory>();
                assetInstances = new UnityObject[AssetIdentifiers.Length];
                for (int i = 0; i < AssetIdentifiers.Length; ++i)
                {
                    PersistentObject asset = Assets[i];

                    Type uoType = m_typeMap.ToUnityType(asset.GetType());
                    if (uoType != null)
                    {
                        if (factory.CanCreateInstance(uoType, asset))
                        {
                            UnityObject assetInstance = factory.CreateInstance(uoType, asset);
                            if (assetInstance != null)
                            {
                                assetInstances[i] = assetInstance;
                                idToUnityObj.Add(AssetIdentifiers[i], assetInstance);
                            }
                        }
                        else
                        {
                            Debug.LogWarning("Unable to create object of type " + uoType.ToString());
                        }
                    }
                    else
                    {
                        Debug.LogWarning("Unable to resolve unity type for " + asset.GetType().FullName);
                    }
                }
            }

            m_assetDB.RegisterSceneObjects(idToUnityObj);

            if (assetInstances != null)
            {
                for (int i = 0; i < AssetIdentifiers.Length; ++i)
                {
                    UnityObject assetInstance = assetInstances[i];
                    if (assetInstance != null)
                    {
                        PersistentObject asset = Assets[i];
                        asset.WriteTo(assetInstance);
                    }
                }
            }

            RestoreDataAndResolveDependencies();
            m_assetDB.UnregisterSceneObjects();

            ClearReferencesCache();

            return(scene);
        }
        private UnityObject AddComponent(Dictionary <int, UnityObject> idToObj, GameObject go, Dictionary <Type, bool> requirements, PersistentDescriptor componentDescriptor, Type componentType)
        {
            Component component;
            bool      isReqFulfilled             = requirements.ContainsKey(componentType) && requirements[componentType];
            bool      maybeComponentAlreadyAdded =
                !isReqFulfilled ||
                componentType.IsSubclassOf(typeof(Transform)) ||
                componentType == typeof(Transform) ||
                componentType.IsDefined(typeof(DisallowMultipleComponent), true) ||
                ComponentDependencies.ContainsKey(componentType) && ComponentDependencies[componentType].Any(d => go.GetComponent(d) != null);

            if (maybeComponentAlreadyAdded)
            {
                component = go.GetComponent(componentType);
                if (component == null)
                {
                    component = go.AddComponent(componentType);
                }
                if (!isReqFulfilled)
                {
                    requirements[componentType] = true;
                }
            }
            else
            {
                component = go.AddComponent(componentType);
                if (component == null)
                {
                    component = go.GetComponent(componentType);
                }
            }
            if (component == null)
            {
                Debug.LogErrorFormat("Unable to add or get component of type {0}", componentType);
            }
            else
            {
                object[] requireComponents = component.GetType().GetCustomAttributes(typeof(RequireComponent), true);
                for (int j = 0; j < requireComponents.Length; ++j)
                {
                    RequireComponent requireComponent = requireComponents[j] as RequireComponent;
                    if (requireComponent != null)
                    {
                        if (requireComponent.m_Type0 != null && !requirements.ContainsKey(requireComponent.m_Type0))
                        {
                            bool fulfilled = go.GetComponent(requireComponent.m_Type0);
                            requirements.Add(requireComponent.m_Type0, fulfilled);
                        }
                        if (requireComponent.m_Type1 != null && !requirements.ContainsKey(requireComponent.m_Type1))
                        {
                            bool fulfilled = go.GetComponent(requireComponent.m_Type1);
                            requirements.Add(requireComponent.m_Type1, fulfilled);
                        }
                        if (requireComponent.m_Type2 != null && !requirements.ContainsKey(requireComponent.m_Type2))
                        {
                            bool fulfilled = go.GetComponent(requireComponent.m_Type2);
                            requirements.Add(requireComponent.m_Type2, fulfilled);
                        }
                    }
                }
                idToObj.Add(m_assetDB.ToInt(componentDescriptor.PersistentID), component);
            }

            return(component);
        }
        /// <summary>
        /// Create GameObjects hierarchy and Add Components recursively
        /// </summary>
        /// <param name="descriptor">PersistentObject descriptor (initially root descriptor)</param>
        /// <param name="idToObj">Dictionary instanceId->UnityObject which will be populated with GameObjects and Components</param>
        public void CreateGameObjectWithComponents(ITypeMap typeMap, PersistentDescriptor descriptor, Dictionary <int, UnityObject> idToObj, Transform parent, List <GameObject> createdGameObjects = null, Dictionary <long, UnityObject> decomposition = null)
        {
            UnityObject objGo;
            GameObject  go;

            if (idToObj.TryGetValue(m_assetDB.ToInt(descriptor.PersistentID), out objGo))
            {
                throw new ArgumentException(string.Format("duplicate object descriptor found in descriptors hierarchy. {0}", descriptor.ToString()), "descriptor");
            }
            else
            {
                go = new GameObject();
                if (parent != null)
                {
                    go.transform.SetParent(parent, false);
                }
                idToObj.Add(m_assetDB.ToInt(descriptor.PersistentID), go);
            }

            if (decomposition != null)
            {
                if (!decomposition.ContainsKey(descriptor.PersistentID))
                {
                    decomposition.Add(descriptor.PersistentID, go);
                }
            }

            if (createdGameObjects != null)
            {
                createdGameObjects.Add(go);
            }

            go.SetActive(false);

            if (descriptor.Parent != null)
            {
                UnityObject parentGO;
                if (!idToObj.TryGetValue(m_assetDB.ToInt(descriptor.Parent.PersistentID), out parentGO))
                {
                    throw new ArgumentException(string.Format("objects dictionary is supposed to have object with PersistentID {0} at this stage. Descriptor {1}", descriptor.Parent.PersistentID, descriptor, "descriptor"));
                }

                if (parentGO == null)
                {
                    throw new ArgumentException(string.Format("object with PersistentID {0} should have GameObject type. Descriptor {1}", descriptor.Parent.PersistentID, descriptor, "descriptor"));
                }
                go.transform.SetParent(((GameObject)parentGO).transform, false);
            }

            if (descriptor.Components != null)
            {
                Dictionary <Type, bool> requirements = new Dictionary <Type, bool>();
                for (int i = 0; i < descriptor.Components.Length; ++i)
                {
                    PersistentDescriptor componentDescriptor = descriptor.Components[i];

                    Type persistentComponentType = m_typeMap.ToType(componentDescriptor.PersistentTypeGuid);
                    if (persistentComponentType == null)
                    {
                        Debug.LogWarningFormat("Unknown type {0} associated with component Descriptor {1}", componentDescriptor.PersistentTypeGuid, componentDescriptor.ToString());
                        idToObj.Add(m_assetDB.ToInt(componentDescriptor.PersistentID), null);
                        continue;
                    }
                    Type componentType = typeMap.ToUnityType(persistentComponentType);
                    if (componentType == null)
                    {
                        Debug.LogWarningFormat("There is no mapped type for " + persistentComponentType.FullName + " in TypeMap");
                        idToObj.Add(m_assetDB.ToInt(componentDescriptor.PersistentID), null);
                        continue;
                    }

                    if (!componentType.IsSubclassOf(typeof(Component)))
                    {
                        Debug.LogErrorFormat("{0} is not subclass of {1}", componentType.FullName, typeof(Component).FullName);
                        idToObj.Add(m_assetDB.ToInt(componentDescriptor.PersistentID), null);
                        continue;
                    }

                    UnityObject obj;
                    if (idToObj.TryGetValue(m_assetDB.ToInt(componentDescriptor.PersistentID), out obj))
                    {
                        if (obj != null && !(obj is Component))
                        {
                            Debug.LogError("Invalid Type. Component " + obj.name + " " + obj.GetType() + " " + obj.GetInstanceID() + " " + descriptor.PersistentTypeGuid + " " + componentDescriptor.PersistentTypeGuid);
                        }
                    }
                    else
                    {
                        obj = AddComponent(idToObj, go, requirements, componentDescriptor, componentType);
                    }

                    if (decomposition != null)
                    {
                        if (!decomposition.ContainsKey(componentDescriptor.PersistentID))
                        {
                            decomposition.Add(componentDescriptor.PersistentID, obj);
                        }
                    }
                }
            }

            if (descriptor.Children != null)
            {
                for (int i = 0; i < descriptor.Children.Length; ++i)
                {
                    PersistentDescriptor childDescriptor = descriptor.Children[i];
                    CreateGameObjectWithComponents(typeMap, childDescriptor, idToObj, null, createdGameObjects, decomposition);
                }
            }
        }
예제 #6
0
 protected override PersistentDescriptor CreateDescriptorAndData(GameObject go, List <PersistentObject> persistentData, List <long> persistentIdentifiers, GetDepsFromContext getDepsFromCtx, PersistentDescriptor parentDescriptor = null)
 {
     if ((go.hideFlags & HideFlags.DontSave) != 0)
     {
         return(null);
     }
     return(base.CreateDescriptorAndData(go, persistentData, persistentIdentifiers, getDepsFromCtx, parentDescriptor));
 }
        protected override void ReadFromImpl(object obj)
        {
            ClearReferencesCache();

            Scene scene = (Scene)obj;

            GameObject[] rootGameObjects;
            if (scene.IsValid())
            {
                rootGameObjects = scene.GetRootGameObjects();
            }
            else
            {
                rootGameObjects = new GameObject[0];
            }

            List <Tuple <PersistentObject <TID>, UnityObject> > data = new List <Tuple <PersistentObject <TID>, UnityObject> >();
            List <TID> identifiers = new List <TID>();
            List <PersistentDescriptor <TID> > descriptors = new List <PersistentDescriptor <TID> >(rootGameObjects.Length);
            GetDepsFromContext getSceneDepsCtx             = new GetDepsFromContext();

            for (int i = 0; i < rootGameObjects.Length; ++i)
            {
                GameObject rootGO = rootGameObjects[i];
                PersistentDescriptor <TID> descriptor = CreateDescriptorAndData(rootGO, data, identifiers, getSceneDepsCtx);
                if (descriptor != null)
                {
                    descriptors.Add(descriptor);
                }
            }

            HashSet <object>    allDeps   = getSceneDepsCtx.Dependencies;
            Queue <UnityObject> depsQueue = new Queue <UnityObject>(allDeps.OfType <UnityObject>());
            List <Tuple <PersistentObject <TID>, UnityObject> > assets = new List <Tuple <PersistentObject <TID>, UnityObject> >();
            List <TID> assetIds = new List <TID>();

            GetDepsFromContext getDepsCtx = new GetDepsFromContext();

            while (depsQueue.Count > 0)
            {
                UnityObject uo = depsQueue.Dequeue();
                if (!uo)
                {
                    continue;
                }


                Type persistentType = m_typeMap.ToPersistentType(uo.GetType());
                if (persistentType != null)
                {
                    getDepsCtx.Clear();

                    try
                    {
                        PersistentObject <TID> persistentObject = (PersistentObject <TID>)Activator.CreateInstance(persistentType);
                        if (!(uo is GameObject) && !(uo is Component) && (uo.hideFlags & HideFlags.DontSave) == 0)
                        {
                            if (!m_assetDB.IsMapped(uo))
                            {
                                assets.Add(new Tuple <PersistentObject <TID>, UnityObject>(persistentObject, uo));
                                assetIds.Add(ToID(uo));
                                persistentObject.GetDepsFrom(uo, getDepsCtx);
                            }
                            else
                            {
                                persistentObject.GetDepsFrom(uo, getDepsCtx);
                            }
                        }
                        else
                        {
                            persistentObject.GetDepsFrom(uo, getDepsCtx);
                        }
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(e.ToString());
                    }

                    foreach (UnityObject dep in getDepsCtx.Dependencies)
                    {
                        if (!allDeps.Contains(dep))
                        {
                            allDeps.Add(dep);
                            depsQueue.Enqueue(dep);
                        }
                    }
                }
            }

            List <UnityObject> externalDeps = new List <UnityObject>(allDeps.OfType <UnityObject>());

            for (int i = externalDeps.Count - 1; i >= 0; i--)
            {
                if (!m_assetDB.IsMapped(externalDeps[i]))
                {
                    externalDeps.RemoveAt(i);
                }
            }

            Descriptors = descriptors.ToArray();
            Identifiers = identifiers.ToArray();
            Data        = data.Select(t =>
            {
                PersistentObject <TID> persistentObject = t.Item1;
                persistentObject.ReadFrom(t.Item2);
                return(persistentObject);
            }).ToArray();
            Dependencies = externalDeps.Select(uo => ToID(uo)).ToArray();

            Assets = assets.Select(t =>
            {
                PersistentObject <TID> persistentObject = t.Item1;
                persistentObject.ReadFrom(t.Item2);
                return(persistentObject);
            }).ToArray();

            AssetIds = assetIds.ToArray();

            m_assetDB.UnregisterSceneObjects();
            ClearReferencesCache();
        }
예제 #8
0
        protected virtual PersistentDescriptor <TID> CreateDescriptorAndData(GameObject go, List <Tuple <PersistentObject <TID>, UnityObject> > persistentData, List <TID> persistentIdentifiers, GetDepsFromContext getDepsFromCtx, PersistentDescriptor <TID> parentDescriptor = null)
        {
            if (go.GetComponent <RTSLIgnore>())
            {
                //Do not save persistent ignore objects
                return(null);
            }
            Type type           = go.GetType();
            Type persistentType = m_typeMap.ToPersistentType(type);

            if (persistentType == null)
            {
                return(null);
            }

            TID persistentID = ToID(go);

            PersistentDescriptor <TID> descriptor = new PersistentDescriptor <TID>(m_typeMap.ToGuid(persistentType), persistentID, go.name, m_typeMap.ToGuid(type));

            descriptor.Parent = parentDescriptor;

            PersistentObject <TID> goData = (PersistentObject <TID>)Activator.CreateInstance(persistentType);

            goData.GetDepsFrom(go, getDepsFromCtx);
            persistentData.Add(new Tuple <PersistentObject <TID>, UnityObject>(goData, go));
            persistentIdentifiers.Add(persistentID);

            Component[] components = go.GetComponents <Component>().Where(c => c != null).ToArray();
            if (components.Length > 0)
            {
                List <PersistentDescriptor <TID> > componentDescriptors = new List <PersistentDescriptor <TID> >();
                for (int i = 0; i < components.Length; ++i)
                {
                    Component component               = components[i];
                    Type      componentType           = component.GetType();
                    Type      persistentComponentType = m_typeMap.ToPersistentType(componentType);
                    if (persistentComponentType == null)
                    {
                        continue;
                    }

                    TID componentID = ToID(component);

                    PersistentDescriptor <TID> componentDescriptor = new PersistentDescriptor <TID>(m_typeMap.ToGuid(persistentComponentType), componentID, component.name, m_typeMap.ToGuid(componentType));
                    componentDescriptor.Parent = descriptor;
                    componentDescriptors.Add(componentDescriptor);

                    PersistentObject <TID> componentData = (PersistentObject <TID>)Activator.CreateInstance(persistentComponentType);
                    componentData.GetDepsFrom(component, getDepsFromCtx);
                    persistentData.Add(new Tuple <PersistentObject <TID>, UnityObject>(componentData, component));
                    persistentIdentifiers.Add(componentID);
                }

                if (componentDescriptors.Count > 0)
                {
                    descriptor.Components = componentDescriptors.ToArray();
                }
            }

            Transform transform = go.transform;

            if (transform.childCount > 0)
            {
                List <PersistentDescriptor <TID> > children = new List <PersistentDescriptor <TID> >();
                foreach (Transform child in transform)
                {
                    PersistentDescriptor <TID> childDescriptor = CreateDescriptorAndData(child.gameObject, persistentData, persistentIdentifiers, getDepsFromCtx, descriptor);
                    if (childDescriptor != null)
                    {
                        children.Add(childDescriptor);
                    }
                }

                descriptor.Children = children.ToArray();
            }

            return(descriptor);
        }