This commit is contained in:
lachrymaLF 2024-05-27 14:08:36 -04:00
parent 5f6adef565
commit 10ae63c763
4 changed files with 49 additions and 34 deletions

3
.gitmodules vendored
View file

@ -7,6 +7,3 @@
[submodule "Keishiki/ext/freetype"]
path = Keishiki/ext/freetype
url = https://github.com/freetype/freetype.git
[submodule "Keishiki/ext/ImNodeFlow"]
path = Keishiki/ext/ImNodeFlow
url = https://github.com/Fattorino/ImNodeFlow.git

View file

@ -19,7 +19,8 @@ namespace {
draw_plugboard = true,
draw_shader = true,
draw_comp = true,
draw_interpolation = true;
draw_interpolation = true,
draw_properties = true;
const f32 row_height = 20.0f;
@ -340,7 +341,7 @@ namespace K::UI {
}
void PlugboardNodeDrawSockets(PlugboardGraph::NodeInstance& n, ImGuiStyle& style,
bool& dragging_on_socket, ImVec2& source, std::unordered_map<PlugboardGraph::ConnectInfo, ImVec4, PlugboardGraph::_ConnectInfoHasher>& link_pos,
bool& dragging_on_socket, ImVec2& source, std::unordered_map<PlugboardGraph::ConnectInfo, PlugboardGraph::LinksFromSource, PlugboardGraph::_ConnectInfoHasher>& link_pos,
bool dummy = true) {
i32 row = 1;
for (u32 out = 0; out < n.node->out_names.size(); out++, row++) {
@ -374,12 +375,13 @@ namespace K::UI {
ImGui::PopID();
// Update link info if needed
if (n.outputs_going[out].p != nullptr) {
auto pos = ImGui::GetCursorScreenPos() + ImVec2{ ImGui::GetFrameHeight() / 2, -ImGui::GetFrameHeight() / 2 - style.ItemInnerSpacing.y};
auto& d = link_pos[std::get<PlugboardGraph::ConnectInfo>(n.outputs_going[out].p->inputs_fed[n.outputs_going[out].index])];
d.w = pos.x;
d.z = pos.y;
}
if (n.outputs_going[out].p != nullptr)
std::visit([&link_pos, &style](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, PlugboardGraph::ConnectInfo>)
link_pos[arg].source = ImGui::GetCursorScreenPos() + ImVec2{ ImGui::GetFrameHeight() / 2, -ImGui::GetFrameHeight() / 2 - style.ItemInnerSpacing.y};
}, n.outputs_going[out].p->inputs_fed[n.outputs_going[out].index]);
}
for (u32 in = 0; in < n.inputs_fed.size(); in++, row++) {
ImGui::PushID(row);
@ -405,12 +407,11 @@ namespace K::UI {
}
// Update link info if needed
if (n.inputs_fed[in].index() == 0) {
auto pos = ImGui::GetCursorScreenPos() + ImVec2{ ImGui::GetFrameHeight() / 2, -ImGui::GetFrameHeight() / 2 - style.ItemInnerSpacing.y};
auto& d = link_pos[std::get<PlugboardGraph::ConnectInfo>(n.inputs_fed[in])];
d.x = pos.x;
d.y = pos.y;
}
std::visit([&link_pos, &style](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, PlugboardGraph::ConnectInfo>)
link_pos[arg].sinks.push_back(ImGui::GetCursorScreenPos() + ImVec2{ ImGui::GetFrameHeight() / 2, -ImGui::GetFrameHeight() / 2 - style.ItemInnerSpacing.y});
}, n.inputs_fed[in]);
ImGui::TableNextColumn();
ImGui::Text("%s", n.node->in_names[in].c_str());
@ -421,10 +422,10 @@ namespace K::UI {
}
void PlugboardDrawNode(PlugboardGraph::NodeInstance& n, ImVec2& view_pos, i32 id, ImGuiIO& io, ImGuiStyle& style,
bool& dragging_on_socket, ImVec2& source, std::unordered_map<PlugboardGraph::ConnectInfo, ImVec4, PlugboardGraph::_ConnectInfoHasher>& link_pos) {
bool& dragging_on_socket, ImVec2& source, std::unordered_map<PlugboardGraph::ConnectInfo, PlugboardGraph::LinksFromSource, PlugboardGraph::_ConnectInfoHasher>& link_pos) {
ImGui::SetCursorPos(view_pos + n.pos);
ImGui::PushID(id);
ImGui::PushStyleColor(ImGuiCol_ChildBg, 0xFF080813);
ImGui::PushStyleColor(ImGuiCol_ChildBg, 0xAA080813);
ImGui::BeginChild(n.node->name.c_str(), {}, ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_Border);
ImGui::PopStyleColor();
if (ImGui::BeginTable(n.node->name.c_str(), 3)) {
@ -498,8 +499,9 @@ namespace K::UI {
view_pos = old_view_pos + (io.MousePos - io.MouseClickedPos[0]);
}
for (u32 i = 0; i < s.plugboard.nodes.size(); i++)
PlugboardDrawNode(s.plugboard.nodes[i], view_pos, i, io, style, dragging_on_socket, drag_source, s.plugboard.links_pos);
u32 i = 0;
for (auto it = s.plugboard.nodes.begin(); it != s.plugboard.nodes.end(); it++, i++)
PlugboardDrawNode(*it, view_pos, i, io, style, dragging_on_socket, drag_source, s.plugboard.links_pos);
ImGui::SetCursorPos({});
ImGui::PushStyleColor(ImGuiCol_ChildBg, 0x33FFFFFF);
@ -526,7 +528,8 @@ namespace K::UI {
right_offset += ImGui::GetItemRectMax().x - ImGui::GetWindowWidth();
for (auto& [_, link] : s.plugboard.links_pos)
window->DrawList->AddLine({link.x, link.y}, {link.w, link.z}, 0xFFFFFFFF, 2.0f);
for (auto& sink : link.sinks)
window->DrawList->AddLine(link.source, sink, 0xFFFFFFFF, 2.0f);
if (dragging_on_socket)
window->DrawList->AddLine(ImGui::GetMousePos(), drag_source, 0xFFFFFFFF, 2.0f);
@ -585,7 +588,7 @@ namespace K::UI {
it->second.exposure = {&s.plugboard.out_instance, static_cast<u32>(s.plugboard.out_instance.node->in_names.size())};
s.plugboard.out_instance.node->in_names.push_back(id);
s.plugboard.out_instance.node->in_types.push_back(PlugboardGraph::Type(it->second.val.index())); // this is shaky and bug prone -- relies on the shader types being in line with plugboard types
s.plugboard.out_instance.inputs_fed.push_back(ShaderValToPlugboard(it->second.val));
s.plugboard.out_instance.inputs_fed.emplace_back(ShaderValToPlugboard(it->second.val));
}
else {
it->second.exposure.p->disconnect(it->second.exposure.index);
@ -639,6 +642,14 @@ namespace K::UI {
void Interpolation(CompState& s) {
if (ImGui::Begin("Interpolation", &draw_interpolation)) {
}
ImGui::End();
}
void Properties(CompState& s) {
if (ImGui::Begin("Properties", &draw_properties)) {
}
ImGui::End();
}
@ -650,7 +661,7 @@ namespace K::UI {
ImGui::DockSpaceOverViewport(ImGui::GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);
// ImGui::ShowDemoWindow();
ImGui::ShowDemoWindow();
static ImGuiStyle& style = ImGui::GetStyle();
style.GrabRounding = style.FrameRounding = 5.0f;
MainMenuBar(s);
@ -659,6 +670,7 @@ namespace K::UI {
if (draw_plugboard) Plugboard(s);
if (draw_comp) Composition(s);
if (draw_interpolation) Interpolation(s);
if (draw_properties) Properties(s);
if (save_called && ready_frame == frame) {
stbi_write_png("frame.png", s.width, s.height, 4, save_buffer, s.width * 4);

@ -1 +0,0 @@
Subproject commit 3e4ed6e5b51cc9a874480b94f112d5965b0412b0

View file

@ -4,6 +4,7 @@
#include <variant>
#include <functional>
#include <imgui.h>
#include <list>
namespace K::PlugboardGraph {
enum Type {
@ -72,7 +73,8 @@ namespace K::PlugboardGraph {
struct NodeInstance;
struct ConnectInfo {
NodeInstance *p; u32 index;
NodeInstance *p; // NOTE: so NodeInstances must be stored in a list, otherwise vector realloc leads to UAF
u32 index;
auto operator<=>(const ConnectInfo&) const = default;
};
@ -85,9 +87,9 @@ namespace K::PlugboardGraph {
};
struct NodeInstance {
Node *node;
Node *node; // should be safe if we require those to be static, UAF might pop up later
Vector<std::variant<ConnectInfo, T_Map<Type::T_Count>::type>> inputs_fed;
Vector<std::variant<T_Map<Type::T_Count>::type, ConnectInfo>> inputs_fed;
Vector<ConnectInfo> outputs_going;
ImVec2 pos, old_pos;
@ -111,10 +113,10 @@ namespace K::PlugboardGraph {
inline NodeInstance MakeInstance(Node& n) {
Vector<std::variant<ConnectInfo, T_Map<Type::T_Count>::type>> inp;
Vector<std::variant<T_Map<Type::T_Count>::type, ConnectInfo>> inp;
Vector<ConnectInfo> out;
for (auto t : n.in_types)
inp.push_back(expand_type(t));
inp.emplace_back(expand_type(t));
for (auto t : n.out_types)
out.push_back({});
return {
@ -137,16 +139,21 @@ namespace K::PlugboardGraph {
return info.p->node->fetch[info.index](pack);
}
struct LinksFromSource {
ImVec2 source;
Vector<ImVec2> sinks;
};
struct PlugboardGraph {
Vector<NodeInstance> nodes;
std::unordered_map<ConnectInfo, ImVec4, _ConnectInfoHasher> links_pos; // this is hilariously bad
std::list<NodeInstance> nodes; // OK complexity wise since we would usually traverse the entire thing anyway, locality will likely be bad
std::unordered_map<ConnectInfo, LinksFromSource, _ConnectInfoHasher> links_pos; // this is hilariously bad
Node comp_in = {
"Composition In",
{},
{},
{"Time"},
{T_Float},
{[](Vector<T_Map<T_Count>::type> v) { return T_Map<T_Count>::type{ static_cast<f32>(SDL_GetTicks()) / 20.0f }; }} // kill me
{[](const Vector<T_Map<T_Count>::type>& v) { return T_Map<T_Count>::type{ static_cast<f32>(SDL_GetTicks()) / 20.0f }; }} // kill me
},
comp_out = {
"Composition Out",