Skip to content

Commit 006afaf

Browse files
authored
Simplify set prop value (#251)
Fixes #250 This may be a compiler issue (since it only started to show up in recent msvc updates), but regardless it makes sense to simplify this code a bit anyway. ###### Microsoft Reviewers: [Open in CodeFlow](https://portal.fabricbot.ms/api/codeflow?pullrequest=https://github.com/microsoft/react-native-xaml/pull/251)
1 parent da5f7db commit 006afaf

File tree

2 files changed

+50
-68
lines changed

2 files changed

+50
-68
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "simplify overload resolution for SetPropValue",
4+
"packageName": "react-native-xaml",
5+
"email": "asklar@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}

package/windows/ReactNativeXaml/XamlMetadata.h

Lines changed: 43 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -57,94 +57,69 @@ namespace winrt::Microsoft::ReactNative {
5757

5858
template <typename T> bool IsType(const winrt::Windows::Foundation::IInspectable& i) { return i.try_as<T>() != nullptr; }
5959

60-
template<typename T, std::enable_if_t<std::is_enum<T>::value, int> = 0>
61-
void SetPropValue(const xaml::DependencyObject o, const xaml::DependencyProperty& prop, const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext&) {
62-
auto valueEnum = MakeEnum<T>(v.AsInt32());
63-
o.SetValue(prop, valueEnum);
60+
61+
inline void ReadValue(JSValue const& jsValue, xaml::Media::Geometry& value) noexcept {
62+
const auto v = winrt::to_hstring(jsValue.AsJSString());
63+
value = Markup::XamlBindingHelper::ConvertValue(winrt::xaml_typename<xaml::Media::PathGeometry>(), winrt::box_value(v)).as<xaml::Media::Geometry>();
6464
}
6565

66-
template<typename T, std::enable_if_t<
67-
!std::is_enum<T>::value &&
68-
!std::is_same<winrt::hstring, T>::value &&
69-
!std::is_same<winrt::Windows::Foundation::IInspectable, T>::value &&
70-
!std::is_same<winrt::Windows::Foundation::Uri, T>::value &&
71-
!std::is_same<xaml::Media::ImageSource, T>::value
72-
, int> = 0>
73-
void SetPropValue(const xaml::DependencyObject& o, const xaml::DependencyProperty& prop, const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext&) {
74-
auto b = v.To<T>();
75-
o.SetValue(prop, winrt::box_value(b));
66+
inline void ReadValue(JSValue const& jsValue, Windows::UI::Text::FontWeight& value) noexcept {
67+
value.Weight = jsValue.AsInt16();
7668
}
69+
}
7770

78-
template<typename T, std::enable_if_t<
79-
std::is_same<xaml::Media::ImageSource, T>::value, int> = 0>
80-
void SetPropValue(const xaml::DependencyObject& o, const xaml::DependencyProperty& prop, const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext&) {
8171

72+
template<typename T>
73+
void SetPropValue(const xaml::DependencyObject& o, const xaml::DependencyProperty& prop,
74+
const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext& context) {
75+
if constexpr (std::is_same_v<winrt::Windows::UI::Xaml::Controls::Maps::MapStyle, T>) {
76+
auto boxed = v.To<winrt::Windows::UI::Xaml::Controls::Maps::MapStyle>();
77+
o.SetValue(prop, winrt::box_value(boxed));
78+
} else if constexpr (std::is_same_v<T, winrt::hstring>) {
79+
auto b = v.AsString();
80+
o.SetValue(prop, winrt::box_value(winrt::to_hstring(b)));
81+
} else if constexpr (std::is_same_v<T, winrt::Windows::Foundation::Uri>) {
82+
auto cn = winrt::get_class_name(o);
83+
auto uri = Uri{ winrt::to_hstring(v.AsString()) };
84+
o.SetValue(prop, uri);
85+
} else if constexpr (std::is_same_v<T, winrt::Windows::Foundation::IInspectable>) {
86+
switch (v.Type()) {
87+
case JSValueType::String: return SetPropValue<winrt::hstring>(o, prop, v, context);
88+
case JSValueType::Boolean: return SetPropValue<bool>(o, prop, v, context);
89+
case JSValueType::Double: return SetPropValue<double>(o, prop, v, context);
90+
case JSValueType::Int64: return SetPropValue<int64_t>(o, prop, v, context);
91+
case JSValueType::Object: {
92+
const auto& obj = v.AsObject();
93+
if (obj.find("string") != obj.cend()) {
94+
const auto& value = obj["string"];
95+
return SetPropValue<winrt::Windows::Foundation::IInspectable>(o, prop, value, context);
96+
}
97+
}
98+
}
99+
} else if constexpr (std::is_enum_v<T>) {
100+
auto valueEnum = MakeEnum<T>(v.AsInt32());
101+
o.SetValue(prop, valueEnum);
102+
} else if constexpr (std::is_same_v<xaml::Media::ImageSource, T>) {
82103
const auto str = v.AsString();
83104
const auto uri = Uri{ winrt::to_hstring(str) };
84105

85106
xaml::Media::ImageSource value{ nullptr };
86107
if (uri.SchemeName() == L"data") {
87108
SetImageSourceForInlineData(str, o, prop);
88-
}
89-
else if (str.ends_with(".svg") || str.ends_with(".svgz")) {
109+
} else if (str.ends_with(".svg") || str.ends_with(".svgz")) {
90110
value = xaml::Media::Imaging::SvgImageSource{ uri };
91111
o.SetValue(prop, value);
92-
}
93-
else {
112+
} else {
94113
value = xaml::Media::Imaging::BitmapImage{ uri };
95114
o.SetValue(prop, value);
96115
}
97-
}
98-
99-
inline void ReadValue(JSValue const& jsValue, xaml::Media::Geometry& value) noexcept {
100-
const auto v = winrt::to_hstring(jsValue.AsJSString());
101-
value = Markup::XamlBindingHelper::ConvertValue(winrt::xaml_typename<xaml::Media::PathGeometry>(), winrt::box_value(v)).as<xaml::Media::Geometry>();
102-
}
103-
104-
inline void ReadValue(JSValue const& jsValue, Windows::UI::Text::FontWeight& value) noexcept {
105-
value.Weight = jsValue.AsInt16();
116+
} else {
117+
auto b = v.To<T>();
118+
o.SetValue(prop, winrt::box_value(b));
106119
}
107120
}
108121

109122

110-
// MapStyle has a bug where it expects the property to be set as an IReference<MapStyle> always, and does not support IReference<uint32_t>
111-
template<typename T, std::enable_if_t<
112-
std::is_same<winrt::Windows::UI::Xaml::Controls::Maps::MapStyle, T>::value, int> = 0>
113-
void SetPropValue(const xaml::DependencyObject& o, const xaml::DependencyProperty& prop, const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext&) {
114-
auto boxed = v.To<winrt::Windows::UI::Xaml::Controls::Maps::MapStyle>();
115-
o.SetValue(prop, winrt::box_value(boxed));
116-
}
117-
118-
template<typename T, std::enable_if_t<std::is_same<T, winrt::hstring>::value, int> = 0>
119-
void SetPropValue(const xaml::DependencyObject& o, const xaml::DependencyProperty& prop, const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext&) {
120-
auto b = v.AsString();
121-
o.SetValue(prop, winrt::box_value(winrt::to_hstring(b)));
122-
}
123-
124-
template<typename T, std::enable_if_t<std::is_same<T, winrt::Windows::Foundation::Uri>::value, int> = 0>
125-
void SetPropValue(const xaml::DependencyObject& o, const xaml::DependencyProperty& prop, const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext&) {
126-
auto cn = winrt::get_class_name(o);
127-
auto uri = Uri{ winrt::to_hstring(v.AsString()) };
128-
o.SetValue(prop, uri);
129-
}
130-
131-
template<typename T, std::enable_if_t<std::is_same<T, winrt::Windows::Foundation::IInspectable>::value, int> = 0>
132-
void SetPropValue(const xaml::DependencyObject& o, const xaml::DependencyProperty& prop, const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext& context) {
133-
switch (v.Type()) {
134-
case JSValueType::String: return SetPropValue<winrt::hstring>(o, prop, v, context);
135-
case JSValueType::Boolean: return SetPropValue<bool>(o, prop, v, context);
136-
case JSValueType::Double: return SetPropValue<double>(o, prop, v, context);
137-
case JSValueType::Int64: return SetPropValue<int64_t>(o, prop, v, context);
138-
case JSValueType::Object: {
139-
const auto& obj = v.AsObject();
140-
if (obj.find("string") != obj.cend()) {
141-
const auto& value = obj["string"];
142-
return SetPropValue<winrt::Windows::Foundation::IInspectable>(o, prop, value, context);
143-
}
144-
}
145-
}
146-
}
147-
148123
struct PropInfo {
149124
stringKey propName;
150125

0 commit comments

Comments
 (0)