예제 #1
0
        /// <summary>
        /// Saves the current project or module to the assets directory
        ///
        /// NOTE: If the project has never been saved before a `Save As` is called instead
        /// </summary>
        public static bool Save()
        {
            var persistentObject = EditorContext.PersistentObject;

            // No `PersistenceId` means this object has never been saved, promt the user with the `Save As` instead
            if (string.IsNullOrEmpty(persistentObject.PersistenceId))
            {
                return(SaveAs());
            }

            // Use a DontSaveScope since saving may trigger the `OnWillSaveAssets` callback
            using (new UTinyModificationProcessor.DontSaveScope())
            {
                var path = UTinyPersistence.PersistObject(persistentObject);

                if (string.IsNullOrEmpty(path))
                {
                    return(false);
                }
            }

            UTinyEditorPrefs.SaveWorkspace(EditorContext.Workspace, persistentObject.PersistenceId);
            OnSaveProject?.Invoke(EditorContext.Project);
            UTinyModificationProcessor.ClearChanged();

            return(true);
        }
예제 #2
0
        public static bool SaveAs()
        {
            var persistentObject = EditorContext.PersistentObject;
            var extension        = UTinyPersistence.GetFileExtension(persistentObject);

            var path = EditorUtility.SaveFilePanelInProject($"Save {ContextType}", persistentObject.Name, extension.Substring(1), string.Empty);

            if (string.IsNullOrEmpty(path))
            {
                return(false);
            }

            // Use a DontSaveScope since saving may trigger the `OnWillSaveAssets` callback
            using (new UTinyModificationProcessor.DontSaveScope())
            {
                // Fix-up the name
                persistentObject.Name = Path.GetFileNameWithoutExtension(path);

                // Flush the caretaker so this operation is not undoable
                EditorContext.Caretaker.Update();

                path = UTinyPersistence.PersistObjectAs(persistentObject, path);

                if (string.IsNullOrEmpty(path))
                {
                    return(false);
                }
            }

            UTinyEditorPrefs.SaveWorkspace(EditorContext.Workspace, persistentObject.PersistenceId);
            OnSaveProject?.Invoke(EditorContext.Project);
            UTinyModificationProcessor.ClearChanged();

            return(true);
        }
예제 #3
0
        /// <summary>
        /// Creates and loads a new .utmodule
        /// @NOTE The module only exists in memory until Save() is called
        /// </summary>
        public static void NewModule()
        {
            var context  = new UTinyContext();
            var registry = context.Registry;

            UTinyPersistence.LoadAllModules(registry);

            // Create a `workspace` project to host the module for editing purposes
            var project = registry.CreateProject(UTinyId.Generate(KWorkspaceProjectName), KWorkspaceProjectName);

            // Create objects for the new module
            var module = registry.CreateModule(UTinyId.New(), "NewModule");

            // Setup initial state for the module
            module.Namespace = "module";

            SetupModule(registry, module);

            project.Module = (UTinyModule.Reference)module;

            var workspace = new UTinyEditorWorkspace();

            UTinyEditorPrefs.SaveWorkspace(workspace);

            var editorContext = new UTinyEditorContext((UTinyProject.Reference)project, EditorContextType.Module, context, workspace);

            LoadContext(editorContext, isChanged: true);
        }
