@@ -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