Skip to content

Commit 1951ce4

Browse files
authored
[v0.3.9] Entity Recipe & migration from Authoring Component Database
* [v0.3.9] Entity recipe & migration tool * Fixes & polyshing * + * +
1 parent a20755b commit 1951ce4

25 files changed

Lines changed: 777 additions & 107 deletions
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// © 2023-2026 Depra <n.melnikov@depra.org>
3+
4+
using Depra.Ecs.Hybrid.Editor.Migration;
5+
using UnityEditor;
6+
using UnityEditor.SceneManagement;
7+
using UnityEngine;
8+
9+
namespace Depra.Ecs.Hybrid.Editor
10+
{
11+
[CustomEditor(typeof(AuthoringComponentDatabase))]
12+
internal sealed class AuthoringComponentDatabaseEditor : UnityEditor.Editor
13+
{
14+
public override void OnInspectorGUI()
15+
{
16+
DrawDefaultInspector();
17+
var component = (AuthoringComponentDatabase)target;
18+
var go = component.gameObject;
19+
var isPrefabAsset = PrefabUtility.IsPartOfPrefabAsset(go);
20+
var isPrefabMode = PrefabStageUtility.GetCurrentPrefabStage();
21+
var canMigrate = isPrefabAsset || isPrefabMode;
22+
using (new EditorGUI.DisabledScope(!canMigrate))
23+
{
24+
if (GUILayout.Button("Migrate"))
25+
{
26+
TryMigrateToRecipe(component);
27+
}
28+
}
29+
}
30+
31+
private static void TryMigrateToRecipe(AuthoringComponentDatabase component)
32+
{
33+
var stage = PrefabStageUtility.GetCurrentPrefabStage();
34+
var prefabPath = stage ? stage.assetPath : AssetDatabase.GetAssetPath(component.gameObject);
35+
36+
if (string.IsNullOrEmpty(prefabPath))
37+
{
38+
Debug.LogWarning("Cannot resolve prefab path for migration.");
39+
return;
40+
}
41+
42+
if (AuthoringComponentDatabaseMigration.MigratePrefab(prefabPath))
43+
{
44+
AssetDatabase.SaveAssets();
45+
AssetDatabase.Refresh();
46+
Debug.Log($"✓ Migrated: {prefabPath}");
47+
}
48+
}
49+
}
50+
}

Editor/AuthoringComponentDatabaseEditor.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// © 2023-2026 Depra <n.melnikov@depra.org>
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.IO;
7+
using System.Linq;
8+
using UnityEditor;
9+
using UnityEngine;
10+
using Object = UnityEngine.Object;
11+
12+
namespace Depra.Ecs.Hybrid.Editor.Migration
13+
{
14+
/// <summary>
15+
/// TEMPORARY: Migration utility for AuthoringComponentDatabase -> AuthoringRecipe
16+
/// TODO: Remove this file after migration is complete.
17+
/// </summary>
18+
internal static class AuthoringComponentDatabaseMigration
19+
{
20+
private const string FILE_POSFIX = " Entity.asset";
21+
private const string MIGRATION_KEY = "AuthoringComponentDatabase_Migration_v1_Completed";
22+
23+
[MenuItem("Ecs/Migration/Authoring Component Database/1. Preview Changes")]
24+
public static void PreviewMigration()
25+
{
26+
var targets = FindMigrationTargets().ToArray();
27+
if (targets.Length == 0)
28+
{
29+
EditorUtility.DisplayDialog("Migration Preview",
30+
"No prefabs found with AuthoringComponentDatabase.", "OK");
31+
return;
32+
}
33+
34+
var message = $"Found {targets.Length} prefab(s) to migrate:\n\n";
35+
foreach (var path in targets)
36+
{
37+
message += $"• {path}\n";
38+
}
39+
40+
Debug.Log("[MIGRATION PREVIEW]\n" + message);
41+
EditorUtility.DisplayDialog("Migration Preview", message, "OK");
42+
}
43+
44+
[MenuItem("Ecs/Migration/Authoring Component Database/2. Run Migration")]
45+
public static void RunMigration()
46+
{
47+
if (EditorPrefs.GetBool(MIGRATION_KEY, false))
48+
{
49+
if (!EditorUtility.DisplayDialog("Migration Warning",
50+
"Migration was already completed before. Run again?",
51+
"Yes, Run Again", "Cancel"))
52+
{
53+
return;
54+
}
55+
}
56+
57+
var targets = FindMigrationTargets().ToArray();
58+
if (targets.Length == 0)
59+
{
60+
EditorUtility.DisplayDialog("Migration", "No prefabs to migrate.", "OK");
61+
return;
62+
}
63+
64+
if (!EditorUtility.DisplayDialog("Confirm Migration",
65+
$"This will modify {targets.Length} prefab(s).\n\n" +
66+
"Make sure you have a backup or are using version control!\n\n" +
67+
"Continue?",
68+
"Yes, Migrate", "Cancel"))
69+
{
70+
return;
71+
}
72+
73+
var results = PerformMigration(targets);
74+
75+
EditorPrefs.SetBool(MIGRATION_KEY, true);
76+
EditorUtility.DisplayDialog("Migration Complete",
77+
$"Successfully migrated: {results.successCount}\n" +
78+
$"Failed: {results.failCount}\n\n" +
79+
"Check Console for details.",
80+
"OK");
81+
}
82+
83+
[MenuItem("Ecs/Migration/Authoring Component Database/3. Reset Migration Flag")]
84+
public static void ResetMigrationFlag()
85+
{
86+
EditorPrefs.DeleteKey(MIGRATION_KEY);
87+
Debug.Log("Migration flag reset.");
88+
}
89+
90+
public static bool MigratePrefab(string path)
91+
{
92+
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
93+
if (!prefab)
94+
{
95+
return false;
96+
}
97+
98+
var entity = prefab.GetComponent<AuthoringEntity>();
99+
if (!entity)
100+
{
101+
return false;
102+
}
103+
104+
var databases = prefab.GetComponentsInChildren<AuthoringComponentDatabase>();
105+
if (databases.Length == 0)
106+
{
107+
return false;
108+
}
109+
110+
var recipe = prefab.GetComponent<AuthoringEntityRecipe>() ?? prefab.AddComponent<AuthoringEntityRecipe>();
111+
if (!recipe.Recipe)
112+
{
113+
var recipePath = Path.Combine(Path.GetDirectoryName(path)!,
114+
Path.GetFileNameWithoutExtension(path) + FILE_POSFIX);
115+
var newRecipe = ScriptableObject.CreateInstance<EntityRecipe>();
116+
AssetDatabase.CreateAsset(newRecipe, recipePath);
117+
recipe.Recipe = newRecipe;
118+
}
119+
120+
foreach (var database in databases)
121+
{
122+
foreach (var set in database.Enumerate())
123+
{
124+
recipe.Recipe.Add(set);
125+
}
126+
127+
Object.DestroyImmediate(database, true);
128+
}
129+
130+
EditorUtility.SetDirty(prefab);
131+
EditorUtility.SetDirty(recipe.Recipe);
132+
return true;
133+
}
134+
135+
private static IEnumerable<string> FindMigrationTargets() =>
136+
from guid in AssetDatabase.FindAssets("t:Prefab")
137+
select AssetDatabase.GUIDToAssetPath(guid)
138+
into assetPath
139+
let prefab = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath)
140+
where prefab != null && prefab.GetComponent<AuthoringEntity>() != null &&
141+
prefab.GetComponentInChildren<AuthoringComponentDatabase>() != null
142+
select assetPath;
143+
144+
private static (int successCount, int failCount) PerformMigration(string[] paths)
145+
{
146+
var successCount = 0;
147+
var failCount = 0;
148+
149+
for (var index = 0; index < paths.Length; index++)
150+
{
151+
var path = paths[index];
152+
EditorUtility.DisplayProgressBar("Migrating Authoring Component Databases",
153+
$"Processing {index + 1}/{paths.Length}: {path}",
154+
(float)index / paths.Length);
155+
156+
try
157+
{
158+
if (MigratePrefab(path))
159+
{
160+
successCount++;
161+
Debug.Log($"✓ Migrated: {path}");
162+
}
163+
else
164+
{
165+
failCount++;
166+
Debug.LogWarning($"✗ Failed: {path}");
167+
}
168+
}
169+
catch (Exception e)
170+
{
171+
failCount++;
172+
Debug.LogError($"✗ Error migrating {path}: {e.Message}");
173+
}
174+
}
175+
176+
EditorUtility.ClearProgressBar();
177+
AssetDatabase.SaveAssets();
178+
AssetDatabase.Refresh();
179+
180+
return (successCount, failCount);
181+
}
182+
}
183+
}

Editor/AuthoringComponentDatabaseMigration.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Editor/ComponentDatabaseEditor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: Apache-2.0
2-
// © 2023-2025 Depra <n.melnikov@depra.org>
2+
// © 2023-2026 Depra <n.melnikov@depra.org>
33

44
using System.Runtime.InteropServices;
55
using UnityEditor;
@@ -15,7 +15,7 @@ public override void OnInspectorGUI()
1515
DrawSizeLabel(serializedObject.FindProperty("_components"));
1616
}
1717

18-
private void DrawSizeLabel(SerializedProperty property)
18+
private static void DrawSizeLabel(SerializedProperty property)
1919
{
2020
var size = 0;
2121
for (var index = 0; index < property.arraySize; index++)

0 commit comments

Comments
 (0)