예제 #4
0
        /// <summary>
        /// Creates and loads a new .utproject
        /// @NOTE The project only exists in memory until Save() is called
        /// </summary>
        public static void NewProject()
        {
            Assert.IsFalse(EditorApplication.isPlayingOrWillChangePlaymode);

            var context  = new UTinyContext();
            var registry = context.Registry;

            UTinyPersistence.LoadAllModules(registry);

            // Create new objects for the project
            var project = registry.CreateProject(UTinyId.New(), "NewProject");
            var module  = registry.CreateModule(UTinyId.New(), "Main");

            // Setup the start scene
            var entityGroup    = registry.CreateEntityGroup(UTinyId.New(), "NewEntityGroup");
            var entityGroupRef = (UTinyEntityGroup.Reference)entityGroup;
            var cameraEntity   = registry.CreateEntity(UTinyId.New(), "Camera");
            var transform      = cameraEntity.AddComponent(registry.GetTransformType());

            transform.Refresh();
            var camera = cameraEntity.AddComponent(registry.GetCamera2DType());

            camera.Refresh();
            camera["clearFlags"] = new UTinyEnum.Reference(registry.GetCameraClearFlagsType().Dereference(registry), 1);
            camera.AssignPropertyFrom("backgroundColor", Color.black);
            camera["depth"] = -1.0f;
            entityGroup.AddEntityReference((UTinyEntity.Reference)cameraEntity);

            // Setup initial state for the project
            module.Options           |= UTinyModuleOptions.ProjectModule;
            module.Namespace          = "game";
            module.StartupEntityGroup = (UTinyEntityGroup.Reference)entityGroup;

            module.AddEntityGroupReference(entityGroupRef);

            project.Module = (UTinyModule.Reference)module;
            project.Settings.EmbedAssets  = true;
            project.Settings.CanvasWidth  = 1920;
            project.Settings.CanvasHeight = 1080;

            SetupProject(registry, project);

            module.AddExplicitModuleDependency((UTinyModule.Reference)registry.FindByName <UTinyModule>("UTiny.Core2D"));

            // Always include a dependency on core, math, core2d by default
            // And HTML for now, since it is the only renderer we have right now.
            module.AddExplicitModuleDependency((UTinyModule.Reference)registry.FindByName <UTinyModule>("UTiny.HTML"));

            var workspace = new UTinyEditorWorkspace
            {
                OpenedEntityGroups = { entityGroupRef },
                ActiveEntityGroup  = entityGroupRef
            };

            UTinyEditorPrefs.SaveWorkspace(workspace);

            var editorContext = new UTinyEditorContext((UTinyProject.Reference)project, EditorContextType.Project, context, workspace);

            LoadContext(editorContext, isChanged: true);
        }
예제 #5
0
        /// <summary>
        /// Trys to loads the last saved temp file
        /// </summary>
        public static void LoadTemp()
        {
            Assert.IsFalse(EditorApplication.isPlayingOrWillChangePlaymode);

            if (!UTinyTemp.Exists())
            {
                return;
            }

            var context  = new UTinyContext();
            var registry = context.Registry;

            string persistenceId;

            if (!UTinyTemp.Accept(registry, out persistenceId))
            {
                LoadPersistenceId(persistenceId);
                return;
            }

            var project = registry.FindAllByType <UTinyProject>().FirstOrDefault();
            UTinyEditorContext editorContext = null;

            if (project != null)
            {
                SetupProject(registry, project);

                editorContext = new UTinyEditorContext((UTinyProject.Reference)project, EditorContextType.Project, context, UTinyEditorPrefs.LoadLastWorkspace());
            }
            else
            {
                var module = registry.FindAllBySource(UTinyRegistry.DefaultSourceIdentifier).OfType <UTinyModule>().First();

                SetupModule(registry, module);

                if (null != module)
                {
                    project        = registry.CreateProject(UTinyId.Generate(KWorkspaceProjectName), KWorkspaceProjectName);
                    project.Module = (UTinyModule.Reference)module;

                    editorContext = new UTinyEditorContext((UTinyProject.Reference)project, EditorContextType.Module, context, UTinyEditorPrefs.LoadLastWorkspace());
                }
            }

            Assert.IsNotNull(project);
            LoadContext(editorContext, true);
        }
예제 #6
0
        /// <summary>
        /// Loads the utmodule at the given file path
        /// </summary>
        /// <param name="moduleFile">Relative path to the .utmodule file</param>
        public static void LoadModule(string moduleFile)
        {
            Assert.IsFalse(EditorApplication.isPlayingOrWillChangePlaymode);

            var context  = new UTinyContext();
            var registry = context.Registry;

            UTinyPersistence.LoadModule(moduleFile, registry);

            var module = registry.FindAllBySource(UTinyRegistry.DefaultSourceIdentifier).OfType <UTinyModule>().First();

            Assert.IsNotNull(module);

            module.Name = Path.GetFileNameWithoutExtension(moduleFile);

            SetupModule(registry, module);

            var project = registry.CreateProject(UTinyId.Generate(KWorkspaceProjectName), KWorkspaceProjectName);

            project.Module = (UTinyModule.Reference)module;

            var editorContext = new UTinyEditorContext((UTinyProject.Reference)project, EditorContextType.Module, context, UTinyEditorPrefs.LoadWorkspace(project.PersistenceId));

            LoadContext(editorContext, isChanged: false);
        }
