comparison DPF-Prymula-audioplugins/dpf/dgl/src/ApplicationPrivateData.cpp @ 3:84e66ea83026

DPF-Prymula-audioplugins-0.231015-2
author prymula <prymula76@outlook.com>
date Mon, 16 Oct 2023 21:53:34 +0200
parents
children
comparison
equal deleted inserted replaced
2:cf2cb71d31dd 3:84e66ea83026
1 /*
2 * DISTRHO Plugin Framework (DPF)
3 * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
4 *
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.
8 *
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.
15 */
16
17 #include "ApplicationPrivateData.hpp"
18 #include "../Window.hpp"
19
20 #include "pugl.hpp"
21
22 #include <ctime>
23
24 START_NAMESPACE_DGL
25
26 typedef std::list<DGL_NAMESPACE::Window*>::reverse_iterator WindowListReverseIterator;
27
28 static d_ThreadHandle getCurrentThreadHandle() noexcept
29 {
30 #ifdef DISTRHO_OS_WINDOWS
31 return GetCurrentThread();
32 #else
33 return pthread_self();
34 #endif
35 }
36
37 static bool isThisTheMainThread(const d_ThreadHandle mainThreadHandle) noexcept
38 {
39 #ifdef DISTRHO_OS_WINDOWS
40 return GetCurrentThread() == mainThreadHandle; // IsGUIThread ?
41 #else
42 return pthread_equal(getCurrentThreadHandle(), mainThreadHandle) != 0;
43 #endif
44 }
45
46 // --------------------------------------------------------------------------------------------------------------------
47
48 const char* Application::getClassName() const noexcept
49 {
50 return puglGetClassName(pData->world);
51 }
52
53 // --------------------------------------------------------------------------------------------------------------------
54
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()
66 {
67 DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,);
68
69 puglSetWorldHandle(world, this);
70 #ifdef __EMSCRIPTEN__
71 puglSetClassName(world, "canvas");
72 #else
73 puglSetClassName(world, DISTRHO_MACRO_AS_STRING(DGL_NAMESPACE));
74 #endif
75 }
76
77 Application::PrivateData::~PrivateData()
78 {
79 DISTRHO_SAFE_ASSERT(isStarting || isQuitting);
80 DISTRHO_SAFE_ASSERT(visibleWindows == 0);
81
82 windows.clear();
83 idleCallbacks.clear();
84
85 if (world != nullptr)
86 puglFreeWorld(world);
87 }
88
89 // --------------------------------------------------------------------------------------------------------------------
90
91 void Application::PrivateData::oneWindowShown() noexcept
92 {
93 if (++visibleWindows == 1)
94 {
95 isQuitting = false;
96 isStarting = false;
97 }
98 }
99
100 void Application::PrivateData::oneWindowClosed() noexcept
101 {
102 DISTRHO_SAFE_ASSERT_RETURN(visibleWindows != 0,);
103
104 if (--visibleWindows == 0)
105 isQuitting = true;
106 }
107
108 // --------------------------------------------------------------------------------------------------------------------
109
110 void Application::PrivateData::idle(const uint timeoutInMs)
111 {
112 if (isQuittingInNextCycle)
113 {
114 quit();
115 isQuittingInNextCycle = false;
116 }
117
118 if (world != nullptr)
119 {
120 const double timeoutInSeconds = timeoutInMs != 0
121 ? static_cast<double>(timeoutInMs) / 1000.0
122 : 0.0;
123
124 puglUpdate(world, timeoutInSeconds);
125 }
126
127 triggerIdleCallbacks();
128 }
129
130 void Application::PrivateData::triggerIdleCallbacks()
131 {
132 for (std::list<IdleCallback*>::iterator it = idleCallbacks.begin(), ite = idleCallbacks.end(); it != ite; ++it)
133 {
134 IdleCallback* const idleCallback(*it);
135 idleCallback->idleCallback();
136 }
137 }
138
139 void Application::PrivateData::quit()
140 {
141 if (! isThisTheMainThread(mainThreadHandle))
142 {
143 if (! isQuittingInNextCycle)
144 {
145 isQuittingInNextCycle = true;
146 return;
147 }
148 }
149
150 isQuitting = true;
151
152 #ifndef DPF_TEST_APPLICATION_CPP
153 for (WindowListReverseIterator rit = windows.rbegin(), rite = windows.rend(); rit != rite; ++rit)
154 {
155 DGL_NAMESPACE::Window* const window(*rit);
156 window->close();
157 }
158 #endif
159 }
160
161 double Application::PrivateData::getTime() const
162 {
163 DISTRHO_SAFE_ASSERT_RETURN(world != nullptr, 0.0);
164
165 return puglGetTime(world);
166 }
167
168 void Application::PrivateData::setClassName(const char* const name)
169 {
170 DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,);
171 DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',);
172
173 puglSetClassName(world, name);
174 }
175
176 // --------------------------------------------------------------------------------------------------------------------
177
178 END_NAMESPACE_DGL