/// <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); }
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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
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(); } }