public override string ToString() { string pathToDesriptor = string.Empty; PersistentDescriptor descriptor = this; if (descriptor.Parent == null) { pathToDesriptor += "/"; } else { while (descriptor.Parent != null) { pathToDesriptor += "/" + descriptor.Parent.PersistentID; descriptor = descriptor.Parent; } } return(string.Format("Descriptor InstanceId = {0}, Type = {1}, Path = {2}, Children = {3} Components = {4}", PersistentID, PersistentTypeGuid, pathToDesriptor, Children != null ? Children.Length : 0, Components != null ? Components.Length : 0)); }
protected override object WriteToImpl(object obj) { if (Descriptors == null && Data == null) { return(obj); } if (Descriptors == null && Data != null || Data != null && Descriptors == null) { throw new ArgumentException("data is corrupted", "scene"); } if (Descriptors.Length == 0) { return(obj); } if (Identifiers == null || Identifiers.Length != Data.Length) { throw new ArgumentException("data is corrupted", "scene"); } Scene scene = (Scene)obj; GameObject[] rootGameObjects = scene.GetRootGameObjects(); for (int i = 0; i < rootGameObjects.Length; ++i) { GameObject rootGO = rootGameObjects[i]; if (rootGO.GetComponent <RTSLIgnore>()) { continue; } UnityObject.DestroyImmediate(rootGO); } 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(); return(scene); }
protected override void ReadFromImpl(object obj) { Scene scene = (Scene)obj; GameObject[] rootGameObjects = scene.GetRootGameObjects(); 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; List <UnityObject> externalDeps = new List <UnityObject>(allDeps.OfType <UnityObject>()); 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; } if (!m_assetDB.IsMapped(uo)) { if (!(uo is GameObject) && !(uo is Component)) { Type persistentType = m_typeMap.ToPersistentType(uo.GetType()); if (persistentType != null) { getDepsCtx.Clear(); PersistentObject persistentObject = (PersistentObject)Activator.CreateInstance(persistentType); persistentObject.ReadFrom(uo); persistentObject.GetDepsFrom(uo, getDepsCtx); assets.Add(persistentObject); assetIdentifiers.Add(uo.GetInstanceID()); foreach (UnityObject dep in getDepsCtx.Dependencies) { if (!allDeps.Contains(dep)) { allDeps.Add(dep); depsQueue.Enqueue(dep); } } } } externalDeps.Remove(uo); } } Descriptors = descriptors.ToArray(); Identifiers = identifiers.ToArray(); Data = data.ToArray(); Dependencies = externalDeps.Select(uo => m_assetDB.ToID(uo)).ToArray(); Assets = assets.ToArray(); AssetIdentifiers = assetIdentifiers.ToArray(); }
protected 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); }
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); } } }