Cleanup
[carla.git] / source / modules / dgl / src / ApplicationPrivateData.cpp
blobca06a1bbdb36d5250f0b828e2061031b0c771372
1 /*
2 * DISTRHO Plugin Framework (DPF)
3 * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
5 * Permission to use, copy, modify, and/or distribute this software for any purpose with
6 * or without fee is hereby granted, provided that the above copyright notice and this
7 * permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include "ApplicationPrivateData.hpp"
18 #include "../Window.hpp"
20 #include "pugl.hpp"
22 #include <ctime>
24 START_NAMESPACE_DGL
26 typedef std::list<DGL_NAMESPACE::Window*>::reverse_iterator WindowListReverseIterator;
28 static d_ThreadHandle getCurrentThreadHandle() noexcept
30 #ifdef DISTRHO_OS_WINDOWS
31 return GetCurrentThread();
32 #else
33 return pthread_self();
34 #endif
37 static bool isThisTheMainThread(const d_ThreadHandle mainThreadHandle) noexcept
39 #ifdef DISTRHO_OS_WINDOWS
40 return GetCurrentThread() == mainThreadHandle; // IsGUIThread ?
41 #else
42 return pthread_equal(getCurrentThreadHandle(), mainThreadHandle) != 0;
43 #endif
46 // --------------------------------------------------------------------------------------------------------------------
48 const char* Application::getClassName() const noexcept
50 return puglGetClassName(pData->world);
53 // --------------------------------------------------------------------------------------------------------------------
55 Application::PrivateData::PrivateData(const bool standalone)
56 : world(puglNewWorld(standalone ? PUGL_PROGRAM : PUGL_MODULE,
57 standalone ? PUGL_WORLD_THREADS : 0x0)),
58 isStandalone(standalone),
59 isQuitting(false),
60 isQuittingInNextCycle(false),
61 isStarting(true),
62 visibleWindows(0),
63 mainThreadHandle(getCurrentThreadHandle()),
64 windows(),
65 idleCallbacks()
67 DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,);
69 puglSetWorldHandle(world, this);
70 #ifndef __EMSCRIPTEN__
71 puglSetClassName(world, DISTRHO_MACRO_AS_STRING(DGL_NAMESPACE));
72 #endif
75 Application::PrivateData::~PrivateData()
77 DISTRHO_SAFE_ASSERT(isStarting || isQuitting);
78 DISTRHO_SAFE_ASSERT(visibleWindows == 0);
80 windows.clear();
81 idleCallbacks.clear();
83 if (world != nullptr)
84 puglFreeWorld(world);
87 // --------------------------------------------------------------------------------------------------------------------
89 void Application::PrivateData::oneWindowShown() noexcept
91 if (++visibleWindows == 1)
93 isQuitting = false;
94 isStarting = false;
98 void Application::PrivateData::oneWindowClosed() noexcept
100 DISTRHO_SAFE_ASSERT_RETURN(visibleWindows != 0,);
102 if (--visibleWindows == 0)
103 isQuitting = true;
106 // --------------------------------------------------------------------------------------------------------------------
108 void Application::PrivateData::idle(const uint timeoutInMs)
110 if (isQuittingInNextCycle)
112 quit();
113 isQuittingInNextCycle = false;
116 if (world != nullptr)
118 const double timeoutInSeconds = timeoutInMs != 0
119 ? static_cast<double>(timeoutInMs) / 1000.0
120 : 0.0;
122 puglUpdate(world, timeoutInSeconds);
125 triggerIdleCallbacks();
128 void Application::PrivateData::triggerIdleCallbacks()
130 for (std::list<IdleCallback*>::iterator it = idleCallbacks.begin(), ite = idleCallbacks.end(); it != ite; ++it)
132 IdleCallback* const idleCallback(*it);
133 idleCallback->idleCallback();
137 void Application::PrivateData::quit()
139 if (! isThisTheMainThread(mainThreadHandle))
141 if (! isQuittingInNextCycle)
143 isQuittingInNextCycle = true;
144 return;
148 isQuitting = true;
150 #ifndef DPF_TEST_APPLICATION_CPP
151 for (WindowListReverseIterator rit = windows.rbegin(), rite = windows.rend(); rit != rite; ++rit)
153 DGL_NAMESPACE::Window* const window(*rit);
154 window->close();
156 #endif
159 double Application::PrivateData::getTime() const
161 DISTRHO_SAFE_ASSERT_RETURN(world != nullptr, 0.0);
163 return puglGetTime(world);
166 void Application::PrivateData::setClassName(const char* const name)
168 DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,);
169 DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',);
171 puglSetClassName(world, name);
174 // --------------------------------------------------------------------------------------------------------------------
176 END_NAMESPACE_DGL