@@ -57,10 +57,7 @@ private void OnDestroy()
5757
5858 public bool Set ( Renderer renderer , Props props )
5959 {
60- if ( renderer == null ) {
61- this . LogWarning ( $ "cannot set property on null renderer { renderer . GetHashCode ( ) } ") ;
62- return false ;
63- }
60+ if ( ! CheckRendererAlive ( renderer ) ) return false ;
6461
6562 if ( ! rendererCascades . TryGetValue ( renderer , out var cascade ) ) {
6663 rendererCascades [ renderer ] = cascade = new PropsCascade ( renderer ) ;
@@ -69,15 +66,18 @@ public bool Set(Renderer renderer, Props props)
6966 return cascade . Add ( props ) ;
7067 }
7168
72- public bool Remove ( Renderer renderer , Props props )
69+ public bool Unset ( Renderer renderer , Props props )
7370 {
71+ if ( ! CheckRendererAlive ( renderer ) ) return false ;
7472 if ( ! rendererCascades . TryGetValue ( renderer , out var cascade ) ) return false ;
7573 return cascade . Remove ( props ) ;
7674 }
7775
78- public bool Remove ( Renderer renderer )
76+ public bool Unregister ( Renderer renderer )
7977 {
78+ if ( ( object ) renderer == null ) return false ;
8079 if ( ! rendererCascades . Remove ( renderer , out var cascade ) ) return false ;
80+ if ( renderer == null ) this . LogDebug ( $ "dead renderer { renderer . GetHashCode ( ) } ") ;
8181 cascade . Dispose ( ) ;
8282 return true ;
8383 }
@@ -89,10 +89,34 @@ public static void RegisterPropertyNamesForDebugLogging(params string[] properti
8989
9090 #endregion
9191
92+ private bool CheckRendererAlive ( Renderer renderer )
93+ {
94+ if ( renderer != null ) return true ;
95+ this . LogWarning ( $ "cannot modify null renderer { renderer ? . GetHashCode ( ) } ") ;
96+ if ( ( object ) renderer != null ) Unregister ( renderer ) ;
97+ return false ;
98+ }
99+
100+ private readonly List < Renderer > _deadRenderers = [ ] ;
101+
102+ internal void CheckRemoveDeadRenderers ( )
103+ {
104+ foreach ( var renderer in rendererCascades . Keys ) {
105+ if ( renderer == null ) _deadRenderers . Add ( renderer ) ;
106+ }
107+
108+ foreach ( var deadRenderer in _deadRenderers ) Unregister ( deadRenderer ) ;
109+ _deadRenderers . Clear ( ) ;
110+ }
111+
92112 /// Public API equivalent is calling `Props.Dispose`.
93- internal void Remove ( Props props )
113+ internal void Unregister ( Props props )
94114 {
95- foreach ( var cascade in rendererCascades . Values ) cascade . Remove ( props ) ;
115+ foreach ( var ( renderer , cascade ) in rendererCascades ) {
116+ if ( renderer != null ) cascade . Remove ( props ) ;
117+ }
118+
119+ CheckRemoveDeadRenderers ( ) ;
96120 }
97121
98122 private bool _propRefreshScheduled = false ;
0 commit comments