Skip to content

Commit

Permalink
Merge pull request #132 from NuiCpp/fix/listen_recursion
Browse files Browse the repository at this point in the history
Fix/listen recursion
  • Loading branch information
5cript authored Feb 5, 2025
2 parents a1e1bea + bb64876 commit e761363
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ubuntu_20.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:

steps:
- uses: actions/checkout@v3
- uses: awalsh128/cache-apt-pkgs-action@v1.3.0
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libwebkit2gtk-4.0-dev libcurl4-openssl-dev libcrypto++-dev ninja-build

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ubuntu_22.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:

steps:
- uses: actions/checkout@v3
- uses: awalsh128/cache-apt-pkgs-action@v1.3.0
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libwebkit2gtk-4.0-dev libcurl4-openssl-dev libcrypto++-dev ninja-build

Expand Down
4 changes: 4 additions & 0 deletions cmake/backend/emscripten.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,17 @@ function(nui_add_emscripten_target)
set(PATCH_DOTENV_COMMAND COMMAND cmake -E true)
endif()

get_target_property(TARGET_CXX_STANDARD ${NUI_ADD_EMSCRIPTEN_TARGET_ARGS_TARGET} CXX_STANDARD)
message(STATUS "C++ standard of frontend subproject: ${TARGET_CXX_STANDARD}")

include(ExternalProject)
ExternalProject_Add(
"${NUI_ADD_EMSCRIPTEN_TARGET_ARGS_TARGET}-emscripten"
SOURCE_DIR "${SOURCE_DIR}"
# emscripten cmake with passed down Release/Debug build type
CONFIGURE_COMMAND
${EMCMAKE} cmake
"-DCMAKE_CXX_STANDARD=${TARGET_CXX_STANDARD}"
${NUI_ADD_EMSCRIPTEN_TARGET_ARGS_CMAKE_OPTIONS}
"-DNUI_NPM=${NUI_NPM}"
"-DNUI_NODE=${NUI_NODE}"
Expand Down
8 changes: 6 additions & 2 deletions cmake/frontend/emscripten.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ function(nui_prepare_emscripten_target)
cmake_parse_arguments(
NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS
"NO_INLINE;NO_INLINE_INJECT;LEAN_INDEX_HTML"
"TARGET;PREJS;STATIC;UNPACKED_MODE"
"TARGET;PREJS;STATIC;UNPACKED_MODE;CXX_STANDARD"
"EMSCRIPTEN_LINK_OPTIONS;EMSCRIPTEN_COMPILE_OPTIONS;PARCEL_ARGS;NPM_INSTALL_ARGS;OBSERVED_BUNDLE_FILES"
${ARGN}
)
Expand All @@ -28,9 +28,13 @@ function(nui_prepare_emscripten_target)
set(NUI_LEAN_HTML "lean")
endif()

if (NOT NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_CXX_STANDARD)
get_target_property(NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_CXX_STANDARD ${NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_TARGET} CXX_STANDARD)
endif()

set(INLINER_COMMAND "")
if (NOT NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_NO_INLINE)
nui_enable_inline(TARGET ${NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_TARGET} RELATIVE_TO ${CMAKE_CURRENT_SOURCE_DIR})
nui_enable_inline(TARGET ${NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_TARGET} RELATIVE_TO ${CMAKE_CURRENT_SOURCE_DIR} CXX_STANDARD ${NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_CXX_STANDARD})
if (NOT NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_NO_INLINE_INJECT)
set(INLINER_COMMAND COMMAND ${NUI_INLINE_INJECTOR_TARGET_FILE} "${CMAKE_BINARY_DIR}/static/index.html" "${CMAKE_BINARY_DIR}/nui-inline/inline_imports.js" "${CMAKE_BINARY_DIR}/nui-inline/inline_imports.css" ${NUI_DEFER_INLINE_SCRIPTS_TAG} ${NUI_LEAN_HTML})
endif()
Expand Down
95 changes: 87 additions & 8 deletions nui/include/nui/event_system/listen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,20 @@
#include <utility>
#include <memory>
#include <functional>
#include <type_traits>

namespace Nui
{
namespace Detail
{
template <typename>
struct IsStdFunction : std::false_type
{};
template <typename RetT, typename... ArgsT>
struct IsStdFunction<std::function<RetT(ArgsT...)>> : std::true_type
{};
}

template <typename ValueT>
void listen(EventContext& eventContext, Observed<ValueT> const& obs, std::function<bool(ValueT const&)> onEvent)
{
Expand All @@ -22,6 +33,20 @@ namespace Nui
obs.attachEvent(eventId);
}

template <typename ValueT>
requires std::is_scalar_v<ValueT>
void listen(EventContext& eventContext, Observed<ValueT> const& obs, std::function<bool(ValueT)> onEvent)
{
const auto eventId = eventContext.registerEvent(Event{
[obs = Detail::CopyableObservedWrap{obs}, onEvent = std::move(onEvent)](auto) {
return onEvent(obs.value());
},
[]() {
return true;
}});
obs.attachEvent(eventId);
}

template <typename ValueT>
void listen(EventContext& eventContext, Observed<ValueT> const& obs, std::function<void(ValueT const&)> onEvent)
{
Expand All @@ -31,10 +56,23 @@ namespace Nui
});
}