예제 #7
0
        /// <summary>
        /// Loads the utproject at the given file path
        /// </summary>
        /// <param name="projectFile">Relative path to the .utproject file</param>
        public static void LoadProject(string projectFile)
        {
            Assert.IsFalse(EditorApplication.isPlayingOrWillChangePlaymode);

            var context  = new UTinyContext();
            var registry = context.Registry;

            UTinyPersistence.LoadProject(projectFile, registry);

            var project = registry.FindAllByType <UTinyProject>().First();

            Assert.IsNotNull(project);

            project.Name = Path.GetFileNameWithoutExtension(projectFile);

            SetupProject(registry, project);

            var editorContext = new UTinyEditorContext((UTinyProject.Reference)project, EditorContextType.Project, context, UTinyEditorPrefs.LoadWorkspace(project.PersistenceId));

            LoadContext(editorContext, isChanged: false);
        }
예제 #8
0
        private static void Update()
        {
            if (EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return;
            }

            if (null == EditorContext)
            {
                // Flush asset changes from the persistence system
                // We don't care about any changes unless we have a project loaded
                UTinyPersistence.ClearChanges();
                return;
            }

            // Poll for workspace changes
            if (null != EditorContext.Workspace && s_WorkspaceVersion != EditorContext.Workspace.Version)
            {
                UTinyEditorPrefs.SaveWorkspace(EditorContext.Workspace, EditorContext.PersistentObject.PersistenceId);
                s_WorkspaceVersion = EditorContext.Workspace.Version;
            }

            // Poll for file/asset changes
            var changes = UTinyPersistence.DetectChanges(Registry);

            if (changes.changesDetected)
            {
                var persistenceId = EditorContext.PersistentObject.PersistenceId;

                foreach (var change in changes.changedSources)
                {
                    // The currently opened project or module has been changed on disc
                    if (change.Equals(persistenceId))
                    {
                        // Ask the user if they want to keep their changes or reload from disc
                        if (EditorUtility.DisplayDialog($"{UTinyConstants.ApplicationName} assets changed", $"{UTinyConstants.ApplicationName} assets have changed on disk, would you like to reload the current project?", "Yes", "No"))
                        {
                            LoadPersistenceId(persistenceId);
                        }
                        else
                        {
                            UTinyModificationProcessor.MarkChanged();
                        }
                    }
                    else
                    {
                        // This is some other file. We assume they are in a readonly state and we silently reload the object
                        UTinyPersistence.ReloadObject(EditorContext.Registry, change);
                    }
                }

                foreach (var deletion in changes.deletedSources)
                {
                    // The currently opened project or module has been deleted on disc
                    if (deletion.Equals(persistenceId))
                    {
                        // Ask the user if they want to keep their changes or close the project
                        if (EditorUtility.DisplayDialog($"{UTinyConstants.ApplicationName} assets changed", "The current project has been deleted, would you like to close the current project?", "Yes", "No"))
                        {
                            // Force close the project
                            Close();
                        }
                        else
                        {
                            UTinyModificationProcessor.MarkChanged();
                            EditorContext.PersistentObject.PersistenceId = string.Empty;
                        }
                    }
                    else
                    {
                        // This is some other file. We assume they are in a readonly state and we silently reload the object
                        EditorContext.Registry.UnregisterAllBySource(deletion);
                    }
                }

                foreach (var moved in changes.movedSources)
                {
                    if (!moved.Equals(persistenceId))
                    {
                        continue;
                    }

                    var path  = AssetDatabase.GUIDToAssetPath(moved);
                    var asset = AssetDatabase.LoadAssetAtPath(path, typeof(UnityEngine.Object));
                    if (null != asset)
                    {
                        EditorContext.PersistentObject.Name = asset.name;
                    }
                }

                OnChangesDetected?.Invoke();
            }

            // Poll for module or project changes
            if (EditorContext.ContextType == EditorContextType.Project && (s_ProjectVersion != EditorContext.Project.Version || s_ModuleVersion != EditorContext.Module.Version))
            {
                EditorContext.Project.RefreshConfiguration();
                s_ProjectVersion = EditorContext.Project.Version;
                s_ModuleVersion  = EditorContext.Module.Version;
            }

            if (s_Save)
            {
                s_Save = false;

                // NOTE: It is possible that this call will fail
                Save();
            }
        }