Skip to content

Commit e9a34a4

Browse files
committed
CMake improvements for DLL version compilation; Wrapped ImGui::GetCurrentWindow() in GetCurrentWindowImpl() as a hack fix for DLL version usage; Changed singleton definition macros to make the singleton better suited for DLL usage; Introduced a new way to define an easy-to-access macro for singletons that is DLL-friendly.
1 parent 252484d commit e9a34a4

14 files changed

Lines changed: 156 additions & 48 deletions

CMakeLists.txt

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ set(CMAKE_CONFIGURATION_TYPES Debug Release)
77
# set the project name
88
project(VisualNodeSystem LANGUAGES CXX)
99

10+
option(VISUAL_NODE_SYSTEM_USE_EXTERNAL_IMGUI "Use an external ImGui library instead of compiling our own" OFF)
11+
option(VISUAL_NODE_SYSTEM_BUILD_SHARED_LIBS "Build VisualNodeSystem as a shared library" OFF)
12+
option(VISUAL_NODE_SYSTEM_USE_STATIC_RUNTIME "Use static runtime (/MT) instead of dynamic (/MD) for VisualNodeSystem" ON)
13+
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
14+
1015
# Turn on the ability to create folders to organize projects (.vcproj)
1116
# It creates "CMakePredefinedTargets" folder by default and adds CMake
1217
# defined projects like INSTALL.vcproj and ZERO_CHECK.vcproj
@@ -33,6 +38,7 @@ file(GLOB VisualNodeSystem_SRC
3338
"VisualNodeSocket.h"
3439
"VisualNodeCore.cpp"
3540
"VisualNodeCore.h"
41+
"VisualNodeSystemAPI.h"
3642
)
3743

