Keep backwards compatability with non-virtual connectSignalsToEventEmitter()

This commit is contained in:
Simon Edwards 2021-08-19 21:00:38 +02:00
parent 1f11f1cf8b
commit 4f0f64884d
2 changed files with 72 additions and 47 deletions

View File

@ -9,20 +9,22 @@ set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "Minimum OS X deployment ve
function(AddCommonConfig addonName) function(AddCommonConfig addonName)
target_compile_features(${addonName} PRIVATE target_compile_features(${addonName} PRIVATE
cxx_constexpr
cxx_inheriting_constructors cxx_inheriting_constructors
cxx_lambdas cxx_lambdas
cxx_auto_type cxx_auto_type
cxx_variadic_templates cxx_variadic_templates
cxx_variable_templates cxx_variable_templates
cxx_std_17
) )
if(napi_build_version) if(napi_build_version)
target_compile_definitions(${addonName} PRIVATE target_compile_definitions(${addonName} PRIVATE
NAPI_VERSION=${napi_build_version} NAPI_VERSION=${napi_build_version}
) )
endif() endif()
if (WIN32) if (WIN32)
target_compile_definitions(${addonName} PRIVATE target_compile_definitions(${addonName} PRIVATE
ENUM_BITFIELDS_NOT_SUPPORTED ENUM_BITFIELDS_NOT_SUPPORTED
) )

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <QWidget> #include <QWidget>
#include <type_traits>
#include "core/Component/component_macro.h" #include "core/Component/component_macro.h"
#include "eventwidget.h" #include "eventwidget.h"
@ -11,51 +12,73 @@
and every widget we export. and every widget we export.
*/ */
template <typename W>
struct InitHelper {
static void connectSignalsToEventEmitter(W* instance) {
if constexpr (std::is_base_of<EventWidget, W>::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<EventWidget*>(instance);
if (eventWidget) {
eventWidget->connectSignalsToEventEmitter();
}
}
}
};
#ifndef EVENTWIDGET_WRAPPED_METHODS_DECLARATION #ifndef EVENTWIDGET_WRAPPED_METHODS_DECLARATION
#define EVENTWIDGET_WRAPPED_METHODS_DECLARATION \ #define EVENTWIDGET_WRAPPED_METHODS_DECLARATION \
COMPONENT_WRAPPED_METHODS_DECLARATION \ COMPONENT_WRAPPED_METHODS_DECLARATION \
Napi::Value initNodeEventEmitter(const Napi::CallbackInfo& info) { \ Napi::Value initNodeEventEmitter(const Napi::CallbackInfo& info) { \
Napi::Env env = info.Env(); \ Napi::Env env = info.Env(); \
EventWidget* eventWidget = \ EventWidget* eventWidget = \
dynamic_cast<EventWidget*>(this->instance.data()); \ dynamic_cast<EventWidget*>(this->instance.data()); \
if (eventWidget) { \ if (eventWidget) { \
eventWidget->emitOnNode = \ eventWidget->emitOnNode = \
Napi::Persistent(info[0].As<Napi::Function>()); \ Napi::Persistent(info[0].As<Napi::Function>()); \
eventWidget->connectSignalsToEventEmitter(); \ } \
} \ InitHelper<std::remove_pointer<decltype(this->instance.data())>::type>:: \
return env.Null(); \ connectSignalsToEventEmitter(this->instance.data()); \
} \ return env.Null(); \
Napi::Value getNodeEventEmitter(const Napi::CallbackInfo& info) { \ } \
Napi::Env env = info.Env(); \ Napi::Value getNodeEventEmitter(const Napi::CallbackInfo& info) { \
EventWidget* eventWidget = \ Napi::Env env = info.Env(); \
dynamic_cast<EventWidget*>(this->instance.data()); \ EventWidget* eventWidget = \
if (eventWidget && eventWidget->emitOnNode) { \ dynamic_cast<EventWidget*>(this->instance.data()); \
return eventWidget->emitOnNode.Value(); \ if (eventWidget && eventWidget->emitOnNode) { \
} else { \ return eventWidget->emitOnNode.Value(); \
return env.Null(); \ } else { \
} \ return env.Null(); \
} \ } \
Napi::Value subscribeToQtEvent(const Napi::CallbackInfo& info) { \ } \
Napi::Env env = info.Env(); \ Napi::Value subscribeToQtEvent(const Napi::CallbackInfo& info) { \
Napi::String eventString = info[0].As<Napi::String>(); \ Napi::Env env = info.Env(); \
EventWidget* eventWidget = \ Napi::String eventString = info[0].As<Napi::String>(); \
dynamic_cast<EventWidget*>(this->instance.data()); \ EventWidget* eventWidget = \
bool success = false; \ dynamic_cast<EventWidget*>(this->instance.data()); \
if (eventWidget) { \ bool success = false; \
eventWidget->subscribeToQtEvent(eventString.Utf8Value()); \ if (eventWidget) { \
success = true; \ eventWidget->subscribeToQtEvent(eventString.Utf8Value()); \
} \ success = true; \
return Napi::Boolean::New(env, success); \ } \
} \ return Napi::Boolean::New(env, success); \
Napi::Value unSubscribeToQtEvent(const Napi::CallbackInfo& info) { \ } \
Napi::Env env = info.Env(); \ Napi::Value unSubscribeToQtEvent(const Napi::CallbackInfo& info) { \
Napi::String eventString = info[0].As<Napi::String>(); \ Napi::Env env = info.Env(); \
EventWidget* eventWidget = \ Napi::String eventString = info[0].As<Napi::String>(); \
dynamic_cast<EventWidget*>(this->instance.data()); \ EventWidget* eventWidget = \
if (eventWidget) { \ dynamic_cast<EventWidget*>(this->instance.data()); \
eventWidget->unSubscribeToQtEvent(eventString.Utf8Value()); \ if (eventWidget) { \
} \ eventWidget->unSubscribeToQtEvent(eventString.Utf8Value()); \
return env.Null(); \ } \
return env.Null(); \
} }
#endif // EVENTWIDGET_WRAPPED_METHODS_DECLARATION #endif // EVENTWIDGET_WRAPPED_METHODS_DECLARATION