Created
December 9, 2024 20:02
-
-
Save jonwis/4c5044c96f5b7e18ce6aa9e10e9de87c to your computer and use it in GitHub Desktop.
A model for free-threaded properties in a C++/WinRT Object
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <winrt/base.h> | |
/* Assume this type: | |
runtimeclass Foo { | |
String Name; | |
UInt32 Id { get; }; | |
Foo[] GetMoreFoos(); | |
} | |
*/ | |
template<typename TValue> | |
auto read_with_lock(winrt::srwlock& lock, TValue const& v) { | |
auto l = lock.lock_shared(); | |
return v; | |
} | |
template<typename TValue, typename TInput> | |
void read_with_lock(winrt::srwlock& lock, TValue& stored, TInput&& input) { | |
auto l = lock.lock_exclusive(); | |
stored = std::forward<TInput>(input); | |
} | |
struct Foo : FooT<Foo> { | |
winrt::hstring Name() { return read_with_lock(m_lock, m_name); } | |
void Name(winrt::hstring const& value) { return write_with_lock(m_lock, m_name, value); } | |
uint32_t Id() { return read_with_lock(m_lock, m_count); } | |
winrt::com_array<Foo> GetMoreFoos() { | |
auto l = m_lock.lock_shared(); | |
// Generate a bunch more foos using complicated logic over m_name & m_count | |
return that; | |
} | |
private: | |
winrt::srwlock m_lock; | |
winrt::hstring m_name; | |
uint32_t m_count; | |
}; | |
/* | |
Note that the existing wil/cppwinrt_authoring.h single_threaded_property types are not thread | |
safe (that's what "single threaded" there means - they're good for UX things, but general | |
purpose properties on free-threaded/MTA types. | |
Currently, it's not possible to (easily) mimic the same "acquire lock, return value" thing | |
without a bunch more typing in the field definitions. You could say something like: | |
class Foo { | |
locked_type<Foo, winrt::hstring> m_name; | |
locked_type<Foo, uint32_t> m_count; | |
Foo() : m_name(this), m_count(this, 15) { } | |
}; | |
... but that inflates the size of each field by sizeof(this), which isn't great. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment