Skip to content

Commit b068e1a

Browse files
committed
optimize: better generation experience
1 parent 9e575d3 commit b068e1a

File tree

1 file changed

+34
-13
lines changed

1 file changed

+34
-13
lines changed

Editor/USGEngine.cs

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ public class USGEngine : AssetPostprocessor
2020
public static bool IgnoreOverwriteSettingByAttribute = false;
2121

2222

23-
const string EDITOR_PREFS_LENGTH = "__STMG_USG__TARGET_LENGTH";
24-
const string EDITOR_PREFS_PREFIX = "__STMG_USG__TARGET_";
23+
const string EDITOR_PREFS_PREFIX = "__STMG_USG__";
24+
const string EDITOR_PREFS_TARGET = EDITOR_PREFS_PREFIX + "TARGET_";
25+
const string EDITOR_PREFS_LENGTH = EDITOR_PREFS_PREFIX + "TARGET_LENGTH";
2526
const int BUFFER_LENGTH = 61_440;
2627
const int BUFFER_MAX_CHAR_LENGTH = BUFFER_LENGTH / 3; // worst case of UTF-8
2728
const string GENERATOR_PREFIX = ".";
@@ -67,13 +68,14 @@ static void OnPostprocessAllAssets(
6768
// menu command but OnPostprocessAllAssets event doesn't work as expected.
6869
// (script runs with static field cleared even though .Clear() is only in ProcessingFiles().
6970
// it's weird that event happens and asset paths retrieved but hashset items gone.)
71+
// --> https://docs.unity3d.com/2021.3/Documentation/Manual/DomainReloading.html
7072
// NOTE: Use EditorPrefs as a temporary storage.
7173
var nPaths = 0;
7274
for (int i = 0; i < importedAssets.Length; i++)
7375
{
7476
if (!IsAppropriateTarget(importedAssets[i])) continue;
75-
EditorPrefs.SetString(EDITOR_PREFS_PREFIX + nPaths++, importedAssets[i]);
76-
Debug.Log($"[USG]: Saved into EditorPrefs: {importedAssets[i]}");
77+
if (s_pathsToSkipNextImportEvent.Remove(importedAssets[i])) continue;
78+
EditorPrefs.SetString(EDITOR_PREFS_TARGET + nPaths++, importedAssets[i]);
7779
}
7880
EditorPrefs.SetInt(EDITOR_PREFS_LENGTH, nPaths);
7981

@@ -85,7 +87,10 @@ static void OnPostprocessAllAssets(
8587
}
8688

8789

90+
readonly static HashSet<string> s_pathsToSkipNextImportEvent = new();
91+
8892
readonly static HashSet<string> s_updatedGeneratorNames = new();
93+
readonly static HashSet<string> s_processedFiles = new();
8994
static void ProcessingFiles()
9095
{
9196
bool somethingUpdated = false;
@@ -94,14 +99,16 @@ static void ProcessingFiles()
9499
EditorPrefs.DeleteKey(EDITOR_PREFS_LENGTH);
95100
for (int i = 0; i < nPaths; i++)
96101
{
97-
var key = EDITOR_PREFS_PREFIX + i;
102+
var key = EDITOR_PREFS_TARGET + i;
98103
//if (!EditorPrefs.HasKey(key)) continue;
99104

100105
var path = EditorPrefs.GetString(key);
101106
EditorPrefs.DeleteKey(key);
102107

103108
if (ProcessFile(path))
104109
somethingUpdated = true;
110+
111+
s_processedFiles.Add(path);
105112
}
106113

107114
// TODO: more efficient way to process related targets
@@ -115,7 +122,7 @@ static void ProcessingFiles()
115122
continue;
116123

117124
var path = USGUtility.GetAssetPathByName(info.TargetClass.Name);
118-
if (path != null && IsAppropriateTarget(path))
125+
if (path != null && s_processedFiles.Add(path) && IsAppropriateTarget(path))
119126
{
120127
IgnoreOverwriteSettingByAttribute = overwriteEnabledByCaller
121128
|| info.Attribute.OverwriteIfFileExists;
@@ -129,6 +136,7 @@ static void ProcessingFiles()
129136
AssetDatabase.Refresh();
130137

131138
s_updatedGeneratorNames.Clear();
139+
s_processedFiles.Clear();
132140

133141
IgnoreOverwriteSettingByAttribute = false; // always turn it off.
134142
}
@@ -146,10 +154,16 @@ public static bool ProcessFile(string assetsRelPath)
146154

147155
if (!s_typeNameToInfo.ContainsKey(clsName))
148156
{
149-
if (!clsName.EndsWith(GENERATOR_EXT))
157+
// NOTE: When generated code has error, removing error code and save will invoke
158+
// import event and error code will be re-generated again.
159+
// (delaying code generation won't solve this behaviour...? disable anyway)
160+
if (!IgnoreOverwriteSettingByAttribute)
150161
return false;
151162

152163
// try find generator
164+
if (!clsName.EndsWith(GENERATOR_EXT))
165+
return false;
166+
153167
clsName = Path.GetFileNameWithoutExtension(clsName);
154168
clsName = Path.GetExtension(clsName);
155169

@@ -164,9 +178,10 @@ public static bool ProcessFile(string assetsRelPath)
164178
var info = s_typeNameToInfo[clsName];
165179
if (info == null) return false;
166180

167-
// TODO: more streamlined.
168181
if (info.TargetClass == null)
169182
{
183+
// NOTE: this list contains referenced only generator names that used to perform
184+
// code generation on referencing classes.
170185
s_updatedGeneratorNames.Add(clsName);
171186
return false;
172187
}
@@ -215,12 +230,17 @@ public static bool ProcessFile(string assetsRelPath)
215230
return false;
216231

217232
// NOTE: overwrite check must be done after Emit() due to allowing output path modification.
218-
// TODO: code generation happens but file is not written. any way to skip code generation?
219-
if (File.Exists(context.OutputPath) &&
220-
(!info.Attribute.OverwriteIfFileExists && !IgnoreOverwriteSettingByAttribute)
221-
)
233+
// TODO: code generation happens but file is not written when overwrite is disabled.
234+
// any way to skip code generation?
235+
if (File.Exists(context.OutputPath))
222236
{
223-
return false;
237+
if (!info.Attribute.OverwriteIfFileExists && !IgnoreOverwriteSettingByAttribute)
238+
return false;
239+
}
240+
else
241+
{
242+
// used to prevent import event happens on newly generated file.
243+
s_pathsToSkipNextImportEvent.Add(context.OutputPath);
224244
}
225245

226246

@@ -303,6 +323,7 @@ static void CollectTargets()
303323
*/
304324

305325

326+
// OPTIMIZE: ReflectionOnlyGetType() can be used??
306327
var infos = AppDomain.CurrentDomain.GetAssemblies()
307328
.Where(static x =>
308329
{

0 commit comments

Comments
 (0)