暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

SynchronizationContext.cpp 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include "il2cpp-config.h"
  2. #if IL2CPP_TARGET_WINDOWS && IL2CPP_HAS_OS_SYNCHRONIZATION_CONTEXT
  3. #include "os/SynchronizationContext.h"
  4. #include "os/WindowsRuntime.h"
  5. #include "vm/Class.h"
  6. #include "vm/Exception.h"
  7. #include "vm/RCW.h"
  8. #include "WindowsHelpers.h"
  9. #ifndef WINDOWS_SDK_BUILD_VERSION
  10. #error "We need to know which Windows SDK version we are compiling against!"
  11. #endif
  12. #include <windows.System.h>
  13. #include <windows.ui.core.h>
  14. #include <wrl.h>
  15. using il2cpp::os::SynchronizationContext;
  16. using Microsoft::WRL::Callback;
  17. using Microsoft::WRL::ComPtr;
  18. using Microsoft::WRL::Wrappers::HStringReference;
  19. template<typename T>
  20. using AgileCallback = Microsoft::WRL::Implements<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, T, Microsoft::WRL::FtmBase>;
  21. #if !IL2CPP_TARGET_WINDOWS_DESKTOP
  22. ComPtr<ABI::Windows::UI::Core::ICoreWindowStatic> s_CoreWindowStatics;
  23. #endif
  24. ComPtr<ABI::Windows::System::IDispatcherQueueStatics> s_DispatcherQueueStatics;
  25. Il2CppObject* SynchronizationContext::GetForCurrentThread()
  26. {
  27. HRESULT hr;
  28. #if !IL2CPP_TARGET_WINDOWS_DESKTOP
  29. if (s_CoreWindowStatics != nullptr)
  30. {
  31. ComPtr<ABI::Windows::UI::Core::ICoreWindow> currentThreadWindow;
  32. hr = s_CoreWindowStatics->GetForCurrentThread(&currentThreadWindow);
  33. if (SUCCEEDED(hr) && currentThreadWindow != nullptr)
  34. {
  35. ComPtr<ABI::Windows::UI::Core::ICoreDispatcher> dispatcher;
  36. hr = currentThreadWindow->get_Dispatcher(&dispatcher);
  37. if (SUCCEEDED(hr))
  38. return vm::RCW::GetOrCreateFromIInspectable(reinterpret_cast<Il2CppIInspectable*>(dispatcher.Get()), il2cpp_defaults.il2cpp_com_object_class);
  39. }
  40. }
  41. #endif
  42. if (s_DispatcherQueueStatics != nullptr)
  43. {
  44. ComPtr<ABI::Windows::System::IDispatcherQueue> dispatcherQueue;
  45. hr = s_DispatcherQueueStatics->GetForCurrentThread(&dispatcherQueue);
  46. if (SUCCEEDED(hr) && dispatcherQueue != nullptr)
  47. return vm::RCW::GetOrCreateFromIInspectable(reinterpret_cast<Il2CppIInspectable*>(dispatcherQueue.Get()), il2cpp_defaults.il2cpp_com_object_class);
  48. }
  49. return nullptr;
  50. }
  51. void SynchronizationContext::Post(Il2CppObject* context, SynchronizationContextCallback callback, intptr_t arg)
  52. {
  53. IL2CPP_ASSERT(vm::Class::HasParent(context->klass, il2cpp_defaults.il2cpp_com_object_class));
  54. HRESULT hr;
  55. auto dispatcherUnknown = reinterpret_cast<IUnknown*>(static_cast<Il2CppComObject*>(context)->identity);
  56. #if !IL2CPP_TARGET_WINDOWS_DESKTOP
  57. ComPtr<ABI::Windows::UI::Core::ICoreDispatcher> dispatcher;
  58. hr = dispatcherUnknown->QueryInterface(__uuidof(dispatcher), &dispatcher);
  59. if (SUCCEEDED(hr))
  60. {
  61. ComPtr<ABI::Windows::Foundation::IAsyncAction> ignoredAction;
  62. hr = dispatcher->RunAsync(ABI::Windows::UI::Core::CoreDispatcherPriority_Normal, Callback<AgileCallback<ABI::Windows::UI::Core::IDispatchedHandler> >([callback, arg]() -> HRESULT
  63. {
  64. callback(arg);
  65. return S_OK;
  66. }).Get(), &ignoredAction);
  67. vm::Exception::RaiseIfFailed(hr, false);
  68. }
  69. #endif
  70. ComPtr<ABI::Windows::System::IDispatcherQueue> dispatcherQueue;
  71. hr = dispatcherUnknown->QueryInterface(__uuidof(dispatcherQueue), &dispatcherQueue);
  72. if (SUCCEEDED(hr))
  73. {
  74. boolean ignoredResult;
  75. hr = dispatcherQueue->TryEnqueueWithPriority(ABI::Windows::System::DispatcherQueuePriority_Normal, Callback<AgileCallback<ABI::Windows::System::IDispatcherQueueHandler> >([callback, arg]() -> HRESULT
  76. {
  77. callback(arg);
  78. return S_OK;
  79. }).Get(), &ignoredResult);
  80. vm::Exception::RaiseIfFailed(hr, false);
  81. }
  82. }
  83. void SynchronizationContext::Initialize()
  84. {
  85. #if !IL2CPP_TARGET_WINDOWS_DESKTOP
  86. RoGetActivationFactory(HStringReference(L"Windows.UI.Core.CoreWindow").Get(), __uuidof(s_CoreWindowStatics), &s_CoreWindowStatics);
  87. #endif
  88. RoGetActivationFactory(HStringReference(L"Windows.System.DispatcherQueue").Get(), __uuidof(s_DispatcherQueueStatics), &s_DispatcherQueueStatics);
  89. }
  90. void SynchronizationContext::Shutdown()
  91. {
  92. #if !IL2CPP_TARGET_WINDOWS_DESKTOP
  93. s_CoreWindowStatics = nullptr;
  94. #endif
  95. s_DispatcherQueueStatics = nullptr;
  96. }
  97. #endif // IL2CPP_TARGET_WINDOWS && IL2CPP_HAS_OS_SYNCHRONIZATION_CONTEXT