Skip to content

Commit 90a8f20

Browse files
committed
refactor: clean up PropertyChangeEventSource
1 parent de69639 commit 90a8f20

File tree

3 files changed

+92
-41
lines changed

3 files changed

+92
-41
lines changed

XamlToolkit.WinUI.Controls/LayoutTransformControl/LayoutTransformControl.cpp

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -428,14 +428,12 @@ namespace winrt::XamlToolkit::WinUI::Controls::implementation
428428

429429
void LayoutTransformControl::UnsubscribeFromTransformPropertyChanges(winrt::Microsoft::UI::Xaml::Media::Transform const& transform)
430430
{
431-
const auto& propertyChangeEventSources =
432-
_transformPropertyChangeEventSources[transform];
431+
//const auto& propertyChangeEventSources = _transformPropertyChangeEventSources[transform];
433432

434-
for (auto& propertyChangeEventSource : propertyChangeEventSources)
435-
{
436-
propertyChangeEventSource->ValueChanged.clear(); // -= OnTransformPropertyChanged;
437-
propertyChangeEventSource->Unregister();
438-
}
433+
//for (auto& propertyChangeEventSource : propertyChangeEventSources)
434+
//{
435+
// propertyChangeEventSource->unsubscribe();
436+
//}
439437

440438
_transformPropertyChangeEventSources.erase(transform);
441439
}
@@ -452,45 +450,45 @@ namespace winrt::XamlToolkit::WinUI::Controls::implementation
452450
return;
453451
}
454452

455-
auto propertyChangeEventSources = std::vector<std::unique_ptr<event_source>>();
453+
auto propertyChangeEventSources = std::vector<std::unique_ptr<event_source_registration>>();
456454
_transformPropertyChangeEventSources.emplace(transform, std::move(propertyChangeEventSources));
457455

458456
if (auto rotateTransform = transform.try_as<RotateTransform>())
459457
{
460-
auto anglePropertyChangeEventSource = std::make_unique<event_source>(rotateTransform, RotateTransform::AngleProperty());
461-
anglePropertyChangeEventSource->ValueChanged.add({ get_weak(), &LayoutTransformControl::OnTransformPropertyChanged });
458+
auto anglePropertyChangeEventSource = std::make_unique<event_source_registration>(rotateTransform, RotateTransform::AngleProperty());
459+
anglePropertyChangeEventSource->subscribe({ get_weak(), &LayoutTransformControl::OnTransformPropertyChanged });
462460
propertyChangeEventSources.emplace_back(std::move(anglePropertyChangeEventSource));
463461
return;
464462
}
465463

466464
if (auto scaleTransform = transform.try_as<ScaleTransform>())
467465
{
468-
auto scaleXPropertyChangeEventSource = std::make_unique<event_source>(scaleTransform, ScaleTransform::ScaleXProperty());
469-
scaleXPropertyChangeEventSource->ValueChanged.add({ get_weak(), &LayoutTransformControl::OnTransformPropertyChanged });
466+
auto scaleXPropertyChangeEventSource = std::make_unique<event_source_registration>(scaleTransform, ScaleTransform::ScaleXProperty());
467+
scaleXPropertyChangeEventSource->subscribe({ get_weak(), &LayoutTransformControl::OnTransformPropertyChanged });
470468
propertyChangeEventSources.emplace_back(std::move(scaleXPropertyChangeEventSource));
471469

472-
auto scaleYPropertyChangeEventSource = std::make_unique<event_source>(scaleTransform, ScaleTransform::ScaleYProperty());
473-
scaleYPropertyChangeEventSource->ValueChanged.add({ get_weak(), &LayoutTransformControl::OnTransformPropertyChanged });
470+
auto scaleYPropertyChangeEventSource = std::make_unique<event_source_registration>(scaleTransform, ScaleTransform::ScaleYProperty());
471+
scaleYPropertyChangeEventSource->subscribe({ get_weak(), &LayoutTransformControl::OnTransformPropertyChanged });
474472
propertyChangeEventSources.emplace_back(std::move(scaleYPropertyChangeEventSource));
475473
return;
476474
}
477475

