Skip to content
15 changes: 11 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
cmake_minimum_required(VERSION 3.10)

set(BUILD_TYPE "Debug and Release" CACHE STRING "Choose Build type")
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CONFIGURATION_TYPES Debug Release)

# set the project name
Expand Down Expand Up @@ -103,7 +102,6 @@ set(VariablesNodes_SOURCE_FILES)
set(ControlFlowNodes_SOURCE_FILES)

if(VISUAL_NODE_SYSTEM_BUILD_EXECUTION_FLOW_NODES)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /DVISUAL_NODE_SYSTEM_BUILD_EXECUTION_FLOW_NODES")

# *************** EXECUTION_FLOW_NODES ***************
list(APPEND BaseExecutionFlowNodes_SOURCE_FILES
Expand Down Expand Up @@ -181,6 +179,8 @@ if(VISUAL_NODE_SYSTEM_BUILD_EXECUTION_FLOW_NODES)
"StandardNodes/ExecutionFlowNodes/LiteralsNodes/IntegerLiteralNode.h"
"StandardNodes/ExecutionFlowNodes/LiteralsNodes/IntegerLiteralNode.cpp"

"StandardNodes/ExecutionFlowNodes/LiteralsNodes/UnsignedLiteralNode.cpp"

"StandardNodes/ExecutionFlowNodes/LiteralsNodes/FloatLiteralNode.h"
"StandardNodes/ExecutionFlowNodes/LiteralsNodes/FloatLiteralNode.cpp"

Expand Down Expand Up @@ -210,6 +210,8 @@ if(VISUAL_NODE_SYSTEM_BUILD_EXECUTION_FLOW_NODES)
"StandardNodes/ExecutionFlowNodes/VariablesNodes/IntegerVariableNode.h"
"StandardNodes/ExecutionFlowNodes/VariablesNodes/IntegerVariableNode.cpp"

"StandardNodes/ExecutionFlowNodes/VariablesNodes/UnsignedVariableNode.cpp"

"StandardNodes/ExecutionFlowNodes/VariablesNodes/FloatVariableNode.h"
"StandardNodes/ExecutionFlowNodes/VariablesNodes/FloatVariableNode.cpp"

Expand Down Expand Up @@ -282,7 +284,10 @@ else()
add_library(VisualNodeSystem STATIC ${ALL_SOURCE_FILES})
endif()

target_include_directories(VisualNodeSystem PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/jsoncpp)
if(VISUAL_NODE_SYSTEM_BUILD_EXECUTION_FLOW_NODES)
#NOTE use cross platform method to set compile definitions
target_compile_definitions(VisualNodeSystem PRIVATE VISUAL_NODE_SYSTEM_BUILD_EXECUTION_FLOW_NODES)
endif()

source_group("Source Files" FILES ${VisualNodeSystem_SRC})
source_group("Source Files/SubSystems/VisualNodeArea/" FILES ${VisualNodeArea_SRC})
Expand All @@ -303,6 +308,7 @@ endif()
source_group("Source Files/ThirdParty/jsoncpp" FILES ${jsoncpp_SRC})

set(VISUAL_NODE_SYSTEM_THIRDPARTY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty)
set(VISUAL_NODE_SYSTEM_THIRDPARTY_JSONCPP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/jsoncpp)

# set the startup project
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT VisualNodeSystem)
Expand Down Expand Up @@ -338,6 +344,7 @@ endif()
include_directories(
${DEAR_IMGUI_INCLUDE_DIR}
${VISUAL_NODE_SYSTEM_THIRDPARTY_DIR}
${VISUAL_NODE_SYSTEM_THIRDPARTY_JSONCPP_DIR}
)

set(VISUAL_NODE_SYSTEM_THIRDPARTY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty PARENT_SCOPE)
Expand All @@ -355,4 +362,4 @@ add_custom_target(VisualNodeSystemPreBuild
${CMAKE_CURRENT_SOURCE_DIR}/VersionInfo/VISUAL_NODE_SYSTEM_Version.h
)

add_dependencies(VisualNodeSystem VisualNodeSystemPreBuild)
add_dependencies(VisualNodeSystem VisualNodeSystemPreBuild)
116 changes: 116 additions & 0 deletions StandardNodes/ExecutionFlowNodes/LiteralsNodes/UnsignedLiteralNode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#include "UnsignedLiteralNode.h"
#include "imgui.h"
using namespace VisNodeSys;

UnsignedLiteralNode::UnsignedLiteralNode() : VisNodeSys::Node()
{
Type = "UnsignedLiteralNode";

SetStyle(DEFAULT);
SetName("Unsigned Literal");

TitleBackgroundColor = ImColor(30, 221, 170);
TitleBackgroundColorHovered = ImColor(139, 235, 199);

AddSocket(new NodeSocket(this, "UINT", "Out", NodeSocket::SocketFlow::Output));

SetSize(ImVec2(170, NODE_HEIGHT_PER_SOCKET * 2));
if (!Output.empty())
{
Output[0]->SetFunctionToOutputData(UIntDataGetter);
Output[0]->SetCanBeDeletedByUser(false);
}
}