template <typename ValueT>
requires std::is_scalar_v<ValueT>
void listen(EventContext& eventContext, Observed<ValueT> const& obs, std::function<void(ValueT)> onEvent)
{
return listen(eventContext, obs, [onEvent = std::move(onEvent)](ValueT value) {
onEvent(value);
return true;
});
}

template <typename ValueT, typename FunctionT>
void listen(EventContext& eventContext, Observed<ValueT> const& obs, FunctionT onEvent)
requires(
(std::invocable<FunctionT, ValueT const&> || std::invocable<FunctionT, ValueT>) &&
!Detail::IsStdFunction<FunctionT>::value)
void listen(EventContext& eventContext, Observed<ValueT> const& obs, FunctionT&& onEvent)
{
return listen(eventContext, obs, std::function(std::move(onEvent)));
return listen(eventContext, obs, std::function(std::forward<FunctionT>(onEvent)));
}

template <typename ValueT>
Expand All @@ -55,6 +93,25 @@ namespace Nui
obs->attachEvent(eventId);
}

template <typename ValueT>
requires std::is_scalar_v<ValueT>
void listen(
EventContext& eventContext,
std::shared_ptr<Observed<ValueT>> const& obs,
std::function<bool(ValueT)> onEvent)
{
const auto eventId = eventContext.registerEvent(Event{
[weak = std::weak_ptr<Observed<ValueT>>{obs}, onEvent = std::move(onEvent)](auto) {
if (auto obs = weak.lock(); obs)
return onEvent(obs->value());
return false;
},
[weak = std::weak_ptr<Observed<ValueT>>{obs}]() {
return !weak.expired();
}});
obs->attachEvent(eventId);
}

template <typename ValueT>
void listen(
EventContext& eventContext,
Expand All @@ -67,21 +124,43 @@ namespace Nui
});
}

template <typename ValueT>
requires std::is_scalar_v<ValueT>
void listen(
EventContext& eventContext,
std::shared_ptr<Observed<ValueT>> const& obs,
std::function<void(ValueT)> onEvent)
{
return listen(eventContext, obs, [onEvent = std::move(onEvent)](ValueT value) {
onEvent(value);
return true;
});
}

template <typename ValueT, typename FunctionT>
void listen(EventContext& eventContext, std::shared_ptr<Observed<ValueT>> const& obs, FunctionT onEvent)
requires(
(std::invocable<FunctionT, ValueT const&> || std::invocable<FunctionT, ValueT>) &&
!Detail::IsStdFunction<FunctionT>::value)
void listen(EventContext& eventContext, std::shared_ptr<Observed<ValueT>> const& obs, FunctionT&& onEvent)
{
return listen(eventContext, obs, std::function(std::move(onEvent)));
return listen(eventContext, obs, std::function(std::forward<FunctionT>(onEvent)));
}

template <typename ValueT, typename FunctionT>
void listen(std::shared_ptr<Observed<ValueT>> const& obs, FunctionT onEvent)
requires(
(std::invocable<FunctionT, ValueT const&> || std::invocable<FunctionT, ValueT>) &&
!Detail::IsStdFunction<FunctionT>::value)
void listen(std::shared_ptr<Observed<ValueT>> const& obs, FunctionT&& onEvent)
{
return listen(globalEventContext, obs, std::function(std::move(onEvent)));
return listen(globalEventContext, obs, std::function(std::forward<FunctionT>(onEvent)));
}

template <typename ValueT, typename FunctionT>
void listen(Observed<ValueT> const& obs, FunctionT onEvent)
requires(
(std::invocable<FunctionT, ValueT const&> || std::invocable<FunctionT, ValueT>) &&
!Detail::IsStdFunction<FunctionT>::value)
void listen(Observed<ValueT> const& obs, FunctionT&& onEvent)
{
return listen(globalEventContext, obs, std::function(std::move(onEvent)));
return listen(globalEventContext, obs, std::function(std::forward<FunctionT>(onEvent)));
}
}
4 changes: 2 additions & 2 deletions nui/include/nui/frontend/utility/val_conversion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ namespace Nui
template <typename T>
Nui::val convertToVal(std::map<std::string, T> const& map);
template <typename T>
Nui::val convertToVal(std::unique_ptr<T> const& map);
Nui::val convertToVal(std::unique_ptr<T> const& ptr);
template <typename T>
Nui::val convertToVal(std::shared_ptr<T> const& map);
Nui::val convertToVal(std::shared_ptr<T> const& ptr);
inline Nui::val convertToVal(long long)
{
throw std::runtime_error("Cannot convert long long to val");
Expand Down
2 changes: 1 addition & 1 deletion tools/inline_parser/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
include(GoogleTest)

find_package(Boost REQUIRED)
find_package(Boost CONFIG REQUIRED)

add_executable(inline_parser-tests
tests.cpp
Expand Down

0 comments on commit e761363

Please sign in to comment.