-
Notifications
You must be signed in to change notification settings - Fork 275
Add property, event, and INPC helpers #317
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
This PR would be very useful in my effort to make WinRT component authoring idl-free via idlgen (sorry for the shameless plug). Specifically, |
…loc spies one because of an issue in COM
|
Neat - I've written that namespace wil
{
/// @cond
namespace details
{
template<typename T> struct prop_storage
{
T m_value{};
operator T& () { return m_value; }
operator T const& () const { return m_value; }
template<typename Q> auto operator=(Q&& q) {
m_value = wistd::forward<Q>(q);
return *this;
}
};
}
/// @endcond
/** Produces the property operator() adapters around a type
C++/WinRT property syntax requires operator()(value) to set and operator()() to get. This type
is both the storage of the underlying property and the operator() overloads for access. It can
be used in the same way as the property type as simple_property<Q> is-a Q.
~~~
struct MyType : MyTypeT<MyType> {
wil::simple_property<winrt::hstring> DisplayName{ L"puppies" };
wil::simple_property<bool> IsEnabled { false };
void Flip() {
if (IsEnabled) {
DisplayName = L"kittens";
IsEnabled = false;
} else {
DisplayName = L"puppies";
IsEnabled = true;
}
}
};
~~~
*/
template<typename T> struct simple_property :
wistd::conditional_t<wistd::is_scalar_v<T>, details::prop_storage<T>, T>
{
template<typename Q> auto& operator()(Q&& q)
{
*this = std::forward<Q>(q);
return *this;
}
auto& operator()()
{
return *this;
}
template<typename Q> auto operator=(Q&& q)
{
return static_cast<T&>(*this) = std::forward<Q>(q);
}
};
}This "is-a" means I couldn't get a "glom on" version like this to work nicely because template<typename T> struct property_adapter
{
T& m_source;
template<typename Q> auto& operator()(Q&& q)
{
return m_source = std::forward<Q>(q);
}
auto& operator()()
{
return m_source;
}
};
struct thing
{
int m_value{3};
property_adapter<int> TheValue{ m_value };
}; |
|
I would also recommend adding a CTAD guide so that you can avoid writing the property type (only works if it's static). inline static single_threaded_rw_property MyInt { 10 }; |
|
@citelao looks like I forgot to add docs (oops!); mind adding some? (it doesn't look like we have detailed docs for the rest of wil?) |
This adds the following helpers:
read_only_property<T>read_write_property<T>simple_event<T>(maps to an event that notifies aEventHandler<T>)typed_event<S, T>(maps to an event that notifies aTypedEventHandler<S, T>)notify_property_changed<CRTP>- base class for a default INotifyPropertyChangedproperty_with_notify<T>- a notifiable propertyadded tests. The INPC test requires instantiating the xaml type PropertyChangedEventArgs, which requires having XAML running, so that necessitates the test being either UWP or having a xaml island. Chose the latter, which means having a sxs manifest with maxversiontested. It also requires updating the command line to cppwinrt to include extensions, hence the
-input sdk+now instead of-input sdk