UnsignedLiteralNode::UnsignedLiteralNode(const UnsignedLiteralNode& Other) : VisNodeSys::Node(Other)
{
SetStyle(DEFAULT);
Data = Other.Data;

// Here I am restoring the output data function.
// Because the function is not serializable, I have to set it manually.
if (!Output.empty())
Output[0]->SetFunctionToOutputData(UIntDataGetter);
}

Json::Value UnsignedLiteralNode::ToJson()
{
Json::Value Result = Node::ToJson();
Result["Value"] = Data;
return Result;
}

bool UnsignedLiteralNode::FromJson(Json::Value Json)
{
bool bResult = Node::FromJson(Json);
if (!bResult)
return false;

if (!Json.isMember("Value"))
return false;

if (!Json["Value"].isUInt())
return false;

Data = Json["Value"].asUInt();

// Here I am restoring the output data function.
// Because the function is not serializable, I have to set it manually.
if (Output.size() < 1)
return false;

if (Output[0] == nullptr)
return false;

Output[0]->SetFunctionToOutputData(UIntDataGetter);

return true;
}

void UnsignedLiteralNode::Draw()
{
Node::Draw();

float Zoom = ParentArea->GetZoomFactor();

ImGui::SetCursorScreenPos(ImVec2(ImGui::GetCursorScreenPos().x + 30.0f * Zoom, ImGui::GetCursorScreenPos().y + 45.0f * Zoom));

float XPosition = ImGui::GetCursorScreenPos().x - 17.0f * Zoom;
float YPosition = ImGui::GetCursorScreenPos().y + 0.0f * Zoom;

ImGui::SetCursorScreenPos(ImVec2(XPosition, YPosition));
ImGui::SetNextItemWidth(100 * Zoom);
if (ImGui::InputScalar("##value", ImGuiDataType_U64, &Data))
{
if (Output.size() > 0)
{
for (size_t i = 0; i < Output[0]->GetConnectedSockets().size(); ++i)
{
ParentArea->TriggerSocketEvent(Output[0], Output[0]->GetConnectedSockets()[i], UPDATE);
}
}
}
}

void UnsignedLiteralNode::SocketEvent(NodeSocket* OwnSocket, NodeSocket* ConnectedSocket, NODE_SOCKET_EVENT EventType)
{
Node::SocketEvent(OwnSocket, ConnectedSocket, EventType);
}

bool UnsignedLiteralNode::CanConnect(NodeSocket* OwnSocket, NodeSocket* CandidateSocket, char** MsgToUser)
{
if (!Node::CanConnect(OwnSocket, CandidateSocket, nullptr))
return false;

return true;
}

unsigned int UnsignedLiteralNode::GetData() const
{
return Data;
}

