diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 42924a8487..73444d1198 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -64,6 +64,7 @@ Agent::Agent(ReceivedMessage& message) : DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender); DependencyManager::set<ResourceManager>(); + DependencyManager::set<PluginManager>(); DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>(); @@ -833,6 +834,8 @@ void Agent::aboutToFinish() { DependencyManager::get<ResourceManager>()->cleanup(); + DependencyManager::destroy<PluginManager>(); + // cleanup the AudioInjectorManager (and any still running injectors) DependencyManager::destroy<AudioInjectorManager>(); diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 34eb138697..d56b22466e 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -65,7 +65,8 @@ AudioMixer::AudioMixer(ReceivedMessage& message) : // hash the available codecs (on the mixer) _availableCodecs.clear(); // Make sure struct is clean - auto codecPlugins = PluginManager::getInstance()->getCodecPlugins(); + auto pluginManager = DependencyManager::set<PluginManager>(); + auto codecPlugins = pluginManager->getCodecPlugins(); std::for_each(codecPlugins.cbegin(), codecPlugins.cend(), [&](const CodecPluginPointer& codec) { _availableCodecs[codec->getName()] = codec; @@ -106,6 +107,10 @@ AudioMixer::AudioMixer(ReceivedMessage& message) : connect(nodeList.data(), &NodeList::nodeKilled, this, &AudioMixer::handleNodeKilled); } +void AudioMixer::aboutToFinish() { + DependencyManager::destroy<PluginManager>(); +} + void AudioMixer::queueAudioPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer node) { if (message->getType() == PacketType::SilentAudioFrame) { _numSilentPackets++; diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h index 8c47893aa3..f9eb18da6d 100644 --- a/assignment-client/src/audio/AudioMixer.h +++ b/assignment-client/src/audio/AudioMixer.h @@ -58,6 +58,9 @@ public: to.getPublicSocket() != from.getPublicSocket() && to.getLocalSocket() != from.getLocalSocket(); } + + virtual void aboutToFinish() override; + public slots: void run() override; void sendStatsPacket() override; diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index eea8e8b470..607ab28b20 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -58,6 +58,7 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender); DependencyManager::set<ResourceManager>(); + DependencyManager::set<PluginManager>(); DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>(); @@ -572,6 +573,8 @@ void EntityScriptServer::aboutToFinish() { DependencyManager::get<ResourceManager>()->cleanup(); + DependencyManager::destroy<PluginManager>(); + // cleanup the AudioInjectorManager (and any still running injectors) DependencyManager::destroy<AudioInjectorManager>(); DependencyManager::destroy<ScriptEngines>(); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9c262c1980..fb7d6a4a0f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -269,9 +269,6 @@ public: } _renderContext->doneCurrent(); - // Deleting the object with automatically shutdown the thread - connect(qApp, &QCoreApplication::aboutToQuit, this, &QObject::deleteLater); - // Transfer to a new thread moveToNewNamedThread(this, "RenderThread", [this](QThread* renderThread) { hifi::qt::addBlockingForbiddenThread("Render", renderThread); @@ -814,6 +811,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { } // Tell the plugin manager about our statically linked plugins + DependencyManager::set<PluginManager>(); auto pluginManager = PluginManager::getInstance(); pluginManager->setInputPluginProvider([] { return getInputPlugins(); }); pluginManager->setDisplayPluginProvider([] { return getDisplayPlugins(); }); @@ -1378,6 +1376,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo initializeRenderEngine(); qCDebug(interfaceapp, "Initialized Render Engine."); + // Overlays need to exist before we set the ContextOverlayInterface dependency + _overlays.init(); // do this before scripts load + DependencyManager::set<ContextOverlayInterface>(); + // Initialize the user interface and menu system // Needs to happen AFTER the render engine initialization to access its configuration initializeUi(); @@ -1514,10 +1516,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // allow you to move an entity around in your hand _entityEditSender.setPacketsPerSecond(3000); // super high!! - // Overlays need to exist before we set the ContextOverlayInterface dependency - _overlays.init(); // do this before scripts load - DependencyManager::set<ContextOverlayInterface>(); - // Make sure we don't time out during slow operations at startup updateHeartbeat(); @@ -2555,25 +2553,28 @@ Application::~Application() { _octreeProcessor.terminate(); _entityEditSender.terminate(); + if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { + steamClient->shutdown(); + } + DependencyManager::destroy<PluginManager>(); + + DependencyManager::destroy<CompositorHelper>(); // must be destroyed before the FramebufferCache + DependencyManager::destroy<AvatarManager>(); DependencyManager::destroy<AnimationCache>(); DependencyManager::destroy<FramebufferCache>(); DependencyManager::destroy<TextureCache>(); DependencyManager::destroy<ModelCache>(); - DependencyManager::destroy<GeometryCache>(); DependencyManager::destroy<ScriptCache>(); DependencyManager::destroy<SoundCache>(); DependencyManager::destroy<OctreeStatsProvider>(); + DependencyManager::destroy<GeometryCache>(); DependencyManager::get<ResourceManager>()->cleanup(); // remove the NodeList from the DependencyManager DependencyManager::destroy<NodeList>(); - if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { - steamClient->shutdown(); - } - #if 0 ConnexionClient::getInstance().destroy(); #endif @@ -2593,6 +2594,8 @@ Application::~Application() { // Can't log to file passed this point, FileLogger about to be deleted qInstallMessageHandler(LogHandler::verboseMessageHandler); + + _renderEventHandler->deleteLater(); } void Application::initializeGL() { @@ -2893,6 +2896,7 @@ void Application::initializeUi() { auto compositorHelper = DependencyManager::get<CompositorHelper>(); connect(compositorHelper.data(), &CompositorHelper::allowMouseCaptureChanged, this, [=] { if (isHMDMode()) { + auto compositorHelper = DependencyManager::get<CompositorHelper>(); // don't capture outer smartpointer showCursor(compositorHelper->getAllowMouseCapture() ? Cursor::Manager::lookupIcon(_preferredCursor.get()) : Cursor::Icon::SYSTEM); diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index 2daa49dcf7..6b4840e3e5 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -139,7 +139,10 @@ void Application::paintGL() { frame->frameIndex = _renderFrameCount; frame->framebuffer = finalFramebuffer; frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) { - DependencyManager::get<FramebufferCache>()->releaseFramebuffer(framebuffer); + auto frameBufferCache = DependencyManager::get<FramebufferCache>(); + if (frameBufferCache) { + frameBufferCache->releaseFramebuffer(framebuffer); + } }; // deliver final scene rendering commands to the display plugin { diff --git a/libraries/gpu/src/gpu/Frame.cpp b/libraries/gpu/src/gpu/Frame.cpp index d08a8ab56d..f1001d97d2 100644 --- a/libraries/gpu/src/gpu/Frame.cpp +++ b/libraries/gpu/src/gpu/Frame.cpp @@ -21,10 +21,7 @@ Frame::~Frame() { framebuffer.reset(); } - assert(bufferUpdates.empty()); - if (!bufferUpdates.empty()) { - qFatal("Buffer sync error... frame destroyed without buffer updates being applied"); - } + bufferUpdates.clear(); } void Frame::finish() { diff --git a/libraries/networking/src/ResourceManager.cpp b/libraries/networking/src/ResourceManager.cpp index 6df15129a2..553f0d0a61 100644 --- a/libraries/networking/src/ResourceManager.cpp +++ b/libraries/networking/src/ResourceManager.cpp @@ -39,8 +39,13 @@ ResourceManager::ResourceManager(bool atpSupportEnabled) : _atpSupportEnabled(at } ResourceManager::~ResourceManager() { - _thread.terminate(); - _thread.wait(); + if (_thread.isRunning()) { + _thread.quit(); + static const auto MAX_RESOURCE_MANAGER_THREAD_QUITTING_TIME = MSECS_PER_SECOND / 2; + if (!_thread.wait(MAX_RESOURCE_MANAGER_THREAD_QUITTING_TIME)) { + _thread.terminate(); + } + } } void ResourceManager::setUrlPrefixOverride(const QString& prefix, const QString& replacement) { diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index e9c084e132..94ce16cf00 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -40,9 +40,8 @@ void PluginManager::setInputPluginSettingsPersister(const InputPluginSettingsPer _inputSettingsPersister = persister; } -PluginManager* PluginManager::getInstance() { - static PluginManager _manager; - return &_manager; +PluginManagerPointer PluginManager::getInstance() { + return DependencyManager::get<PluginManager>(); } QString getPluginNameFromMetaData(QJsonObject object) { @@ -136,9 +135,6 @@ const LoaderList& getLoadedPlugins() { return loadedPlugins; } -PluginManager::PluginManager() { -} - const CodecPluginList& PluginManager::getCodecPlugins() { static CodecPluginList codecPlugins; static std::once_flag once; diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h index f16ad7d09f..65a4012aed 100644 --- a/libraries/plugins/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -9,12 +9,19 @@ #include <QObject> +#include <DependencyManager.h> + #include "Forward.h" -class PluginManager : public QObject { + +class PluginManager; +using PluginManagerPointer = QSharedPointer<PluginManager>; + +class PluginManager : public QObject, public Dependency { + SINGLETON_DEPENDENCY + public: - static PluginManager* getInstance(); - PluginManager(); + static PluginManagerPointer getInstance(); const DisplayPluginList& getDisplayPlugins(); const InputPluginList& getInputPlugins(); @@ -39,6 +46,8 @@ public: void setInputPluginSettingsPersister(const InputPluginSettingsPersister& persister); private: + PluginManager() = default; + DisplayPluginProvider _displayPluginProvider { []()->DisplayPluginList { return {}; } }; InputPluginProvider _inputPluginProvider { []()->InputPluginList { return {}; } }; CodecPluginProvider _codecPluginProvider { []()->CodecPluginList { return {}; } };