From 006afafc0a2bd9319c194438bf2b9756431b8409 Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Tue, 14 Mar 2023 10:36:25 -0700 Subject: [PATCH] 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) --- ...-6a4ff73d-3375-4842-aded-97da28555622.json | 7 ++ .../windows/ReactNativeXaml/XamlMetadata.h | 119 +++++++----------- 2 files changed, 54 insertions(+), 72 deletions(-) create mode 100644 change/react-native-xaml-6a4ff73d-3375-4842-aded-97da28555622.json diff --git a/change/react-native-xaml-6a4ff73d-3375-4842-aded-97da28555622.json b/change/react-native-xaml-6a4ff73d-3375-4842-aded-97da28555622.json new file mode 100644 index 0000000..d7f9eac --- /dev/null +++ b/change/react-native-xaml-6a4ff73d-3375-4842-aded-97da28555622.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "simplify overload resolution for SetPropValue", + "packageName": "react-native-xaml", + "email": "asklar@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/package/windows/ReactNativeXaml/XamlMetadata.h b/package/windows/ReactNativeXaml/XamlMetadata.h index 976dbcf..f1fbd84 100644 --- a/package/windows/ReactNativeXaml/XamlMetadata.h +++ b/package/windows/ReactNativeXaml/XamlMetadata.h @@ -57,44 +57,6 @@ namespace winrt::Microsoft::ReactNative { template bool IsType(const winrt::Windows::Foundation::IInspectable& i) { return i.try_as() != nullptr; } - template::value, int> = 0> - void SetPropValue(const xaml::DependencyObject o, const xaml::DependencyProperty& prop, const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext&) { - auto valueEnum = MakeEnum(v.AsInt32()); - o.SetValue(prop, valueEnum); - } - - template::value && - !std::is_same::value && - !std::is_same::value && - !std::is_same::value && - !std::is_same::value - , int> = 0> - void SetPropValue(const xaml::DependencyObject& o, const xaml::DependencyProperty& prop, const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext&) { - auto b = v.To(); - o.SetValue(prop, winrt::box_value(b)); - } - - template::value, int> = 0> - void SetPropValue(const xaml::DependencyObject& o, const xaml::DependencyProperty& prop, const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext&) { - - const auto str = v.AsString(); - const auto uri = Uri{ winrt::to_hstring(str) }; - - xaml::Media::ImageSource value{ nullptr }; - if (uri.SchemeName() == L"data") { - SetImageSourceForInlineData(str, o, prop); - } - else if (str.ends_with(".svg") || str.ends_with(".svgz")) { - value = xaml::Media::Imaging::SvgImageSource{ uri }; - o.SetValue(prop, value); - } - else { - value = xaml::Media::Imaging::BitmapImage{ uri }; - o.SetValue(prop, value); - } - } inline void ReadValue(JSValue const& jsValue, xaml::Media::Geometry& value) noexcept { const auto v = winrt::to_hstring(jsValue.AsJSString()); @@ -107,44 +69,57 @@ namespace winrt::Microsoft::ReactNative { } -// MapStyle has a bug where it expects the property to be set as an IReference always, and does not support IReference -template::value, int> = 0> - void SetPropValue(const xaml::DependencyObject& o, const xaml::DependencyProperty& prop, const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext&) { - auto boxed = v.To(); - o.SetValue(prop, winrt::box_value(boxed)); -} - -template::value, int> = 0> -void SetPropValue(const xaml::DependencyObject& o, const xaml::DependencyProperty& prop, const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext&) { - auto b = v.AsString(); - o.SetValue(prop, winrt::box_value(winrt::to_hstring(b))); -} - -template::value, int> = 0> -void SetPropValue(const xaml::DependencyObject& o, const xaml::DependencyProperty& prop, const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext&) { - auto cn = winrt::get_class_name(o); - auto uri = Uri{ winrt::to_hstring(v.AsString()) }; - o.SetValue(prop, uri); -} - -template::value, int> = 0> -void SetPropValue(const xaml::DependencyObject& o, const xaml::DependencyProperty& prop, const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext& context) { - switch (v.Type()) { - case JSValueType::String: return SetPropValue(o, prop, v, context); - case JSValueType::Boolean: return SetPropValue(o, prop, v, context); - case JSValueType::Double: return SetPropValue(o, prop, v, context); - case JSValueType::Int64: return SetPropValue(o, prop, v, context); - case JSValueType::Object: { - const auto& obj = v.AsObject(); - if (obj.find("string") != obj.cend()) { - const auto& value = obj["string"]; - return SetPropValue(o, prop, value, context); +template +void SetPropValue(const xaml::DependencyObject& o, const xaml::DependencyProperty& prop, + const winrt::Microsoft::ReactNative::JSValue& v, const winrt::Microsoft::ReactNative::IReactContext& context) { + if constexpr (std::is_same_v) { + auto boxed = v.To(); + o.SetValue(prop, winrt::box_value(boxed)); + } else if constexpr (std::is_same_v) { + auto b = v.AsString(); + o.SetValue(prop, winrt::box_value(winrt::to_hstring(b))); + } else if constexpr (std::is_same_v) { + auto cn = winrt::get_class_name(o); + auto uri = Uri{ winrt::to_hstring(v.AsString()) }; + o.SetValue(prop, uri); + } else if constexpr (std::is_same_v) { + switch (v.Type()) { + case JSValueType::String: return SetPropValue(o, prop, v, context); + case JSValueType::Boolean: return SetPropValue(o, prop, v, context); + case JSValueType::Double: return SetPropValue(o, prop, v, context); + case JSValueType::Int64: return SetPropValue(o, prop, v, context); + case JSValueType::Object: { + const auto& obj = v.AsObject(); + if (obj.find("string") != obj.cend()) { + const auto& value = obj["string"]; + return SetPropValue(o, prop, value, context); + } } - } + } + } else if constexpr (std::is_enum_v) { + auto valueEnum = MakeEnum(v.AsInt32()); + o.SetValue(prop, valueEnum); + } else if constexpr (std::is_same_v) { + const auto str = v.AsString(); + const auto uri = Uri{ winrt::to_hstring(str) }; + + xaml::Media::ImageSource value{ nullptr }; + if (uri.SchemeName() == L"data") { + SetImageSourceForInlineData(str, o, prop); + } else if (str.ends_with(".svg") || str.ends_with(".svgz")) { + value = xaml::Media::Imaging::SvgImageSource{ uri }; + o.SetValue(prop, value); + } else { + value = xaml::Media::Imaging::BitmapImage{ uri }; + o.SetValue(prop, value); + } + } else { + auto b = v.To(); + o.SetValue(prop, winrt::box_value(b)); } } + struct PropInfo { stringKey propName;