From 42113e28e6d55d715e9f8158379bf6bb2d911ed0 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Mon, 28 Oct 2024 09:47:15 +0100 Subject: [PATCH] Lua: Fix properties Previously the `HAS_MEM_FUNC` would only work if func was a direct member of `T` but not if it was a member of a Base of `T`. Using C++20 concepts the checks get much easier and now work for members of a base class too. Change-Id: I4e35069f4609cd65365d3c4e5883ae3b27204131 Reviewed-by: Christian Stenger --- src/plugins/lua/bindings/gui.cpp | 126 +++++++++++++++---------------- 1 file changed, 59 insertions(+), 67 deletions(-) diff --git a/src/plugins/lua/bindings/gui.cpp b/src/plugins/lua/bindings/gui.cpp index 437e716c067..ed84c3056bf 100644 --- a/src/plugins/lua/bindings/gui.cpp +++ b/src/plugins/lua/bindings/gui.cpp @@ -77,131 +77,123 @@ void constructWidget(std::unique_ptr &widget, const sol::table &children) } } -#define HAS_MEM_FUNC(func, name) \ - template \ - struct name \ - { \ - typedef char yes[1]; \ - typedef char no[2]; \ - template \ - struct type_check; \ - template \ - static yes &chk(type_check *); \ - template \ - static no &chk(...); \ - static bool const value = sizeof(chk(0)) == sizeof(yes); \ - } +// clang-format off +#define CREATE_HAS_FUNC(name, ...) \ + template concept has_##name = requires { \ + { std::declval().name(__VA_ARGS__) } -> std::same_as; \ + }; +// clang-format on -HAS_MEM_FUNC(onTextChanged, hasOnTextChanged); -HAS_MEM_FUNC(onClicked, hasOnClicked); -HAS_MEM_FUNC(setText, hasSetText); -HAS_MEM_FUNC(setMarkdown, hasSetMarkdown); -HAS_MEM_FUNC(setReadOnly, hasSetReadOnly); -HAS_MEM_FUNC(setTitle, hasSetTitle); -HAS_MEM_FUNC(setValue, hasSetValue); -HAS_MEM_FUNC(setSize, hasSetSize); -HAS_MEM_FUNC(setWindowFlags, hasSetWindowFlags); -HAS_MEM_FUNC(setWidgetAttribute, hasSetWidgetAttribute); -HAS_MEM_FUNC(setAutoFillBackground, hasSetAutoFillBackground); -HAS_MEM_FUNC(setIconPath, hasSetIconPath); -HAS_MEM_FUNC(setFlat, hasSetFlat); -HAS_MEM_FUNC(setOpenExternalLinks, hasSetOpenExternalLinks); -HAS_MEM_FUNC(setIconSize, hasSetIconSize); -HAS_MEM_FUNC(setWordWrap, hasSetWordWrap); -HAS_MEM_FUNC(setTextFormat, hasSetTextFormat); -HAS_MEM_FUNC(setRightSideIconPath, hasSetRightSideIconPath); -HAS_MEM_FUNC(setPlaceHolderText, hasSetPlaceHolderText); -HAS_MEM_FUNC(setCompleter, hasSetCompleter); -HAS_MEM_FUNC(setMinimumHeight, hasSetMinimumHeight); -HAS_MEM_FUNC(onReturnPressed, hasOnReturnPressed); -HAS_MEM_FUNC(onRightSideIconClicked, hasOnRightSideIconClicked); -HAS_MEM_FUNC(setTextInteractionFlags, hasSetTextInteractionFlags); -HAS_MEM_FUNC(setFixedSize, hasSetFixedSize); +CREATE_HAS_FUNC(onTextChanged, nullptr, nullptr) +CREATE_HAS_FUNC(onClicked, nullptr, nullptr) +CREATE_HAS_FUNC(setText, QString()) +CREATE_HAS_FUNC(setMarkdown, QString()) +CREATE_HAS_FUNC(setReadOnly, bool()) +CREATE_HAS_FUNC(setTitle, QString()) +CREATE_HAS_FUNC(setValue, int()) +CREATE_HAS_FUNC(setSize, int(), int()) +CREATE_HAS_FUNC(setWindowFlags, Qt::WindowFlags()) +CREATE_HAS_FUNC(setWidgetAttribute, Qt::WidgetAttribute(), bool()) +CREATE_HAS_FUNC(setAutoFillBackground, bool()) +CREATE_HAS_FUNC(setIconPath, Utils::FilePath()) +CREATE_HAS_FUNC(setFlat, bool()) +CREATE_HAS_FUNC(setOpenExternalLinks, bool()) +CREATE_HAS_FUNC(setIconSize, QSize()) +CREATE_HAS_FUNC(setWordWrap, bool()) +CREATE_HAS_FUNC(setTextFormat, Qt::TextFormat()) +CREATE_HAS_FUNC(setRightSideIconPath, Utils::FilePath()) +CREATE_HAS_FUNC(setPlaceHolderText, QString()) +CREATE_HAS_FUNC(setCompleter, nullptr) +CREATE_HAS_FUNC(setMinimumHeight, int()) +CREATE_HAS_FUNC(onReturnPressed, nullptr, nullptr) +CREATE_HAS_FUNC(onRightSideIconClicked, nullptr, nullptr) +CREATE_HAS_FUNC(setTextInteractionFlags, Qt::TextInteractionFlags()) +CREATE_HAS_FUNC(setFixedSize, QSize()) template -void setProperties(std::unique_ptr &item, const sol::table &children, QObject *guard) { - if constexpr (hasSetTextInteractionFlags::value) { +void setProperties(std::unique_ptr &item, const sol::table &children, QObject *guard) +{ + if constexpr (has_setTextInteractionFlags) { const auto interactionFlags = children.get>("interactionFlags"); if (interactionFlags) { item->setTextInteractionFlags(tableToFlags(*interactionFlags)); } } - if constexpr (hasSetFixedSize::value) { + if constexpr (has_setFixedSize) { sol::optional size = children.get>("fixedSize"); if (size) item->setFixedSize(size->width(), size->height()); } - if constexpr (hasSetWordWrap::value) { + if constexpr (has_setWordWrap) { const auto wrap = children.get>("wordWrap"); if (wrap) item->setWordWrap(*wrap); } - if constexpr (hasSetTextFormat::value) { + if constexpr (has_setTextFormat) { const auto format = children.get>("textFormat"); if (format) item->setTextFormat(*format); } - if constexpr (hasSetRightSideIconPath::value) { + if constexpr (has_setRightSideIconPath) { const auto path = children.get>("rightSideIconPath"); if (path) item->setRightSideIconPath(*path); } - if constexpr (hasSetPlaceHolderText::value) { + if constexpr (has_setPlaceHolderText) { const auto text = children.get>("placeHolderText"); if (text) item->setPlaceHolderText(*text); } - if constexpr (hasSetCompleter::value) { + if constexpr (has_setCompleter) { const auto completer = children.get("completer"); if (completer) item->setCompleter(completer); } - if constexpr (hasSetMinimumHeight::value) { + if constexpr (has_setMinimumHeight) { const auto minHeight = children.get>("minimumHeight"); if (minHeight) item->setMinimumHeight(*minHeight); } - if constexpr (hasOnReturnPressed &, QObject *)>::value) { + if constexpr (has_onReturnPressed) { const auto callback = children.get>("onReturnPressed"); - if (callback) - { + if (callback) { item->onReturnPressed([func = *callback]() { void_safe_call(func); }, guard); } } - if constexpr (hasOnRightSideIconClicked &)>::value) { + if constexpr (has_onRightSideIconClicked) { const auto callback = children.get>("onRightSideIconClicked"); if (callback) item->onRightSideIconClicked([func = *callback]() { void_safe_call(func); }, guard); } - if constexpr (hasSetFlat::value) { + if constexpr (has_setFlat) { const auto flat = children.get>("flat"); if (flat) item->setFlat(*flat); } - if constexpr (hasSetIconPath::value) { + if constexpr (has_setIconPath) { const auto iconPath = children.get>("iconPath"); if (iconPath) item->setIconPath(*iconPath); } - if constexpr (hasSetIconSize::value) { + if constexpr (has_setIconSize) { const auto iconSize = children.get>("iconSize"); if (iconSize) item->setIconSize(*iconSize); } - if constexpr (hasSetWindowFlags::value) { + if constexpr (has_setWindowFlags) { sol::optional windowFlags = children.get>( "windowFlags"); if (windowFlags) { @@ -212,13 +204,13 @@ void setProperties(std::unique_ptr &item, const sol::table &children, QObject } } - if constexpr (hasSetSize::value) { + if constexpr (has_setSize) { sol::optional size = children.get>("size"); if (size) item->setSize(size->width(), size->height()); } - if constexpr (hasSetWidgetAttribute::value) { + if constexpr (has_setWidgetAttribute) { sol::optional widgetAttributes = children.get>( "widgetAttributes"); if (widgetAttributes) { @@ -228,14 +220,14 @@ void setProperties(std::unique_ptr &item, const sol::table &children, QObject } } - if constexpr (hasSetAutoFillBackground::value) { + if constexpr (has_setAutoFillBackground) { sol::optional autoFillBackground = children.get>( "autoFillBackground"); if (autoFillBackground) item->setAutoFillBackground(*autoFillBackground); } - if constexpr (hasOnTextChanged::value) { + if constexpr (has_onTextChanged) { sol::optional onTextChanged = children.get>("onTextChanged"); if (onTextChanged) { @@ -247,7 +239,7 @@ void setProperties(std::unique_ptr &item, const sol::table &children, QObject guard); } } - if constexpr (hasOnClicked &, QObject *guard)>::value) { + if constexpr (has_onClicked) { sol::optional onClicked = children.get>("onClicked"); if (onClicked) { @@ -259,30 +251,30 @@ void setProperties(std::unique_ptr &item, const sol::table &children, QObject guard); } } - if constexpr (hasSetText::value) { + if constexpr (has_setText) { auto text = children.get>("text"); if (text) item->setText(*text); } - if constexpr (hasSetMarkdown::value) { + if constexpr (has_setMarkdown) { auto markdown = children.get>("markdown"); if (markdown) item->setMarkdown(*markdown); } - if constexpr (hasSetTitle::value) { + if constexpr (has_setTitle) { item->setTitle(children.get_or("title", "")); } - if constexpr (hasSetValue::value) { + if constexpr (has_setValue) { sol::optional value = children.get>("value"); if (value) item->setValue(*value); } - if constexpr (hasSetReadOnly::value) { + if constexpr (has_setReadOnly) { sol::optional readOnly = children.get>("readOnly"); if (readOnly) item->setReadOnly(*readOnly); } - if constexpr (hasSetOpenExternalLinks::value) { + if constexpr (has_setOpenExternalLinks) { sol::optional openExternalLinks = children.get>( "openExternalLinks"); if (openExternalLinks)