From 4f0f64884dda102ada6e6fab4cc6912f4b2a5c96 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 19 Aug 2021 21:00:38 +0200 Subject: [PATCH] Keep backwards compatability with non-virtual `connectSignalsToEventEmitter()` --- config/common.cmake | 8 +- .../nodegui/core/Events/eventwidget_macro.h | 111 +++++++++++------- 2 files changed, 72 insertions(+), 47 deletions(-) diff --git a/config/common.cmake b/config/common.cmake index cbacf7519..4420216c4 100644 --- a/config/common.cmake +++ b/config/common.cmake @@ -9,20 +9,22 @@ set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "Minimum OS X deployment ve function(AddCommonConfig addonName) target_compile_features(${addonName} PRIVATE + cxx_constexpr cxx_inheriting_constructors cxx_lambdas cxx_auto_type cxx_variadic_templates cxx_variable_templates + cxx_std_17 ) - + if(napi_build_version) target_compile_definitions(${addonName} PRIVATE NAPI_VERSION=${napi_build_version} ) endif() - - if (WIN32) + + if (WIN32) target_compile_definitions(${addonName} PRIVATE ENUM_BITFIELDS_NOT_SUPPORTED ) diff --git a/src/cpp/include/nodegui/core/Events/eventwidget_macro.h b/src/cpp/include/nodegui/core/Events/eventwidget_macro.h index b258e76ca..1a7aed96f 100644 --- a/src/cpp/include/nodegui/core/Events/eventwidget_macro.h +++ b/src/cpp/include/nodegui/core/Events/eventwidget_macro.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include "core/Component/component_macro.h" #include "eventwidget.h" @@ -11,51 +12,73 @@ and every widget we export. */ +template +struct InitHelper { + static void connectSignalsToEventEmitter(W* instance) { + if constexpr (std::is_base_of::value) { + // Call the possibly non-virtual `connectSignalsToEventEmitter()` on the + // class directly. This is common when the type is one of our + // `NFooBarWidget` subclasses and not a plain Qt `QFooBarWidget`. + instance->connectSignalsToEventEmitter(); + } else { + // This branch is used when we need to support wrapping `NFooBarWidget` + // and `QFooBarWidget` instances at runtime. + // `connectSignalsToEventEmitter()` must be virtual for this to work + // correctly though. + EventWidget* eventWidget = dynamic_cast(instance); + if (eventWidget) { + eventWidget->connectSignalsToEventEmitter(); + } + } + } +}; + #ifndef EVENTWIDGET_WRAPPED_METHODS_DECLARATION -#define EVENTWIDGET_WRAPPED_METHODS_DECLARATION \ - COMPONENT_WRAPPED_METHODS_DECLARATION \ - Napi::Value initNodeEventEmitter(const Napi::CallbackInfo& info) { \ - Napi::Env env = info.Env(); \ - EventWidget* eventWidget = \ - dynamic_cast(this->instance.data()); \ - if (eventWidget) { \ - eventWidget->emitOnNode = \ - Napi::Persistent(info[0].As()); \ - eventWidget->connectSignalsToEventEmitter(); \ - } \ - return env.Null(); \ - } \ - Napi::Value getNodeEventEmitter(const Napi::CallbackInfo& info) { \ - Napi::Env env = info.Env(); \ - EventWidget* eventWidget = \ - dynamic_cast(this->instance.data()); \ - if (eventWidget && eventWidget->emitOnNode) { \ - return eventWidget->emitOnNode.Value(); \ - } else { \ - return env.Null(); \ - } \ - } \ - Napi::Value subscribeToQtEvent(const Napi::CallbackInfo& info) { \ - Napi::Env env = info.Env(); \ - Napi::String eventString = info[0].As(); \ - EventWidget* eventWidget = \ - dynamic_cast(this->instance.data()); \ - bool success = false; \ - if (eventWidget) { \ - eventWidget->subscribeToQtEvent(eventString.Utf8Value()); \ - success = true; \ - } \ - return Napi::Boolean::New(env, success); \ - } \ - Napi::Value unSubscribeToQtEvent(const Napi::CallbackInfo& info) { \ - Napi::Env env = info.Env(); \ - Napi::String eventString = info[0].As(); \ - EventWidget* eventWidget = \ - dynamic_cast(this->instance.data()); \ - if (eventWidget) { \ - eventWidget->unSubscribeToQtEvent(eventString.Utf8Value()); \ - } \ - return env.Null(); \ +#define EVENTWIDGET_WRAPPED_METHODS_DECLARATION \ + COMPONENT_WRAPPED_METHODS_DECLARATION \ + Napi::Value initNodeEventEmitter(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + EventWidget* eventWidget = \ + dynamic_cast(this->instance.data()); \ + if (eventWidget) { \ + eventWidget->emitOnNode = \ + Napi::Persistent(info[0].As()); \ + } \ + InitHelperinstance.data())>::type>:: \ + connectSignalsToEventEmitter(this->instance.data()); \ + return env.Null(); \ + } \ + Napi::Value getNodeEventEmitter(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + EventWidget* eventWidget = \ + dynamic_cast(this->instance.data()); \ + if (eventWidget && eventWidget->emitOnNode) { \ + return eventWidget->emitOnNode.Value(); \ + } else { \ + return env.Null(); \ + } \ + } \ + Napi::Value subscribeToQtEvent(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::String eventString = info[0].As(); \ + EventWidget* eventWidget = \ + dynamic_cast(this->instance.data()); \ + bool success = false; \ + if (eventWidget) { \ + eventWidget->subscribeToQtEvent(eventString.Utf8Value()); \ + success = true; \ + } \ + return Napi::Boolean::New(env, success); \ + } \ + Napi::Value unSubscribeToQtEvent(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + Napi::String eventString = info[0].As(); \ + EventWidget* eventWidget = \ + dynamic_cast(this->instance.data()); \ + if (eventWidget) { \ + eventWidget->unSubscribeToQtEvent(eventString.Utf8Value()); \ + } \ + return env.Null(); \ } #endif // EVENTWIDGET_WRAPPED_METHODS_DECLARATION