Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graph Subscription Sync in Remote Service #1231

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion frontend/main/src/CLIConfigParsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,9 @@ std::vector<std::string> megamol::frontend::extract_config_file_paths(const int
}

// remove empty files: enables to start megamol without config file
std::remove_if(config_files.begin(), config_files.end(), [](auto const& file) { return file.empty(); });
config_files.erase(
std::remove_if(config_files.begin(), config_files.end(), [](auto const& file) { return file.empty(); }),
config_files.end());

// check remaining files exist
files_exist(config_files, "Config file");
Expand Down
116 changes: 110 additions & 6 deletions frontend/services/remote_service/Remote_Service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "GUIRegisterWindow.h" // register UI window for remote control
#include "HeadNode.hpp"
#include "MPI_Context.h"
#include "ModuleGraphSubscription.h"
#include "MpiNode.hpp"
#include "RenderNode.hpp"
#include "mmcore/MegaMolGraph.h"
Expand Down Expand Up @@ -116,10 +117,12 @@ bool Remote_Service::init(const Config& config) {

this->m_providedResourceReferences = {};

this->m_requestedResourcesNames = {"MegaMolGraph",
"ExecuteLuaScript" // std::function<std::tuple<bool,std::string>(std::string const&)>
,
"optional<GUIRegisterWindow>"};
this->m_requestedResourcesNames = {
"MegaMolGraph",
"ExecuteLuaScript", // std::function<std::tuple<bool,std::string>(std::string const&)>
"optional<GUIRegisterWindow>",
frontend_resources::MegaMolGraph_SubscriptionRegistry_Req_Name,
};

m_do_remote_things = std::function{[&]() {}};

Expand Down Expand Up @@ -196,11 +199,84 @@ const std::vector<std::string> Remote_Service::getRequestedResourceNames() const
void Remote_Service::setRequestedResources(std::vector<FrontendResource> resources) {
this->m_requestedResourceReferences = resources;

auto& graph_subscription_registry =
m_requestedResourceReferences[3].getResource<frontend_resources::MegaMolGraph_SubscriptionRegistry>();
subscribe_megamol_graph(
(void*)&const_cast<frontend_resources::MegaMolGraph_SubscriptionRegistry&>(graph_subscription_registry));

if (m_config.role == Role::HeadNode) {
remote_control_window();
}
}

void Remote_Service::subscribe_megamol_graph(void* registry) {
frontend_resources::ModuleGraphSubscription subscription("Remote_Service");

auto lua_cmd = [](std::string const& cmd, std::string const& args) -> std::string {
return cmd + "(" + args + ")";
};

auto cmd = [this, lua_cmd](std::string const& cmd, std::string const& args) {
this->m_headnode_remote_control.subscription_graph_commands += ("\n" + lua_cmd(cmd, args));
};

auto q = [](std::string const& str) { return std::string{"[=[" + str + "]=]"}; };

subscription.AddModule = [cmd, q](core::ModuleInstance_t const& module_inst) {
cmd("mmCreateModule", q(module_inst.request.className) + ", " + q(module_inst.request.id));
return true;
};
subscription.DeleteModule = [cmd, q](core::ModuleInstance_t const& module_inst) {
cmd("mmDeleteModule", q(module_inst.request.id));
return true;
};
subscription.RenameModule = [cmd, q](std::string const& old_name, std::string const& new_name,
core::ModuleInstance_t const& module_inst) {
cmd("mmRenameModule", q(old_name) + ", " + q(new_name));
return true;
};

subscription.AddParameters =
[&](std::vector<megamol::frontend_resources::ModuleGraphSubscription::ParamSlotPtr> const& param_slots) {
return true;
};
subscription.RemoveParameters =
[&](std::vector<megamol::frontend_resources::ModuleGraphSubscription::ParamSlotPtr> const& param_slots) {
return true;
};
subscription.ParameterChanged =
[cmd, q](megamol::frontend_resources::ModuleGraphSubscription::ParamSlotPtr const& param_slot,
std::string const& new_value) {
cmd("mmSetParamValue", q(std::string{param_slot->FullName().PeekBuffer()}) + ", " + q(new_value));
return true;
};

subscription.ParameterPresentationChanged =
[&](megamol::frontend_resources::ModuleGraphSubscription::ParamSlotPtr const& param_slot) { return true; };

subscription.AddCall = [cmd, q](core::CallInstance_t const& call_inst) {
cmd("mmCreateCall",
q(call_inst.request.className) + ", " + q(call_inst.request.from) + ", " + q(call_inst.request.to));
return true;
};
subscription.DeleteCall = [cmd, q](core::CallInstance_t const& call_inst) {
cmd("mmDeleteCall", q(call_inst.request.from) + ", " + q(call_inst.request.to));
return true;
};

subscription.EnableEntryPoint = [cmd, q](core::ModuleInstance_t const& module_inst) {
cmd("mmSetGraphEntryPoint", q(module_inst.request.id));
return true;
};
subscription.DisableEntryPoint = [cmd, q](core::ModuleInstance_t const& module_inst) {
cmd("mmRemoveGraphEntryPoint", q(module_inst.request.id));
return true;
};

auto& sub_registry = *reinterpret_cast<frontend_resources::MegaMolGraph_SubscriptionRegistry*>(registry);
sub_registry.subscribe(subscription);
}

void Remote_Service::updateProvidedResources() {}

void Remote_Service::digestChangedRequestedResources() {
Expand All @@ -220,6 +296,7 @@ void Remote_Service::postGraphRender() {}
void Remote_Service::do_headnode_things() {
auto& graph = m_requestedResourceReferences[0].getResource<megamol::core::MegaMolGraph>();

// one-time commands
for (auto command : m_headnode_remote_control.commands_queue)
switch (command) {
case HeadNodeRemoteControl::Command::ClearGraph:
Expand All @@ -234,8 +311,13 @@ void Remote_Service::do_headnode_things() {
default:
break;
}

m_headnode_remote_control.commands_queue.clear();

auto graph_changes = m_headnode_remote_control.sync_graph_subscription();
if (!graph_changes.empty())
head_send_message(graph_changes);

auto split_module_names = [&](std::string const& modules_list_string, auto& module_list) {
if (modules_list_string.empty())
return;
Expand Down Expand Up @@ -301,6 +383,19 @@ void Remote_Service::add_headnode_remote_command(HeadNodeRemoteControl::Command
case HeadNodeRemoteControl::Command::SendLuaCommand:
m_headnode_remote_control.lua_command = value;
break;
case HeadNodeRemoteControl::Command::SyncGraphChanges:
m_headnode_remote_control.sync_graph_subscription = [&]() {
auto r = m_headnode_remote_control.subscription_graph_commands;
m_headnode_remote_control.subscription_graph_commands.clear();
return std::move(r);
};
break;
case HeadNodeRemoteControl::Command::DontSyncGraphChanges:
m_headnode_remote_control.sync_graph_subscription = [this]() {
m_headnode_remote_control.subscription_graph_commands.clear();
return std::string{};
};
break;
default:
break;
}
Expand All @@ -322,6 +417,7 @@ void Remote_Service::remote_control_window() {
"Head Node Remote Control", [&](megamol::gui::AbstractWindow::BasicConfig& window_config) {
window_config.flags = ImGuiWindowFlags_AlwaysAutoResize;

static bool sync_graph_subscription = false;
static bool keep_sending_params = false;
static std::string param_send_modules = "all";
static std::string lua_command = "mmQuit()";
Expand Down Expand Up @@ -351,10 +447,17 @@ void Remote_Service::remote_control_window() {
keep_sending_params = false;
}

if (ImGui::RadioButton("Sync Graph Subscription", sync_graph_subscription)) {
sync_graph_subscription = !sync_graph_subscription;
add_headnode_remote_command(sync_graph_subscription
? HeadNodeRemoteControl::Command::SyncGraphChanges
: HeadNodeRemoteControl::Command::DontSyncGraphChanges);
}

if (ImGui::RadioButton("Sync Module Params", keep_sending_params)) {
keep_sending_params = !keep_sending_params;
keep_sending_params ? add_headnode_remote_command(HeadNodeRemoteControl::Command::KeepSendingParams)
: add_headnode_remote_command(HeadNodeRemoteControl::Command::DontSendParams);
add_headnode_remote_command(keep_sending_params ? HeadNodeRemoteControl::Command::KeepSendingParams
: HeadNodeRemoteControl::Command::DontSendParams);
}
ImGui::SameLine();
if (ImGui::InputText("Sync Modules", &param_send_modules, ImGuiInputTextFlags_EnterReturnsTrue)) {
Expand Down Expand Up @@ -432,6 +535,7 @@ void Remote_Service::execute_message(std::vector<char> const& message) {

if (!std::get<0>(result)) {
log_error("Error executing Lua: " + std::get<1>(result));
log_error("Error Script: " + commands_string);
}
}

Expand Down
10 changes: 10 additions & 0 deletions frontend/services/remote_service/Remote_Service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ class Remote_Service final : public AbstractFrontendService {
CloseHeadNode,
ClearGraph,
SendGraph,
SyncGraphChanges,
DontSyncGraphChanges,
KeepSendingParams,
DontSendParams,
SetParamSendingModules,
Expand All @@ -111,13 +113,21 @@ class Remote_Service final : public AbstractFrontendService {
std::string modules_to_send_params_of = "all";
std::string lua_command = "";

std::function<std::string()> sync_graph_subscription = [this]() {
this->subscription_graph_commands.clear();
return std::string{};
};
std::string subscription_graph_commands;

std::vector<Command> commands_queue;
};
HeadNodeRemoteControl m_headnode_remote_control;
void add_headnode_remote_command(HeadNodeRemoteControl::Command command, std::string const& value = "");
void remote_control_window();

bool start_headnode(bool start_or_shutdown = true);

void subscribe_megamol_graph(void* registry);
};

std::string handle_remote_session_config(
Expand Down
Loading