478476
if (auto skewTransform = transform.try_as<SkewTransform>())
479477
{
480-
auto angleXPropertyChangeEventSource = std::make_unique<event_source>(skewTransform, SkewTransform::AngleXProperty());
481-
angleXPropertyChangeEventSource->ValueChanged.add({ get_weak(), &LayoutTransformControl::OnTransformPropertyChanged });
478+
auto angleXPropertyChangeEventSource = std::make_unique<event_source_registration>(skewTransform, SkewTransform::AngleXProperty());
479+
angleXPropertyChangeEventSource->subscribe({ get_weak(), &LayoutTransformControl::OnTransformPropertyChanged });
482480
propertyChangeEventSources.emplace_back(std::move(angleXPropertyChangeEventSource));
483481

484-
auto angleYPropertyChangeEventSource = std::make_unique<event_source>(skewTransform, SkewTransform::AngleYProperty());
485-
angleYPropertyChangeEventSource->ValueChanged.add({ get_weak(), &LayoutTransformControl::OnTransformPropertyChanged });
482+
auto angleYPropertyChangeEventSource = std::make_unique<event_source_registration>(skewTransform, SkewTransform::AngleYProperty());
483+
angleYPropertyChangeEventSource->subscribe({ get_weak(), &LayoutTransformControl::OnTransformPropertyChanged });
486484
propertyChangeEventSources.emplace_back(std::move(angleYPropertyChangeEventSource));
487485
return;
488486
}
489487

490488
if (auto matrixTransform = transform.try_as<MatrixTransform>())
491489
{
492-
auto matrixPropertyChangeEventSource = std::make_unique<event_source>(matrixTransform, MatrixTransform::MatrixProperty());
493-
matrixPropertyChangeEventSource->ValueChanged.add({ get_weak(), &LayoutTransformControl::OnTransformPropertyChanged });
490+
auto matrixPropertyChangeEventSource = std::make_unique<event_source_registration>(matrixTransform, MatrixTransform::MatrixProperty());
491+
matrixPropertyChangeEventSource->subscribe({ get_weak(), &LayoutTransformControl::OnTransformPropertyChanged });
494492
propertyChangeEventSources.emplace_back(std::move(matrixPropertyChangeEventSource));
495493
}
496494
}

XamlToolkit.WinUI.Controls/LayoutTransformControl/LayoutTransformControl.h

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,42 @@ namespace winrt::XamlToolkit::WinUI::Controls::implementation
1010
using namespace winrt::Windows::Foundation;
1111
using event_source = winrt::XamlToolkit::WinUI::Controls::PropertyChangeEventSource<double>;
1212

13+
struct event_source_registration
14+
{
15+
private:
16+
event_source event_source;
17+
std::optional<winrt::event_token> token;
18+
public:
19+
event_source_registration(const event_source_registration&) = delete;
20+
event_source_registration& operator=(const event_source_registration&) = delete;
21+
event_source_registration(const event_source_registration&&) = delete;
22+
event_source_registration& operator=(const event_source_registration&&) = delete;
23+
24+
event_source_registration(
25+
winrt::Microsoft::UI::Xaml::DependencyObject const& source,
26+
winrt::Microsoft::UI::Xaml::DependencyProperty const& property) : event_source(source, property) { }
27+
28+
void subscribe(winrt::Windows::Foundation::EventHandler<double> const& handler)
29+
{
30+
unsubscribe();
31+
token = event_source.ValueChanged(handler);
32+
}
33+
34+
void unsubscribe()
35+
{
36+
if (token)
37+
{
38+
event_source.ValueChanged(*token);
39+
token.reset();
40+
}
41+
}
42+
43+
~event_source_registration()
44+
{
45+
unsubscribe();
46+
}
47+
};
48+
1349
struct LayoutTransformControl : LayoutTransformControlT<LayoutTransformControl>
1450
{
1551
LayoutTransformControl();
@@ -87,12 +123,12 @@ namespace winrt::XamlToolkit::WinUI::Controls::implementation
87123
winrt::unbox_value<FrameworkElement>(e.NewValue()));
88124
}
89125
/// <summary>
90-
/// Gets or sets the single child of the LayoutTransformControl.
91-
/// </summary>
92-
/// <remarks>
93-
/// Corresponds to WPF's Decorator.Child
94-
/// property.
95-
/// </remarks>
126+
/// Gets or sets the single child of the LayoutTransformControl.
127+
/// </summary>
128+
/// <remarks>
129+
/// Corresponds to WPF's Decorator.Child
130+
/// property.
131+
/// </remarks>
96132
FrameworkElement Child() { return winrt::unbox_value<FrameworkElement>(GetValue(ChildProperty)); }
97133
void Child(winrt::Windows::Foundation::IInspectable const& value) { return SetValue(ChildProperty, value); }
98134