3844
# *************** THIRD_PARTY ***************
@@ -47,13 +53,29 @@ file(GLOB jsoncpp_SRC
4753

4854
# *************** THIRD_PARTY END ***************
4955

50-
add_library(VisualNodeSystem
51-
${VisualNodeSystem_SRC}
56+
set(ALL_SOURCE_FILES "")
57+
list(APPEND ALL_SOURCE_FILES
58+
${VisualNodeSystem_SRC}
5259
${VisualNodeArea_SRC}
5360
# *************** THIRD_PARTY ***************
5461
${jsoncpp_SRC}
5562
)
5663

64+
if(VISUAL_NODE_SYSTEM_BUILD_SHARED_LIBS)
65+
add_library(VisualNodeSystem SHARED ${ALL_SOURCE_FILES})
66+
target_compile_definitions(VisualNodeSystem PRIVATE VISUAL_NODE_SYSTEM_EXPORTS)
67+
target_compile_definitions(VisualNodeSystem PUBLIC VISUAL_NODE_SYSTEM_SHARED)
68+
69+
# Some times /GL conflicts with WINDOWS_EXPORT_ALL_SYMBOLS
70+
set_target_properties(VisualNodeSystem PROPERTIES COMPILE_OPTIONS "/GL-")
71+
set_target_properties(VisualNodeSystem PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
72+
73+
# Disable C4251 warning
74+
target_compile_options(VisualNodeSystem PRIVATE /wd4251)
75+
else()
76+
add_library(VisualNodeSystem STATIC ${ALL_SOURCE_FILES})
77+
endif()
78+
5779
source_group("Source Files" FILES ${VisualNodeSystem_SRC})
5880
source_group("Source Files/SubSystems/VisualNodeArea/" FILES ${VisualNodeArea_SRC})
5981
# *************** THIRD_PARTY ***************
@@ -67,6 +89,31 @@ set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT V
6789
# Promt to give Dear ImGui path
6890
set(DEAR_IMGUI_INCLUDE_DIR "" CACHE PATH "Path to Dear ImGui directory.")
6991

92+
if(VISUAL_NODE_SYSTEM_BUILD_SHARED_LIBS)
93+
if(VISUAL_NODE_SYSTEM_USE_EXTERNAL_IMGUI)
94+
# Use external ImGui library
95+
set(EXTERNAL_IMGUI_LIBRARY "" CACHE FILEPATH "Path to external ImGui library")
96+
if(NOT EXTERNAL_IMGUI_LIBRARY)
97+
message(FATAL_ERROR "EXTERNAL_IMGUI_LIBRARY must be set when VISUAL_NODE_SYSTEM_USE_EXTERNAL_IMGUI is ON")
98+
endif()
99+
target_link_libraries(VisualNodeSystem PRIVATE ${EXTERNAL_IMGUI_LIBRARY})
100+
else()
101+
# If we are building .dll we would need GLFW information.
102+
set(VISUAL_NODE_SYSTEM_GLFW_INCLUDE_DIR "" CACHE PATH "Path to GLFW include directory.")
103+
target_include_directories(VisualNodeSystem PRIVATE ${VISUAL_NODE_SYSTEM_GLFW_INCLUDE_DIR})
104+
set(VISUAL_NODE_SYSTEM_GLFW_LIBRARY "" CACHE PATH "Path to GLFW library.")
105+
target_link_libraries(VisualNodeSystem PRIVATE ${VISUAL_NODE_SYSTEM_GLFW_LIBRARY})
106+
107+
# Add Dear ImGui source files
108+
file(GLOB IMGUI_SOURCES
109+
"${DEAR_IMGUI_INCLUDE_DIR}/*.cpp"
110+
"${DEAR_IMGUI_INCLUDE_DIR}/*.h"
111+
)
112+
target_sources(VisualNodeSystem PRIVATE ${IMGUI_SOURCES})
113+
source_group("Source Files/ThirdParty/ImGui" FILES ${IMGUI_SOURCES})
114+
endif()
115+
endif()
116+
70117
include_directories(
71118
${DEAR_IMGUI_INCLUDE_DIR}
72119
${VISUAL_NODE_SYSTEM_THIRDPARTY_DIR}

GroupComment.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace VisNodeSys
77
#define GROUP_COMMENT_CAPTION_MAX_LENGHT 1024
88
#define GROUP_COMMENT_TITLE_HEIGHT 30.0f
99

10-
class GroupComment
10+
class VISUAL_NODE_SYSTEM_API GroupComment
1111
{
1212
protected:
1313
friend class NodeSystem;

SubSystems/VisualNodeArea/VisualNodeArea.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -641,17 +641,17 @@ std::vector<ConnectionSegment> NodeArea::GetConnectionSegments(const Connection*
641641
ImVec2 NodeArea::LocalToScreen(ImVec2 LocalPosition) const
642642
{
643643
ImVec2 WindowPosition = ImVec2(0.0f, 0.0f);
644-
if (ImGui::GetCurrentContext() != nullptr && ImGui::GetCurrentContext()->CurrentWindow != nullptr)
645-
WindowPosition = ImGui::GetCurrentWindow()->Pos;
644+
if (GetCurrentWindowImpl() != nullptr)
645+
WindowPosition = GetCurrentWindowImpl()->Pos;
646646

647647
return WindowPosition + LocalPosition * Zoom + RenderOffset;
648648
}
649649

650650
ImVec2 NodeArea::ScreenToLocal(ImVec2 ScreenPosition) const
651651
{
652652
ImVec2 WindowPosition = ImVec2(0.0f, 0.0f);
653-
if (ImGui::GetCurrentContext() != nullptr && ImGui::GetCurrentContext()->CurrentWindow != nullptr)
654-
WindowPosition = ImGui::GetCurrentWindow()->Pos;
653+
if (GetCurrentWindowImpl() != nullptr)
654+
WindowPosition = GetCurrentWindowImpl()->Pos;
655655

656656
return (ScreenPosition - WindowPosition - RenderOffset) / Zoom;
657657
}
@@ -700,4 +700,13 @@ bool NodeArea::IsSecondRectInsideFirstOne(ImVec2 FirstRectMin, ImVec2 FirstRectS
700700
}
701701

702702
return false;
703+
}
704+
705+
ImGuiWindow* NodeArea::GetCurrentWindowImpl() const
706+
{
707+
ImGuiContext* Context = ImGui::GetCurrentContext();
708+
if (Context == nullptr)
709+
return nullptr;
710+
711+
return Context->CurrentWindow;
703712
}

SubSystems/VisualNodeArea/VisualNodeArea.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ namespace VisNodeSys
6464
bool bReduceTransparencyForUnconnectableSockets = true;
6565
};
6666

67-
class NodeArea
67+
class VISUAL_NODE_SYSTEM_API NodeArea
6868
{
6969
friend NodeSystem;
7070
public:
@@ -336,5 +336,8 @@ namespace VisNodeSys
336336

337337
ImVec2 ScreenToLocal(ImVec2 ScreenPosition) const;
338338
ImVec2 LocalToScreen(ImVec2 LocalPosition) const;
339+
340+
// TO DO: Here I am using internal ImGui functions. Need to find a way to avoid it.
341+
ImGuiWindow* GetCurrentWindowImpl() const;
339342
};
340343
}

SubSystems/VisualNodeArea/VisualNodeAreaRendering.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -288,18 +288,18 @@ void NodeArea::Render()
288288
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
289289
ImGui::PushStyleColor(ImGuiCol_ChildBg, Settings.Style.Grid.GridBackgroundColor);
290290

291-
const ImVec2 CurrentPosition = ImGui::GetCurrentWindow()->Pos + Position;
291+
const ImVec2 CurrentPosition = GetCurrentWindowImpl()->Pos + Position;
292292
ImGui::SetNextWindowPos(CurrentPosition);
293293

294294
if (bFillWindow)
295295
{
296-
auto NodeAreaParentWindow = ImGui::GetCurrentWindow();
296+
auto NodeAreaParentWindow = GetCurrentWindowImpl();
297297
SetSize(NodeAreaParentWindow->Size - ImVec2(2, 2));
298298
}
299299

300300
ImGui::BeginChild("Nodes area", GetSize(), true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoMove);
301301

302-
NodeAreaWindow = ImGui::GetCurrentWindow();
302+
NodeAreaWindow = GetCurrentWindowImpl();
303303
CurrentDrawList = ImGui::GetWindowDrawList();
304304

305305
RenderGrid(CurrentPosition);
@@ -701,7 +701,7 @@ ImVec2 NodeArea::GetRenderedViewCenter() const
701701
}
702702
else
703703
{
704-
return (ImGui::GetCurrentWindow()->Size / 2.0f - RenderOffset) / Zoom;
704+
return (GetCurrentWindowImpl()->Size / 2.0f - RenderOffset) / Zoom;
705705
}
706706
}
707707

@@ -851,7 +851,7 @@ void NodeArea::RenderGroupComment(GroupComment* GroupComment)
851851
if (!GroupComment->bLastFrameRenameEditWasVisiable)
852852
{
853853
ImGui::SetKeyboardFocusHere(0);
854-
ImGui::SetFocusID(ImGui::GetID("##newCommentEditor"), ImGui::GetCurrentWindow());
854+
ImGui::SetFocusID(ImGui::GetID("##newCommentEditor"), GetCurrentWindowImpl());
855855
ImGui::SetItemDefaultFocus();
856856
GroupComment->bLastFrameRenameEditWasVisiable = true;
857857

@@ -864,7 +864,7 @@ void NodeArea::RenderGroupComment(GroupComment* GroupComment)
864864
ImGui::SetCursorScreenPos(CaptionPosition + TextOffset);
865865
ImGui::SetNextItemWidth(GroupComment->GetSize().x * Zoom - TextOffset.x * 4.0f);
866866
if (ImGui::InputText("##newCommentEditor", GroupComment->GroupCommentRename, IM_ARRAYSIZE(GroupComment->GroupCommentRename), ImGuiInputTextFlags_EnterReturnsTrue) ||
867-
ImGui::IsMouseClicked(0) && !ImGui::IsItemHovered() || ImGui::GetFocusID() != ImGui::GetID("##newCommentEditor"))
867+
ImGui::IsMouseClicked(0) && !ImGui::IsItemHovered() || !ImGui::IsItemFocused())
868868
{
869869
GroupComment->bIsRenamingActive = false;
870870
GroupComment->SetCaption(GroupComment->GroupCommentRename);

VisualNode.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace VisNodeSys
2323
EXECUTE = 4
2424
};
2525

26-
class Node
26+
class VISUAL_NODE_SYSTEM_API Node
2727
{
2828
protected:
2929
friend class NodeSystem;

VisualNodeCore.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
#include "VisualNodeCore.h"
22
using namespace VisNodeSys;
33

4-
NodeCore* NodeCore::Instance = nullptr;
4+
#ifdef VISUAL_NODE_SYSTEM_SHARED
5+
extern "C" __declspec(dllexport) void* GetNodeCore()
6+
{
7+
return NodeCore::GetInstancePointer();
8+
}
9+
#endif
510

611
NodeCore::NodeCore() {}
712
NodeCore::~NodeCore() {}

VisualNodeCore.h

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,38 +27,46 @@
2727

2828
#include "jsoncpp/json/json.h"
2929

30+
#include "VisualNodeSystemAPI.h"
31+
3032
namespace VisNodeSys
3133
{
32-
#define SINGLETON_PUBLIC_PART(CLASS_NAME) \
33-
static CLASS_NAME& getInstance() \
34-
{ \
35-
if (!Instance) \
36-
Instance = new CLASS_NAME(); \
37-
return *Instance; \
38-
} \
39-
\
40-
~CLASS_NAME();
4134

42-
#define SINGLETON_PRIVATE_PART(CLASS_NAME) \
43-
static CLASS_NAME* Instance; \
44-
CLASS_NAME(); \
45-
CLASS_NAME(const CLASS_NAME &); \
46-
void operator= (const CLASS_NAME &);
35+
#define SINGLETON_PUBLIC_PART(CLASS_NAME) \
36+
static CLASS_NAME& GetInstance() \
37+
{ \
38+
static CLASS_NAME* Instance = nullptr; \
39+
if (!Instance) \
40+
Instance = new CLASS_NAME(); \
41+
return *Instance; \
42+
} \
43+
\
44+
static CLASS_NAME* GetInstancePointer() \
45+
{ \
46+
return &GetInstance(); \
47+
}
48+
49+
#define SINGLETON_PRIVATE_PART(CLASS_NAME) \
50+
CLASS_NAME(); \
51+
~CLASS_NAME(); \
52+
CLASS_NAME(const CLASS_NAME &); \
53+
void operator= (const CLASS_NAME &);
54+
4755

4856
#define FE_MAP_TO_STR_VECTOR(map) \
49-
std::vector<std::string> result; \
50-
auto iterator = map.begin(); \
51-
while (iterator != map.end()) \
52-
{ \
53-
result.push_back(iterator->first); \
54-
iterator++; \
55-
} \
56-
\
57-
return result;
57+
std::vector<std::string> result; \
58+
auto iterator = map.begin(); \
59+
while (iterator != map.end()) \
60+
{ \
61+
result.push_back(iterator->first); \
62+
iterator++; \
63+
} \
64+
\
65+
return result;
5866

5967
#define VISUAL_NODE_SYSTEM_VERSION "0.1.0"
6068

61-
class NodeCore
69+
class VISUAL_NODE_SYSTEM_API NodeCore
6270
{
6371
SINGLETON_PRIVATE_PART(NodeCore)
6472

@@ -93,5 +101,10 @@ return result;
93101
std::string Base64Decode(std::string const& EncodedString);
94102
};
95103

96-
#define NODE_CORE VisNodeSys::NodeCore::getInstance()
104+
#ifdef VISUAL_NODE_SYSTEM_SHARED
105+
extern "C" __declspec(dllexport) void* GetNodeCore();
106+
#define NODE_CORE (*static_cast<VisNodeSys::NodeCore*>(VisNodeSys::GetNodeCore()))
107+
#else
108+
#define NODE_CORE VisNodeSys::NodeCore::GetInstance()
109+
#endif
97110
}

VisualNodeFactory.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
#include "VisualNodeFactory.h"
22
using namespace VisNodeSys;
33

4-
NodeFactory* NodeFactory::Instance = nullptr;
4+
#ifdef VISUAL_NODE_SYSTEM_SHARED
5+
extern "C" __declspec(dllexport) void* GetNodeFactory()
6+
{
7+
return NodeFactory::GetInstancePointer();
8+
}
9+
#endif
510

611
NodeFactory::NodeFactory() {}
712
NodeFactory::~NodeFactory() {}

VisualNodeFactory.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace VisNodeSys
66
{
7-
class NodeFactory
7+
class VISUAL_NODE_SYSTEM_API NodeFactory
88
{
99
SINGLETON_PRIVATE_PART(NodeFactory)
1010

@@ -19,5 +19,10 @@ namespace VisNodeSys
1919
Node* CopyNode(const std::string& Type, const Node& Node) const;
2020
};
2121

22-
#define NODE_FACTORY VisNodeSys::NodeFactory::getInstance()
22+
#ifdef VISUAL_NODE_SYSTEM_SHARED
23+
extern "C" __declspec(dllexport) void* GetNodeFactory();
24+
#define NODE_FACTORY (*static_cast<VisNodeSys::NodeFactory*>(VisNodeSys::GetNodeFactory()))
25+
#else
26+
#define NODE_FACTORY VisNodeSys::NodeFactory::GetInstance()
27+
#endif
2328
}

0 commit comments

Comments
 (0)