From 9edea25fab9c0e4b02ea3f2e508542f18b7d3f4c Mon Sep 17 00:00:00 2001 From: falkTX Date: Sun, 2 May 2021 18:57:38 +0100 Subject: [PATCH] Make Window::PrivateData an IdleCallback, add a few comments Signed-off-by: falkTX --- dgl/Window.hpp | 33 ++++++++++++++++++++++++++++- dgl/src/ApplicationPrivateData.cpp | 12 ----------- dgl/src/ApplicationPrivateData.hpp | 2 -- dgl/src/WindowPrivateData.cpp | 17 ++++++++++----- dgl/src/WindowPrivateData.hpp | 34 +++++++++++++++++++++++++----- tests/Makefile | 10 ++++++--- 6 files changed, 80 insertions(+), 28 deletions(-) diff --git a/dgl/Window.hpp b/dgl/Window.hpp index d297c16c..efff9968 100644 --- a/dgl/Window.hpp +++ b/dgl/Window.hpp @@ -21,15 +21,46 @@ START_NAMESPACE_DGL +class Application; + // ----------------------------------------------------------------------- -class Application; +/** + DGL Window class. + + This is the where all OS-related events initially happen, before being propagated to any widgets. + + A Window MUST have an Application instance tied to it. + It is not possible to swap Application instances from within the lifetime of a Window. + But it is possible to completely change the Widgets that a Window contains during its lifetime. + Typically the event handling functions as following: + Application -> Window -> Top-Level-Widget -> SubWidgets + + ... + + Please note that, unlike many other graphical toolkits out there, + DGL makes a clear distinction between a Window and a Widget. + You cannot directly draw in a Window, you need to create a Widget for that. + + ... + */ class Window { public: + /** + Constructor for a regular, standalone window. + */ explicit Window(Application& app); + + /** + Constructor for an embed Window, typically used in modules or plugins that run inside another host. + */ explicit Window(Application& app, uintptr_t parentWindowHandle, double scaling, bool resizable); + + /** + Destructor. + */ virtual ~Window(); void close(); diff --git a/dgl/src/ApplicationPrivateData.cpp b/dgl/src/ApplicationPrivateData.cpp index 953b4797..400c07b1 100644 --- a/dgl/src/ApplicationPrivateData.cpp +++ b/dgl/src/ApplicationPrivateData.cpp @@ -29,9 +29,7 @@ Application::PrivateData::PrivateData(const bool standalone) isStandalone(standalone), isQuitting(false), visibleWindows(0), -#ifndef DPF_TEST_APPLICATION_CPP windows(), -#endif idleCallbacks() { DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,); @@ -48,9 +46,7 @@ Application::PrivateData::~PrivateData() DISTRHO_SAFE_ASSERT(isQuitting); DISTRHO_SAFE_ASSERT(visibleWindows == 0); -#ifndef DPF_TEST_APPLICATION_CPP windows.clear(); -#endif idleCallbacks.clear(); if (world != nullptr) @@ -87,14 +83,6 @@ void Application::PrivateData::idle(const uint timeoutInMs) puglUpdate(world, timeoutInSeconds); } -// #ifndef DPF_TEST_APPLICATION_CPP -// for (std::list::iterator it = windows.begin(), ite = windows.end(); it != ite; ++it) -// { -// Window* const window(*it); -// window->_idle(); -// } -// #endif - for (std::list::iterator it = idleCallbacks.begin(), ite = idleCallbacks.end(); it != ite; ++it) { IdleCallback* const idleCallback(*it); diff --git a/dgl/src/ApplicationPrivateData.hpp b/dgl/src/ApplicationPrivateData.hpp index 6057b6dc..e202143d 100644 --- a/dgl/src/ApplicationPrivateData.hpp +++ b/dgl/src/ApplicationPrivateData.hpp @@ -43,10 +43,8 @@ struct Application::PrivateData { If 0->1, application is starting. If 1->0, application is quitting/stopping. */ uint visibleWindows; -#ifndef DPF_TEST_APPLICATION_CPP /** List of windows for this application. Used as a way to call each window `idle`. */ std::list windows; -#endif /** List of idle callbacks for this application. Run after all windows `idle`. */ std::list idleCallbacks; diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp index 4e2dfa64..ee32c55d 100644 --- a/dgl/src/WindowPrivateData.cpp +++ b/dgl/src/WindowPrivateData.cpp @@ -52,8 +52,8 @@ Window::PrivateData::PrivateData(Application::PrivateData* const a, Window* cons Window::PrivateData::~PrivateData() { - if (self != nullptr) - appData->windows.remove(self); + appData->idleCallbacks.remove(this); + appData->windows.remove(self); if (view != nullptr) puglFreeView(view); @@ -63,7 +63,10 @@ Window::PrivateData::~PrivateData() void Window::PrivateData::init(const bool resizable) { - if (self == nullptr || view == nullptr) + appData->windows.push_back(self); + appData->idleCallbacks.push_back(this); + + if (view == nullptr) { /* DGL_DBG("Failed!\n"); @@ -89,8 +92,6 @@ void Window::PrivateData::init(const bool resizable) // puglSetFileSelectedFunc(fView, fileBrowserSelectedCallback); // #endif - appData->windows.push_back(self); - // DGL_DBG("Success!\n"); } @@ -114,6 +115,12 @@ void Window::PrivateData::close() // ----------------------------------------------------------------------- +void Window::PrivateData::idleCallback() +{ +} + +// ----------------------------------------------------------------------- + PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const PuglEvent* const event) { Window::PrivateData* const pData = (Window::PrivateData*)puglGetHandle(view); diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp index 5353002d..499a94bd 100644 --- a/dgl/src/WindowPrivateData.hpp +++ b/dgl/src/WindowPrivateData.hpp @@ -18,7 +18,7 @@ #define DGL_WINDOW_PRIVATE_DATA_HPP_INCLUDED #include "../Window.hpp" -#include "ApplicationPrivateData.hpp" +// #include "ApplicationPrivateData.hpp" #include "pugl.hpp" @@ -28,21 +28,45 @@ class Widget; // ----------------------------------------------------------------------- -struct Window::PrivateData { +struct Window::PrivateData : IdleCallback { + /** Handy typedef for ... */ typedef Application::PrivateData AppData; - AppData* const appData; - Window* const self; + /** Direct access to DGL Application private data where we registers ourselves in. */ + AppData* const appData; + + /** Pointer to the DGL Window class that this private data belongs to. */ + Window* const self; + + /** Pugl view instance. */ PuglView* const view; + /** Constructor for a regular, standalone window. */ PrivateData(AppData* appData, Window* self); + + /** Constructor for a regular, standalone window with a transient parent. */ PrivateData(AppData* appData, Window* self, Window& transientWindow); + + /** Constructor for an embed Window, with a few extra hints from the host side. */ PrivateData(AppData* appData, Window* self, uintptr_t parentWindowHandle, double scaling, bool resizable); - ~PrivateData(); + /** Destructor. */ + ~PrivateData() override; + + /** Helper initialization function called at the end of all this class constructors. */ void init(bool resizable); + + /** Hide window and notify application of a window close event. + * Does nothing if window is embed (that is, not standalone). + * The application event-loop will stop if all windows have been closed. + * + * @note It is possible to hide the window while not stopping event-loop. + * A closed window is always hidden, but the reverse is not always true. + */ void close(); + void idleCallback() override; + static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event); DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrivateData) diff --git a/tests/Makefile b/tests/Makefile index 0b50d12f..f4126348 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -30,9 +30,12 @@ endif ifeq ($(HAVE_VULKAN),true) WTESTS = Window.vulkan endif + TARGETS = $(TESTS:%=../build/tests/%) TARGETS += $(WTESTS:Window.%=../build/tests/Window.%) -OBJS = $(TARGETS:%=%.cpp.o) + +OBJS = $(TESTS:%=../build/tests/%.cpp.o) +OBJS += $(WTESTS:Window.%=../build/tests/Window.%.cpp.o) # --------------------------------------------------------------------------------------------------------------------- @@ -65,8 +68,9 @@ all: $(TARGETS) @echo "Linking $*" $(SILENT)$(CXX) $< $(LINK_FLAGS) $(DGL_SYSTEM_LIBS) $(OPENGL_LIBS) -o $@ @echo "Running test for $*" - $(SILENT) - gdb -ex run $@ +# $(SILENT) + $@ +# gdb -ex run ../build/tests/%.vulkan: ../build/tests/%.cpp.vulkan.o @echo "Linking $*"