mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-05-25 06:59:08 -05:00
impr: Run data processor in a worker task
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <imnodes_internal.h>
|
||||
|
||||
#include <string>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
@@ -17,6 +18,8 @@ namespace hex::plugin::builtin {
|
||||
struct Workspace {
|
||||
Workspace() = default;
|
||||
|
||||
|
||||
|
||||
std::unique_ptr<ImNodesContext, void(*)(ImNodesContext*)> context = { []{
|
||||
ImNodesContext *ctx = ImNodes::CreateContext();
|
||||
ctx->Style = ImNodes::GetStyle();
|
||||
@@ -47,7 +50,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
static void eraseLink(Workspace &workspace, int id);
|
||||
static void eraseNodes(Workspace &workspace, const std::vector<int> &ids);
|
||||
static void processNodes(Workspace &workspace);
|
||||
void processNodes(Workspace &workspace);
|
||||
|
||||
void reloadCustomNodes();
|
||||
void updateNodePositions();
|
||||
@@ -74,6 +77,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
PerProvider<Workspace> m_mainWorkspace;
|
||||
PerProvider<std::vector<Workspace*>> m_workspaceStack;
|
||||
TaskHolder m_evaluationTask;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -138,6 +138,10 @@ namespace hex::plugin::builtin {
|
||||
this->setIntegerOnOutput(4, m_value);
|
||||
}
|
||||
|
||||
void reset() override {
|
||||
m_started = false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_started = false;
|
||||
i128 m_value = 0;
|
||||
|
||||
@@ -28,10 +28,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void process() override {
|
||||
m_value.reset();
|
||||
const auto &input = this->getIntegerOnInput(0);
|
||||
|
||||
m_value = input;
|
||||
m_value = this->getIntegerOnInput(0);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -390,10 +390,6 @@ namespace hex::plugin::builtin {
|
||||
m_updateNodePositions = true;
|
||||
});
|
||||
|
||||
EventDataChanged::subscribe(this, [this](prv::Provider *provider) {
|
||||
ViewDataProcessor::processNodes(*m_workspaceStack.get(provider).back());
|
||||
});
|
||||
|
||||
/* Import Nodes */
|
||||
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.data_processor" }, ICON_VS_CHIP, 4050, Shortcut::None, [this]{
|
||||
fs::openFileBrowser(fs::DialogMode::Open, { {"hex.builtin.view.data_processor.name"_lang, "hexnode" } },
|
||||
@@ -532,36 +528,49 @@ namespace hex::plugin::builtin {
|
||||
// Reset any potential node errors
|
||||
workspace.currNodeError.reset();
|
||||
|
||||
// Process all nodes in the workspace
|
||||
try {
|
||||
for (auto &endNode : workspace.endNodes) {
|
||||
// Reset the output data of the end node
|
||||
endNode->resetOutputData();
|
||||
m_evaluationTask = TaskManager::createTask("Evaluating Nodes...", 0, [this, workspace = &workspace](Task& task) {
|
||||
task.setInterruptCallback([]{
|
||||
dp::Node::interrupt();
|
||||
});
|
||||
do {
|
||||
|
||||
// Reset processed inputs of all nodes
|
||||
for (auto &node : workspace.nodes)
|
||||
node->resetProcessedInputs();
|
||||
// Process all nodes in the workspace
|
||||
try {
|
||||
for (auto &endNode : workspace->endNodes) {
|
||||
// Reset the output data of the end node
|
||||
endNode->resetOutputData();
|
||||
|
||||
// Process the end node
|
||||
endNode->process();
|
||||
}
|
||||
} catch (const dp::Node::NodeError &e) {
|
||||
// Handle user errors
|
||||
// Reset processed inputs of all nodes
|
||||
for (auto &node : workspace->nodes) {
|
||||
node->reset();
|
||||
node->resetProcessedInputs();
|
||||
}
|
||||
|
||||
// Add the node error to the current workspace, so it can be displayed
|
||||
workspace.currNodeError = e;
|
||||
// Process the end node
|
||||
endNode->process();
|
||||
}
|
||||
} catch (const dp::Node::NodeError &e) {
|
||||
// Handle user errors
|
||||
|
||||
// Add the node error to the current workspace, so it can be displayed
|
||||
workspace->currNodeError = e;
|
||||
|
||||
// Delete all overlays
|
||||
for (auto overlay : workspace->dataOverlays)
|
||||
ImHexApi::Provider::get()->deleteOverlay(overlay);
|
||||
workspace->dataOverlays.clear();
|
||||
} catch (const std::runtime_error &e) {
|
||||
// Handle internal errors
|
||||
log::fatal("Data processor node implementation bug! {}", e.what());
|
||||
} catch (const std::exception &e) {
|
||||
// Handle other fatal errors
|
||||
log::fatal("Unhandled exception thrown in data processor node! {}", e.what());
|
||||
}
|
||||
|
||||
task.update();
|
||||
} while (m_continuousEvaluation);
|
||||
});
|
||||
|
||||
// Delete all overlays
|
||||
for (auto overlay : workspace.dataOverlays)
|
||||
ImHexApi::Provider::get()->deleteOverlay(overlay);
|
||||
workspace.dataOverlays.clear();
|
||||
} catch (const std::runtime_error &e) {
|
||||
// Handle internal errors
|
||||
log::fatal("Data processor node implementation bug! {}", e.what());
|
||||
} catch (const std::exception &e) {
|
||||
// Handle other fatal errors
|
||||
log::fatal("Unhandled exception thrown in data processor node! {}", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void ViewDataProcessor::reloadCustomNodes() {
|
||||
@@ -774,7 +783,9 @@ namespace hex::plugin::builtin {
|
||||
|
||||
// Draw the node's body
|
||||
ImGui::PopStyleVar();
|
||||
node.drawNode();
|
||||
if (!m_evaluationTask.isRunning()) {
|
||||
node.draw();
|
||||
}
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(1.0F, 1.0F));
|
||||
|
||||
// Draw all attributes of the node
|
||||
@@ -851,6 +862,8 @@ namespace hex::plugin::builtin {
|
||||
void ViewDataProcessor::drawContent() {
|
||||
auto &workspace = *m_workspaceStack->back();
|
||||
|
||||
ImGui::BeginDisabled(m_evaluationTask.isRunning());
|
||||
|
||||
bool popWorkspace = false;
|
||||
// Set the ImNodes context to the current workspace context
|
||||
ImNodes::SetCurrentContext(workspace.context.get());
|
||||
@@ -873,6 +886,9 @@ namespace hex::plugin::builtin {
|
||||
if (ImGui::BeginChild("##node_editor", ImGui::GetContentRegionAvail() - ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * 1.3F))) {
|
||||
ImNodes::BeginNodeEditor();
|
||||
|
||||
if (m_evaluationTask.isRunning())
|
||||
ImNodes::GetCurrentContext()->MousePos = { FLT_MAX, FLT_MAX };
|
||||
|
||||
// Loop over all nodes that have been placed in the workspace
|
||||
bool stillUpdating = m_updateNodePositions;
|
||||
for (auto &node : workspace.nodes) {
|
||||
@@ -933,10 +949,19 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
// Draw the control bar at the bottom
|
||||
{
|
||||
if (ImGuiExt::IconButton(ICON_VS_DEBUG_START, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen)) || m_continuousEvaluation)
|
||||
this->processNodes(workspace);
|
||||
if (!m_evaluationTask.isRunning()) {
|
||||
if (ImGuiExt::IconButton(ICON_VS_DEBUG_START, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen))) {
|
||||
this->processNodes(workspace);
|
||||
}
|
||||
} else {
|
||||
if (ImGuiExt::IconButton(ICON_VS_DEBUG_STOP, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) {
|
||||
m_evaluationTask.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
@@ -944,7 +969,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
|
||||
// Erase links that have been distroyed
|
||||
// Erase links that have been destroyed
|
||||
{
|
||||
int linkId;
|
||||
if (ImNodes::IsLinkDestroyed(&linkId)) {
|
||||
|
||||
Reference in New Issue
Block a user