Skip to content

Commit

Permalink
Merge pull request #66 from NuiCpp/devel
Browse files Browse the repository at this point in the history
Serveral bug fixes.
  • Loading branch information
5cript authored Aug 29, 2023
2 parents 36e4cff + 3c9a439 commit 3f44dbe
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 31 deletions.
8 changes: 5 additions & 3 deletions nui/include/nui/backend/rpc_hub.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,14 @@ namespace Nui
template <typename T>
void registerFunction(std::string const& name, T&& func) const
{
using namespace std::string_literals;
// window is threadsafe
window_->bind(name, Detail::FunctionWrapper<T>::wrapFunction(std::forward<T>(func)));
}
void unregisterFunction(std::string const& name) const
{
// window is threadsafe
window_->unbind(name);
}

/**
* @brief Returns the attached window.
Expand Down Expand Up @@ -216,13 +220,11 @@ namespace Nui
private:
void callRemoteImpl(std::string const& name, nlohmann::json const& json) const
{
using namespace std::string_literals;
// window is threadsafe.
window_->eval(fmt::format(remoteCallScript, name, json.dump()));
}
void callRemoteImpl(std::string const& name) const
{
using namespace std::string_literals;
// window is threadsafe.
window_->eval(fmt::format(remoteCallScript0Args, name));
}
Expand Down
36 changes: 25 additions & 11 deletions nui/include/nui/frontend/utility/val_conversion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,18 +156,10 @@ namespace Nui
return result;
}

template <
typename T,
class Bases = boost::describe::describe_bases<T, boost::describe::mod_any_access>,
class Members = boost::describe::describe_members<T, boost::describe::mod_any_access>,
class Enable = std::enable_if_t<!std::is_union<T>::value>>
void convertFromVal(Nui::val const& val, T& obj)
template <typename T, class Members = boost::describe::describe_members<T, boost::describe::mod_any_access>>
requires(!std::is_union_v<T>)
void convertFromValObjImpl(Nui::val const& val, T& obj)
{
boost::mp11::mp_for_each<Bases>([&](auto&& base) {
using type = typename std::decay_t<decltype(base)>::type;
convertFromVal(val, static_cast<type&>(obj));
});

boost::mp11::mp_for_each<Members>([&](auto&& memAccessor) {
if (val.hasOwnProperty(memAccessor.name))
{
Expand All @@ -185,6 +177,28 @@ namespace Nui
}
});
}

template <typename T, class Members = boost::describe::describe_members<T, boost::describe::mod_any_access>>
requires(!std::is_union_v<T> && !boost::describe::has_describe_bases<T>::value)
void convertFromVal(Nui::val const& val, T& obj)
{
convertFromValObjImpl(val, obj);
}

template <
typename T,
class Bases = boost::describe::describe_bases<T, boost::describe::mod_any_access>,
class Members = boost::describe::describe_members<T, boost::describe::mod_any_access>>
requires(!std::is_union_v<T> && boost::describe::has_describe_bases<T>::value)
void convertFromVal(Nui::val const& val, T& obj)
{
boost::mp11::mp_for_each<Bases>([&](auto&& base) {
using type = typename std::decay_t<decltype(base)>::type;
convertFromVal(val, static_cast<type&>(obj));
});
convertFromValObjImpl(val, obj);
}

template <typename T>
requires Fundamental<T>
void convertFromVal(Nui::val const& val, T& value)
Expand Down
10 changes: 10 additions & 0 deletions nui/include/nui/window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@ namespace Nui
*/
void bind(std::string const& name, std::function<void(nlohmann::json const&)> const& callback);

/**
* @brief Unbind a function from the web context.
*
* @param name The name of the function.
*/
void unbind(std::string const& name);

boost::asio::any_io_executor getExecutor() const;

/**
Expand Down Expand Up @@ -225,6 +232,9 @@ namespace Nui
struct SchemeContext;
#endif

private:
void runInJavascriptThread(std::function<void()>&& func);

private:
struct Implementation;
std::shared_ptr<Implementation> impl_;
Expand Down
51 changes: 34 additions & 17 deletions nui/src/nui/backend/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#endif

#include <random>
#include <unordered_map>
#include <fstream>
#include <filesystem>
#include <iostream>
Expand Down Expand Up @@ -81,7 +82,7 @@ namespace Nui
{
webview::webview view;
std::vector<std::filesystem::path> cleanupFiles;
std::vector<std::function<void(nlohmann::json const&)>> callbacks;
std::unordered_map<std::string, std::function<void(nlohmann::json const&)>> callbacks;
boost::asio::thread_pool pool;
std::recursive_mutex viewGuard;
int width;
Expand Down Expand Up @@ -209,13 +210,7 @@ extern "C" {

void uriSchemeDestroyNotify(void* data)
{
auto* schemeContext = static_cast<Nui::Window::SchemeContext*>(data);
auto impl = schemeContext->impl.lock();
if (!impl)
return;

std::lock_guard lock{impl->schemeResponseRegistryGuard};
impl->schemeResponseRegistry.erase(schemeContext->id);
// Happens when everything else is already dead.
}
}
#endif
Expand Down Expand Up @@ -246,7 +241,7 @@ namespace Nui
impl_->view.install_message_hook([this](std::string const& msg) {
std::scoped_lock lock{impl_->viewGuard};
const auto obj = nlohmann::json::parse(msg);
impl_->callbacks[obj["id"].get<std::size_t>()](obj["args"]);
impl_->callbacks[obj["id"].get<std::string>()](obj["args"]);
return false;
});
// TODO: SetCustomSchemeRegistrations
Expand Down Expand Up @@ -421,14 +416,14 @@ namespace Nui
//---------------------------------------------------------------------------------------------------------------------
void Window::bind(std::string const& name, std::function<void(nlohmann::json const&)> const& callback)
{
auto bindImpl = [this, name, callback]() {
runInJavascriptThread([this, name, callback]() {
std::scoped_lock lock{impl_->viewGuard};
impl_->callbacks.push_back(callback);
impl_->callbacks[name] = callback;
auto script = fmt::format(
R"(
(() => {{
const name = "{}";
const id = {};
const id = "{}";
globalThis.nui_rpc = (globalThis.nui_rpc || {{
frontend: {{}}, backend: {{}}, tempId: 0
}});
Expand All @@ -442,23 +437,45 @@ namespace Nui
}})();
)",
name,
impl_->callbacks.size() - 1);
name);

impl_->view.init(script);
impl_->view.eval(script);
};
});
}
//--------------------------------------------------------------------------------------------------------------------
void Window::unbind(std::string const& name)
{
runInJavascriptThread([this, &name]() {
std::scoped_lock lock{impl_->viewGuard};
auto script = fmt::format(
R"(
(() => {{
const name = "{}";
delete globalThis.nui_rpc.backend[name];
}})();
)",
name);

impl_->callbacks.erase(name);
impl_->view.init(script);
impl_->view.eval(script);
});
}
//--------------------------------------------------------------------------------------------------------------------
void Window::runInJavascriptThread(std::function<void()>&& func)
{
std::scoped_lock lock{impl_->viewGuard};
#if defined(_WIN32)
if (GetCurrentThreadId() == impl_->windowThreadId)
bindImpl();
func();
else
{
impl_->toProcessOnWindowThread.push_back(bindImpl);
impl_->toProcessOnWindowThread.push_back(std::move(func));
PostThreadMessage(impl_->windowThreadId, wakeUpMessage, 0, 0);
}
#else
bindImpl();
func();
#endif
}
//--------------------------------------------------------------------------------------------------------------------
Expand Down

0 comments on commit 3f44dbe

Please sign in to comment.