Mercurial > hg > pub > prymula > com
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DPF-Prymula-audioplugins/dpf/dgl/src/ApplicationPrivateData.cpp Mon Oct 16 21:53:34 2023 +0200 @@ -0,0 +1,178 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> + * + * Permission to use, copy, modify, and/or distribute this software for any purpose with + * or without fee is hereby granted, provided that the above copyright notice and this + * permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "ApplicationPrivateData.hpp" +#include "../Window.hpp" + +#include "pugl.hpp" + +#include <ctime> + +START_NAMESPACE_DGL + +typedef std::list<DGL_NAMESPACE::Window*>::reverse_iterator WindowListReverseIterator; + +static d_ThreadHandle getCurrentThreadHandle() noexcept +{ +#ifdef DISTRHO_OS_WINDOWS + return GetCurrentThread(); +#else + return pthread_self(); +#endif +} + +static bool isThisTheMainThread(const d_ThreadHandle mainThreadHandle) noexcept +{ +#ifdef DISTRHO_OS_WINDOWS + return GetCurrentThread() == mainThreadHandle; // IsGUIThread ? +#else + return pthread_equal(getCurrentThreadHandle(), mainThreadHandle) != 0; +#endif +} + +// -------------------------------------------------------------------------------------------------------------------- + +const char* Application::getClassName() const noexcept +{ + return puglGetClassName(pData->world); +} + +// -------------------------------------------------------------------------------------------------------------------- + +Application::PrivateData::PrivateData(const bool standalone) + : world(puglNewWorld(standalone ? PUGL_PROGRAM : PUGL_MODULE, + standalone ? PUGL_WORLD_THREADS : 0x0)), + isStandalone(standalone), + isQuitting(false), + isQuittingInNextCycle(false), + isStarting(true), + visibleWindows(0), + mainThreadHandle(getCurrentThreadHandle()), + windows(), + idleCallbacks() +{ + DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,); + + puglSetWorldHandle(world, this); + #ifdef __EMSCRIPTEN__ + puglSetClassName(world, "canvas"); + #else + puglSetClassName(world, DISTRHO_MACRO_AS_STRING(DGL_NAMESPACE)); + #endif +} + +Application::PrivateData::~PrivateData() +{ + DISTRHO_SAFE_ASSERT(isStarting || isQuitting); + DISTRHO_SAFE_ASSERT(visibleWindows == 0); + + windows.clear(); + idleCallbacks.clear(); + + if (world != nullptr) + puglFreeWorld(world); +} + +// -------------------------------------------------------------------------------------------------------------------- + +void Application::PrivateData::oneWindowShown() noexcept +{ + if (++visibleWindows == 1) + { + isQuitting = false; + isStarting = false; + } +} + +void Application::PrivateData::oneWindowClosed() noexcept +{ + DISTRHO_SAFE_ASSERT_RETURN(visibleWindows != 0,); + + if (--visibleWindows == 0) + isQuitting = true; +} + +// -------------------------------------------------------------------------------------------------------------------- + +void Application::PrivateData::idle(const uint timeoutInMs) +{ + if (isQuittingInNextCycle) + { + quit(); + isQuittingInNextCycle = false; + } + + if (world != nullptr) + { + const double timeoutInSeconds = timeoutInMs != 0 + ? static_cast<double>(timeoutInMs) / 1000.0 + : 0.0; + + puglUpdate(world, timeoutInSeconds); + } + + triggerIdleCallbacks(); +} + +void Application::PrivateData::triggerIdleCallbacks() +{ + for (std::list<IdleCallback*>::iterator it = idleCallbacks.begin(), ite = idleCallbacks.end(); it != ite; ++it) + { + IdleCallback* const idleCallback(*it); + idleCallback->idleCallback(); + } +} + +void Application::PrivateData::quit() +{ + if (! isThisTheMainThread(mainThreadHandle)) + { + if (! isQuittingInNextCycle) + { + isQuittingInNextCycle = true; + return; + } + } + + isQuitting = true; + +#ifndef DPF_TEST_APPLICATION_CPP + for (WindowListReverseIterator rit = windows.rbegin(), rite = windows.rend(); rit != rite; ++rit) + { + DGL_NAMESPACE::Window* const window(*rit); + window->close(); + } +#endif +} + +double Application::PrivateData::getTime() const +{ + DISTRHO_SAFE_ASSERT_RETURN(world != nullptr, 0.0); + + return puglGetTime(world); +} + +void Application::PrivateData::setClassName(const char* const name) +{ + DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,); + DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); + + puglSetClassName(world, name); +} + +// -------------------------------------------------------------------------------------------------------------------- + +END_NAMESPACE_DGL