Skip to content

Commit

Permalink
perf(memory): Remove RegisterDefaultValueProvider delegate in favor o…
Browse files Browse the repository at this point in the history
…f UIElement cast

This change removes internal support for DependencyObject.GetDefaultValue2, though this is not used anywhere in Uno at this point.
  • Loading branch information
jeromelaban committed Jan 17, 2022
1 parent 97d5328 commit c2d8eb9
Show file tree
Hide file tree
Showing 11 changed files with 59 additions and 138 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,7 @@ public partial class Given_DependencyProperty
[TestMethod]
public void When_DefaultValueProvider_Registered_Provides_Value()
{
bool GetDefaultValue(DependencyProperty property, out object value)
{
if (property == DefaultValueProviderSample.TestProperty)
{
value = 3;
return true;
}

value = null;
return false;
}

var test = new DefaultValueProviderSample();
test.RegisterDefaultValueProvider(GetDefaultValue);

var value = test.GetPrecedenceSpecificValue(DefaultValueProviderSample.TestProperty, DependencyPropertyValuePrecedences.DefaultValue);
Assert.AreEqual(3, value);
Expand All @@ -37,20 +24,7 @@ bool GetDefaultValue(DependencyProperty property, out object value)
[TestMethod]
public void When_DefaultValueProvider_Registered_Other_Property_Not_Affected()
{
bool GetDefaultValue(DependencyProperty property, out object value)
{
if (property == DefaultValueProviderSample.TestProperty)
{
value = 3;
return true;
}

value = 42; // Set arbitrary to verify false has effect
return false;
}

var test = new DefaultValueProviderSample();
test.RegisterDefaultValueProvider(GetDefaultValue);

var value = test.GetPrecedenceSpecificValue(DefaultValueProviderSample.OtherProperty, DependencyPropertyValuePrecedences.DefaultValue);
Assert.AreEqual(0, value);
Expand All @@ -59,33 +33,7 @@ bool GetDefaultValue(DependencyProperty property, out object value)
[TestMethod]
public void When_DefaultValueProvider_Multiple_Registered_Overwrite()
{
bool GetDefaultValue(DependencyProperty property, out object value)
{
if (property == DefaultValueProviderSample.TestProperty)
{
value = 3;
return true;
}

value = null;
return false;
}

bool GetDefaultValue2(DependencyProperty property, out object value)
{
if (property == DefaultValueProviderSample.TestProperty)
{
value = 17;
return true;
}

value = null;
return false;
}

var test = new DefaultValueProviderSample();
test.RegisterDefaultValueProvider(GetDefaultValue);
test.RegisterDefaultValueProvider(GetDefaultValue2);
var test = new InheritedDefaultValueProviderSample();

var value = test.GetPrecedenceSpecificValue(DefaultValueProviderSample.TestProperty, DependencyPropertyValuePrecedences.DefaultValue);
Assert.AreEqual(17, value);
Expand All @@ -94,46 +42,59 @@ bool GetDefaultValue2(DependencyProperty property, out object value)
[TestMethod]
public void When_DefaultValueProvider_Multiple_Registered_Unaffected()
{
bool GetDefaultValue(DependencyProperty property, out object value)
var test = new InheritedDefaultValueProviderSample2();

var value = test.GetPrecedenceSpecificValue(DefaultValueProviderSample.TestProperty, DependencyPropertyValuePrecedences.DefaultValue);
Assert.AreEqual(3, value); // GetDefaultValue should apply
}
}

internal partial class InheritedDefaultValueProviderSample : DefaultValueProviderSample
{
internal override bool GetDefaultValue2(DependencyProperty property, out object value)
{
if (property == DefaultValueProviderSample.TestProperty)
{
if (property == DefaultValueProviderSample.TestProperty)
{
value = 3;
return true;
}

value = null;
return false;
value = 17;
return true;
}

bool GetDefaultValue2(DependencyProperty property, out object value)
return base.GetDefaultValue2(property, out value);
}
}

internal partial class InheritedDefaultValueProviderSample2 : DefaultValueProviderSample
{
internal override bool GetDefaultValue2(DependencyProperty property, out object value)
{
if (property == DefaultValueProviderSample.OtherProperty)
{
if (property == DefaultValueProviderSample.OtherProperty)
{
value = 17;
return true;
}

value = 42;
return false;
value = 17;
return true;
}

var test = new DefaultValueProviderSample();
test.RegisterDefaultValueProvider(GetDefaultValue);
test.RegisterDefaultValueProvider(GetDefaultValue2);

var value = test.GetPrecedenceSpecificValue(DefaultValueProviderSample.TestProperty, DependencyPropertyValuePrecedences.DefaultValue);
Assert.AreEqual(3, value); // GetDefaultValue should apply
return base.GetDefaultValue2(property, out value);
}
}

internal partial class DefaultValueProviderSample : MockDependencyObject
internal partial class DefaultValueProviderSample : UIElement
{
public DefaultValueProviderSample()
{

}

internal override bool GetDefaultValue2(DependencyProperty property, out object value)
{
if (property == DefaultValueProviderSample.TestProperty)
{
value = 3;
return true;
}

return base.GetDefaultValue2(property, out value);
}

public int Test
{
get => (int)GetValue(TestProperty);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1900,14 +1900,13 @@ private void OnMyNullableChanged(DependencyPropertyChangedEventArgs e)

}

partial class MyDependencyObjectWithDefaultValueOverride : DependencyObject
partial class MyDependencyObjectWithDefaultValueOverride : FrameworkElement
{
public MyDependencyObjectWithDefaultValueOverride()
{
this.RegisterDefaultValueProvider(OnProvideDefaultValue);
}

private bool OnProvideDefaultValue(DependencyProperty property, out object defaultValue)
internal override bool GetDefaultValue2(DependencyProperty property, out object defaultValue)
{
if (property == MyPropertyProperty)
{
Expand All @@ -1916,8 +1915,7 @@ private bool OnProvideDefaultValue(DependencyProperty property, out object defau
return true;
}

defaultValue = null;
return false;
return base.GetDefaultValue2(property, out defaultValue);
}

public int MyProperty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public string PlaceholderText

private const int DEFAULT_MIN_MAX_DATE_YEAR_OFFSET = 100;

private bool SetPropertyDefaultValue(DependencyProperty property, out object value)
internal override bool GetDefaultValue2(DependencyProperty property, out object value)
{
Calendar GetOrCreateGregorianCalendar()
{
Expand Down Expand Up @@ -241,8 +241,7 @@ Calendar GetOrCreateGregorianCalendar()
return true;
}

value = default;
return false;
return base.GetDefaultValue2(property, out value);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ public CalendarDatePicker()
{
DefaultStyleKey = typeof(CalendarDatePicker);

this.RegisterDefaultValueProvider(SetPropertyDefaultValue);

m_isYearDecadeViewDimensionRequested = false;
m_colsInYearDecadeView = 0;
m_rowsInYearDecadeView = 0;
Expand Down
4 changes: 1 addition & 3 deletions src/Uno.UI/UI/Xaml/Controls/DatePicker/DatePicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,6 @@ bool IsReactionToSelectionChangeAllowed()

public DatePicker()
{
this.RegisterDefaultValueProvider(GetDefaultValue2);

m_numberOfYears = 0;
m_reactionToSelectionChangeAllowed = true;
m_isInitializing = true;
Expand Down Expand Up @@ -1012,7 +1010,7 @@ async void ShowPickerFlyout()
}

// Gives the default values for our properties.
private bool GetDefaultValue2(
internal override bool GetDefaultValue2(
DependencyProperty pDP,
out object pValue)
{
Expand Down
2 changes: 0 additions & 2 deletions src/Uno.UI/UI/Xaml/Controls/ToggleSwitch/ToggleSwitch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ public ToggleSwitch()
{
DefaultStyleKey = typeof(ToggleSwitch);

this.RegisterDefaultValueProvider(GetDefaultValue2);

//TODO Uno specific: Calling prepare state here, but should be called from DXamlCore.
PrepareState();
}
Expand Down
6 changes: 3 additions & 3 deletions src/Uno.UI/UI/Xaml/Controls/ToggleSwitch/ToggleSwitch.mux.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ private void PrepareState()
/// </summary>
/// <param name="dependencyProperty"></param>
/// <param name="value"></param>
private bool GetDefaultValue2(DependencyProperty dependencyProperty, out object? value)
internal override bool GetDefaultValue2(DependencyProperty dependencyProperty, out object? value)
{
var core = DXamlCore.Current;
if (dependencyProperty == OnContentProperty)
Expand All @@ -234,8 +234,8 @@ private bool GetDefaultValue2(DependencyProperty dependencyProperty, out object?
value = offString;
return true;
}
value = null;
return false;

return base.GetDefaultValue2(dependencyProperty, out value);
}

internal override void OnPropertyChanged2(DependencyPropertyChangedEventArgs args)
Expand Down
3 changes: 0 additions & 3 deletions src/Uno.UI/UI/Xaml/DependencyObjectExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -444,9 +444,6 @@ internal static void InvalidateRender(this DependencyObject d)
uielement?.InvalidateRender();
}

internal static void RegisterDefaultValueProvider(this IDependencyObjectStoreProvider storeProvider, DependencyObjectStore.DefaultValueProvider provider)
=> storeProvider.Store.RegisterDefaultValueProvider(provider);

/// <summary>
/// See <see cref="DependencyObjectStore.RegisterPropertyChangedCallbackStrong(ExplicitPropertyChangedCallback)"/> for more details
/// </summary>
Expand Down
5 changes: 0 additions & 5 deletions src/Uno.UI/UI/Xaml/DependencyObjectStore.Binder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -524,11 +524,6 @@ internal void SetBindingValue(DependencyPropertyDetails propertyDetails, object
_properties.SetSourceValue(propertyDetails, value);
}

internal void RegisterDefaultValueProvider(DefaultValueProvider provider)
{
_properties.RegisterDefaultValueProvider(provider);
}

/// <summary>
/// Subscribes to a dependency property changed handler
/// </summary>
Expand Down
36 changes: 4 additions & 32 deletions src/Uno.UI/UI/Xaml/DependencyPropertyDetailsCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ partial class DependencyPropertyDetailsCollection : IDisposable
private int _entriesLength;
private int _minId;
private int _maxId;
private List<DependencyObjectStore.DefaultValueProvider>? _defaultValueProviders = null;

private object? Owner => _hardOwnerReference ?? _ownerReference.Target;

Expand Down Expand Up @@ -194,18 +193,12 @@ public DependencyPropertyDetails FindPropertyDetails(DependencyProperty property

private bool TryResolveDefaultValueFromProviders(DependencyProperty property, out object? value)
{
if (_defaultValueProviders != null)
// Replicate the WinUI behavior of DependencyObject::GetDefaultValue2 specifically for UIElement.
if (Owner is UIElement uiElement)
{
for (int i = _defaultValueProviders.Count - 1; i >= 0; i--)
{
var provider = _defaultValueProviders[i];
if (provider.Invoke(property, out var resolvedValue))
{
value = resolvedValue;
return true;
}
}
return uiElement.GetDefaultValue2(property, out value);
}

value = null;
return false;
}
Expand All @@ -232,27 +225,6 @@ private void ReturnEntriesToPool()

internal DependencyPropertyDetails?[] GetAllDetails() => Entries;

/// <summary>
/// Adds a default value provider.
/// </summary>
/// <param name="provider">Default value provider.</param>
/// <remarks>
/// Providers which are registered later have higher priority.
/// E.g. when both a derived and base class register their own default
/// value provider in the constructor for the same property, the derived
/// class value is used.
/// </remarks>
public void RegisterDefaultValueProvider(DependencyObjectStore.DefaultValueProvider provider)
{
if (provider == null)
{
throw new ArgumentNullException(nameof(provider));
}

_defaultValueProviders ??= new List<DependencyObjectStore.DefaultValueProvider>(2);
_defaultValueProviders.Add(provider);
}

internal void TryEnableHardReferences()
{
_hardOwnerReference = _ownerReference.Target;
Expand Down
9 changes: 7 additions & 2 deletions src/Uno.UI/UI/Xaml/UIElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,17 @@ public static void RegisterAsScrollPort(UIElement element)

private void Initialize()
{
this.RegisterDefaultValueProvider(OnGetDefaultValue);
}

private protected virtual bool IsTabStopDefaultValue => false;

private bool OnGetDefaultValue(DependencyProperty property, out object defaultValue)
/// <summary>
/// Provide an instance-specific default value for the specified property
/// </summary>
/// <remarks>
/// In general, it is best do define the property default value using <see cref="PropertyMetadata"/>.
/// </remarks>
internal virtual bool GetDefaultValue2(DependencyProperty property, out object defaultValue)
{
if (property == KeyboardAcceleratorsProperty)
{
Expand Down

0 comments on commit c2d8eb9

Please sign in to comment.