-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
263 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
#pragma once | ||
#include <imgui_node_editor.h> | ||
#include "Microservice/Workflow.hpp" | ||
namespace ed = ax::NodeEditor; | ||
|
||
struct NodeEditor | ||
{ | ||
// Struct to hold basic information about connection between | ||
// pins. Note that connection (aka. link) has its own ID. | ||
// This is useful later with dealing with selections, deletion | ||
// or other operations. | ||
struct LinkInfo | ||
{ | ||
ed::LinkId Id; | ||
ed::PinId InputId; | ||
ed::PinId OutputId; | ||
}; | ||
|
||
ed::EditorContext* m_Context = nullptr; // Editor context, required to trace a editor state. | ||
bool m_FirstFrame = true; // Flag set for first frame only, some action need to be executed once. | ||
ImVector<LinkInfo> m_Links; // List of live links. It is dynamic unless you want to create read-only view over nodes. | ||
int m_NextLinkId = 100; // Counter to help generate link ids. In real application this will probably based on pointer to user data structure. | ||
Workflow m_Workflow; | ||
|
||
void OnStart() | ||
{ | ||
ed::Config config; | ||
config.SettingsFile = "BasicInteraction.json"; | ||
m_Context = ed::CreateEditor(&config); | ||
m_Workflow.TestInitialize(); | ||
} | ||
|
||
void OnStop() { ed::DestroyEditor(m_Context); } | ||
|
||
void ImGuiEx_BeginColumn() { ImGui::BeginGroup(); } | ||
|
||
void ImGuiEx_NextColumn() | ||
{ | ||
ImGui::EndGroup(); | ||
ImGui::SameLine(); | ||
ImGui::BeginGroup(); | ||
} | ||
|
||
void ImGuiEx_EndColumn() { ImGui::EndGroup(); } | ||
|
||
void DrawNode(Microservice& microservice) | ||
{ | ||
usize id = microservice.GetId(); | ||
ed::BeginNode(id); | ||
ImGui::Text(microservice.GetName().c_str()); | ||
|
||
ImGuiEx_BeginColumn(); | ||
for (const auto& [name, param] : microservice.GetInputParameters()) | ||
{ | ||
ed::BeginPin(++id, ed::PinKind::Input); | ||
ImGui::Text(fmt::format("-> {}", name).c_str()); | ||
ed::EndPin(); | ||
} | ||
|
||
ImGuiEx_NextColumn(); | ||
for (const auto& [name, param] : microservice.GetOutputParameters()) | ||
{ | ||
ed::BeginPin(++id, ed::PinKind::Input); | ||
ImGui::Text(fmt::format("{} ->", name).c_str()); | ||
ed::EndPin(); | ||
} | ||
|
||
ImGuiEx_EndColumn(); | ||
ed::EndNode(); | ||
} | ||
|
||
void OnFrame() | ||
{ | ||
auto& io = ImGui::GetIO(); | ||
ImGui::Separator(); | ||
|
||
ed::SetCurrentEditor(m_Context); | ||
|
||
// Start interaction with editor. | ||
ed::Begin("Microservice Editor", ImVec2(0.0, 0.0f)); | ||
|
||
for (const auto& microservice : m_Workflow.GetMicroservices()) | ||
DrawNode(*microservice); | ||
|
||
// for (const auto& connection : m_Workflow.GetMicroserviceConnections()) | ||
// ed::Link(linkInfo.Id, linkInfo.InputId, linkInfo.OutputId); | ||
|
||
// Submit Links | ||
for (auto& linkInfo : m_Links) | ||
ed::Link(linkInfo.Id, linkInfo.InputId, linkInfo.OutputId); | ||
|
||
// | ||
// 2) Handle interactions | ||
// | ||
|
||
// Handle creation action, returns true if editor want to create new object (node or link) | ||
if (ed::BeginCreate()) | ||
{ | ||
ed::PinId inputPinId, outputPinId; | ||
if (ed::QueryNewLink(&inputPinId, &outputPinId)) | ||
{ | ||
// QueryNewLink returns true if editor want to create new link between pins. | ||
// | ||
// Link can be created only for two valid pins, it is up to you to | ||
// validate if connection make sense. Editor is happy to make any. | ||
// | ||
// Link always goes from input to output. User may choose to drag | ||
// link from output pin or input pin. This determine which pin ids | ||
// are valid and which are not: | ||
// * input valid, output invalid - user started to drag new link from input pin | ||
// * input invalid, output valid - user started to drag new link from output pin | ||
// * input valid, output valid - user dragged link over other pin, can be validated | ||
|
||
if (inputPinId && outputPinId) // both are valid, let's accept link | ||
{ | ||
// ed::AcceptNewItem() return true when user release mouse button. | ||
if (ed::AcceptNewItem()) | ||
{ | ||
// Since we accepted new link, lets add one to our list of links. | ||
m_Links.push_back({ed::LinkId(m_NextLinkId++), inputPinId, outputPinId}); | ||
|
||
// Draw new link. | ||
ed::Link(m_Links.back().Id, m_Links.back().InputId, m_Links.back().OutputId); | ||
} | ||
|
||
// You may choose to reject connection between these nodes | ||
// by calling ed::RejectNewItem(). This will allow editor to give | ||
// visual feedback by changing link thickness and color. | ||
} | ||
} | ||
} | ||
ed::EndCreate(); // Wraps up object creation action handling. | ||
|
||
// Handle deletion action | ||
if (ed::BeginDelete()) | ||
{ | ||
// There may be many links marked for deletion, let's loop over them. | ||
ed::LinkId deletedLinkId; | ||
while (ed::QueryDeletedLink(&deletedLinkId)) | ||
{ | ||
// If you agree that link can be deleted, accept deletion. | ||
if (ed::AcceptDeletedItem()) | ||
{ | ||
// Then remove link from your data. | ||
for (auto& link : m_Links) | ||
{ | ||
if (link.Id == deletedLinkId) | ||
{ | ||
m_Links.erase(&link); | ||
break; | ||
} | ||
} | ||
} | ||
|
||
// You may reject link deletion by calling: | ||
// ed::RejectDeletedItem(); | ||
} | ||
} | ||
ed::EndDelete(); // Wrap up deletion action | ||
|
||
// End of interaction with editor. | ||
ed::End(); | ||
|
||
if (m_FirstFrame) | ||
ed::NavigateToContent(0.0f); | ||
|
||
ed::SetCurrentEditor(nullptr); | ||
|
||
m_FirstFrame = false; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.