/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static Component CreateComponent(Metadata.TypeInfo type, object[] constructorParams, bool createHierarchyController,
                                                bool componentEnable)
        {
            var component = (Component)type.InvokeInstance(constructorParams);

            component.Enabled = componentEnable;

            if (createHierarchyController)
            {
                CreateHierarchyControllerForRootComponent(component, null, true);                  //, true );
            }
            return(component);
        }
Beispiel #2
0
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static Resource.Instance CreateResource(ResourceType resourceType, Resource.InstanceType instanceType, string name, bool wait,
                                                       Metadata.TypeInfo createResultObjectWithType, bool componentCreateHierarchyController, bool?componentSetEnabled, out string error)
        {
            //!!!!
            if (!wait)
            {
                Log.Fatal("ResourceManager: CreateResource: wait == false. Background loading is not implemented.");
            }

            error = "";

            //!!!!!threading

            if (string.IsNullOrEmpty(name))
            {
                Log.Fatal("ResourceManager: CreateResource: The name can't be empty.");
                return(null);
            }

            Resource res;

            Resource.Instance ins;
            bool insCreated = false;

            lock ( lockObject )
            {
                //get or create resource
                res = GetByName(name);
                if (res == null)
                {
                    //!!!!override loader

                    ConstructorInfo constructor = resourceType.resourceClass.GetConstructor(new Type[0]);
                    res = (Resource)constructor.Invoke(new object[0]);
                    res.resourceType = resourceType;
                    res.name         = name;
                    res.loadFromFile = true;

                    //add to the list
                    resources.Add(GetKey(name), res);
                }

                //create instance
                if (instanceType == Resource.InstanceType.Resource)
                {
                    //as Resource
                    if (res.PrimaryInstance == null)
                    {
                        ins = res.CreateInstanceClassObject(instanceType, componentCreateHierarchyController, componentSetEnabled);
                        res.PrimaryInstance = ins;
                        insCreated          = true;
                    }
                    else
                    {
                        ins = res.PrimaryInstance;
                    }
                }
                else
                {
                    //as Separate instance
                    ins        = res.CreateInstanceClassObject(instanceType, componentCreateHierarchyController, componentSetEnabled);
                    insCreated = true;
                }
            }

            if (insCreated)
            {
                if (createResultObjectWithType != null)
                {
                    object obj = createResultObjectWithType.InvokeInstance(null);

                    var component = obj as Component;
                    if (component != null)
                    {
                        if (componentSetEnabled != null)
                        {
                            component.Enabled = componentSetEnabled.Value;
                        }
                        if (componentCreateHierarchyController)
                        {
                            ComponentUtility.CreateHierarchyControllerForRootComponent(component, ins, true);                              //, true );
                        }
                    }

                    ins.ResultObject = obj;
                }

                //resource is ready
                ins.Status = Resource.Instance.StatusEnum.Ready;
            }
            ////_Load function
            //if( insCreated )
            //{
            //	//load

            //	if( wait )
            //	{
            //		LoadTaskFunction( ins );
            //	}
            //	else
            //	{
            //		Task task = new Task( LoadTaskFunction, ins );
            //		task.Start();
            //	}
            //}

            //wait
            if (wait)
            {
                //wait end of creation
                while (ins.Status == Resource.Instance.StatusEnum.CreationProcess)
                {
                    //!!!!slow? maybe we can increase priority for this instance or something like this?

                    if (VirtualFileSystem.MainThread == Thread.CurrentThread)
                    {
                        //process main thread tasks
                        EngineThreading.ExecuteQueuedActionsFromMainThread();
                    }

                    //!!!!?
                    Thread.Sleep(0);
                }
            }

            //!!!!так?
            if (wait && ins.Status == Resource.Instance.StatusEnum.Error)
            {
                error = ins.StatusError;
                ins.Dispose();
                return(null);
            }

            return(ins);
        }
        //!!!!
        //static void LoadContext_ProcessNotCompiledComponentItems( Metadata.LoadContext context, out bool changed )
        //{
        //	changed = false;

        //	var items = context.GetNotCompiledItems();
        //	if( items.Count != 0 )
        //	{
        //		//creation stage
        //		foreach( var item in items )
        //		{
        //			//try create component
        //			if( item.component == null && item.parent != null && item.parent.component != null )
        //			{
        //				//!!!!
        //				xx xx;
        //				//if( componentBlock.Data == "_Dev\\Import3D\\ColladaTest2.dae:Originals\\Materials\\ColladaTestStoneStatic" )
        //				//	Log.Warning( "dfgdfg" );

        //				xx xx;

        //				bool readyOnly = xx;

        //				Metadata.TypeInfo type = MetadataManager.GetType( item.textBlock.Data );

        //				xx xx;//загружен тип должен быть

        //				if( type == null )
        //				{
        //					xx xx;

        //					//!!!!
        //					Log.Fatal( "impl" );
        //				}

        //				xx xx;//а также проверять на loaded. клонироваться же


        //				item.component = (Component)type.InvokeInstance( null );
        //				item.component.providedTypeAllow = false;

        //				//!!!!!!так?
        //				item.parent.component.AddComponent( item.component );

        //				//!!!!
        //				//string error3;
        //				//if( !component._LoadHierarchy( context, componentBlock, out error3 ) )
        //				//{
        //				//	//!!!!
        //				//	Log.Fatal( "impl" );

        //				//	//!!!!!?
        //				//	//RemoveComponent
        //				//	//component = null;
        //				//}

        //				changed = true;
        //			}
        //		}

        //		//if changed on creation stage then reply creation stage
        //		if( changed )
        //			return;

        //		//loading properties stage
        //		{
        //			xx xx;

        //		}

        //		xx xx;

        //		xx xx;
        //		//changed = true;
        //	}
        //}

        //static void LoadContext_ProcessComponentItemsRecursive( Metadata.LoadContext.ComponentItem componentItem )
        //{
        //}

        //public static bool LoadComponentFromTextBlock( Component component, Metadata.LoadContext overrideContextObject, TextBlock block, string loadedFromFile, out string error )
        //{
        //	xx xx;

        //	xx xx;

        //	loadedFromFile = VirtualPathUtils.NormalizePath( loadedFromFile );

        //	Metadata.LoadContext context = overrideContextObject;
        //	if( context == null )
        //		context = new Metadata.LoadContext();
        //	context.virtualFileName = loadedFromFile;

        //	error = "";

        //	if( block.Children.Count != 1 )
        //	{
        //		//!!!!
        //		Log.Fatal( "impl" );
        //	}

        //	TextBlock componentBlock = block.Children[ 0 ];
        //	if( componentBlock.Name != ".component" )
        //	{
        //		//!!!!
        //		Log.Fatal( "impl" );
        //	}

        //	if( string.IsNullOrEmpty( componentBlock.Data ) )
        //	{
        //		//!!!!
        //		Log.Fatal( "impl" );
        //	}

        //	//get type
        //	Metadata.TypeInfo type = MetadataManager.GetType( componentBlock.Data );
        //	if( type == null )
        //	{
        //		//!!!!
        //		Log.Fatal( "impl" );
        //	}

        //	xx xx;
        //	//create instance
        //	var component = (Component)type.InvokeInstance( null );

        //	//create context, init tree structure of components
        //	context.rootComponentItem = new Metadata.LoadContext.ComponentItem();
        //	context.rootComponentItem.textBlock = componentBlock;
        //	LoadContext_InitComponentItemsRecursive( context, context.rootComponentItem );

        //	//processing
        //	context.rootComponentItem.component = component;
        //	LoadContext_ProcessComponentItems( context );

        //	if( !context.rootComponentItem.loaded )
        //	{
        //		//!!!!
        //		Log.Fatal( "impl" );
        //	}

        //	return true;
        //}

        public static Component LoadComponentFromTextBlock(Metadata.LoadContext overrideContextObject, TextBlock block, string loadedFromFile,
                                                           Resource.Instance createdByResource, bool?componentSetEnabled, bool componentCreateHierarchyController, out string error)
        {
            loadedFromFile = VirtualPathUtility.NormalizePath(loadedFromFile);

            Metadata.LoadContext context = overrideContextObject;
            if (context == null)
            {
                context = new Metadata.LoadContext();
            }
            context.virtualFileName = loadedFromFile;

            error = "";

            if (block.Children.Count != 1)
            {
                error = "Invalid format. block.Children.Count != 1";
                return(null);
            }

            TextBlock componentBlock = block.Children[0];

            if (componentBlock.Name != ".component")
            {
                error = "Invalid format. componentBlock.Name != \".component\"";
                return(null);
            }

            if (string.IsNullOrEmpty(componentBlock.Data))
            {
                error = "Invalid format. string.IsNullOrEmpty( componentBlock.Data )";
                return(null);
            }

            //get type
            Metadata.TypeInfo type = MetadataManager.GetType(componentBlock.Data);
            if (type == null)
            {
                error = $"Type with name \'{componentBlock.Data}\' is not exists.";
                return(null);
            }

            //create instance
            var component = (Component)type.InvokeInstance(null);

            //set ResultObject for resource
            if (createdByResource != null)
            {
                createdByResource.ResultObject = component;
            }

            //create hierarchy controller. disabled at creation.
            if (componentCreateHierarchyController)
            {
                ComponentUtility.CreateHierarchyControllerForRootComponent(component, createdByResource, false);                  //, true );
            }
            //create context, init tree structure of components
            context.rootComponentItem           = new Metadata.LoadContext.ComponentItem();
            context.rootComponentItem.textBlock = componentBlock;

            if (!LoadContext_InitComponentItemsRecursive(context, context.rootComponentItem, out error))
            {
                component?.Dispose();
                return(null);
            }

            //processing
            context.rootComponentItem.component = component;
            if (!LoadContext_ProcessComponentItems(context, out error))
            {
                component?.Dispose();
                return(null);
            }

            if (!context.rootComponentItem.loaded)
            {
                error = "Root component is not loaded.";
                component?.Dispose();
                return(null);
            }

            //set Enabled
            if (componentSetEnabled != null)
            {
                component.Enabled = componentSetEnabled.Value;
            }
            //enable hierarchy controller
            if (component.HierarchyController != null)
            {
                component.HierarchyController.HierarchyEnabled = true;
            }

            return(component);
        }
        static void LoadContext_ProcessComponentCreation(Metadata.LoadContext context, Metadata.LoadContext.ComponentItem item,
                                                         out bool changed, out bool finished, ESet <string> unableToGetTypeName)
        {
            changed = false;

            if (item.component == null && (item.parent != null && item.parent.component != null || item.parent == null))
            {
                Metadata.TypeInfo type = MetadataManager.GetType(item.textBlock.Data);
                if (type != null)
                {
                    //!!!!new
                    //use component by base type
                    if (item.parent != null && item.parent.component != null && item.textBlock.AttributeExists("CreatedByBaseType"))
                    {
                        bool createdByBaseType = bool.Parse(item.textBlock.GetAttribute("CreatedByBaseType"));
                        if (createdByBaseType)
                        {
                            int hierarchyIndex = int.Parse(item.textBlock.GetAttribute("CreatedByBaseTypeHierarchyIndex", "0"));
                            int nameIndex      = int.Parse(item.textBlock.GetAttribute("CreatedByBaseTypeNameIndex", "0"));

                            Component useComponent = null;

                            foreach (var c in item.parent.component.Components)
                            {
                                if (c.Name == item.name)
                                {
                                    //!!!!return true проверять может таки
                                    c.GetBaseTypeIndex(out int baseHierarchyIndex, out string baseName, out int baseNameIndex);
                                    if (baseHierarchyIndex == hierarchyIndex && baseNameIndex == nameIndex)
                                    {
                                        useComponent = c;
                                        break;
                                    }
                                }
                            }

                            if (useComponent != null)
                            {
                                item.component = useComponent;
                            }
                        }
                    }

                    if (item.component == null)
                    {
                        //create
                        item.component = (Component)type.InvokeInstance(null);

                        //remove was deleted components created by base type
                        {
                            //!!!!slowly maybe

                            //reverse order
                            foreach (TextBlock childBlock in item.textBlock.Children.GetReverse())
                            {
                                if (childBlock.Name == ".componentCreatedByBaseTypeWasDeleted")
                                {
                                    int    hierarchyIndex = int.Parse(childBlock.GetAttribute("CreatedByBaseTypeHierarchyIndex", "0"));
                                    string name           = childBlock.GetAttribute("CreatedByBaseTypeName");
                                    int    nameIndex      = int.Parse(childBlock.GetAttribute("CreatedByBaseTypeNameIndex", "0"));

                                    Component foundComponent = null;
                                    foreach (var c in item.component.Components)
                                    {
                                        if (c.Name == name)
                                        {
                                            //!!!!return true проверять может таки
                                            c.GetBaseTypeIndex(out int baseHierarchyIndex, out string baseName, out int baseNameIndex);
                                            if (baseHierarchyIndex == hierarchyIndex && baseNameIndex == nameIndex)
                                            {
                                                foundComponent = c;
                                                break;
                                            }
                                        }
                                    }

                                    if (foundComponent != null)
                                    {
                                        foundComponent.RemoveFromParent(false);
                                        foundComponent.Dispose();
                                    }
                                }
                            }
                        }

                        item.component.providedTypeAllow = false;

                        //!!!!new
                        item.component.Name = item.name;

                        //!!!!сортировать

                        item.parent.component.AddComponent(item.component);
                    }

                    changed = true;
                }
                else
                {
                    unableToGetTypeName.AddWithCheckAlreadyContained(item.textBlock.Data);
                }
            }

            finished = item.component != null;
        }
        bool CreateObject()
        {
            creationData.ClearCreatedObjects();

            //!!!!в окнах/окне делать активным после создания

            //creationData.selectedType = SelectedType;
            //creationData.replaceSelectedTypeFunction?.Invoke( this );

            //!!!!
            //create objects
            {
                creationData.beforeCreateObjectsFunction?.Invoke(this, SelectedType);

                //default creation behaviour
                if (creationData.createdObjects == null)
                {
                    creationData.createdObjects = new List <object>();

                    if (creationData.initParentObjects != null)
                    {
                        foreach (var parentObject in creationData.initParentObjects)
                        {
                            var parentComponent = parentObject as Component;

                            object obj;
                            if (parentComponent != null)
                            {
                                var insertIndex = EditorUtility.GetNewObjectInsertIndex(parentComponent, SelectedType);
                                obj = parentComponent.CreateComponent(SelectedType, insertIndex, false);
                            }
                            else
                            {
                                obj = SelectedType.InvokeInstance(null);
                            }

                            creationData.createdObjects.Add(obj);
                            creationData.createdObjectsToApplySettings.Add(obj);
                            var c = obj as Component;
                            if (c != null)
                            {
                                creationData.createdComponentsOnTopLevel.Add(c);
                            }
                        }
                    }
                    else
                    {
                        var obj = SelectedType.InvokeInstance(null);

                        creationData.createdObjects.Add(obj);
                        creationData.createdObjectsToApplySettings.Add(obj);
                        var c = obj as Component;
                        if (c != null)
                        {
                            creationData.createdComponentsOnTopLevel.Add(c);
                        }
                    }
                }
            }

            //!!!!
            //no created objects
            if (creationData.createdObjects.Count == 0)
            {
                //!!!!
                return(false);
            }

            string realFileName = "";

            if (IsFileCreation())
            {
                realFileName = VirtualPathUtility.GetRealPathByVirtual(textBoxName.Text);
            }

            //create folder for file creation
            if (IsFileCreation())
            {
                var directoryName = Path.GetDirectoryName(realFileName);
                if (!Directory.Exists(directoryName))
                {
                    try
                    {
                        Directory.CreateDirectory(directoryName);
                    }
                    catch (Exception e)
                    {
                        Log.Warning(e.Message);
                        return(false);
                    }
                }
            }

            //init settings of objects
            bool disableFileCreation = false;

            foreach (var createdObject in creationData.createdObjectsToApplySettings)
            {
                if (!ApplyCreationSettingsToObject(createdObject, ref disableFileCreation))
                {
                    return(false);
                }
            }

            //action before enabled
            creationData.additionActionBeforeEnabled?.Invoke(this);

            //finalization of creation
            foreach (var component in creationData.createdComponentsOnTopLevel)
            {
                component.Enabled = true;
            }

            creationData.additionActionAfterEnabled?.Invoke(this);
            //foreach( var obj in createdObjects )
            //	creationData.additionActionAfterEnabled?.Invoke( this, obj, newObjectsFromAdditionActions );

            //file creation. save to file
            if (IsFileCreation())
            {
                //!!!!проверки
                //!!!!!!!overwrite

                if (creationData.createdComponentsOnTopLevel.Count == 1 && !disableFileCreation)
                {
                    var createdComponent = creationData.createdComponentsOnTopLevel[0];
                    if (!ComponentUtility.SaveComponentToFile(createdComponent, realFileName, null, out string error))
                    {
                        if (!string.IsNullOrEmpty(error))
                        {
                            //!!!!
                            Log.Warning(error);
                            return(false);
                        }
                    }
                }

                //Dispose created objects for file creation mode
                foreach (var obj in creationData.createdObjects)
                {
                    var d = obj as IDisposable;
                    if (d != null)
                    {
                        d.Dispose();
                    }
                }
            }

            //update document
            if (!IsFileCreation())
            {
                //update document
                //!!!!!
                var document = creationData.initDocumentWindow.Document;
                if (document != null)
                {
                    //!!!!только компоненты?

                    var action = new UndoActionComponentCreateDelete(document, creationData.createdComponentsOnTopLevel, true);

                    //List<Component> created = new List<Component>();
                    //created.AddRange( createdComponents );
                    //foreach( var obj in newObjectsFromAdditionActions )
                    //{
                    //	var component = obj as Component;
                    //	if( component != null )
                    //		created.Add( component );
                    //}
                    //var action = new UndoActionComponentCreateDelete( created, true );
                    document.UndoSystem.CommitAction(action);

                    document.Modified = true;
                }
                else
                {
                    //!!!!надо ли?
                    Log.Warning("impl");
                }
            }

            //select and open
            if (IsFileCreation())
            {
                //!!!!не обязательно основное окно

                EditorAPI.GetRestartApplication(out var needRestart, out _);
                if (needRestart)
                {
                    EditorSettingsSerialization.OpenFileAtStartup = realFileName;
                }
                else
                {
                    //select new file in Resources window
                    EditorAPI.SelectFilesOrDirectoriesInMainResourcesWindow(new string[] { realFileName });

                    //open file
                    EditorAPI.OpenFileAsDocument(realFileName, true, true);
                }
            }
            else
            {
                //select created components
                if (creationData.createdFromContentBrowser != null)
                {
                    var creator = creationData.createdFromContentBrowser;
                    if (creator.IsHandleCreated && !creator.IsDisposed)
                    {
                        ContentBrowserUtility.SelectComponentItems(creator, creationData.createdComponentsOnTopLevel.ToArray());
                    }
                }
                else
                {
                    EditorAPI.SelectComponentsInMainObjectsWindow(creationData.initDocumentWindow, creationData.createdComponentsOnTopLevel.ToArray());
                }

                //open editor
                if (creationData.createdComponentsOnTopLevel.Count == 1)
                {
                    var component = creationData.createdComponentsOnTopLevel[0];

                    if (!component.EditorReadOnlyInHierarchy)
                    {
                        //!!!!пока так
                        if (component is Component_FlowGraph || component is Component_CSharpScript)
                        {
                            EditorAPI.OpenDocumentWindowForObject(creationData.initDocumentWindow.Document, component);
                        }
                    }
                    //if( EditorAPI.IsDocumentObjectSupport( component ) && !component.EditorReadOnlyInHierarchy )
                    //	EditorAPI.OpenDocumentWindowForObject( creationData.initDocumentWindow.Document, component );
                }
            }

            //finish creation
            creationData.ClearCreatedObjects();

            return(true);
        }