private static void OnPlayModeStateChanged(PlayModeStateChange state) { switch (state) { case PlayModeStateChange.EnteredEditMode: // call any queued code processing methods if (!QueuedAssetsToBeProcessed) { break; } QueuedAssetsToBeProcessed = false; var importedAssets = PostprocessBatch.ImportedAssets.ToArray(); var deletedAssets = PostprocessBatch.DeletedAssets.ToArray(); var movedAssets = PostprocessBatch.MovedAssets.ToArray(); var movedFromAssets = PostprocessBatch.MovedFromAssets.ToArray(); PostprocessBatch.Clear(); ContentAssetProcessor.OnPostprocessAllAssets(importedAssets, deletedAssets, movedAssets, movedFromAssets); break; case PlayModeStateChange.ExitingEditMode: // generate bundles if necessary var config = MasterConfig.GetInstance(); var needBuild = config.AssetsNeedBuild; if (!needBuild) { break; } var bundles = ContentObjectModel.GetInstance().AssetBundleObjects.Where(x => x.NeedBuild).ToList(); if (bundles.Count > 0) { try { ContentAssetProcessor.IgnoreChanges = true; ContentParser.BuildAssetBundles(bundles); } finally { ContentAssetProcessor.IgnoreChanges = false; } } break; case PlayModeStateChange.EnteredPlayMode: break; case PlayModeStateChange.ExitingPlayMode: break; } }
public static void GenerateApiDocTemplate() { var sb = new StringBuilder(); var apiDocsTemplateFile = "Assets/DevTools/Docs/ApiDocs-Template.txt"; var contentObjectModel = ContentObjectModel.GetInstance(); var config = MasterConfig.GetInstance(); // iterate through all views and their dependency properties foreach (var viewObject in contentObjectModel.ViewObjects.OrderBy(x => x.Name)) { var docObject = config.DocObjects.FirstOrDefault(x => x.Name == viewObject.Name); var propertyDeclarations = CodeGenerator.GetPropertyDeclarations(viewObject, false, true, true).Where(x => x.Declaration.DeclarationType != PropertyDeclarationType.Template && x.Declaration.DeclarationType != PropertyDeclarationType.View && x.Declaration.DeclarationType != PropertyDeclarationType.UnityComponent).OrderBy(x => x.Declaration.PropertyName); string docObjectComment = docObject?.Comment ?? string.Empty; sb.AppendLine("{0}: {1}", viewObject.Name, docObjectComment); if (!propertyDeclarations.Any()) { continue; } foreach (var propertyDeclaration in propertyDeclarations) { if (propertyDeclaration.Declaration.DeclarationType == PropertyDeclarationType.Template || propertyDeclaration.Declaration.DeclarationType == PropertyDeclarationType.UnityComponent || (propertyDeclaration.Declaration.DeclarationType == PropertyDeclarationType.View && !propertyDeclaration.IsMapped)) { continue; // ignore component, template and view properties as we'll generate default docs for those } var docProperty = docObject?.Properties.FirstOrDefault(x => x.Name == propertyDeclaration.Declaration.PropertyName); if (!String.IsNullOrEmpty(docProperty?.Comment)) { continue; // ignore properties that already have comments } // add empty entries for properties that aren't commented string comment = string.Empty; sb.AppendLine("- {0}: {1}", propertyDeclaration.Declaration.PropertyName, comment); } sb.AppendLine(); } // write text to file File.WriteAllText(apiDocsTemplateFile, sb.ToString()); Debug.Log(String.Format("#Delight# Documentation generated at \"{0}\"", apiDocsTemplateFile)); }
/// <summary> /// Called when inspector GUI is to be rendered. /// </summary> public override async void OnInspectorGUI() { var viewPresenter = (ViewPresenter)target; var config = MasterConfig.GetInstance(); // currently presented view int selectedViewIndex = config.Views.IndexOf(viewPresenter.ViewTypeName) + 1; // .. add empty selection var viewList = new List <string>(config.Views); viewList.Insert(0, "-- none --"); int newSelectedViewIndex = EditorGUILayout.Popup("View", selectedViewIndex, viewList.ToArray()); viewPresenter.ViewTypeName = newSelectedViewIndex > 0 ? config.Views[newSelectedViewIndex - 1] : String.Empty; if (newSelectedViewIndex != selectedViewIndex) { EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); } // TODO here we can look up assembly qualified name to make instantiation quicker DrawDefaultInspector(); // loads view GUI.enabled = Application.isPlaying; GUIContent load = new GUIContent("Load", "Instantiates and loads the view."); if (GUILayout.Button(load)) { await viewPresenter.Load(); } // unloads view GUIContent unload = new GUIContent("Unload", "Unloads the view."); if (GUILayout.Button(unload)) { viewPresenter.Unload(); } GUI.enabled = true; }
//[MenuItem("Assets/Create/Delight View + Code-behind", false, -19)] //private static void CreateViewXmlAndCodeBehind() //{ // CreateViewXml(true); //} private static void CreateViewXml(bool generateCodeBehind) { var contentObjectModel = ContentObjectModel.GetInstance(); var path = ContentParser.GetContentFolderPathFromSelectedFile(ContentParser.ViewsFolder); var filename = ""; int i = 0; string viewName = ""; do { viewName = String.Format("NewView{0}", i == 0 ? string.Empty : i.ToString()); filename = String.Format("{0}{1}.xml", path, viewName); ++i; // find unique name if (!File.Exists(filename)) { // check if view name exists if (!contentObjectModel.ViewObjects.Any(x => x.Name == viewName)) { // name is valid break; } } } while (true); // set indicator to generate code-behind once file is renamed if (generateCodeBehind) { var config = MasterConfig.GetInstance(); config.GenerateBlankCodeBehind = true; config.SaveConfig(); } // create XML file that the user will be allowed to name, once created the XML parser will generate the content ProjectWindowUtil.CreateAssetWithContent(filename, string.Empty); }
/// <summary> /// Processes XML assets that are added/changed and generates code-behind. /// </summary> public static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssets) { if (EditorPrefs.GetBool("Delight_DisableAutoContentParser") && !ForceProcessing) { return; } // check if any views have been added or changed var config = MasterConfig.GetInstance(); config.UpdateExtensionContentFolders(); // update extension content folders in case new extension content is added // xml content var addedOrUpdatedXmlAssets = new List <string>(); // assets var addedOrUpdatedAssetObjects = new List <string>(); var deletedAssetObjects = new List <string>(); var movedAssetObjects = new List <string>(); var movedFromAssetObjects = new List <string>(); // data schemas var addedOrUpdatedSchemaObjects = new List <string>(); var deletedSchemaObjects = new List <string>(); var movedSchemaObjects = new List <string>(); var movedFromSchemaObjects = new List <string>(); bool rebuildConfig = false; bool rebuildViews = false; // process imported assets foreach (var path in importedAssets) { // is the asset in a content folder? var contentFolder = config.ContentFolders.FirstOrDefault(x => path.IIndexOf(x) >= 0); if (contentFolder == null) { continue; // no. } // is it an cs file? if (path.IIndexOf(".cs") >= 0) { continue; // yes. ignore } // is the asset in the assets folder? if (IsInAssetsFolder(path, contentFolder)) { addedOrUpdatedAssetObjects.Add(path); continue; } // is the asset in the models folder? if (IsInContentTypeFolder(path, contentFolder, ContentParser.ModelsFolder)) { if (!path.IContains("Schema")) { continue; } addedOrUpdatedSchemaObjects.Add(path); continue; } // is the asset a config file? if (path.IContains(".txt") && path.IContains("Config")) { // rebuild config rebuildConfig = true; continue; } // is the asset in a styles folder? if (IsInStylesFolder(path, contentFolder)) { // yes. rebuild all views rebuildViews = true; continue; } // is it an xml asset? if (path.IIndexOf(".xml") >= 0) { addedOrUpdatedXmlAssets.Add(path); } } // process deleted assets foreach (var path in deletedAssets) { // is the asset in a content folder? var contentFolder = config.ContentFolders.FirstOrDefault(x => path.IIndexOf(x) >= 0); if (contentFolder == null) { continue; // no. } // is it an cs file? if (path.IIndexOf(".cs") >= 0) { continue; // yes. ignore } // is the asset in the assets folder? if (IsInAssetsFolder(path, contentFolder)) { deletedAssetObjects.Add(path); continue; } // is the asset in the models folder? if (IsInContentTypeFolder(path, contentFolder, ContentParser.ModelsFolder)) { if (!path.IContains("Schema")) { continue; } deletedSchemaObjects.Add(path); continue; } // is the asset a config file? if (path.IContains(".txt") && path.IContains("Config")) { // rebuild config rebuildConfig = true; continue; } // is it an xml asset? if (path.IIndexOf(".xml") >= 0) { rebuildViews = true; } } // process moved assets for (int i = 0; i < movedAssets.Length; ++i) { var movedToPath = movedAssets[i]; var movedFromPath = movedFromAssets[i]; // is it an cs file? if (movedToPath.IIndexOf(".cs") >= 0) { continue; // yes. ignore } // is the asset moved to or from a content folder? var toContentFolder = config.ContentFolders.FirstOrDefault(x => movedToPath.IIndexOf(x) >= 0); var fromContentFolder = config.ContentFolders.FirstOrDefault(x => movedFromPath.IIndexOf(x) >= 0); if (toContentFolder == null && fromContentFolder == null) { continue; // no. } // is the asset in the assets folder? bool movedFromAssetFolder = IsInAssetsFolder(movedFromPath, fromContentFolder); if (IsInAssetsFolder(movedToPath, toContentFolder) || movedFromAssetFolder) { movedAssetObjects.Add(movedToPath); if (movedFromAssetFolder) { movedFromAssetObjects.Add(movedFromPath); } continue; } // is the asset in the models folder? if (IsInContentTypeFolder(movedToPath, toContentFolder, ContentParser.ModelsFolder)) { if (!movedToPath.IContains("Schema")) { continue; } movedSchemaObjects.Add(movedToPath); if (IsInContentTypeFolder(movedFromPath, fromContentFolder, ContentParser.ModelsFolder)) { movedFromSchemaObjects.Add(movedFromPath); } continue; } // is the asset a config file? if (movedToPath.IContains(".txt") && movedToPath.IContains("Config")) { // rebuild config rebuildConfig = true; continue; } // is it an xml asset? if (movedToPath.IIndexOf(".xml") >= 0) { rebuildViews = true; } } bool viewsChanged = addedOrUpdatedXmlAssets.Count() > 0; bool assetsChanged = addedOrUpdatedAssetObjects.Count() > 0 || deletedAssetObjects.Count() > 0 || movedAssetObjects.Count() > 0; bool schemasChanged = addedOrUpdatedSchemaObjects.Count() > 0 || deletedSchemaObjects.Count() > 0 || movedSchemaObjects.Count() > 0; bool contentChanged = assetsChanged || rebuildViews || viewsChanged || schemasChanged || rebuildConfig; bool logComplete = contentChanged; bool refreshScripts = false; bool generateXsdSchema = false; // if editor is playing queue assets to be processed after exiting play mode if (Application.isPlaying && !ForceProcessing) { if (contentChanged) { Debug.Log("#Delight# Content (View, Assets, etc) changed while editor is playing. Content will be processed after editor exits play mode."); EditorEventListener.AddPostProcessBatch(importedAssets, deletedAssets, movedAssets, movedFromAssets); } return; } var sw = System.Diagnostics.Stopwatch.StartNew(); // TODO for tracking processing time // check if model file is new, then rebuild all content var contentObjectModel = ContentObjectModel.GetInstance(); if (contentObjectModel.NeedRebuild) { ContentParser.RebuildAll(true, true, true, true); return; } // any config changed? if (rebuildConfig) { var result = ContentParser.ParseAllConfigFiles(); if (result.HasFlag(ConfigParseResult.RebuildAll)) { ContentParser.RebuildAll(true, true, false, false); return; } else { if (result.HasFlag(ConfigParseResult.RebuildSchemas)) { ContentParser.ParseAllSchemaFiles(); schemasChanged = false; } if (result.HasFlag(ConfigParseResult.RebuildBundles)) { ContentParser.RebuildAssets(true); assetsChanged = false; generateXsdSchema = true; } } refreshScripts = true; } // any asset objects added, moved or deleted? if (assetsChanged) { ContentParser.ParseAssetFiles(addedOrUpdatedAssetObjects, deletedAssetObjects, movedAssetObjects, movedFromAssetObjects); refreshScripts = true; generateXsdSchema = true; } // any schema files added, moved or deleted? if (schemasChanged) { ContentParser.ParseSchemaFiles(addedOrUpdatedSchemaObjects, deletedSchemaObjects, movedSchemaObjects, movedFromSchemaObjects); refreshScripts = true; generateXsdSchema = true; } // any xml content moved or deleted? if (rebuildViews) { // yes. rebuild all views ContentParser.RebuildViews(); refreshScripts = false; generateXsdSchema = false; } else if (viewsChanged) { // parse new content and generate code ContentParser.ParseXmlFiles(addedOrUpdatedXmlAssets); refreshScripts = true; generateXsdSchema = true; } if (refreshScripts) { // refresh generated scripts AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport); } if (generateXsdSchema) { CodeGenerator.GenerateXsdSchema(); } if (contentChanged) { ConsoleLogger.Log(String.Format("#Delight# Content processed. {0}", DateTime.Now)); //Debug.Log(String.Format("Total content processing time: {0}", sw.ElapsedMilliseconds)); } }
private static void OnPlayModeStateChanged(PlayModeStateChange state) { switch (state) { case PlayModeStateChange.EnteredEditMode: break; case PlayModeStateChange.ExitingEditMode: // generate bundles if necessary var config = MasterConfig.GetInstance(); var needBuild = config.AssetsNeedBuild; if (!needBuild) { break; } var bundles = ContentObjectModel.GetInstance().AssetBundleObjects.Where(x => x.NeedBuild).ToList(); if (bundles.Count > 0) { ContentParser.BuildAssetBundles(bundles); } break; case PlayModeStateChange.EnteredPlayMode: break; case PlayModeStateChange.ExitingPlayMode: bool exitInterrupted = false; #if DELIGHT_MODULE_TEXTMESHPRO if (IsInDelightDesigner) { //var activeScene = EditorSceneManager.GetActiveScene(); // TODO cleanup // check if delight designer has unsaved progress var viewPresenter = GameObject.Find("/Delight")?.GetComponent <ViewPresenter>(); if (viewPresenter == null) { break; } var delightDesignerView = viewPresenter.PresentedView as DelightDesigner; if (delightDesignerView == null) { break; } if (delightDesignerView.CheckForUnsavedChanges()) { EditorApplication.isPlaying = true; exitInterrupted = true; } } #endif if (!exitInterrupted && QueuedAssetsToBeProcessed) { // call any queued code processing methods var importedAssets = PostprocessBatch.ImportedAssets.ToArray(); var deletedAssets = PostprocessBatch.DeletedAssets.ToArray(); var movedAssets = PostprocessBatch.MovedAssets.ToArray(); var movedFromAssets = PostprocessBatch.MovedFromAssets.ToArray(); PostprocessBatch.Clear(); QueuedAssetsToBeProcessed = false; ContentAssetProcessor.ForceProcessing = true; ContentAssetProcessor.OnPostprocessAllAssets(importedAssets, deletedAssets, movedAssets, movedFromAssets); ContentAssetProcessor.ForceProcessing = false; } break; } }
/// <summary> /// Called when GUI is to be rendered. /// </summary> public void OnGUI() { bool buildAssetBundles = EditorPrefs.GetBool("Delight_BuildAssetBundles"); bool deployBuild = EditorPrefs.GetBool("Delight_DeployBuild"); // rebuild all GUIContent rebuildAll = new GUIContent("Rebuild All", "Rebuilds all delight content (views, assets, etc)."); if (GUILayout.Button(rebuildAll)) { ContentParser.RebuildAll(buildAssetBundles || deployBuild); } var newBuildAssetBundles = EditorGUILayout.Toggle("Build Asset Bundles", EditorPrefs.GetBool("Delight_BuildAssetBundles")); if (newBuildAssetBundles != buildAssetBundles) { EditorPrefs.SetBool("Delight_BuildAssetBundles", newBuildAssetBundles); } //var newDeployBuild = EditorGUILayout.Toggle("Rivality Deploy Build", EditorPrefs.GetBool("Delight_DeployBuild")); //if (newDeployBuild != deployBuild) //{ // EditorPrefs.SetBool("Delight_DeployBuild", newDeployBuild); //} bool disableAutoGenerateViews = EditorPrefs.GetBool("Delight_DisableAutoGenerateViews"); var newDisableAutoGenerateViews = EditorGUILayout.Toggle("Disable view autogen", disableAutoGenerateViews); if (newDisableAutoGenerateViews != disableAutoGenerateViews) { EditorPrefs.SetBool("Delight_DisableAutoGenerateViews", newDisableAutoGenerateViews); } bool disableAutoGenerateHandlers = EditorPrefs.GetBool("Delight_DisableAutoGenerateHandlers"); var newDisableAutoGenerateHandlers = EditorGUILayout.Toggle("Disable handler autogen", disableAutoGenerateHandlers); if (newDisableAutoGenerateHandlers != disableAutoGenerateHandlers) { EditorPrefs.SetBool("Delight_DisableAutoGenerateHandlers", newDisableAutoGenerateHandlers); } bool disableContentParser = EditorPrefs.GetBool("Delight_DisableAutoContentParser"); var newDisableContentParser = EditorGUILayout.Toggle("Disable content parser", disableContentParser); if (newDisableContentParser != disableContentParser) { EditorPrefs.SetBool("Delight_DisableAutoContentParser", newDisableContentParser); } // open designer GUIContent openDesigner = new GUIContent("Open Designer", "Opens delight designer."); if (GUILayout.Button(openDesigner)) { // check if designer is activated var config = MasterConfig.GetInstance(); if (!config.Modules.Contains("TextMeshPro")) { // open window explaining designer need to be activated string message = "The designer need to be activated by enabling TextMeshPro in the project. https://delight-dev.github.io/Tutorials/Designer.html#enabling-the-designer"; Application.OpenURL("https://delight-dev.github.io/Tutorials/Designer.html#enabling-the-designer"); EditorUtility.DisplayDialog("Enabling the designer", message, "Ok"); } else { EditorSceneManager.OpenScene("Assets/Delight/Content/Scenes/DelightDesigner.unity"); EditorApplication.isPlaying = true; } } // button for testing //GUIContent test = new GUIContent("Assets Refresh", ""); //if (GUILayout.Button(test)) //{ // AssetDatabase.Refresh(); //} }