@@ -14,6 +14,8 @@ namespace UnityMvvmToolkit.Core.Internal.ObjectHandlers
1414{
1515 internal sealed class ObjectWrapperHandler : IDisposable
1616 {
17+ private static readonly int ReadOnlyPropertyHashCode = typeof ( IReadOnlyProperty < > ) . GetHashCode ( ) ;
18+
1719 private readonly ValueConverterHandler _valueConverterHandler ;
1820
1921 private readonly Dictionary < int , ICommandWrapper > _commandWrappers ;
@@ -77,22 +79,18 @@ public TProperty GetPropertyAs<TProperty, TValueType>(IBindingContext context, M
7779
7880 var converterId = HashCodeHelper . GetPropertyWrapperConverterId ( targetType , sourceType ) ;
7981
80- if ( _wrappersByConverter . TryGetValue ( converterId , out var propertyWrappers ) )
81- {
82- if ( propertyWrappers . Count > 0 )
83- {
84- return ( TProperty ) propertyWrappers
85- . Dequeue ( )
86- . AsPropertyWrapper ( )
87- . SetProperty ( property ) ;
88- }
89- }
90- else
82+ var isProperty = property is IProperty ;
83+
84+ var wrapperId = isProperty ? converterId : GetReadOnlyWrapperId ( converterId ) ;
85+
86+ if ( TryGetObjectWrapper ( wrapperId , out var objectWrapper ) )
9187 {
92- _wrappersByConverter . Add ( converterId , new Queue < IObjectWrapper > ( ) ) ;
88+ return ( TProperty ) objectWrapper
89+ . AsPropertyWrapper ( )
90+ . SetProperty ( property ) ;
9391 }
9492
95- var wrapperType = property is IProperty
93+ var wrapperType = isProperty
9694 ? typeof ( PropertyCastWrapper < , > ) . MakeGenericType ( sourceType , targetType )
9795 : typeof ( ReadOnlyPropertyCastWrapper < , > ) . MakeGenericType ( sourceType , targetType ) ;
9896
@@ -115,19 +113,15 @@ public TProperty GetProperty<TProperty, TValueType>(IBindingContext context, Bin
115113 var converterId =
116114 HashCodeHelper . GetPropertyWrapperConverterId ( targetType , sourceType , bindingData . ConverterName ) ;
117115
118- if ( _wrappersByConverter . TryGetValue ( converterId , out var propertyWrappers ) )
119- {
120- if ( propertyWrappers . Count > 0 )
121- {
122- return ( TProperty ) propertyWrappers
123- . Dequeue ( )
124- . AsPropertyWrapper ( )
125- . SetProperty ( property ) ;
126- }
127- }
128- else
116+ var isProperty = property is IProperty ;
117+
118+ var wrapperId = isProperty ? converterId : GetReadOnlyWrapperId ( converterId ) ;
119+
120+ if ( TryGetObjectWrapper ( wrapperId , out var objectWrapper ) )
129121 {
130- _wrappersByConverter . Add ( converterId , new Queue < IObjectWrapper > ( ) ) ;
122+ return ( TProperty ) objectWrapper
123+ . AsPropertyWrapper ( )
124+ . SetProperty ( property ) ;
131125 }
132126
133127 if ( _valueConverterHandler . TryGetValueConverterById ( converterId , out var valueConverter ) == false )
@@ -138,7 +132,7 @@ public TProperty GetProperty<TProperty, TValueType>(IBindingContext context, Bin
138132
139133 var args = new object [ ] { valueConverter } ;
140134
141- var wrapperType = property is IProperty
135+ var wrapperType = isProperty
142136 ? typeof ( PropertyConvertWrapper < , > ) . MakeGenericType ( sourceType , targetType )
143137 : typeof ( ReadOnlyPropertyConvertWrapper < , > ) . MakeGenericType ( sourceType , targetType ) ;
144138
@@ -177,20 +171,12 @@ public ICommandWrapper GetCommandWrapper(IBindingContext context, CommandBinding
177171 var converterId =
178172 HashCodeHelper . GetCommandWrapperConverterId ( commandValueType , bindingData . ConverterName ) ;
179173
180- if ( _wrappersByConverter . TryGetValue ( converterId , out var commandWrappers ) )
174+ if ( TryGetObjectWrapper ( converterId , out var objectWrapper ) )
181175 {
182- if ( commandWrappers . Count > 0 )
183- {
184- return commandWrappers
185- . Dequeue ( )
186- . AsCommandWrapper ( )
187- . SetCommand ( commandId , command )
188- . RegisterParameter ( bindingData . ElementId , bindingData . ParameterValue ) ;
189- }
190- }
191- else
192- {
193- _wrappersByConverter . Add ( converterId , new Queue < IObjectWrapper > ( ) ) ;
176+ return objectWrapper
177+ . AsCommandWrapper ( )
178+ . SetCommand ( commandId , command )
179+ . RegisterParameter ( bindingData . ElementId , bindingData . ParameterValue ) ;
194180 }
195181
196182 if ( _valueConverterHandler . TryGetValueConverterById ( converterId , out var valueConverter ) == false )
@@ -215,7 +201,7 @@ public void ReturnProperty(IPropertyWrapper propertyWrapper)
215201 {
216202 AssureIsNotDisposed ( ) ;
217203
218- ReturnWrapper ( propertyWrapper ) ;
204+ ReturnObjectWrapper ( propertyWrapper ) ;
219205 }
220206
221207 public void ReturnCommandWrapper ( ICommandWrapper commandWrapper , int elementId )
@@ -228,7 +214,8 @@ public void ReturnCommandWrapper(ICommandWrapper commandWrapper, int elementId)
228214 }
229215
230216 _commandWrappers . Remove ( commandWrapper . CommandId ) ;
231- ReturnWrapper ( commandWrapper ) ;
217+
218+ ReturnObjectWrapper ( commandWrapper ) ;
232219 }
233220
234221 public void Dispose ( )
@@ -347,10 +334,41 @@ private void CreateParameterValueConverterInstances(int converterId, IParameterV
347334 }
348335
349336 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
350- private void ReturnWrapper ( IObjectWrapper wrapper )
337+ private bool TryGetObjectWrapper ( int wrapperId , out IObjectWrapper objectWrapper )
338+ {
339+ if ( _wrappersByConverter . TryGetValue ( wrapperId , out var objectWrappers ) )
340+ {
341+ if ( objectWrappers . Count > 0 )
342+ {
343+ objectWrapper = objectWrappers . Dequeue ( ) ;
344+ return true ;
345+ }
346+ }
347+ else
348+ {
349+ _wrappersByConverter . Add ( wrapperId , new Queue < IObjectWrapper > ( ) ) ;
350+ }
351+
352+ objectWrapper = default ;
353+ return false ;
354+ }
355+
356+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
357+ private void ReturnObjectWrapper ( IObjectWrapper wrapper )
351358 {
352359 wrapper . Reset ( ) ;
353- _wrappersByConverter [ wrapper . ConverterId ] . Enqueue ( wrapper ) ;
360+
361+ switch ( wrapper )
362+ {
363+ case IProperty :
364+ case ICommandWrapper :
365+ _wrappersByConverter [ wrapper . ConverterId ] . Enqueue ( wrapper ) ;
366+ break ;
367+
368+ default :
369+ _wrappersByConverter [ GetReadOnlyWrapperId ( wrapper . ConverterId ) ] . Enqueue ( wrapper ) ;
370+ break ;
371+ }
354372 }
355373
356374 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -361,5 +379,11 @@ private void AssureIsNotDisposed()
361379 throw new ObjectDisposedException ( nameof ( ObjectWrapperHandler ) ) ;
362380 }
363381 }
382+
383+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
384+ private static int GetReadOnlyWrapperId ( int wrapperConverterId )
385+ {
386+ return HashCodeHelper . CombineHashCode ( wrapperConverterId , ReadOnlyPropertyHashCode ) ;
387+ }
364388 }
365389}
0 commit comments