@@ -27,6 +27,12 @@ static napi_status (*napi_get_uv_event_loop)(napi_env env, struct uv_loop_s** lo
2727#if defined(_WIN32)
2828#define WIN32_LEAN_AND_MEAN
2929#include < windows.h>
30+ #include < DispatcherQueue.h>
31+ #pragma comment(lib, "CoreMessaging.lib")
32+
33+ #include < wrl.h>
34+ using namespace Microsoft ::WRL;
35+ using namespace ABI ::Windows;
3036
3137extern " C" void app_init (const char *path)
3238{
@@ -39,6 +45,39 @@ extern "C" void app_activate(void)
3945
4046extern " C" void display_link (void (*cb)(uv_idle_t *), uv_idle_t *data)
4147{
48+ static ComPtr<System::IDispatcherQueue> m_queue;
49+
50+ ComPtr<System::IDispatcherQueueStatics> queueStatics;
51+ if (FAILED (Foundation::GetActivationFactory (Wrappers::HStringReference (RuntimeClass_Windows_System_DispatcherQueue).Get (), &queueStatics)) ||
52+ FAILED (queueStatics->GetForCurrentThread (&m_queue)) || !m_queue)
53+ {
54+ DispatcherQueueOptions options = { sizeof (DispatcherQueueOptions) };
55+ options.threadType = DQTYPE_THREAD_CURRENT;
56+
57+ System::IDispatcherQueueController *controller;
58+ if (FAILED (::CreateDispatcherQueueController (options, &controller)))
59+ abort ();
60+
61+ controller->get_DispatcherQueue (&m_queue);
62+ }
63+
64+ System::IDispatcherQueueTimer *timer;
65+ if (FAILED (m_queue->CreateTimer (&timer)))
66+ abort ();
67+
68+ EventRegistrationToken token;
69+ timer->add_Tick (Callback<Implements<RuntimeClassFlags<Delegate>, Foundation::ITypedEventHandler<System::DispatcherQueueTimer*, IInspectable*>, FtmBase>>([=](auto sender, auto args)
70+ {
71+ if (InSendMessage ())
72+ return S_OK;
73+
74+ cb (data);
75+ return S_OK;
76+ }).Get (), &token);
77+
78+ // $TODO proper vsync event
79+ timer->put_Interval ({ INT64 (1000000ll * 10 / 60 ) });
80+ timer->Start ();
4281}
4382#endif
4483
@@ -138,7 +177,11 @@ extern "C" EXPORTED_SYMBOL void *napi_register_module_v1(napi_env env, void *exp
138177 app_activate ();
139178
140179 auto errorState = Baselib_ErrorState_Create ();
180+ #if defined(_WIN32)
181+ auto progHandle = Baselib_DynamicLibrary_FromNativeHandle (reinterpret_cast <uint64_t >(GetModuleHandleW (nullptr )), Baselib_DynamicLibrary_WinApiHMODULE, &errorState);
182+ #else
141183 auto progHandle = Baselib_DynamicLibrary_OpenProgramHandle (&errorState);
184+ #endif
142185 napi_get_uv_event_loop = (decltype (napi_get_uv_event_loop))Baselib_DynamicLibrary_GetFunction (progHandle, " napi_get_uv_event_loop" , &errorState);
143186 uv_idle_init = (decltype (uv_idle_init))Baselib_DynamicLibrary_GetFunction (progHandle, " uv_idle_init" , &errorState);
144187 uv_idle_start = (decltype (uv_idle_start))Baselib_DynamicLibrary_GetFunction (progHandle, " uv_idle_start" , &errorState);
@@ -147,7 +190,6 @@ extern "C" EXPORTED_SYMBOL void *napi_register_module_v1(napi_env env, void *exp
147190 printf (" error: %s\n " , utils::Exception::FormatBaselibErrorState (errorState).c_str ());
148191 return nullptr ;
149192 }
150- Baselib_DynamicLibrary_Close (progHandle);
151193
152194 uv_loop_t *loop;
153195 napi_get_uv_event_loop (env, &loop);
0 commit comments