void UnsignedLiteralNode::SetData(unsigned int NewData)
{
Data = NewData;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include "../../../VisualNodeSystem.h"

class UnsignedLiteralNode : public VisNodeSys::Node
{
bool CanConnect(VisNodeSys::NodeSocket* OwnSocket, VisNodeSys::NodeSocket* CandidateSocket, char** MsgToUser);
void SocketEvent(VisNodeSys::NodeSocket* OwnSocket, VisNodeSys::NodeSocket* ConnectedSocket, VisNodeSys::NODE_SOCKET_EVENT EventType);

uint64_t Data = 0;

std::function<void* ()> UIntDataGetter = [this]() -> void* {
return &Data;
};

public:
UnsignedLiteralNode();
UnsignedLiteralNode(const UnsignedLiteralNode& Other);

Json::Value ToJson();
bool FromJson(Json::Value Json);

unsigned int GetData() const;
void SetData(unsigned int NewValue);

void Draw();
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
#include "../../../../SubSystems/VisualNodeArea/VisualNodeArea.h"
using namespace VisNodeSys;

BaseArithmeticOperatorNode::BaseArithmeticOperatorNode(std::vector<std::string> AllowedTypes) : BaseExecutionFlowNode()
BaseArithmeticOperatorNode::BaseArithmeticOperatorNode(
std::vector<std::string> AllowedTypes
) : BaseExecutionFlowNode(),
DefaultAllowedTypes(AllowedTypes)
{
Type = "BaseArithmeticOperatorNode";

Expand Down Expand Up @@ -113,13 +116,54 @@ std::string BaseArithmeticOperatorNode::GetActiveINDataType()
void BaseArithmeticOperatorNode::SocketEvent(NodeSocket* OwnSocket, NodeSocket* ConnectedSocket, NODE_SOCKET_EVENT EventType)
{
Node::SocketEvent(OwnSocket, ConnectedSocket, EventType);

if (EventType == EXECUTE)
{
Execute();

if (Output.size() > 0 && Output[0]->GetConnectedSockets().size() > 0)
ParentArea->TriggerSocketEvent(Output[0], Output[0]->GetConnectedSockets()[0], EXECUTE);
if (OwnSocket->GetFlowDirection() == VisNodeSys::NodeSocket::SocketFlow::Input) {
switch (EventType) {
case VisNodeSys::CONNECTED: {
// socket is connected
Execute();
if (Output.size() > 1) {
for (size_t i = 0; i < Output[1]->GetConnectedSockets().size(); ++i) {
ParentArea->TriggerSocketEvent(Output[1], Output[1]->GetConnectedSockets()[i], UPDATE);
}
}
break;
}
case VisNodeSys::DISCONNECTED: {
// socket is disconnected
Execute();
if (Input[0]->GetConnectedSockets().empty() && Input[1]->GetConnectedSockets().empty()) {
Output[1]->SetAllowedTypes(DefaultAllowedTypes);
}
if (Output.size() > 1) {
for (size_t i = 0; i < Output[1]->GetConnectedSockets().size(); ++i) {
ParentArea->TriggerSocketEvent(Output[1], Output[1]->GetConnectedSockets()[i], UPDATE);
}
}
break;
}
case VisNodeSys::DESTRUCTION:
// when connected node is destroyed (probably should just disconnect...)
break;
case VisNodeSys::UPDATE:
// when connected node is updated
Execute();
if (Output.size() > 1) {
for (size_t i = 0; i < Output[1]->GetConnectedSockets().size(); ++i) {
ParentArea->TriggerSocketEvent(Output[1], Output[1]->GetConnectedSockets()[i], UPDATE);
}
}
break;
case VisNodeSys::EXECUTE:
// special operation when node operations are executed
// (dont understand why this doesnt just happen on update...)
Execute();
if (Output.size() > 0) {
for (size_t i = 0; i < Output[0]->GetConnectedSockets().size(); ++i) {
ParentArea->TriggerSocketEvent(Output[0], Output[0]->GetConnectedSockets()[i], EXECUTE);
}
}
break;
}
}
}

Expand Down Expand Up @@ -167,4 +211,106 @@ bool BaseArithmeticOperatorNode::CanConnect(NodeSocket* OwnSocket, NodeSocket* C
}

return true;
}
}

void BaseArithmeticOperatorNode::Execute()
{
// Both A and B input sockets are required to perform the operation.
if (Input.size() <= 2)
return;

std::string CurrentMode = GetActiveINDataType();
if (CurrentMode.empty())
return;

// If we don't have both A and B inputs connected, we can't do anything.
if (Input[1]->GetConnectedSockets().empty() &&
Input[2]->GetConnectedSockets().empty())
return;

void* AData = nullptr;
if (!Input[1]->GetConnectedSockets().empty())
AData = Input[1]->GetConnectedSockets()[0]->GetData();

void* BData = nullptr;
if (!Input[2]->GetConnectedSockets().empty())
BData = Input[2]->GetConnectedSockets()[0]->GetData();

if (AData == nullptr && BData == nullptr)
return;

Output[1]->SetAllowedTypes({CurrentMode});
// Call the appropriate operation method based on the data type.
if (CurrentMode == "INT")
{
int A = 0;
if (AData != nullptr)
A = *reinterpret_cast<int*>(AData);

int B = 0;
if (BData != nullptr)
B = *reinterpret_cast<int*>(BData);

LocalIntegerData = PerformOperation(A, B);
}
if (CurrentMode == "UINT")
{
unsigned int A = 0;
if (AData != nullptr)
A = *reinterpret_cast<unsigned int*>(AData);

unsigned int B = 0;
if (BData != nullptr)
B = *reinterpret_cast<unsigned int*>(BData);

LocalUnsignedData = PerformOperation(A, B);
}
else if (CurrentMode == "FLOAT")
{
float A = 0.0f;
if (AData != nullptr)
A = *reinterpret_cast<float*>(AData);

float B = 0.0f;
if (BData != nullptr)
B = *reinterpret_cast<float*>(BData);

LocalFloatData = PerformOperation(A, B);
}
else if (CurrentMode == "VEC2")
{
glm::vec2 A = glm::vec2(0.0f);
if (AData != nullptr)
A = *reinterpret_cast<glm::vec2*>(AData);

glm::vec2 B = glm::vec2(0.0f);
if (BData != nullptr)
B = *reinterpret_cast<glm::vec2*>(BData);

LocalVec2Data = PerformOperation(A, B);
}
else if (CurrentMode == "VEC3")
{
glm::vec3 A = glm::vec3(0.0f);
if (AData != nullptr)
A = *reinterpret_cast<glm::vec3*>(AData);

glm::vec3 B = glm::vec3(0.0f);
if (BData != nullptr)
B = *reinterpret_cast<glm::vec3*>(BData);

LocalVec3Data = PerformOperation(A, B);
}
else if (CurrentMode == "VEC4")
{
glm::vec4 A = glm::vec4(0.0f);
if (AData != nullptr)
A = *reinterpret_cast<glm::vec4*>(AData);

glm::vec4 B = glm::vec4(0.0f);
if (BData != nullptr)
B = *reinterpret_cast<glm::vec4*>(BData);

LocalVec4Data = PerformOperation(A, B);
}
}
Loading
Loading