@@ -165,10 +201,10 @@ namespace winrt::XamlToolkit::WinUI::Controls::implementation
165201
}
166202

167203
/// <summary>
168-
/// Processes the transform when the transform is changed.
169-
/// </summary>
170-
/// <param name="oldValue">The old transform</param>
171-
/// <param name="newValue">The transform to process.</param>
204+
/// Processes the transform when the transform is changed.
205+
/// </summary>
206+
/// <param name="oldValue">The old transform</param>
207+
/// <param name="newValue">The transform to process.</param>
172208
void OnTransformChanged(winrt::Microsoft::UI::Xaml::Media::Transform const& oldValue, winrt::Microsoft::UI::Xaml::Media::Transform const& newValue);
173209

174210
void UnsubscribeFromTransformPropertyChanges(winrt::Microsoft::UI::Xaml::Media::Transform const& transform);
@@ -195,7 +231,7 @@ namespace winrt::XamlToolkit::WinUI::Controls::implementation
195231
/// </summary>
196232
std::unordered_map<
197233
winrt::Microsoft::UI::Xaml::Media::Transform,
198-
std::vector<std::unique_ptr<event_source>>>
234+
std::vector<std::unique_ptr<event_source_registration>>>
199235
_transformPropertyChangeEventSources;
200236

201237
/// <summary>
@@ -216,7 +252,7 @@ namespace winrt::XamlToolkit::WinUI::Controls::implementation
216252
/// <summary>
217253
/// Actual DesiredSize of Child element.
218254
/// </summary>
219-
Size _childActualSize { 0, 0 };
255+
Size _childActualSize{ 0, 0 };
220256
};
221257
}
222258

XamlToolkit.WinUI.Controls/LayoutTransformControl/PropertyChangeEventSource.h

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@ namespace winrt::XamlToolkit::WinUI::Controls
88
struct PropertyChangeEventSource
99
{
1010
private:
11-
winrt::Microsoft::UI::Xaml::DependencyObject _source{ nullptr };
12-
winrt::Microsoft::UI::Xaml::DependencyProperty _property{ nullptr };
13-
int64_t _registrationToken{ 0 };
11+
winrt::Microsoft::UI::Xaml::DependencyObject _source;
12+
winrt::Microsoft::UI::Xaml::DependencyProperty _property;
13+
std::optional<int64_t> _registrationToken;
14+
15+
winrt::event<winrt::Windows::Foundation::EventHandler<TPropertyType>> _valueChanged;
1416

1517
public:
16-
winrt::event<winrt::Windows::Foundation::TypedEventHandler<
17-
winrt::Windows::Foundation::IInspectable,
18-
TPropertyType>> ValueChanged;
18+
PropertyChangeEventSource(const PropertyChangeEventSource&) = delete;
19+
PropertyChangeEventSource& operator=(const PropertyChangeEventSource&) = delete;
20+
PropertyChangeEventSource(PropertyChangeEventSource&&) = delete;
21+
PropertyChangeEventSource& operator=(PropertyChangeEventSource&&) = delete;
1922

2023
PropertyChangeEventSource(
2124
winrt::Microsoft::UI::Xaml::DependencyObject const& source,
@@ -27,16 +30,30 @@ namespace winrt::XamlToolkit::WinUI::Controls
2730
winrt::Microsoft::UI::Xaml::DependencyProperty const& dp)
2831
{
2932
auto value = winrt::unbox_value<TPropertyType>(sender.GetValue(dp));
30-
ValueChanged(nullptr, value);
33+
_valueChanged(nullptr, value);
3134
});
3235
}
3336

37+
winrt::event_token ValueChanged(winrt::Windows::Foundation::EventHandler<TPropertyType> const& handler)
38+
{
39+
return _valueChanged.add(handler);
40+
}
41+
42+
void ValueChanged(winrt::event_token token)
43+
{
44+
_valueChanged.remove(token);
45+
}
46+
47+
TPropertyType Value() { return winrt::unbox_value<TPropertyType>(_source.GetValue(_property)); }
48+
49+
void Value(TPropertyType const& value) { _source.SetValue(winrt::box_value(_property)); }
50+
3451
void Unregister()
3552
{
3653
if (_registrationToken)
3754
{
38-
_source.UnregisterPropertyChangedCallback(_property, _registrationToken);
39-
_registrationToken = 0;
55+
_source.UnregisterPropertyChangedCallback(_property, *_registrationToken);
56+
_registrationToken.reset();
4057
}
4158
}
4259

0 commit comments

Comments
 (0)