void lcpp::LispRuntimeState::shutdown() { EZ_ASSERT(m_stats.m_initializationCount > 0, "LCPP_pRuntime was never initialized."); EZ_ASSERT(m_stats.m_initializationCount > m_stats.m_shutdownCount, "The LCPP_pRuntime was not shut down often enough!"); ++m_stats.m_shutdownCount; m_pGC->removeRoot(m_pReaderState->m_pMacroEnv.get()); m_pGC->removeRoot(m_pGlobalEnvironment); m_pGC->removeRoot(m_pSyntaxEnvironment); m_pReaderState->m_pMacroEnv = nullptr; EZ_DELETE(defaultAllocator(), m_pReaderState); m_pPrinterState->m_pOutStream = nullptr; EZ_DELETE(defaultAllocator(), m_pPrinterState); m_pGlobalEnvironment = nullptr; m_pSyntaxEnvironment = nullptr; // TODO Once we have a per-runtime garbage collector system running, uncomment the following line. //m_pGC->clear(); m_pGC->collect(0); }
static void shutdown() { ezGlobalLog::RemoveLogWriter(ezLoggingEvent::Handler(&ezLogWriter::HTML::LogMessageHandler, g_pHtmlLog)); ezGlobalLog::RemoveLogWriter(ezLogWriter::VisualStudio::LogMessageHandler); ezGlobalLog::RemoveLogWriter(ezLogWriter::Console::LogMessageHandler); g_pHtmlLog->EndLog(); EZ_DELETE(lcpp::defaultAllocator(), g_pHtmlLog); EZ_DELETE(lcpp::defaultAllocator(), g_pEzEngineLogger); lcpp::shutdown(); }
ezWorld::~ezWorld() { // allow reading and writing during destruction m_Data.m_WriteThreadID = ezThreadUtils::GetCurrentThreadID(); m_Data.m_iReadCounter.Increment(); // set all objects to inactive so components and children know that they shouldn't access the objects anymore. for (auto it = m_Data.m_ObjectStorage.GetIterator(); it.IsValid(); it.Next()) { it->m_Flags.Remove(ezObjectFlags::Active); } // deinitialize all modules before we invalidate the world. Components can still access the world during deinitialization. for (ezWorldModule* pModule : m_Data.m_Modules) { if (pModule != nullptr) { pModule->DeinitializeInternal(); } } // now delete all modules for (ezWorldModule* pModule : m_Data.m_Modules) { if (pModule != nullptr) { EZ_DELETE(&m_Data.m_Allocator, pModule); } } m_Data.m_Modules.Clear(); s_Worlds[m_uiIndex] = nullptr; m_uiIndex = ezInvalidIndex; }
void ezWorld::DeleteModule(const ezRTTI* pRtti) { CheckForWriteAccess(); const ezUInt16 uiTypeId = ezWorldModuleFactory::GetInstance()->GetTypeId(pRtti); if (uiTypeId < m_Data.m_Modules.GetCount()) { if (ezWorldModule* pModule = m_Data.m_Modules[uiTypeId]) { m_Data.m_Modules[uiTypeId] = nullptr; pModule->DeinitializeInternal(); DeregisterUpdateFunctions(pModule); EZ_DELETE(&m_Data.m_Allocator, pModule); } } }
void ezWorld::ProcessQueuedMessages(ezObjectMsgQueueType::Enum queueType) { struct MessageComparer { EZ_FORCE_INLINE bool Less(const ezInternal::WorldData::MessageQueue::Entry& a, const ezInternal::WorldData::MessageQueue::Entry& b) const { if (a.m_MetaData.m_Due != b.m_MetaData.m_Due) return a.m_MetaData.m_Due < b.m_MetaData.m_Due; const ezInt32 iKeyA = a.m_pMessage->GetSortingKey(); const ezInt32 iKeyB = b.m_pMessage->GetSortingKey(); if (iKeyA != iKeyB) return iKeyA < iKeyB; if (a.m_pMessage->GetId() != b.m_pMessage->GetId()) return a.m_pMessage->GetId() < b.m_pMessage->GetId(); if (a.m_MetaData.m_uiReceiverComponent != b.m_MetaData.m_uiReceiverComponent) return a.m_MetaData.m_uiReceiverComponent < b.m_MetaData.m_uiReceiverComponent; return a.m_pMessage->GetHash() < b.m_pMessage->GetHash(); } }; // regular messages { ezInternal::WorldData::MessageQueue& queue = m_Data.m_MessageQueues[queueType]; queue.Sort(MessageComparer()); for (ezUInt32 i = 0; i < queue.GetCount(); ++i) { ProcessQueuedMessage(queue[i]); // no need to deallocate these messages, they are allocated through a frame allocator } queue.Clear(); } // timed messages { ezInternal::WorldData::MessageQueue& queue = m_Data.m_TimedMessageQueues[queueType]; queue.Sort(MessageComparer()); const ezTime now = m_Data.m_Clock.GetAccumulatedTime(); while (!queue.IsEmpty()) { auto& entry = queue.Peek(); if (entry.m_MetaData.m_Due > now) break; ProcessQueuedMessage(entry); EZ_DELETE(&m_Data.m_Allocator, entry.m_pMessage); queue.Dequeue(); } } }