!XI (Audio) Integrating CL 2038317 from ce/main to ce/release_candidate
[CRYENGINE.git] / Code / CryEngine / CryAudioSystem / System.cpp
blob9edee2f94ce78c0d1fdc1bbbf9a508cc51606abf
1 // Copyright 2001-2019 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "stdafx.h"
4 #include "System.h"
5 #include "Impl.h"
6 #include "PoolObject_impl.h"
7 #include "Managers.h"
8 #include "FileCacheManager.h"
9 #include "ListenerManager.h"
10 #include "EventListenerManager.h"
11 #include "XMLProcessor.h"
12 #include "SystemRequestData.h"
13 #include "ObjectRequestData.h"
14 #include "ListenerRequestData.h"
15 #include "CallbackRequestData.h"
16 #include "CVars.h"
17 #include "File.h"
18 #include "Listener.h"
19 #include "Object.h"
20 #include "LoseFocusTrigger.h"
21 #include "GetFocusTrigger.h"
22 #include "MuteAllTrigger.h"
23 #include "UnmuteAllTrigger.h"
24 #include "PauseAllTrigger.h"
25 #include "ResumeAllTrigger.h"
26 #include "Environment.h"
27 #include "Parameter.h"
28 #include "PreloadRequest.h"
29 #include "Setting.h"
30 #include "Switch.h"
31 #include "SwitchState.h"
32 #include "Trigger.h"
33 #include "TriggerInstance.h"
34 #include "Common/IObject.h"
35 #include <CrySystem/ITimer.h>
36 #include <CryString/CryPath.h>
37 #include <CryEntitySystem/IEntitySystem.h>
38 #include <CryMath/Cry_Camera.h>
40 #if defined(CRY_AUDIO_USE_OCCLUSION)
41 #include "PropagationProcessor.h"
42 #endif // CRY_AUDIO_USE_OCCLUSION
44 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
45 #include "PreviewTrigger.h"
46 #include "Debug.h"
47 #include "Common/Logger.h"
48 #include "Common/DebugStyle.h"
49 #include <CryRenderer/IRenderAuxGeom.h>
50 #endif // CRY_AUDIO_USE_DEBUG_CODE
52 namespace CryAudio
54 ContextId g_currentLevelContextId = InvalidContextId;
56 constexpr uint16 g_systemExecuteTriggerPoolSize = 4;
57 constexpr uint16 g_systemExecuteTriggerExPoolSize = 16;
58 constexpr uint16 g_systemExecuteTriggerWithCallbacksPoolSize = 16;
59 constexpr uint16 g_systemStopTriggerPoolSize = 4;
60 constexpr uint16 g_systemRegisterObjectPoolSize = 16;
61 constexpr uint16 g_systemReleaseObjectPoolSize = 16;
62 constexpr uint16 g_systemSetParameterPoolSize = 4;
63 constexpr uint16 g_systemSetSwitchStatePoolSize = 4;
65 constexpr uint16 g_objectExecuteTriggerPoolSize = 64;
66 constexpr uint16 g_objectExecuteTriggerWithCallbacksPoolSize = 16;
67 constexpr uint16 g_objectStopTriggerPoolSize = 128;
68 constexpr uint16 g_objectSetTransformationPoolSize = 128;
69 constexpr uint16 g_objectSetParameterPoolSize = 128;
70 constexpr uint16 g_objectSetSwitchStatePoolSize = 64;
71 constexpr uint16 g_objectSetCurrentEnvironmentsPoolSize = 16;
72 constexpr uint16 g_objectSetEnvironmentPoolSize = 64;
73 constexpr uint16 g_objectProcessPhysicsRayPoolSize = 128;
75 constexpr uint16 g_listenerSetTransformationPoolSize = 2;
77 constexpr uint16 g_callbackReportStartedTriggerConnectionInstancePoolSize = 64;
78 constexpr uint16 g_callbackReportFinishedTriggerConnectionInstancePoolSize = 128;
79 constexpr uint16 g_callbackReportFinishedTriggerInstancePoolSize = 128;
80 constexpr uint16 g_callbackReportTriggerConnectionInstanceCallbackPoolSize = 16;
81 constexpr uint16 g_callbackSendTriggerInstanceCallbackPoolSize = 16;
82 constexpr uint16 g_callbackReportPhysicalizedObjectPoolSize = 64;
83 constexpr uint16 g_callbackReportVirtualizedObjectPoolSize = 64;
85 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
86 enum class ELoggingOptions : EnumFlagsType
88 None,
89 Errors = BIT(6), // a
90 Warnings = BIT(7), // b
91 Comments = BIT(8), // c
93 CRY_CREATE_ENUM_FLAG_OPERATORS(ELoggingOptions);
95 enum class EDebugUpdateFilter : EnumFlagsType
97 None = 0,
98 FileCacheManager = BIT(0),
99 Contexts = BIT(1),
101 CRY_CREATE_ENUM_FLAG_OPERATORS(EDebugUpdateFilter);
103 struct SRequestCount final
105 uint16 requests = 0;
107 uint16 systemExecuteTrigger = 0;
108 uint16 systemExecuteTriggerEx = 0;
109 uint16 systemExecuteTriggerWithCallbacks = 0;
110 uint16 systemStopTrigger = 0;
111 uint16 systemRegisterObject = 0;
112 uint16 systemReleaseObject = 0;
113 uint16 systemSetParameter = 0;
114 uint16 systemSetSwitchState = 0;
116 uint16 objectExecuteTrigger = 0;
117 uint16 objectExecuteTriggerWithCallbacks = 0;
118 uint16 objectStopTrigger = 0;
119 uint16 objectSetTransformation = 0;
120 uint16 objectSetParameter = 0;
121 uint16 objectSetSwitchState = 0;
122 uint16 objectSetCurrentEnvironments = 0;
123 uint16 objectSetEnvironment = 0;
124 uint16 objectProcessPhysicsRay = 0;
126 uint16 listenerSetTransformation = 0;
128 uint16 callbackReportStartedriggerConnectionInstance = 0;
129 uint16 callbackReportFinishedTriggerConnectionInstance = 0;
130 uint16 callbackReportFinishedTriggerInstance = 0;
131 uint16 callbackReportTriggerConnectionInstanceCallback = 0;
132 uint16 callbackSendTriggerInstanceCallback = 0;
133 uint16 callbackReportPhysicalizedObject = 0;
134 uint16 callbackReportVirtualizedObject = 0;
137 SRequestCount g_requestsPerUpdate;
138 SRequestCount g_requestPeaks;
139 Debug::StateDrawInfo g_stateDrawInfo;
141 //////////////////////////////////////////////////////////////////////////
142 void CountRequestPerUpdate(CRequest const& request)
144 auto const pRequestData = request.GetData();
146 if (pRequestData != nullptr)
148 g_requestsPerUpdate.requests++;
150 switch (request.GetData()->requestType)
152 case ERequestType::SystemRequest:
154 auto const pBase = static_cast<SSystemRequestDataBase const*>(pRequestData);
156 switch (pBase->systemRequestType)
158 case ESystemRequestType::RegisterObject:
160 g_requestsPerUpdate.systemRegisterObject++;
162 break;
164 case ESystemRequestType::ReleaseObject:
166 g_requestsPerUpdate.systemReleaseObject++;
168 break;
170 case ESystemRequestType::ExecuteTrigger:
172 g_requestsPerUpdate.systemExecuteTrigger++;
174 break;
176 case ESystemRequestType::ExecuteTriggerEx:
178 g_requestsPerUpdate.systemExecuteTriggerEx++;
180 break;
182 case ESystemRequestType::ExecuteTriggerWithCallbacks:
184 g_requestsPerUpdate.systemExecuteTriggerWithCallbacks++;
186 break;
188 case ESystemRequestType::StopTrigger:
190 g_requestsPerUpdate.systemStopTrigger++;
192 break;
194 case ESystemRequestType::SetParameter:
196 g_requestsPerUpdate.systemSetParameter++;
198 break;
200 case ESystemRequestType::SetSwitchState:
202 g_requestsPerUpdate.systemSetSwitchState++;
204 break;
206 default:
208 break;
212 break;
214 case ERequestType::ObjectRequest:
216 auto const pBase = static_cast<SObjectRequestDataBase const*>(pRequestData);
218 switch (pBase->objectRequestType)
220 case EObjectRequestType::ExecuteTrigger:
222 g_requestsPerUpdate.objectExecuteTrigger++;
224 break;
226 case EObjectRequestType::ExecuteTriggerWithCallbacks:
228 g_requestsPerUpdate.objectExecuteTriggerWithCallbacks++;
230 break;
232 case EObjectRequestType::StopTrigger:
234 g_requestsPerUpdate.objectStopTrigger++;
236 break;
238 case EObjectRequestType::SetTransformation:
240 g_requestsPerUpdate.objectSetTransformation++;
242 break;
244 case EObjectRequestType::SetParameter:
246 g_requestsPerUpdate.objectSetParameter++;
248 break;
250 case EObjectRequestType::SetSwitchState:
252 g_requestsPerUpdate.objectSetSwitchState++;
254 break;
256 case EObjectRequestType::SetCurrentEnvironments:
258 g_requestsPerUpdate.objectSetCurrentEnvironments++;
260 break;
262 case EObjectRequestType::SetEnvironment:
264 g_requestsPerUpdate.objectSetEnvironment++;
266 break;
268 case EObjectRequestType::ProcessPhysicsRay:
270 g_requestsPerUpdate.objectProcessPhysicsRay++;
272 break;
274 default:
276 break;
280 break;
282 case ERequestType::ListenerRequest:
284 auto const pBase = static_cast<SListenerRequestDataBase const*>(pRequestData);
286 if (pBase->listenerRequestType == EListenerRequestType::SetTransformation)
288 g_requestsPerUpdate.listenerSetTransformation++;
291 break;
293 case ERequestType::CallbackRequest:
295 auto const pBase = static_cast<SCallbackRequestDataBase const*>(pRequestData);
297 switch (pBase->callbackRequestType)
299 case ECallbackRequestType::ReportStartedTriggerConnectionInstance:
301 g_requestsPerUpdate.callbackReportStartedriggerConnectionInstance++;
303 break;
305 case ECallbackRequestType::ReportFinishedTriggerConnectionInstance:
307 g_requestsPerUpdate.callbackReportFinishedTriggerConnectionInstance++;
309 break;
311 case ECallbackRequestType::ReportFinishedTriggerInstance:
313 g_requestsPerUpdate.callbackReportFinishedTriggerInstance++;
315 break;
317 case ECallbackRequestType::ReportTriggerConnectionInstanceCallback:
319 g_requestsPerUpdate.callbackReportTriggerConnectionInstanceCallback++;
321 break;
323 case ECallbackRequestType::SendTriggerInstanceCallback:
325 g_requestsPerUpdate.callbackSendTriggerInstanceCallback++;
327 break;
329 case ECallbackRequestType::ReportPhysicalizedObject:
331 g_requestsPerUpdate.callbackReportPhysicalizedObject++;
333 break;
335 case ECallbackRequestType::ReportVirtualizedObject:
337 g_requestsPerUpdate.callbackReportVirtualizedObject++;
339 break;
341 default:
343 break;
347 break;
349 default:
351 break;
357 //////////////////////////////////////////////////////////////////////////
358 void SetRequestCountPeak()
360 g_requestPeaks.requests = std::max(g_requestPeaks.requests, g_requestsPerUpdate.requests);
362 g_requestPeaks.systemRegisterObject = std::max(g_requestPeaks.systemRegisterObject, g_requestsPerUpdate.systemRegisterObject);
363 g_requestPeaks.systemReleaseObject = std::max(g_requestPeaks.systemReleaseObject, g_requestsPerUpdate.systemReleaseObject);
364 g_requestPeaks.systemExecuteTrigger = std::max(g_requestPeaks.systemExecuteTrigger, g_requestsPerUpdate.systemExecuteTrigger);
365 g_requestPeaks.systemExecuteTriggerEx = std::max(g_requestPeaks.systemExecuteTriggerEx, g_requestsPerUpdate.systemExecuteTriggerEx);
366 g_requestPeaks.systemExecuteTriggerWithCallbacks = std::max(g_requestPeaks.systemExecuteTriggerWithCallbacks, g_requestsPerUpdate.systemExecuteTriggerWithCallbacks);
367 g_requestPeaks.systemStopTrigger = std::max(g_requestPeaks.systemStopTrigger, g_requestsPerUpdate.systemStopTrigger);
368 g_requestPeaks.systemSetParameter = std::max(g_requestPeaks.systemSetParameter, g_requestsPerUpdate.systemSetParameter);
369 g_requestPeaks.systemSetSwitchState = std::max(g_requestPeaks.systemSetSwitchState, g_requestsPerUpdate.systemSetSwitchState);
371 g_requestPeaks.objectExecuteTrigger = std::max(g_requestPeaks.objectExecuteTrigger, g_requestsPerUpdate.objectExecuteTrigger);
372 g_requestPeaks.objectExecuteTriggerWithCallbacks = std::max(g_requestPeaks.objectExecuteTriggerWithCallbacks, g_requestsPerUpdate.objectExecuteTriggerWithCallbacks);
373 g_requestPeaks.objectStopTrigger = std::max(g_requestPeaks.objectStopTrigger, g_requestsPerUpdate.objectStopTrigger);
374 g_requestPeaks.objectSetTransformation = std::max(g_requestPeaks.objectSetTransformation, g_requestsPerUpdate.objectSetTransformation);
375 g_requestPeaks.objectSetParameter = std::max(g_requestPeaks.objectSetParameter, g_requestsPerUpdate.objectSetParameter);
376 g_requestPeaks.objectSetSwitchState = std::max(g_requestPeaks.objectSetSwitchState, g_requestsPerUpdate.objectSetSwitchState);
377 g_requestPeaks.objectSetCurrentEnvironments = std::max(g_requestPeaks.objectSetCurrentEnvironments, g_requestsPerUpdate.objectSetCurrentEnvironments);
378 g_requestPeaks.objectSetEnvironment = std::max(g_requestPeaks.objectSetEnvironment, g_requestsPerUpdate.objectSetEnvironment);
379 g_requestPeaks.objectProcessPhysicsRay = std::max(g_requestPeaks.objectProcessPhysicsRay, g_requestsPerUpdate.objectProcessPhysicsRay);
381 g_requestPeaks.listenerSetTransformation = std::max(g_requestPeaks.listenerSetTransformation, g_requestsPerUpdate.listenerSetTransformation);
383 g_requestPeaks.callbackReportStartedriggerConnectionInstance = std::max(g_requestPeaks.callbackReportStartedriggerConnectionInstance, g_requestsPerUpdate.callbackReportStartedriggerConnectionInstance);
384 g_requestPeaks.callbackReportFinishedTriggerConnectionInstance = std::max(g_requestPeaks.callbackReportFinishedTriggerConnectionInstance, g_requestsPerUpdate.callbackReportFinishedTriggerConnectionInstance);
385 g_requestPeaks.callbackReportFinishedTriggerInstance = std::max(g_requestPeaks.callbackReportFinishedTriggerInstance, g_requestsPerUpdate.callbackReportFinishedTriggerInstance);
386 g_requestPeaks.callbackReportTriggerConnectionInstanceCallback = std::max(g_requestPeaks.callbackReportTriggerConnectionInstanceCallback, g_requestsPerUpdate.callbackReportTriggerConnectionInstanceCallback);
387 g_requestPeaks.callbackSendTriggerInstanceCallback = std::max(g_requestPeaks.callbackSendTriggerInstanceCallback, g_requestsPerUpdate.callbackSendTriggerInstanceCallback);
388 g_requestPeaks.callbackReportPhysicalizedObject = std::max(g_requestPeaks.callbackReportPhysicalizedObject, g_requestsPerUpdate.callbackReportPhysicalizedObject);
389 g_requestPeaks.callbackReportVirtualizedObject = std::max(g_requestPeaks.callbackReportVirtualizedObject, g_requestsPerUpdate.callbackReportVirtualizedObject);
391 ZeroStruct(g_requestsPerUpdate);
394 //////////////////////////////////////////////////////////////////////////
395 bool ExecuteDefaultTrigger(ControlId const id)
397 bool wasSuccess = true;
399 switch (id)
401 case g_loseFocusTriggerId:
403 g_loseFocusTrigger.Execute();
404 break;
406 case g_getFocusTriggerId:
408 g_getFocusTrigger.Execute();
409 break;
411 case g_muteAllTriggerId:
413 g_muteAllTrigger.Execute();
414 break;
416 case g_unmuteAllTriggerId:
418 g_unmuteAllTrigger.Execute();
419 break;
421 case g_pauseAllTriggerId:
423 g_pauseAllTrigger.Execute();
424 break;
426 case g_resumeAllTriggerId:
428 g_resumeAllTrigger.Execute();
429 break;
431 default:
433 wasSuccess = false;
434 break;
438 return wasSuccess;
441 ///////////////////////////////////////////////////////////////////////////
442 void ForceGlobalDataImplRefresh()
444 // Parameters
445 for (auto const& parameterPair : g_parameters)
447 CParameter const* const pParameter = stl::find_in_map(g_parameterLookup, parameterPair.first, nullptr);
449 if (pParameter != nullptr)
451 pParameter->Set(parameterPair.second);
453 else
455 Cry::Audio::Log(ELogType::Warning, "Parameter \"%u\" does not exist!", parameterPair.first);
459 for (auto const& parameterPair : g_parametersGlobally)
461 CParameter const* const pParameter = stl::find_in_map(g_parameterLookup, parameterPair.first, nullptr);
463 if (pParameter != nullptr)
465 pParameter->SetGlobally(parameterPair.second);
467 else
469 Cry::Audio::Log(ELogType::Warning, "Parameter \"%u\" does not exist!", parameterPair.first);
473 // Switches
474 for (auto const& switchPair : g_switchStates)
476 CSwitch const* const pSwitch = stl::find_in_map(g_switchLookup, switchPair.first, nullptr);
478 if (pSwitch != nullptr)
480 CSwitchState const* const pState = stl::find_in_map(pSwitch->GetStates(), switchPair.second, nullptr);
482 if (pState != nullptr)
484 pState->Set();
489 for (auto const& switchPair : g_switchStatesGlobally)
491 CSwitch const* const pSwitch = stl::find_in_map(g_switchLookup, switchPair.first, nullptr);
493 if (pSwitch != nullptr)
495 CSwitchState const* const pState = stl::find_in_map(pSwitch->GetStates(), switchPair.second, nullptr);
497 if (pState != nullptr)
499 pState->SetGlobally();
504 uint16 triggerCounter = 0;
505 // Last re-execute its active triggers.
506 for (auto const& triggerInstancePair : g_triggerInstances)
508 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, triggerInstancePair.second->GetTriggerId(), nullptr);
510 if (pTrigger != nullptr)
512 pTrigger->Execute(triggerInstancePair.first, triggerInstancePair.second, triggerCounter);
513 ++triggerCounter;
515 else if (!ExecuteDefaultTrigger(triggerInstancePair.second->GetTriggerId()))
517 Cry::Audio::Log(ELogType::Warning, "Trigger \"%u\" does not exist!", triggerInstancePair.second->GetTriggerId());
522 //////////////////////////////////////////////////////////////////////////
523 void UpdateContextDebugInfo(char const* const szDebugFilter)
525 g_contextDebugInfo.clear();
527 CryFixedStringT<MaxControlNameLength> lowerCaseSearchString(szDebugFilter);
528 lowerCaseSearchString.MakeLower();
530 for (auto const& contextPair : g_contextInfo)
532 if (contextPair.second.isRegistered)
534 char const* const szContextName = contextPair.first.c_str();
535 CryFixedStringT<MaxControlNameLength> lowerCaseContextName(szContextName);
536 lowerCaseContextName.MakeLower();
538 if ((lowerCaseSearchString.empty() || (lowerCaseSearchString == "0")) || (lowerCaseContextName.find(lowerCaseSearchString) != CryFixedStringT<MaxControlNameLength>::npos))
540 g_contextDebugInfo.emplace(std::piecewise_construct, std::forward_as_tuple(szContextName), std::forward_as_tuple(contextPair.second.isActive));
546 //////////////////////////////////////////////////////////////////////////
547 void HandleUpdateDebugInfo(EDebugUpdateFilter const filter)
549 char const* const szDebugFilter = g_cvars.m_pDebugFilter->GetString();
551 if ((filter& EDebugUpdateFilter::FileCacheManager) != EDebugUpdateFilter::None)
553 g_fileCacheManager.UpdateDebugInfo(szDebugFilter);
556 if ((filter& EDebugUpdateFilter::Contexts) != EDebugUpdateFilter::None)
558 UpdateContextDebugInfo(szDebugFilter);
561 #endif // CRY_AUDIO_USE_DEBUG_CODE
563 //////////////////////////////////////////////////////////////////////////
564 void ReleaseGlobalData()
566 for (auto& triggerInstancePair : g_triggerInstances)
568 triggerInstancePair.second->Release();
571 g_pIObject = nullptr;
574 ///////////////////////////////////////////////////////////////////////////
575 void ReportStartedGlobalTriggerInstance(TriggerInstanceId const triggerInstanceId, ETriggerResult const result)
577 TriggerInstances::iterator const iter(g_triggerInstances.find(triggerInstanceId));
579 if (iter != g_triggerInstances.end())
581 iter->second->SetPendingToPlaying();
585 ///////////////////////////////////////////////////////////////////////////
586 void ReportFinishedTriggerInstance(TriggerInstanceId const triggerInstanceId, ETriggerResult const result)
588 TriggerInstances::iterator const iter(g_triggerInstances.find(triggerInstanceId));
590 if (iter != g_triggerInstances.end())
592 CTriggerInstance* const pTriggerInstance = iter->second;
594 if (result != ETriggerResult::Pending)
596 if (pTriggerInstance->IsPlayingInstanceFinished())
598 g_triggerInstanceIds.erase(std::remove(g_triggerInstanceIds.begin(), g_triggerInstanceIds.end(), triggerInstanceId), g_triggerInstanceIds.end());
599 pTriggerInstance->SendFinishedRequest();
601 g_triggerInstances.erase(iter);
602 delete pTriggerInstance;
605 else
607 if (pTriggerInstance->IsPendingInstanceFinished())
609 g_triggerInstanceIds.erase(std::remove(g_triggerInstanceIds.begin(), g_triggerInstanceIds.end(), triggerInstanceId), g_triggerInstanceIds.end());
610 pTriggerInstance->SendFinishedRequest();
612 g_triggerInstances.erase(iter);
613 delete pTriggerInstance;
617 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
618 else
620 Cry::Audio::Log(ELogType::Warning, "Unknown trigger instance id %u during %s", triggerInstanceId, __FUNCTION__);
622 #endif // CRY_AUDIO_USE_DEBUG_CODE
625 ///////////////////////////////////////////////////////////////////////////
626 void ReportTriggerInstanceCallback(TriggerInstanceId const triggerInstanceId, ESystemEvents const events)
628 TriggerInstances::iterator const iter(g_triggerInstances.find(triggerInstanceId));
630 if (iter != g_triggerInstances.end())
632 iter->second->SendCallbackRequest(events);
634 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
635 else
637 Cry::Audio::Log(ELogType::Warning, "Unknown trigger instance id %u during %s", triggerInstanceId, __FUNCTION__);
639 #endif // CRY_AUDIO_USE_DEBUG_CODE
642 ///////////////////////////////////////////////////////////////////////////
643 void UpdateGlobalData(float const deltaTime)
645 if (!g_triggerInstances.empty())
647 g_pIObject->Update(deltaTime);
651 //////////////////////////////////////////////////////////////////////////
652 void AllocateMemoryPools()
654 // Controls
655 CTrigger::CreateAllocator(g_poolSizes.triggers);
656 CParameter::CreateAllocator(g_poolSizes.parameters);
657 CSwitch::CreateAllocator(g_poolSizes.switches);
658 CSwitchState::CreateAllocator(g_poolSizes.states);
659 CEnvironment::CreateAllocator(g_poolSizes.environments);
660 CPreloadRequest::CreateAllocator(g_poolSizes.preloads);
661 CSetting::CreateAllocator(g_poolSizes.settings);
663 // Files
664 CFile::CreateAllocator(g_poolSizes.files);
666 // System requests
667 SSystemRequestData<ESystemRequestType::ExecuteTrigger>::CreateAllocator(g_systemExecuteTriggerPoolSize);
668 SSystemRequestData<ESystemRequestType::ExecuteTriggerEx>::CreateAllocator(g_systemExecuteTriggerExPoolSize);
669 SSystemRequestData<ESystemRequestType::ExecuteTriggerWithCallbacks>::CreateAllocator(g_systemExecuteTriggerWithCallbacksPoolSize);
670 SSystemRequestData<ESystemRequestType::StopTrigger>::CreateAllocator(g_systemStopTriggerPoolSize);
671 SSystemRequestData<ESystemRequestType::RegisterObject>::CreateAllocator(g_systemRegisterObjectPoolSize);
672 SSystemRequestData<ESystemRequestType::ReleaseObject>::CreateAllocator(g_systemReleaseObjectPoolSize);
673 SSystemRequestData<ESystemRequestType::SetParameter>::CreateAllocator(g_systemSetParameterPoolSize);
674 SSystemRequestData<ESystemRequestType::SetSwitchState>::CreateAllocator(g_systemSetSwitchStatePoolSize);
676 // Object requests
677 SObjectRequestData<EObjectRequestType::ExecuteTrigger>::CreateAllocator(g_objectExecuteTriggerPoolSize);
678 SObjectRequestData<EObjectRequestType::ExecuteTriggerWithCallbacks>::CreateAllocator(g_objectExecuteTriggerWithCallbacksPoolSize);
679 SObjectRequestData<EObjectRequestType::StopTrigger>::CreateAllocator(g_objectStopTriggerPoolSize);
680 SObjectRequestData<EObjectRequestType::SetTransformation>::CreateAllocator(g_objectSetTransformationPoolSize);
681 SObjectRequestData<EObjectRequestType::SetParameter>::CreateAllocator(g_objectSetParameterPoolSize);
682 SObjectRequestData<EObjectRequestType::SetSwitchState>::CreateAllocator(g_objectSetSwitchStatePoolSize);
683 SObjectRequestData<EObjectRequestType::SetCurrentEnvironments>::CreateAllocator(g_objectSetCurrentEnvironmentsPoolSize);
684 SObjectRequestData<EObjectRequestType::SetEnvironment>::CreateAllocator(g_objectSetEnvironmentPoolSize);
685 SObjectRequestData<EObjectRequestType::ProcessPhysicsRay>::CreateAllocator(g_objectProcessPhysicsRayPoolSize);
687 // Listener requests
688 SListenerRequestData<EListenerRequestType::SetTransformation>::CreateAllocator(g_listenerSetTransformationPoolSize);
690 // Callback requests
691 SCallbackRequestData<ECallbackRequestType::ReportStartedTriggerConnectionInstance>::CreateAllocator(g_callbackReportStartedTriggerConnectionInstancePoolSize);
692 SCallbackRequestData<ECallbackRequestType::ReportFinishedTriggerConnectionInstance>::CreateAllocator(g_callbackReportFinishedTriggerConnectionInstancePoolSize);
693 SCallbackRequestData<ECallbackRequestType::ReportFinishedTriggerInstance>::CreateAllocator(g_callbackReportFinishedTriggerInstancePoolSize);
694 SCallbackRequestData<ECallbackRequestType::ReportTriggerConnectionInstanceCallback>::CreateAllocator(g_callbackReportTriggerConnectionInstanceCallbackPoolSize);
695 SCallbackRequestData<ECallbackRequestType::SendTriggerInstanceCallback>::CreateAllocator(g_callbackSendTriggerInstanceCallbackPoolSize);
696 SCallbackRequestData<ECallbackRequestType::ReportPhysicalizedObject>::CreateAllocator(g_callbackReportPhysicalizedObjectPoolSize);
697 SCallbackRequestData<ECallbackRequestType::ReportVirtualizedObject>::CreateAllocator(g_callbackReportVirtualizedObjectPoolSize);
700 //////////////////////////////////////////////////////////////////////////
701 void FreeMemoryPools()
703 // Controls
704 CTrigger::FreeMemoryPool();
705 CParameter::FreeMemoryPool();
706 CSwitch::FreeMemoryPool();
707 CSwitchState::FreeMemoryPool();
708 CEnvironment::FreeMemoryPool();
709 CPreloadRequest::FreeMemoryPool();
710 CSetting::FreeMemoryPool();
712 // Files
713 CFile::FreeMemoryPool();
715 // System requests
716 SSystemRequestData<ESystemRequestType::ExecuteTrigger>::FreeMemoryPool();
717 SSystemRequestData<ESystemRequestType::ExecuteTriggerEx>::FreeMemoryPool();
718 SSystemRequestData<ESystemRequestType::ExecuteTriggerWithCallbacks>::FreeMemoryPool();
719 SSystemRequestData<ESystemRequestType::StopTrigger>::FreeMemoryPool();
720 SSystemRequestData<ESystemRequestType::RegisterObject>::FreeMemoryPool();
721 SSystemRequestData<ESystemRequestType::ReleaseObject>::FreeMemoryPool();
722 SSystemRequestData<ESystemRequestType::SetParameter>::FreeMemoryPool();
723 SSystemRequestData<ESystemRequestType::SetSwitchState>::FreeMemoryPool();
725 // Object requests
726 SObjectRequestData<EObjectRequestType::ExecuteTrigger>::FreeMemoryPool();
727 SObjectRequestData<EObjectRequestType::ExecuteTriggerWithCallbacks>::FreeMemoryPool();
728 SObjectRequestData<EObjectRequestType::StopTrigger>::FreeMemoryPool();
729 SObjectRequestData<EObjectRequestType::SetTransformation>::FreeMemoryPool();
730 SObjectRequestData<EObjectRequestType::SetParameter>::FreeMemoryPool();
731 SObjectRequestData<EObjectRequestType::SetSwitchState>::FreeMemoryPool();
732 SObjectRequestData<EObjectRequestType::SetCurrentEnvironments>::FreeMemoryPool();
733 SObjectRequestData<EObjectRequestType::SetEnvironment>::FreeMemoryPool();
734 SObjectRequestData<EObjectRequestType::ProcessPhysicsRay>::FreeMemoryPool();
736 // Listener requests
737 SListenerRequestData<EListenerRequestType::SetTransformation>::FreeMemoryPool();
739 // Callback requests
740 SCallbackRequestData<ECallbackRequestType::ReportStartedTriggerConnectionInstance>::FreeMemoryPool();
741 SCallbackRequestData<ECallbackRequestType::ReportFinishedTriggerConnectionInstance>::FreeMemoryPool();
742 SCallbackRequestData<ECallbackRequestType::ReportFinishedTriggerInstance>::FreeMemoryPool();
743 SCallbackRequestData<ECallbackRequestType::ReportTriggerConnectionInstanceCallback>::FreeMemoryPool();
744 SCallbackRequestData<ECallbackRequestType::SendTriggerInstanceCallback>::FreeMemoryPool();
745 SCallbackRequestData<ECallbackRequestType::ReportPhysicalizedObject>::FreeMemoryPool();
746 SCallbackRequestData<ECallbackRequestType::ReportVirtualizedObject>::FreeMemoryPool();
749 //////////////////////////////////////////////////////////////////////////
750 void UpdateActiveObjects(float const deltaTime)
752 #if defined(CRY_AUDIO_USE_DEBUG_CODE) && defined(CRY_AUDIO_USE_OCCLUSION)
753 CPropagationProcessor::s_totalAsyncPhysRays = 0;
754 CPropagationProcessor::s_totalSyncPhysRays = 0;
755 #endif // CRY_AUDIO_USE_DEBUG_CODE && CRY_AUDIO_USE_OCCLUSION
757 if (deltaTime > 0.0f)
759 UpdateGlobalData(deltaTime);
761 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
762 if (g_previewObject.IsActive())
764 g_previewObject.Update(deltaTime);
766 #endif // CRY_AUDIO_USE_DEBUG_CODE
768 auto iter = g_activeObjects.begin();
769 auto iterEnd = g_activeObjects.end();
771 while (iter != iterEnd)
773 CObject* const pObject = *iter;
775 if (pObject->IsActive())
777 pObject->Update(deltaTime);
779 else if (!pObject->HasPendingCallbacks())
781 pObject->RemoveFlag(EObjectFlags::Active);
783 if ((pObject->GetFlags() & EObjectFlags::InUse) == EObjectFlags::None)
785 pObject->Destruct();
788 if (iter != (iterEnd - 1))
790 (*iter) = g_activeObjects.back();
793 g_activeObjects.pop_back();
794 iter = g_activeObjects.begin();
795 iterEnd = g_activeObjects.end();
796 continue;
799 ++iter;
802 else
804 UpdateGlobalData(deltaTime);
806 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
807 if (g_previewObject.IsActive())
809 g_previewObject.Update(deltaTime);
811 #endif // CRY_AUDIO_USE_DEBUG_CODE
813 for (auto const pObject : g_activeObjects)
815 pObject->GetImplData()->Update(deltaTime);
820 //////////////////////////////////////////////////////////////////////////
821 CSystem::~CSystem()
823 CRY_ASSERT_MESSAGE(g_pIImpl == nullptr, "<Audio> The implementation must get destroyed before the audio system is destructed during %s", __FUNCTION__);
824 CRY_ASSERT_MESSAGE(g_activeObjects.empty(), "There are still active objects during %s", __FUNCTION__);
826 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
827 CRY_ASSERT_MESSAGE(g_constructedObjects.empty(), "There are still objects during %s", __FUNCTION__);
828 #endif // CRY_AUDIO_USE_DEBUG_CODE
831 //////////////////////////////////////////////////////////////////////////
832 void CSystem::AddRequestListener(void (*func)(SRequestInfo const* const), void* const pObjectToListenTo, ESystemEvents const eventMask)
834 SSystemRequestData<ESystemRequestType::AddRequestListener> const requestData(pObjectToListenTo, func, eventMask);
835 CRequest const request(&requestData, ERequestFlags::ExecuteBlocking, pObjectToListenTo); // This makes sure that the listener is notified.
836 PushRequest(request);
839 //////////////////////////////////////////////////////////////////////////
840 void CSystem::RemoveRequestListener(void (*func)(SRequestInfo const* const), void* const pObjectToListenTo)
842 SSystemRequestData<ESystemRequestType::RemoveRequestListener> const requestData(pObjectToListenTo, func);
843 CRequest const request(&requestData, ERequestFlags::ExecuteBlocking, pObjectToListenTo); // This makes sure that the listener is notified.
844 PushRequest(request);
847 //////////////////////////////////////////////////////////////////////////
848 void CSystem::ExternalUpdate()
850 CRY_PROFILE_SECTION(PROFILE_AUDIO, "Audio: External Update");
852 CRY_ASSERT(gEnv->mMainThreadId == CryGetCurrentThreadId());
853 CRequest request;
855 while (m_syncCallbacks.dequeue(request))
857 NotifyListener(request);
859 if (request.GetData()->requestType == ERequestType::ObjectRequest)
861 auto const pBase = static_cast<SObjectRequestDataBase const*>(request.GetData());
862 pBase->pObject->DecrementSyncCallbackCounter();
863 // No sync callback counting for default object, because it gets released on unloading of the audio system dll.
867 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
868 DrawDebug();
869 #endif // CRY_AUDIO_USE_DEBUG_CODE
871 m_accumulatedFrameTime += gEnv->pTimer->GetFrameTime();
872 ++m_externalThreadFrameId;
874 // If sleeping, wake up the audio thread to start processing requests again.
875 m_audioThreadWakeupEvent.Set();
878 //////////////////////////////////////////////////////////////////////////
879 void CSystem::PushRequest(CRequest const& request)
881 CRY_PROFILE_FUNCTION(PROFILE_AUDIO);
883 if ((g_systemStates& ESystemStates::ImplShuttingDown) == ESystemStates::None)
885 m_requestQueue.enqueue(request);
887 if ((request.flags & ERequestFlags::ExecuteBlocking) != ERequestFlags::None)
889 // If sleeping, wake up the audio thread to start processing requests again.
890 m_audioThreadWakeupEvent.Set();
892 m_mainEvent.Wait();
893 m_mainEvent.Reset();
895 if ((request.flags & ERequestFlags::CallbackOnExternalOrCallingThread) != ERequestFlags::None)
897 NotifyListener(m_syncRequest);
901 else
903 Log(ELogType::Warning, "Discarded PushRequest due to Audio System not allowing for new ones!");
907 //////////////////////////////////////////////////////////////////////////
908 void CSystem::OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam)
910 switch (event)
912 case ESYSTEM_EVENT_LEVEL_LOAD_START:
914 // This event is issued in Editor and Game mode.
915 string const contextName = PathUtil::GetFileName(reinterpret_cast<const char*>(wparam));
917 if (!contextName.empty() && (contextName.compareNoCase("Untitled") != 0))
919 g_currentLevelContextId = StringToId(contextName.c_str());
921 CryFixedStringT<MaxFilePathLength> contextPath(g_configPath);
922 contextPath += g_szContextsFolderName;
923 contextPath += "/";
924 contextPath += contextName;
926 SSystemRequestData<ESystemRequestType::ParseControlsData> const requestData1(contextPath.c_str(), contextName.c_str(), g_currentLevelContextId);
927 CRequest const request1(&requestData1);
928 PushRequest(request1);
930 SSystemRequestData<ESystemRequestType::ParsePreloadsData> const requestData2(contextPath.c_str(), g_currentLevelContextId);
931 CRequest const request2(&requestData2);
932 PushRequest(request2);
934 auto const preloadRequestId = static_cast<PreloadRequestId>(g_currentLevelContextId);
935 SSystemRequestData<ESystemRequestType::PreloadSingleRequest> const requestData3(preloadRequestId, true);
936 CRequest const request3(&requestData3);
937 PushRequest(request3);
939 SSystemRequestData<ESystemRequestType::AutoLoadSetting> const requestData4(g_currentLevelContextId);
940 CRequest const request4(&requestData4);
941 PushRequest(request4);
943 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
944 ResetRequestCount();
945 #endif // CRY_AUDIO_USE_DEBUG_CODE
948 break;
950 case ESYSTEM_EVENT_LEVEL_UNLOAD:
952 // This event is issued in Editor and Game mode.
953 #if defined(CRY_AUDIO_USE_OCCLUSION)
954 CPropagationProcessor::s_bCanIssueRWIs = false;
955 #endif // CRY_AUDIO_USE_OCCLUSION
957 SSystemRequestData<ESystemRequestType::ReleasePendingRays> const requestData1;
958 CRequest const request1(&requestData1);
959 PushRequest(request1);
961 SSystemRequestData<ESystemRequestType::UnloadAFCMDataByContext> const requestData2(g_currentLevelContextId);
962 CRequest const request2(&requestData2);
963 PushRequest(request2);
965 SSystemRequestData<ESystemRequestType::ClearControlsData> const requestData3(g_currentLevelContextId);
966 CRequest const request3(&requestData3);
967 PushRequest(request3);
969 SSystemRequestData<ESystemRequestType::ClearPreloadsData> const requestData4(g_currentLevelContextId);
970 CRequest const request4(&requestData4);
971 PushRequest(request4);
973 break;
975 #if defined(CRY_AUDIO_USE_OCCLUSION)
976 case ESYSTEM_EVENT_LEVEL_LOAD_END:
978 // This event is issued in Editor and Game mode.
979 CPropagationProcessor::s_bCanIssueRWIs = true;
981 break;
983 #endif // CRY_AUDIO_USE_OCCLUSION
984 case ESYSTEM_EVENT_CRYSYSTEM_INIT_DONE:
986 if (gEnv->pInput != nullptr)
988 gEnv->pInput->AddConsoleEventListener(this);
991 break;
993 case ESYSTEM_EVENT_FULL_SHUTDOWN: // Intentional fall-through.
994 case ESYSTEM_EVENT_FAST_SHUTDOWN:
996 if (gEnv->pInput != nullptr)
998 gEnv->pInput->RemoveConsoleEventListener(this);
1001 break;
1003 case ESYSTEM_EVENT_ACTIVATE:
1005 // When Alt+Tabbing out of the application while it's in full-screen mode
1006 // ESYSTEM_EVENT_ACTIVATE is sent instead of ESYSTEM_EVENT_CHANGE_FOCUS.
1007 if (g_cvars.m_ignoreWindowFocus == 0)
1009 // wparam != 0 is active, wparam == 0 is inactive
1010 // lparam != 0 is minimized, lparam == 0 is not minimized
1011 if (wparam == 0 || lparam != 0)
1013 // lost focus
1014 ExecuteDefaultTrigger(EDefaultTriggerType::LoseFocus);
1016 else
1018 // got focus
1019 ExecuteDefaultTrigger(EDefaultTriggerType::GetFocus);
1023 break;
1025 case ESYSTEM_EVENT_CHANGE_FOCUS:
1027 if (g_cvars.m_ignoreWindowFocus == 0)
1029 // wparam != 0 is focused, wparam == 0 is not focused
1030 if (wparam == 0)
1032 // lost focus
1033 ExecuteDefaultTrigger(EDefaultTriggerType::LoseFocus);
1035 else
1037 // got focus
1038 ExecuteDefaultTrigger(EDefaultTriggerType::GetFocus);
1042 break;
1044 case ESYSTEM_EVENT_AUDIO_MUTE:
1046 ExecuteDefaultTrigger(EDefaultTriggerType::MuteAll);
1048 break;
1050 case ESYSTEM_EVENT_AUDIO_UNMUTE:
1052 ExecuteDefaultTrigger(EDefaultTriggerType::UnmuteAll);
1054 break;
1056 case ESYSTEM_EVENT_AUDIO_PAUSE:
1058 ExecuteDefaultTrigger(EDefaultTriggerType::PauseAll);
1060 break;
1062 case ESYSTEM_EVENT_AUDIO_RESUME:
1064 ExecuteDefaultTrigger(EDefaultTriggerType::ResumeAll);
1066 break;
1068 case ESYSTEM_EVENT_AUDIO_LANGUAGE_CHANGED:
1070 OnLanguageChanged();
1072 break;
1074 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1075 case ESYSTEM_EVENT_AUDIO_REFRESH:
1077 SSystemRequestData<ESystemRequestType::RefreshSystem> const requestData;
1078 CRequest const request(&requestData, ERequestFlags::ExecuteBlocking);
1079 PushRequest(request);
1081 break;
1083 #endif // CRY_AUDIO_USE_DEBUG_CODE
1084 default:
1086 break;
1091 //////////////////////////////////////////////////////////////////////////
1092 bool CSystem::OnInputEvent(SInputEvent const& event)
1094 if (event.state == eIS_Changed && event.deviceType == eIDT_Gamepad)
1096 if (event.keyId == eKI_SYS_ConnectDevice)
1098 g_pIImpl->GamepadConnected(event.deviceUniqueID);
1100 else if (event.keyId == eKI_SYS_DisconnectDevice)
1102 g_pIImpl->GamepadDisconnected(event.deviceUniqueID);
1106 // Do not consume event
1107 return false;
1110 //////////////////////////////////////////////////////////////////////////
1111 void CSystem::InternalUpdate()
1113 CRY_PROFILE_SECTION(PROFILE_AUDIO, "Audio: Internal Update");
1115 if (m_lastExternalThreadFrameId != m_externalThreadFrameId)
1117 if (g_pIImpl != nullptr)
1119 g_listenerManager.Update(m_accumulatedFrameTime);
1120 UpdateActiveObjects(m_accumulatedFrameTime);
1121 g_pIImpl->Update();
1124 ProcessRequests(m_requestQueue);
1125 m_lastExternalThreadFrameId = m_externalThreadFrameId;
1126 m_accumulatedFrameTime = 0.0f;
1127 m_didThreadWait = false;
1129 else if (m_didThreadWait)
1131 // Effectively no time has passed for the external thread as it didn't progress.
1132 // Consequently 0.0f is passed for deltaTime.
1133 if (g_pIImpl != nullptr)
1135 g_listenerManager.Update(0.0f);
1136 UpdateActiveObjects(0.0f);
1137 g_pIImpl->Update();
1140 ProcessRequests(m_requestQueue);
1141 m_didThreadWait = false;
1143 else
1145 // If we're faster than the external thread let's wait to make room for other threads.
1146 CRY_PROFILE_SECTION_WAITING(PROFILE_AUDIO, "Wait - Audio Update");
1148 // The external thread will wake the audio thread up effectively syncing it to itself.
1149 // If not however, the audio thread will execute at a minimum of roughly 30 fps.
1150 if (m_audioThreadWakeupEvent.Wait(30))
1152 // Only reset if the event was signaled, not timed-out!
1153 m_audioThreadWakeupEvent.Reset();
1156 m_didThreadWait = true;
1160 ///////////////////////////////////////////////////////////////////////////
1161 bool CSystem::Initialize()
1163 if (!m_isInitialized)
1165 g_cvars.RegisterVariables();
1167 if (g_cvars.m_objectPoolSize < 1)
1169 g_cvars.m_objectPoolSize = 1;
1171 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1172 Cry::Audio::Log(ELogType::Warning, R"(Audio Object pool size must be at least 1. Forcing the cvar "s_AudioObjectPoolSize" to 1!)");
1173 #endif // CRY_AUDIO_USE_DEBUG_CODE
1176 CObject::CreateAllocator(static_cast<uint16>(g_cvars.m_objectPoolSize));
1178 #if defined(CRY_AUDIO_USE_OCCLUSION)
1179 SOcclusionInfo::CreateAllocator(static_cast<uint16>(g_cvars.m_objectPoolSize));
1180 #endif // CRY_AUDIO_USE_OCCLUSION
1182 if (g_cvars.m_triggerInstancePoolSize < 1)
1184 g_cvars.m_triggerInstancePoolSize = 1;
1186 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1187 Cry::Audio::Log(ELogType::Warning, R"(Trigger instance pool size must be at least 1. Forcing the cvar "s_TriggerInstancePoolSize" to 1!)");
1188 #endif // CRY_AUDIO_USE_DEBUG_CODE
1191 CTriggerInstance::CreateAllocator(static_cast<uint16>(g_cvars.m_triggerInstancePoolSize));
1193 #if defined(CRY_AUDIO_USE_OCCLUSION)
1194 // Add the callback for the obstruction calculation.
1195 gEnv->pPhysicalWorld->AddEventClient(
1196 EventPhysRWIResult::id,
1197 &CPropagationProcessor::OnObstructionTest,
1200 CPropagationProcessor::UpdateOcclusionRayFlags();
1201 CPropagationProcessor::UpdateOcclusionPlanes();
1202 #endif // CRY_AUDIO_USE_OCCLUSION
1204 m_objectPoolSize = static_cast<uint16>(g_cvars.m_objectPoolSize);
1206 g_activeObjects.reserve(static_cast<size_t>(m_objectPoolSize));
1208 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1209 g_constructedObjects.reserve(static_cast<size_t>(m_objectPoolSize));
1211 g_contextInfo.emplace(
1212 std::piecewise_construct,
1213 std::forward_as_tuple(g_szGlobalContextName),
1214 std::forward_as_tuple(SContextInfo(GlobalContextId, true, true)));
1215 #endif // CRY_AUDIO_USE_DEBUG_CODE
1217 g_listenerManager.Initialize();
1218 g_fileCacheManager.Initialize();
1220 CRY_ASSERT_MESSAGE(!m_mainThread.IsActive(), "AudioSystem thread active before initialization during %s", __FUNCTION__);
1221 m_mainThread.Activate();
1222 AddRequestListener(&CSystem::OnCallback, nullptr, ESystemEvents::TriggerExecuted | ESystemEvents::TriggerFinished);
1223 m_isInitialized = true;
1225 else
1227 CRY_ASSERT_MESSAGE(false, "AudioSystem has already been initialized during %s", __FUNCTION__);
1230 return m_isInitialized;
1233 ///////////////////////////////////////////////////////////////////////////
1234 void CSystem::Release()
1236 if (m_isInitialized)
1238 RemoveRequestListener(&CSystem::OnCallback, nullptr);
1240 SSystemRequestData<ESystemRequestType::ReleaseImpl> const requestData;
1241 CRequest const request(&requestData, ERequestFlags::ExecuteBlocking);
1242 PushRequest(request);
1244 m_mainThread.Deactivate();
1246 #if defined(CRY_AUDIO_USE_OCCLUSION)
1247 if (gEnv->pPhysicalWorld != nullptr)
1249 // remove the callback for the obstruction calculation
1250 gEnv->pPhysicalWorld->RemoveEventClient(
1251 EventPhysRWIResult::id,
1252 &CPropagationProcessor::OnObstructionTest,
1255 #endif // CRY_AUDIO_USE_OCCLUSION
1257 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1258 for (auto const pObject : g_constructedObjects)
1260 CRY_ASSERT_MESSAGE(pObject->GetImplData() == nullptr, "An object cannot have valid impl data during %s", __FUNCTION__);
1261 delete pObject;
1264 g_constructedObjects.clear();
1265 #endif // CRY_AUDIO_USE_DEBUG_CODE
1267 g_listenerManager.Terminate();
1268 g_cvars.UnregisterVariables();
1270 CObject::FreeMemoryPool();
1271 CTriggerInstance::FreeMemoryPool();
1273 #if defined(CRY_AUDIO_USE_OCCLUSION)
1274 SOcclusionInfo::FreeMemoryPool();
1275 #endif // CRY_AUDIO_USE_OCCLUSION
1277 m_isInitialized = false;
1279 else
1281 CRY_ASSERT_MESSAGE(false, "AudioSystem has already been released or was never properly initialized during %s", __FUNCTION__);
1285 //////////////////////////////////////////////////////////////////////////
1286 void CSystem::SetImpl(Impl::IImpl* const pIImpl, SRequestUserData const& userData /*= SAudioRequestUserData::GetEmptyObject()*/)
1288 SSystemRequestData<ESystemRequestType::SetImpl> const requestData(pIImpl);
1289 CRequest const request(&requestData, userData);
1290 PushRequest(request);
1293 //////////////////////////////////////////////////////////////////////////
1294 void CSystem::ExecuteTriggerEx(SExecuteTriggerData const& triggerData, SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1296 SSystemRequestData<ESystemRequestType::ExecuteTriggerEx> const requestData(triggerData);
1297 CRequest const request(&requestData, userData);
1298 PushRequest(request);
1301 //////////////////////////////////////////////////////////////////////////
1302 void CSystem::ExecuteDefaultTrigger(EDefaultTriggerType const type, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1304 SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const requestData(type);
1305 CRequest const request(&requestData, userData);
1306 PushRequest(request);
1309 //////////////////////////////////////////////////////////////////////////
1310 void CSystem::SetParameter(ControlId const parameterId, float const value, SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1312 SSystemRequestData<ESystemRequestType::SetParameter> const requestData(parameterId, value);
1313 CRequest const request(&requestData, userData);
1314 PushRequest(request);
1317 //////////////////////////////////////////////////////////////////////////
1318 void CSystem::SetParameterGlobally(ControlId const parameterId, float const value, SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1320 SSystemRequestData<ESystemRequestType::SetParameterGlobally> const requestData(parameterId, value);
1321 CRequest const request(&requestData, userData);
1322 PushRequest(request);
1325 //////////////////////////////////////////////////////////////////////////
1326 void CSystem::SetSwitchState(ControlId const switchId, SwitchStateId const switchStateId, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1328 SSystemRequestData<ESystemRequestType::SetSwitchState> const requestData(switchId, switchStateId);
1329 CRequest const request(&requestData, userData);
1330 PushRequest(request);
1333 //////////////////////////////////////////////////////////////////////////
1334 void CSystem::SetSwitchStateGlobally(ControlId const switchId, SwitchStateId const switchStateId, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1336 SSystemRequestData<ESystemRequestType::SetSwitchStateGlobally> const requestData(switchId, switchStateId);
1337 CRequest const request(&requestData, userData);
1338 PushRequest(request);
1341 //////////////////////////////////////////////////////////////////////////
1342 void CSystem::ExecuteTrigger(ControlId const triggerId, SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1344 SSystemRequestData<ESystemRequestType::ExecuteTrigger> const requestData(triggerId);
1345 CRequest const request(&requestData, userData);
1346 PushRequest(request);
1349 //////////////////////////////////////////////////////////////////////////
1350 void CSystem::ExecuteTriggerWithCallbacks(STriggerCallbackData const& callbackData, SRequestUserData const& userData /* = SRequestUserData::GetEmptyObject() */)
1352 SSystemRequestData<ESystemRequestType::ExecuteTriggerWithCallbacks> const requestData(callbackData);
1353 CRequest const request(&requestData, userData);
1354 PushRequest(request);
1357 //////////////////////////////////////////////////////////////////////////
1358 void CSystem::StopTrigger(ControlId const triggerId /* = CryAudio::InvalidControlId */, SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1360 if (triggerId != InvalidControlId)
1362 SSystemRequestData<ESystemRequestType::StopTrigger> const requestData(triggerId);
1363 CRequest const request(&requestData, userData);
1364 PushRequest(request);
1366 else
1368 SSystemRequestData<ESystemRequestType::StopAllTriggers> const requestData;
1369 CRequest const request(&requestData, userData);
1370 PushRequest(request);
1374 //////////////////////////////////////////////////////////////////////////
1375 void CSystem::ExecutePreviewTrigger(ControlId const triggerId)
1377 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1378 switch (triggerId)
1380 case g_loseFocusTriggerId:
1382 SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const requestData(EDefaultTriggerType::LoseFocus);
1383 CRequest const request(&requestData);
1384 PushRequest(request);
1386 break;
1388 case g_getFocusTriggerId:
1390 SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const requestData(EDefaultTriggerType::GetFocus);
1391 CRequest const request(&requestData);
1392 PushRequest(request);
1394 break;
1396 case g_muteAllTriggerId:
1398 SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const requestData(EDefaultTriggerType::MuteAll);
1399 CRequest const request(&requestData);
1400 PushRequest(request);
1402 break;
1404 case g_unmuteAllTriggerId:
1406 SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const requestData(EDefaultTriggerType::UnmuteAll);
1407 CRequest const request(&requestData);
1408 PushRequest(request);
1410 break;
1412 case g_pauseAllTriggerId:
1414 SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const requestData(EDefaultTriggerType::PauseAll);
1415 CRequest const request(&requestData);
1416 PushRequest(request);
1418 break;
1420 case g_resumeAllTriggerId:
1422 SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const requestData(EDefaultTriggerType::ResumeAll);
1423 CRequest const request(&requestData);
1424 PushRequest(request);
1426 break;
1428 default:
1430 SSystemRequestData<ESystemRequestType::ExecutePreviewTrigger> const requestData(triggerId);
1431 CRequest const request(&requestData);
1432 PushRequest(request);
1434 break;
1437 #endif // CRY_AUDIO_USE_DEBUG_CODE
1440 //////////////////////////////////////////////////////////////////////////
1441 void CSystem::ExecutePreviewTriggerEx(Impl::ITriggerInfo const& triggerInfo)
1443 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1444 SSystemRequestData<ESystemRequestType::ExecutePreviewTriggerEx> const requestData(triggerInfo);
1445 CRequest const request(&requestData);
1446 PushRequest(request);
1447 #endif // CRY_AUDIO_USE_DEBUG_CODE
1450 //////////////////////////////////////////////////////////////////////////
1451 void CSystem::ExecutePreviewTriggerEx(XmlNodeRef const& node)
1453 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1454 SSystemRequestData<ESystemRequestType::ExecutePreviewTriggerExNode> const requestData(node);
1455 CRequest const request(&requestData);
1456 PushRequest(request);
1457 #endif // CRY_AUDIO_USE_DEBUG_CODE
1460 //////////////////////////////////////////////////////////////////////////
1461 void CSystem::StopPreviewTrigger()
1463 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1464 SSystemRequestData<ESystemRequestType::StopPreviewTrigger> const requestData;
1465 CRequest const request(&requestData);
1466 PushRequest(request);
1467 #endif // CRY_AUDIO_USE_DEBUG_CODE
1470 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1471 //////////////////////////////////////////////////////////////////////////
1472 void CSystem::ResetRequestCount()
1474 SSystemRequestData<ESystemRequestType::ResetRequestCount> const requestData;
1475 CRequest const request(&requestData);
1476 PushRequest(request);
1478 #endif // CRY_AUDIO_USE_DEBUG_CODE
1480 //////////////////////////////////////////////////////////////////////////
1481 void CSystem::ReportStartedTriggerConnectionInstance(TriggerInstanceId const triggerInstanceId, ETriggerResult const result, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1483 SCallbackRequestData<ECallbackRequestType::ReportStartedTriggerConnectionInstance> const requestData(triggerInstanceId, result);
1484 CRequest const request(&requestData, userData);
1485 PushRequest(request);
1488 //////////////////////////////////////////////////////////////////////////
1489 void CSystem::ReportFinishedTriggerConnectionInstance(TriggerInstanceId const triggerInstanceId, ETriggerResult const result, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1491 SCallbackRequestData<ECallbackRequestType::ReportFinishedTriggerConnectionInstance> const requestData(triggerInstanceId, result);
1492 CRequest const request(&requestData, userData);
1493 PushRequest(request);
1496 //////////////////////////////////////////////////////////////////////////
1497 void CSystem::ReportTriggerConnectionInstanceCallback(TriggerInstanceId const triggerInstanceId, ESystemEvents const systemEvent, SRequestUserData const& userData /* = SRequestUserData::GetEmptyObject() */)
1499 SCallbackRequestData<ECallbackRequestType::ReportTriggerConnectionInstanceCallback> const requestData(triggerInstanceId, systemEvent);
1500 CRequest const request(&requestData, userData);
1501 PushRequest(request);
1504 //////////////////////////////////////////////////////////////////////////
1505 void CSystem::ReportPhysicalizedObject(Impl::IObject* const pIObject, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1507 SCallbackRequestData<ECallbackRequestType::ReportPhysicalizedObject> const requestData(pIObject);
1508 CRequest const request(&requestData, userData);
1509 PushRequest(request);
1512 //////////////////////////////////////////////////////////////////////////
1513 void CSystem::ReportVirtualizedObject(Impl::IObject* const pIObject, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1515 SCallbackRequestData<ECallbackRequestType::ReportVirtualizedObject> const requestData(pIObject);
1516 CRequest const request(&requestData, userData);
1517 PushRequest(request);
1520 //////////////////////////////////////////////////////////////////////////
1521 void CSystem::StopAllSounds(SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1523 SSystemRequestData<ESystemRequestType::StopAllSounds> const requestData;
1524 CRequest const request(&requestData, userData);
1525 PushRequest(request);
1528 //////////////////////////////////////////////////////////////////////////
1529 void CSystem::ParseControlsData(
1530 char const* const szFolderPath,
1531 char const* const szContextName,
1532 ContextId const contextId,
1533 SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1535 SSystemRequestData<ESystemRequestType::ParseControlsData> const requestData(szFolderPath, szContextName, contextId);
1536 CRequest const request(&requestData, userData);
1537 PushRequest(request);
1540 //////////////////////////////////////////////////////////////////////////
1541 void CSystem::ParsePreloadsData(
1542 char const* const szFolderPath,
1543 ContextId const contextId,
1544 SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1546 SSystemRequestData<ESystemRequestType::ParsePreloadsData> const requestData(szFolderPath, contextId);
1547 CRequest const request(&requestData, userData);
1548 PushRequest(request);
1551 //////////////////////////////////////////////////////////////////////////
1552 void CSystem::PreloadSingleRequest(PreloadRequestId const id, bool const bAutoLoadOnly, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1554 SSystemRequestData<ESystemRequestType::PreloadSingleRequest> const requestData(id, bAutoLoadOnly);
1555 CRequest const request(&requestData, userData);
1556 PushRequest(request);
1559 //////////////////////////////////////////////////////////////////////////
1560 void CSystem::UnloadSingleRequest(PreloadRequestId const id, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1562 SSystemRequestData<ESystemRequestType::UnloadSingleRequest> const requestData(id);
1563 CRequest const request(&requestData, userData);
1564 PushRequest(request);
1567 //////////////////////////////////////////////////////////////////////////
1568 void CSystem::ActivateContext(ContextId const contextId)
1570 if ((contextId != InvalidContextId) && (contextId != GlobalContextId))
1572 SSystemRequestData<ESystemRequestType::ActivateContext> const requestData(contextId);
1573 CRequest const request(&requestData);
1574 PushRequest(request);
1576 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1577 else
1579 if (contextId == InvalidContextId)
1581 Cry::Audio::Log(ELogType::Warning, "Invalid context id passed in %s", __FUNCTION__);
1583 else
1585 Cry::Audio::Log(ELogType::Warning, "The global context cannot get activated manually.");
1588 #endif // CRY_AUDIO_USE_DEBUG_CODE
1591 //////////////////////////////////////////////////////////////////////////
1592 void CSystem::DeactivateContext(ContextId const contextId)
1594 if ((contextId != InvalidContextId) && (contextId != GlobalContextId))
1596 SSystemRequestData<ESystemRequestType::DeactivateContext> const requestData(contextId);
1597 CRequest const request(&requestData);
1598 PushRequest(request);
1600 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1601 else
1603 if (contextId == InvalidContextId)
1605 Cry::Audio::Log(ELogType::Warning, "Invalid context id passed in %s", __FUNCTION__);
1607 else
1609 Cry::Audio::Log(ELogType::Warning, "The global context cannot get deactivated manually.");
1612 #endif // CRY_AUDIO_USE_DEBUG_CODE
1615 //////////////////////////////////////////////////////////////////////////
1616 void CSystem::AutoLoadSetting(ContextId const contextId, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1618 SSystemRequestData<ESystemRequestType::AutoLoadSetting> const requestData(contextId);
1619 CRequest const request(&requestData, userData);
1620 PushRequest(request);
1623 //////////////////////////////////////////////////////////////////////////
1624 void CSystem::LoadSetting(ControlId const id, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1626 SSystemRequestData<ESystemRequestType::LoadSetting> const requestData(id);
1627 CRequest const request(&requestData, userData);
1628 PushRequest(request);
1631 //////////////////////////////////////////////////////////////////////////
1632 void CSystem::UnloadSetting(ControlId const id, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1634 SSystemRequestData<ESystemRequestType::UnloadSetting> const requestData(id);
1635 CRequest const request(&requestData, userData);
1636 PushRequest(request);
1639 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1640 //////////////////////////////////////////////////////////////////////////
1641 void CSystem::RetriggerControls(SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1643 SSystemRequestData<ESystemRequestType::RetriggerControls> const requestData;
1644 CRequest const request(&requestData, userData);
1645 PushRequest(request);
1647 #endif // CRY_AUDIO_USE_DEBUG_CODE
1649 //////////////////////////////////////////////////////////////////////////
1650 void CSystem::ReloadControlsData(SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1652 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1653 SSystemRequestData<ESystemRequestType::ReloadControlsData> const requestData;
1654 CRequest const request(&requestData, userData);
1655 PushRequest(request);
1656 #endif // CRY_AUDIO_USE_DEBUG_CODE
1659 ///////////////////////////////////////////////////////////////////////////
1660 char const* CSystem::GetConfigPath() const
1662 return g_configPath.c_str();
1665 ///////////////////////////////////////////////////////////////////////////
1666 CryAudio::IListener* CSystem::CreateListener(CTransformation const& transformation, char const* const szName)
1668 CListener* pListener = nullptr;
1669 SSystemRequestData<ESystemRequestType::RegisterListener> const requestData(&pListener, transformation, szName);
1670 CRequest const request(&requestData, ERequestFlags::ExecuteBlocking);
1671 PushRequest(request);
1673 return static_cast<CryAudio::IListener*>(pListener);
1676 ///////////////////////////////////////////////////////////////////////////
1677 void CSystem::ReleaseListener(CryAudio::IListener* const pIListener)
1679 if (static_cast<CListener*>(pIListener)->IsUserCreated())
1681 SSystemRequestData<ESystemRequestType::ReleaseListener> const requestData(static_cast<CListener*>(pIListener));
1682 CRequest const request(&requestData);
1683 PushRequest(request);
1685 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1686 else
1688 Cry::Audio::Log(ELogType::Error, "Non-user-created listener cannot get released during %s", __FUNCTION__);
1690 #endif // CRY_AUDIO_USE_DEBUG_CODE
1693 //////////////////////////////////////////////////////////////////////////
1694 IListener* CSystem::GetListener(ListenerId const id /*= DefaultListenerId*/)
1696 CListener* pListener = &g_defaultListener;
1698 if ((id != DefaultListenerId) && (id != InvalidListenerId))
1700 SSystemRequestData<ESystemRequestType::GetListener> const requestData(&pListener, id);
1701 CRequest const request(&requestData, ERequestFlags::ExecuteBlocking);
1702 PushRequest(request);
1705 return static_cast<CryAudio::IListener*>(pListener);
1708 //////////////////////////////////////////////////////////////////////////
1709 CryAudio::IObject* CSystem::CreateObject(SCreateObjectData const& objectData /*= SCreateObjectData::GetEmptyObject()*/)
1711 CObject* pObject = nullptr;
1712 SSystemRequestData<ESystemRequestType::RegisterObject> const requestData(&pObject, objectData);
1713 CRequest const request(&requestData, ERequestFlags::ExecuteBlocking);
1714 PushRequest(request);
1716 return static_cast<CryAudio::IObject*>(pObject);
1719 //////////////////////////////////////////////////////////////////////////
1720 void CSystem::ReleaseObject(CryAudio::IObject* const pIObject)
1722 CRY_ASSERT_MESSAGE(pIObject != nullptr, "pIObject is nullptr during %s", __FUNCTION__);
1723 SSystemRequestData<ESystemRequestType::ReleaseObject> const requestData(static_cast<CObject*>(pIObject));
1724 CRequest const request(&requestData);
1725 PushRequest(request);
1728 //////////////////////////////////////////////////////////////////////////
1729 void CSystem::GetTriggerData(ControlId const triggerId, STriggerData& triggerData)
1731 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1732 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, triggerId, nullptr);
1734 if (pTrigger != nullptr)
1736 triggerData.radius = pTrigger->GetRadius();
1738 #endif // CRY_AUDIO_USE_DEBUG_CODE
1741 //////////////////////////////////////////////////////////////////////////
1742 void CSystem::ReleaseImpl()
1744 // Reject new requests during shutdown.
1745 g_systemStates |= ESystemStates::ImplShuttingDown;
1747 g_pIImpl->OnBeforeRelease();
1749 // Release middleware specific data before its shutdown.
1750 g_listenerManager.ReleaseImplData();
1752 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1753 // Don't delete objects here as we need them to survive a middleware switch!
1754 for (auto const pObject : g_constructedObjects)
1756 g_pIImpl->DestructObject(pObject->GetImplData());
1757 pObject->Release();
1759 #endif // CRY_AUDIO_USE_DEBUG_CODE
1761 g_pIImpl->DestructObject(g_pIObject);
1762 ReleaseGlobalData();
1764 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1765 g_pIImpl->DestructObject(g_previewObject.GetImplData());
1766 g_previewObject.Release();
1767 ResetRequestCount();
1768 #endif // CRY_AUDIO_USE_DEBUG_CODE
1770 g_xmlProcessor.ClearPreloadsData(GlobalContextId, true);
1771 g_xmlProcessor.ClearControlsData(GlobalContextId, true);
1773 ReportContextDeactivated(GlobalContextId);
1775 g_pIImpl->ShutDown();
1776 g_pIImpl->Release();
1777 g_pIImpl = nullptr;
1779 FreeMemoryPools();
1781 g_systemStates &= ~ESystemStates::ImplShuttingDown;
1784 //////////////////////////////////////////////////////////////////////////
1785 void CSystem::OnLanguageChanged()
1787 SSystemRequestData<ESystemRequestType::ChangeLanguage> const requestData;
1788 CRequest const request(&requestData);
1789 PushRequest(request);
1792 //////////////////////////////////////////////////////////////////////////
1793 void CSystem::Log(ELogType const type, char const* const szFormat, ...)
1795 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1796 if (szFormat != nullptr && szFormat[0] != '\0' && gEnv->pLog->GetVerbosityLevel() != -1)
1798 CRY_PROFILE_SECTION(PROFILE_AUDIO, "CSystem::Log");
1800 char buffer[256];
1801 va_list ArgList;
1802 va_start(ArgList, szFormat);
1803 cry_vsprintf(buffer, szFormat, ArgList);
1804 va_end(ArgList);
1806 auto const loggingOptions = static_cast<ELoggingOptions>(g_cvars.m_loggingOptions);
1808 switch (type)
1810 case ELogType::Warning:
1812 if ((loggingOptions& ELoggingOptions::Warnings) != ELoggingOptions::None)
1814 gEnv->pSystem->Warning(VALIDATOR_MODULE_AUDIO, VALIDATOR_WARNING, VALIDATOR_FLAG_AUDIO, nullptr, "<Audio>: %s", buffer);
1817 break;
1819 case ELogType::Error:
1821 if ((loggingOptions& ELoggingOptions::Errors) != ELoggingOptions::None)
1823 gEnv->pSystem->Warning(VALIDATOR_MODULE_AUDIO, VALIDATOR_ERROR, VALIDATOR_FLAG_AUDIO, nullptr, "<Audio>: %s", buffer);
1826 break;
1828 case ELogType::Comment:
1830 if ((gEnv->pLog != nullptr) && (gEnv->pLog->GetVerbosityLevel() >= 4) && ((loggingOptions& ELoggingOptions::Comments) != ELoggingOptions::None))
1832 CryLogAlways("<Audio>: %s", buffer);
1835 break;
1837 case ELogType::Always:
1839 CryLogAlways("<Audio>: %s", buffer);
1841 break;
1843 default:
1845 CRY_ASSERT(false);
1847 break;
1851 #endif // CRY_AUDIO_USE_DEBUG_CODE
1854 //////////////////////////////////////////////////////////////////////////
1855 void CSystem::ProcessRequests(Requests& requestQueue)
1857 CRequest request;
1859 while (requestQueue.dequeue(request))
1861 if (request.status == ERequestStatus::None)
1863 request.status = ERequestStatus::Pending;
1864 ProcessRequest(request);
1866 else
1868 // TODO: handle pending requests!
1871 if (request.status != ERequestStatus::Pending)
1873 if ((request.flags & ERequestFlags::CallbackOnAudioThread) != ERequestFlags::None)
1875 NotifyListener(request);
1877 if ((request.flags & ERequestFlags::ExecuteBlocking) != ERequestFlags::None)
1879 m_mainEvent.Set();
1882 else if ((request.flags & ERequestFlags::CallbackOnExternalOrCallingThread) != ERequestFlags::None)
1884 if ((request.flags & ERequestFlags::ExecuteBlocking) != ERequestFlags::None)
1886 m_syncRequest = request;
1887 m_mainEvent.Set();
1889 else
1891 if (request.GetData()->requestType == ERequestType::ObjectRequest)
1893 auto const pBase = static_cast<SObjectRequestDataBase const*>(request.GetData());
1894 pBase->pObject->IncrementSyncCallbackCounter();
1895 // No sync callback counting for default object, because it gets released on unloading of the audio system dll.
1898 m_syncCallbacks.enqueue(request);
1901 else if ((request.flags & ERequestFlags::ExecuteBlocking) != ERequestFlags::None)
1903 m_mainEvent.Set();
1908 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1909 SetRequestCountPeak();
1910 #endif // CRY_AUDIO_USE_DEBUG_CODE
1913 //////////////////////////////////////////////////////////////////////////
1914 void CSystem::ProcessRequest(CRequest& request)
1916 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1917 CountRequestPerUpdate(request);
1918 #endif // CRY_AUDIO_USE_DEBUG_CODE
1920 ERequestStatus result = ERequestStatus::None;
1922 if (request.GetData())
1924 switch (request.GetData()->requestType)
1926 case ERequestType::ObjectRequest:
1928 result = ProcessObjectRequest(request);
1930 break;
1932 case ERequestType::ListenerRequest:
1934 result = ProcessListenerRequest(request.GetData());
1936 break;
1938 case ERequestType::CallbackRequest:
1940 result = ProcessCallbackRequest(request);
1942 break;
1944 case ERequestType::SystemRequest:
1946 result = ProcessSystemRequest(request);
1948 break;
1950 default:
1952 CRY_ASSERT_MESSAGE(false, "Unknown request type: %u during %s", request.GetData()->requestType, __FUNCTION__);
1954 break;
1959 request.status = result;
1962 //////////////////////////////////////////////////////////////////////////
1963 ERequestStatus CSystem::ProcessSystemRequest(CRequest const& request)
1965 ERequestStatus result = ERequestStatus::Failure;
1966 auto const pBase = static_cast<SSystemRequestDataBase const*>(request.GetData());
1968 switch (pBase->systemRequestType)
1970 case ESystemRequestType::AddRequestListener:
1972 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::AddRequestListener> const*>(request.GetData());
1973 result = g_eventListenerManager.AddRequestListener(pRequestData);
1975 break;
1977 case ESystemRequestType::RemoveRequestListener:
1979 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::RemoveRequestListener> const*>(request.GetData());
1980 result = g_eventListenerManager.RemoveRequestListener(pRequestData->func, pRequestData->pObjectToListenTo);
1982 break;
1984 case ESystemRequestType::SetImpl:
1986 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::SetImpl> const*>(request.GetData());
1987 result = HandleSetImpl(pRequestData->pIImpl);
1989 break;
1991 case ESystemRequestType::ExecuteTrigger:
1993 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecuteTrigger> const* const>(request.GetData());
1995 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->triggerId, nullptr);
1997 if (pTrigger != nullptr)
1999 pTrigger->Execute(request.pOwner, request.pUserData, request.pUserDataOwner, request.flags);
2000 result = ERequestStatus::Success;
2003 break;
2005 case ESystemRequestType::ExecuteTriggerWithCallbacks:
2007 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecuteTriggerWithCallbacks> const* const>(request.GetData());
2009 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->data.triggerId, nullptr);
2011 if (pTrigger != nullptr)
2013 pTrigger->ExecuteWithCallbacks(pRequestData->data, request.pOwner, request.pUserData, request.pUserDataOwner, request.flags);
2014 result = ERequestStatus::Success;
2017 break;
2019 case ESystemRequestType::StopTrigger:
2021 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::StopTrigger> const* const>(request.GetData());
2023 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->triggerId, nullptr);
2025 if (pTrigger != nullptr)
2027 pTrigger->Stop(g_pIObject);
2028 result = ERequestStatus::Success;
2031 break;
2033 case ESystemRequestType::StopAllTriggers:
2035 g_pIObject->StopAllTriggers();
2036 result = ERequestStatus::Success;
2038 break;
2040 case ESystemRequestType::ExecuteTriggerEx:
2042 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecuteTriggerEx> const*>(request.GetData());
2044 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->triggerId, nullptr);
2046 if (pTrigger != nullptr)
2048 Listeners listeners;
2050 for (auto const id : pRequestData->listenerIds)
2052 listeners.push_back(g_listenerManager.GetListener(id));
2055 Impl::IListeners implListeners;
2057 for (auto const pListener : listeners)
2059 implListeners.push_back(pListener->GetImplData());
2062 MEMSTAT_CONTEXT(EMemStatContextType::AudioSystem, "CryAudio::CObject");
2064 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2065 auto const pNewObject = new CObject(pRequestData->transformation, pRequestData->name.c_str());
2066 pNewObject->Init(g_pIImpl->ConstructObject(pRequestData->transformation, implListeners, pNewObject->GetName()), listeners);
2067 g_constructedObjects.push_back(pNewObject);
2068 #else
2069 auto const pNewObject = new CObject(pRequestData->transformation);
2070 pNewObject->Init(g_pIImpl->ConstructObject(pRequestData->transformation, implListeners), listeners);
2071 #endif // CRY_AUDIO_USE_DEBUG_CODE
2073 if (pRequestData->setCurrentEnvironments)
2075 SetCurrentEnvironmentsOnObject(pNewObject, INVALID_ENTITYID);
2078 #if defined(CRY_AUDIO_USE_OCCLUSION)
2079 SetOcclusionType(*pNewObject, pRequestData->occlusionType);
2080 #endif // CRY_AUDIO_USE_OCCLUSION
2081 pTrigger->Execute(*pNewObject, request.pOwner, request.pUserData, request.pUserDataOwner, request.flags, pRequestData->entityId);
2082 pNewObject->RemoveFlag(EObjectFlags::InUse);
2084 if ((pNewObject->GetFlags() & EObjectFlags::Active) == EObjectFlags::None)
2086 pNewObject->Destruct();
2089 result = ERequestStatus::Success;
2092 break;
2094 case ESystemRequestType::ExecuteDefaultTrigger:
2096 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const*>(request.GetData());
2098 switch (pRequestData->triggerType)
2100 case EDefaultTriggerType::LoseFocus:
2102 if ((g_systemStates& ESystemStates::IsMuted) == ESystemStates::None)
2104 g_loseFocusTrigger.Execute();
2107 result = ERequestStatus::Success;
2109 break;
2111 case EDefaultTriggerType::GetFocus:
2113 if ((g_systemStates& ESystemStates::IsMuted) == ESystemStates::None)
2115 g_getFocusTrigger.Execute();
2118 result = ERequestStatus::Success;
2120 break;
2122 case EDefaultTriggerType::MuteAll:
2124 g_muteAllTrigger.Execute();
2125 result = ERequestStatus::Success;
2126 g_systemStates |= ESystemStates::IsMuted;
2128 break;
2130 case EDefaultTriggerType::UnmuteAll:
2132 g_unmuteAllTrigger.Execute();
2133 result = ERequestStatus::Success;
2134 g_systemStates &= ~ESystemStates::IsMuted;
2136 break;
2138 case EDefaultTriggerType::PauseAll:
2140 g_pauseAllTrigger.Execute();
2141 result = ERequestStatus::Success;
2143 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2144 g_systemStates |= ESystemStates::IsPaused;
2145 #endif // CRY_AUDIO_USE_DEBUG_CODE
2147 break;
2149 case EDefaultTriggerType::ResumeAll:
2151 g_resumeAllTrigger.Execute();
2152 result = ERequestStatus::Success;
2154 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2155 g_systemStates &= ~ESystemStates::IsPaused;
2156 #endif // CRY_AUDIO_USE_DEBUG_CODE
2158 break;
2160 default:
2162 break;
2166 break;
2168 case ESystemRequestType::StopAllSounds:
2170 result = g_pIImpl->StopAllSounds();
2172 break;
2174 case ESystemRequestType::ParseControlsData:
2176 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ParseControlsData> const*>(request.GetData());
2177 g_xmlProcessor.ParseControlsData(pRequestData->folderPath.c_str(), pRequestData->contextId, pRequestData->contextName.c_str());
2179 if (pRequestData->contextId != GlobalContextId)
2181 ReportContextActivated(pRequestData->contextId);
2184 result = ERequestStatus::Success;
2186 break;
2188 case ESystemRequestType::ParsePreloadsData:
2190 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ParsePreloadsData> const*>(request.GetData());
2191 g_xmlProcessor.ParsePreloadsData(pRequestData->folderPath.c_str(), pRequestData->contextId);
2193 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2194 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager | EDebugUpdateFilter::Contexts);
2195 #endif // CRY_AUDIO_USE_DEBUG_CODE
2197 result = ERequestStatus::Success;
2199 break;
2201 case ESystemRequestType::ClearControlsData:
2203 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ClearControlsData> const*>(request.GetData());
2204 g_xmlProcessor.ClearControlsData(pRequestData->contextId, false);
2206 ContextId const id = pRequestData->contextId;
2208 if ((id != GlobalContextId) && (id != InvalidContextId))
2210 ReportContextDeactivated(id);
2213 result = ERequestStatus::Success;
2215 break;
2217 case ESystemRequestType::ClearPreloadsData:
2219 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ClearPreloadsData> const*>(request.GetData());
2220 g_xmlProcessor.ClearPreloadsData(pRequestData->contextId, false);
2222 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2223 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager | EDebugUpdateFilter::Contexts);
2224 #endif // CRY_AUDIO_USE_DEBUG_CODE
2226 result = ERequestStatus::Success;
2228 break;
2230 case ESystemRequestType::PreloadSingleRequest:
2232 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::PreloadSingleRequest> const*>(request.GetData());
2233 result = g_fileCacheManager.TryLoadRequest(
2234 pRequestData->preloadRequestId,
2235 ((request.flags & ERequestFlags::ExecuteBlocking) != ERequestFlags::None),
2236 pRequestData->bAutoLoadOnly,
2237 request.flags,
2238 request.pOwner,
2239 request.pUserData,
2240 request.pUserDataOwner);
2242 break;
2244 case ESystemRequestType::UnloadSingleRequest:
2246 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::UnloadSingleRequest> const*>(request.GetData());
2247 result = g_fileCacheManager.TryUnloadRequest(pRequestData->preloadRequestId);
2249 break;
2251 case ESystemRequestType::ActivateContext:
2253 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ActivateContext> const*>(request.GetData());
2255 HandleActivateContext(pRequestData->contextId);
2256 result = ERequestStatus::Success;
2258 break;
2260 case ESystemRequestType::DeactivateContext:
2262 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::DeactivateContext> const*>(request.GetData());
2264 HandleDeactivateContext(pRequestData->contextId);
2265 result = ERequestStatus::Success;
2267 break;
2269 case ESystemRequestType::SetParameter:
2271 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::SetParameter> const*>(request.GetData());
2273 CParameter const* const pParameter = stl::find_in_map(g_parameterLookup, pRequestData->parameterId, nullptr);
2275 if (pParameter != nullptr)
2277 pParameter->Set(pRequestData->value);
2278 result = ERequestStatus::Success;
2281 break;
2283 case ESystemRequestType::SetParameterGlobally:
2285 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::SetParameter> const*>(request.GetData());
2287 CParameter const* const pParameter = stl::find_in_map(g_parameterLookup, pRequestData->parameterId, nullptr);
2289 if (pParameter != nullptr)
2291 pParameter->SetGlobally(pRequestData->value);
2292 result = ERequestStatus::Success;
2295 break;
2297 case ESystemRequestType::SetSwitchState:
2299 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::SetSwitchState> const*>(request.GetData());
2301 CSwitch const* const pSwitch = stl::find_in_map(g_switchLookup, pRequestData->switchId, nullptr);
2303 if (pSwitch != nullptr)
2305 CSwitchState const* const pState = stl::find_in_map(pSwitch->GetStates(), pRequestData->switchStateId, nullptr);
2307 if (pState != nullptr)
2309 pState->Set();
2310 result = ERequestStatus::Success;
2314 break;
2316 case ESystemRequestType::SetSwitchStateGlobally:
2318 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::SetSwitchState> const*>(request.GetData());
2320 CSwitch const* const pSwitch = stl::find_in_map(g_switchLookup, pRequestData->switchId, nullptr);
2322 if (pSwitch != nullptr)
2324 CSwitchState const* const pState = stl::find_in_map(pSwitch->GetStates(), pRequestData->switchStateId, nullptr);
2326 if (pState != nullptr)
2328 pState->SetGlobally();
2329 result = ERequestStatus::Success;
2333 break;
2335 case ESystemRequestType::AutoLoadSetting:
2337 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::AutoLoadSetting> const*>(request.GetData());
2339 for (auto const& settingPair : g_settingLookup)
2341 CSetting const* const pSetting = settingPair.second;
2343 if (pSetting->IsAutoLoad() && (pSetting->GetContextId() == pRequestData->contextId))
2345 pSetting->Load();
2346 break;
2350 result = ERequestStatus::Success;
2352 break;
2354 case ESystemRequestType::LoadSetting:
2356 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::LoadSetting> const*>(request.GetData());
2358 CSetting const* const pSetting = stl::find_in_map(g_settingLookup, pRequestData->id, nullptr);
2360 if (pSetting != nullptr)
2362 pSetting->Load();
2363 result = ERequestStatus::Success;
2366 break;
2368 case ESystemRequestType::UnloadSetting:
2370 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::UnloadSetting> const*>(request.GetData());
2372 CSetting const* const pSetting = stl::find_in_map(g_settingLookup, pRequestData->id, nullptr);
2374 if (pSetting != nullptr)
2376 pSetting->Unload();
2377 result = ERequestStatus::Success;
2380 break;
2382 case ESystemRequestType::UnloadAFCMDataByContext:
2384 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::UnloadAFCMDataByContext> const*>(request.GetData());
2385 result = g_fileCacheManager.UnloadDataByContext(pRequestData->contextId);
2387 break;
2389 case ESystemRequestType::ReleaseImpl:
2391 ReleaseImpl();
2392 result = ERequestStatus::Success;
2394 break;
2396 case ESystemRequestType::ChangeLanguage:
2398 SetImplLanguage();
2400 g_fileCacheManager.UpdateLocalizedFileCacheEntries();
2402 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2403 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager);
2404 #endif // CRY_AUDIO_USE_DEBUG_CODE
2406 result = ERequestStatus::Success;
2408 break;
2410 #if defined(CRY_AUDIO_USE_OCCLUSION)
2411 case ESystemRequestType::ReleasePendingRays:
2413 for (auto const pObject : g_activeObjects)
2415 pObject->ReleasePendingRays();
2418 result = ERequestStatus::Success;
2420 break;
2422 #endif // CRY_AUDIO_USE_OCCLUSION
2423 case ESystemRequestType::GetImplInfo:
2425 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::GetImplInfo> const*>(request.GetData());
2426 g_pIImpl->GetInfo(pRequestData->implInfo);
2427 break;
2429 case ESystemRequestType::RegisterListener:
2431 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::RegisterListener> const*>(request.GetData());
2432 *pRequestData->ppListener = g_listenerManager.CreateListener(pRequestData->transformation, pRequestData->name.c_str(), true);
2433 break;
2435 case ESystemRequestType::ReleaseListener:
2437 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ReleaseListener> const*>(request.GetData());
2439 CRY_ASSERT(pRequestData->pListener != nullptr);
2441 if (pRequestData->pListener != nullptr)
2443 g_listenerManager.ReleaseListener(pRequestData->pListener);
2444 result = ERequestStatus::Success;
2447 break;
2449 case ESystemRequestType::GetListener:
2451 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::GetListener> const*>(request.GetData());
2452 *pRequestData->ppListener = g_listenerManager.GetListener(pRequestData->id);
2453 break;
2455 case ESystemRequestType::RegisterObject:
2457 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::RegisterObject> const*>(request.GetData());
2459 Listeners listeners;
2461 for (auto const id : pRequestData->listenerIds)
2463 listeners.push_back(g_listenerManager.GetListener(id));
2466 Impl::IListeners implListeners;
2467 implListeners.reserve(listeners.size());
2469 for (auto const pListener : listeners)
2471 implListeners.push_back(pListener->GetImplData());
2474 MEMSTAT_CONTEXT(EMemStatContextType::AudioSystem, "CryAudio::CObject");
2476 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2477 auto const pNewObject = new CObject(pRequestData->transformation, pRequestData->name.c_str());
2478 pNewObject->Init(g_pIImpl->ConstructObject(pRequestData->transformation, implListeners, pNewObject->GetName()), listeners);
2479 g_constructedObjects.push_back(pNewObject);
2480 #else
2481 auto const pNewObject = new CObject(pRequestData->transformation);
2482 pNewObject->Init(g_pIImpl->ConstructObject(pRequestData->transformation, implListeners), listeners);
2483 #endif // CRY_AUDIO_USE_DEBUG_CODE
2485 if (pRequestData->setCurrentEnvironments)
2487 SetCurrentEnvironmentsOnObject(pNewObject, INVALID_ENTITYID);
2490 #if defined(CRY_AUDIO_USE_OCCLUSION)
2491 SetOcclusionType(*pNewObject, pRequestData->occlusionType);
2492 #endif // CRY_AUDIO_USE_OCCLUSION
2493 *pRequestData->ppObject = pNewObject;
2494 result = ERequestStatus::Success;
2496 break;
2498 case ESystemRequestType::ReleaseObject:
2500 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ReleaseObject> const*>(request.GetData());
2502 pRequestData->pObject->RemoveFlag(EObjectFlags::InUse);
2504 if ((pRequestData->pObject->GetFlags() & EObjectFlags::Active) == EObjectFlags::None)
2506 pRequestData->pObject->Destruct();
2509 result = ERequestStatus::Success;
2511 break;
2513 case ESystemRequestType::None:
2515 result = ERequestStatus::Success;
2517 break;
2519 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2520 case ESystemRequestType::RefreshSystem:
2522 HandleRefresh();
2523 HandleRetriggerControls();
2524 result = ERequestStatus::Success;
2526 break;
2528 case ESystemRequestType::ExecutePreviewTrigger:
2530 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecutePreviewTrigger> const*>(request.GetData());
2532 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->triggerId, nullptr);
2534 if (pTrigger != nullptr)
2536 pTrigger->Execute(g_previewObject, request.pOwner, request.pUserData, request.pUserDataOwner, request.flags);
2537 result = ERequestStatus::Success;
2540 break;
2542 case ESystemRequestType::ExecutePreviewTriggerEx:
2544 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecutePreviewTriggerEx> const*>(request.GetData());
2546 g_previewTrigger.Execute(pRequestData->triggerInfo);
2547 result = ERequestStatus::Success;
2549 break;
2551 case ESystemRequestType::ExecutePreviewTriggerExNode:
2553 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecutePreviewTriggerExNode> const*>(request.GetData());
2555 g_previewTrigger.Execute(pRequestData->node);
2556 result = ERequestStatus::Success;
2558 break;
2560 case ESystemRequestType::StopPreviewTrigger:
2562 g_previewObject.StopAllTriggers();
2563 result = ERequestStatus::Success;
2565 break;
2567 case ESystemRequestType::ResetRequestCount:
2569 ZeroStruct(g_requestsPerUpdate);
2570 ZeroStruct(g_requestPeaks);
2571 result = ERequestStatus::Success;
2573 break;
2575 case ESystemRequestType::RetriggerControls:
2577 HandleRetriggerControls();
2578 result = ERequestStatus::Success;
2580 break;
2582 case ESystemRequestType::ReloadControlsData:
2584 for (auto const pObject : g_activeObjects)
2586 pObject->StopAllTriggers();
2589 g_pIObject->StopAllTriggers();
2590 g_previewObject.StopAllTriggers();
2592 // Store active contexts for reloading after they have been unloaded which empties the map.
2593 ContextInfo const tempContextInfo = g_contextInfo;
2595 g_xmlProcessor.ClearControlsData(GlobalContextId, true);
2596 ReportContextDeactivated(GlobalContextId);
2598 g_xmlProcessor.ParseSystemData();
2599 g_xmlProcessor.ParseControlsData(g_configPath.c_str(), GlobalContextId, g_szGlobalContextName);
2601 for (auto const& contextPair : tempContextInfo)
2603 ContextId const contextId = contextPair.second.contextId;
2605 if (contextPair.second.isRegistered && contextPair.second.isActive && (contextId != GlobalContextId))
2607 char const* const szContextName = contextPair.first.c_str();
2609 CryFixedStringT<MaxFilePathLength> contextPath = g_configPath;
2610 contextPath += g_szContextsFolderName;
2611 contextPath += "/";
2612 contextPath += szContextName;
2614 g_xmlProcessor.ParseControlsData(contextPath.c_str(), contextId, szContextName);
2616 ReportContextActivated(contextId);
2620 HandleRetriggerControls();
2622 result = ERequestStatus::Success;
2624 break;
2626 case ESystemRequestType::DrawDebugInfo:
2628 HandleDrawDebug();
2629 m_canDraw = true;
2630 result = ERequestStatus::Success;
2632 break;
2634 case ESystemRequestType::UpdateDebugInfo:
2636 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager | EDebugUpdateFilter::Contexts);
2637 result = ERequestStatus::Success;
2639 break;
2641 #endif // CRY_AUDIO_USE_DEBUG_CODE
2642 default:
2644 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2645 Cry::Audio::Log(ELogType::Warning, "Unknown manager request type: %u", pBase->systemRequestType);
2646 #endif // CRY_AUDIO_USE_DEBUG_CODE
2648 break;
2652 return result;
2655 //////////////////////////////////////////////////////////////////////////
2656 ERequestStatus CSystem::ProcessCallbackRequest(CRequest& request)
2658 ERequestStatus result = ERequestStatus::Failure;
2659 auto const pBase = static_cast<SCallbackRequestDataBase const*>(request.GetData());
2661 switch (pBase->callbackRequestType)
2663 case ECallbackRequestType::ReportStartedTriggerConnectionInstance:
2665 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportStartedTriggerConnectionInstance> const*>(request.GetData());
2667 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2668 bool objectFound = false;
2669 #endif // CRY_AUDIO_USE_DEBUG_CODE
2671 CObject* const pObject = stl::find_in_map(g_triggerInstanceIdLookup, pRequestData->triggerInstanceId, nullptr);
2673 if (pObject != nullptr)
2675 pObject->ReportStartedTriggerInstance(pRequestData->triggerInstanceId, pRequestData->result);
2677 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2678 objectFound = true;
2679 #endif // CRY_AUDIO_USE_DEBUG_CODE
2681 else if (std::find(g_triggerInstanceIds.begin(), g_triggerInstanceIds.end(), pRequestData->triggerInstanceId) != g_triggerInstanceIds.end())
2683 ReportStartedGlobalTriggerInstance(pRequestData->triggerInstanceId, pRequestData->result);
2685 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2686 objectFound = true;
2687 #endif // CRY_AUDIO_USE_DEBUG_CODE
2690 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2691 CRY_ASSERT_MESSAGE(objectFound, "TriggerInstanceId %u is not mapped to an object during %s", pRequestData->triggerInstanceId, __FUNCTION__);
2692 #endif // CRY_AUDIO_USE_DEBUG_CODE
2694 result = ERequestStatus::Success;
2696 break;
2698 case ECallbackRequestType::ReportFinishedTriggerConnectionInstance:
2700 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportFinishedTriggerConnectionInstance> const*>(request.GetData());
2702 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2703 bool objectFound = false;
2704 #endif // CRY_AUDIO_USE_DEBUG_CODE
2706 CObject* const pObject = stl::find_in_map(g_triggerInstanceIdLookup, pRequestData->triggerInstanceId, nullptr);
2708 if (pObject != nullptr)
2710 pObject->ReportFinishedTriggerInstance(pRequestData->triggerInstanceId, pRequestData->result);
2712 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2713 objectFound = true;
2714 #endif // CRY_AUDIO_USE_DEBUG_CODE
2717 else if (std::find(g_triggerInstanceIds.begin(), g_triggerInstanceIds.end(), pRequestData->triggerInstanceId) != g_triggerInstanceIds.end())
2719 ReportFinishedTriggerInstance(pRequestData->triggerInstanceId, pRequestData->result);
2721 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2722 objectFound = true;
2723 #endif // CRY_AUDIO_USE_DEBUG_CODE
2726 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2727 CRY_ASSERT_MESSAGE(objectFound, "TriggerInstanceId %u is not mapped to an object during %s", pRequestData->triggerInstanceId, __FUNCTION__);
2728 #endif // CRY_AUDIO_USE_DEBUG_CODE
2730 result = ERequestStatus::Success;
2732 break;
2734 case ECallbackRequestType::ReportTriggerConnectionInstanceCallback:
2736 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportTriggerConnectionInstanceCallback> const*>(request.GetData());
2738 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2739 bool objectFound = false;
2740 #endif // CRY_AUDIO_USE_DEBUG_CODE
2742 CObject* const pObject = stl::find_in_map(g_triggerInstanceIdLookup, pRequestData->triggerInstanceId, nullptr);
2744 if (pObject != nullptr)
2746 pObject->ReportTriggerInstanceCallback(pRequestData->triggerInstanceId, pRequestData->events);
2748 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2749 objectFound = true;
2750 #endif // CRY_AUDIO_USE_DEBUG_CODE
2753 else if (std::find(g_triggerInstanceIds.begin(), g_triggerInstanceIds.end(), pRequestData->triggerInstanceId) != g_triggerInstanceIds.end())
2755 ReportTriggerInstanceCallback(pRequestData->triggerInstanceId, pRequestData->events);
2757 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2758 objectFound = true;
2759 #endif // CRY_AUDIO_USE_DEBUG_CODE
2762 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2763 CRY_ASSERT_MESSAGE(objectFound, "TriggerInstanceId %u is not mapped to an object during %s", pRequestData->triggerInstanceId, __FUNCTION__);
2764 #endif // CRY_AUDIO_USE_DEBUG_CODE
2766 result = ERequestStatus::Success;
2768 break;
2770 case ECallbackRequestType::ReportPhysicalizedObject:
2772 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportPhysicalizedObject> const*>(request.GetData());
2774 for (auto const pObject : g_activeObjects)
2776 if (pObject->GetImplData() == pRequestData->pIObject)
2778 pObject->RemoveFlag(EObjectFlags::Virtual);
2780 #if defined(CRY_AUDIO_USE_DEBUG_CODE) && defined(CRY_AUDIO_USE_OCCLUSION)
2781 pObject->ResetObstructionRays();
2782 #endif // CRY_AUDIO_USE_DEBUG_CODE && CRY_AUDIO_USE_OCCLUSION
2784 break;
2788 result = ERequestStatus::Success;
2790 break;
2792 case ECallbackRequestType::ReportVirtualizedObject:
2794 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportVirtualizedObject> const*>(request.GetData());
2796 for (auto const pObject : g_activeObjects)
2798 if (pObject->GetImplData() == pRequestData->pIObject)
2800 pObject->SetFlag(EObjectFlags::Virtual);
2801 break;
2805 result = ERequestStatus::Success;
2807 break;
2809 case ECallbackRequestType::ReportFinishedTriggerInstance: // Intentional fall-through.
2810 case ECallbackRequestType::ReportContextActivated: // Intentional fall-through.
2811 case ECallbackRequestType::ReportContextDeactivated: // Intentional fall-through.
2812 case ECallbackRequestType::ReportFinishedPreload: // Intentional fall-through.
2813 case ECallbackRequestType::None:
2815 result = ERequestStatus::Success;
2817 break;
2819 default:
2821 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2822 Cry::Audio::Log(ELogType::Warning, "Unknown callback manager request type: %u", pBase->callbackRequestType);
2823 #endif // CRY_AUDIO_USE_DEBUG_CODE
2825 break;
2829 return result;
2832 //////////////////////////////////////////////////////////////////////////
2833 ERequestStatus CSystem::ProcessObjectRequest(CRequest const& request)
2835 ERequestStatus result = ERequestStatus::Failure;
2837 auto const pBase = static_cast<SObjectRequestDataBase const*>(request.GetData());
2838 CObject* const pObject = pBase->pObject;
2840 switch (pBase->objectRequestType)
2842 case EObjectRequestType::ExecuteTrigger:
2844 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::ExecuteTrigger> const*>(request.GetData());
2846 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->triggerId, nullptr);
2848 if (pTrigger != nullptr)
2850 pTrigger->Execute(*pObject, request.pOwner, request.pUserData, request.pUserDataOwner, request.flags, pRequestData->entityId);
2851 result = ERequestStatus::Success;
2854 break;
2856 case EObjectRequestType::ExecuteTriggerWithCallbacks:
2858 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::ExecuteTriggerWithCallbacks> const*>(request.GetData());
2860 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->data.triggerId, nullptr);
2862 if (pTrigger != nullptr)
2864 pTrigger->ExecuteWithCallbacks(*pObject, pRequestData->data, request.pOwner, request.pUserData, request.pUserDataOwner, request.flags, pRequestData->entityId);
2865 result = ERequestStatus::Success;
2868 break;
2870 case EObjectRequestType::StopTrigger:
2872 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::StopTrigger> const*>(request.GetData());
2874 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->triggerId, nullptr);
2876 if (pTrigger != nullptr)
2878 pTrigger->Stop(pObject->GetImplData());
2879 result = ERequestStatus::Success;
2882 break;
2884 case EObjectRequestType::StopAllTriggers:
2886 pObject->StopAllTriggers();
2887 result = ERequestStatus::Success;
2889 break;
2891 case EObjectRequestType::SetTransformation:
2893 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetTransformation> const*>(request.GetData());
2895 pObject->HandleSetTransformation(pRequestData->transformation);
2896 result = ERequestStatus::Success;
2898 break;
2900 case EObjectRequestType::SetParameter:
2902 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetParameter> const*>(request.GetData());
2904 CParameter const* const pParameter = stl::find_in_map(g_parameterLookup, pRequestData->parameterId, nullptr);
2906 if (pParameter != nullptr)
2908 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2909 pParameter->Set(*pObject, pRequestData->value);
2910 #else
2911 pParameter->Set(pObject->GetImplData(), pRequestData->value);
2912 #endif // CRY_AUDIO_USE_DEBUG_CODE
2914 result = ERequestStatus::Success;
2917 break;
2919 case EObjectRequestType::SetSwitchState:
2921 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetSwitchState> const*>(request.GetData());
2923 CSwitch const* const pSwitch = stl::find_in_map(g_switchLookup, pRequestData->switchId, nullptr);
2925 if (pSwitch != nullptr)
2927 CSwitchState const* const pState = stl::find_in_map(pSwitch->GetStates(), pRequestData->switchStateId, nullptr);
2929 if (pState != nullptr)
2931 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2932 pState->Set(*pObject);
2933 #else
2934 pState->Set(pObject->GetImplData());
2935 #endif // CRY_AUDIO_USE_DEBUG_CODE
2937 result = ERequestStatus::Success;
2941 break;
2943 #if defined(CRY_AUDIO_USE_OCCLUSION)
2944 case EObjectRequestType::SetOcclusionType:
2946 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetOcclusionType> const*>(request.GetData());
2948 SetOcclusionType(*pObject, pRequestData->occlusionType);
2949 result = ERequestStatus::Success;
2951 break;
2953 case EObjectRequestType::SetOcclusionRayOffset:
2955 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetOcclusionRayOffset> const*>(request.GetData());
2957 pObject->HandleSetOcclusionRayOffset(pRequestData->occlusionRayOffset);
2958 result = ERequestStatus::Success;
2960 break;
2962 #endif // CRY_AUDIO_USE_OCCLUSION
2963 case EObjectRequestType::SetCurrentEnvironments:
2965 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetCurrentEnvironments> const*>(request.GetData());
2967 SetCurrentEnvironmentsOnObject(pObject, pRequestData->entityToIgnore);
2969 break;
2971 case EObjectRequestType::SetEnvironment:
2973 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetEnvironment> const*>(request.GetData());
2975 CEnvironment const* const pEnvironment = stl::find_in_map(g_environmentLookup, pRequestData->environmentId, nullptr);
2977 if (pEnvironment != nullptr)
2979 pEnvironment->Set(*pObject, pRequestData->amount);
2980 result = ERequestStatus::Success;
2983 break;
2985 #if defined(CRY_AUDIO_USE_OCCLUSION)
2986 case EObjectRequestType::ProcessPhysicsRay:
2988 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::ProcessPhysicsRay> const*>(request.GetData());
2990 pObject->ProcessPhysicsRay(pRequestData->rayInfo);
2991 result = ERequestStatus::Success;
2993 break;
2995 #endif // CRY_AUDIO_USE_OCCLUSION
2996 case EObjectRequestType::AddListener:
2998 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::AddListener> const*>(request.GetData());
3000 pObject->HandleAddListener(pRequestData->listenerId);
3001 result = ERequestStatus::Success;
3003 break;
3005 case EObjectRequestType::RemoveListener:
3007 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::RemoveListener> const*>(request.GetData());
3009 pObject->HandleRemoveListener(pRequestData->listenerId);
3010 result = ERequestStatus::Success;
3012 break;
3014 case EObjectRequestType::ToggleAbsoluteVelocityTracking:
3016 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::ToggleAbsoluteVelocityTracking> const*>(request.GetData());
3018 if (pRequestData->isEnabled)
3020 pObject->GetImplData()->ToggleFunctionality(EObjectFunctionality::TrackAbsoluteVelocity, true);
3022 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3023 pObject->SetFlag(EObjectFlags::TrackAbsoluteVelocity);
3024 #endif // CRY_AUDIO_USE_DEBUG_CODE
3026 else
3028 pObject->GetImplData()->ToggleFunctionality(EObjectFunctionality::TrackAbsoluteVelocity, false);
3030 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3031 pObject->RemoveFlag(EObjectFlags::TrackAbsoluteVelocity);
3032 #endif // CRY_AUDIO_USE_DEBUG_CODE
3035 result = ERequestStatus::Success;
3036 break;
3038 case EObjectRequestType::ToggleRelativeVelocityTracking:
3040 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::ToggleRelativeVelocityTracking> const*>(request.GetData());
3042 if (pRequestData->isEnabled)
3044 pObject->GetImplData()->ToggleFunctionality(EObjectFunctionality::TrackRelativeVelocity, true);
3046 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3047 pObject->SetFlag(EObjectFlags::TrackRelativeVelocity);
3048 #endif // CRY_AUDIO_USE_DEBUG_CODE
3050 else
3052 pObject->GetImplData()->ToggleFunctionality(EObjectFunctionality::TrackRelativeVelocity, false);
3054 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3055 pObject->RemoveFlag(EObjectFlags::TrackRelativeVelocity);
3056 #endif // CRY_AUDIO_USE_DEBUG_CODE
3059 result = ERequestStatus::Success;
3060 break;
3062 case EObjectRequestType::None:
3064 result = ERequestStatus::Success;
3065 break;
3067 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3068 case EObjectRequestType::SetName:
3070 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetName> const*>(request.GetData());
3072 result = pObject->HandleSetName(pRequestData->name.c_str());
3074 if (result == ERequestStatus::SuccessNeedsRefresh)
3076 pObject->ForceImplementationRefresh();
3077 result = ERequestStatus::Success;
3080 break;
3082 #endif // CRY_AUDIO_USE_DEBUG_CODE
3083 default:
3085 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3086 Cry::Audio::Log(ELogType::Warning, "Unknown object request type: %u", pBase->objectRequestType);
3087 #endif // CRY_AUDIO_USE_DEBUG_CODE
3089 break;
3093 return result;
3096 //////////////////////////////////////////////////////////////////////////
3097 ERequestStatus CSystem::ProcessListenerRequest(SRequestData const* const pPassedRequestData)
3099 ERequestStatus result = ERequestStatus::Failure;
3100 auto const pBase = static_cast<SListenerRequestDataBase const*>(pPassedRequestData);
3102 switch (pBase->listenerRequestType)
3104 case EListenerRequestType::SetTransformation:
3106 auto const pRequestData = static_cast<SListenerRequestData<EListenerRequestType::SetTransformation> const* const>(pPassedRequestData);
3108 CRY_ASSERT(pRequestData->pListener != nullptr);
3110 if (pRequestData->pListener != nullptr)
3112 pRequestData->pListener->HandleSetTransformation(pRequestData->transformation);
3115 result = ERequestStatus::Success;
3117 break;
3120 case EListenerRequestType::None:
3122 result = ERequestStatus::Success;
3124 break;
3127 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3128 case EListenerRequestType::SetName:
3130 auto const pRequestData = static_cast<SListenerRequestData<EListenerRequestType::SetName> const*>(pPassedRequestData);
3132 pRequestData->pListener->HandleSetName(pRequestData->name.c_str());
3133 result = ERequestStatus::Success;
3135 break;
3137 #endif // CRY_AUDIO_USE_DEBUG_CODE
3138 default:
3140 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3141 Cry::Audio::Log(ELogType::Warning, "Unknown listener request type: %u", pBase->listenerRequestType);
3142 #endif // CRY_AUDIO_USE_DEBUG_CODE
3144 break;
3148 return result;
3151 //////////////////////////////////////////////////////////////////////////
3152 void CSystem::NotifyListener(CRequest const& request)
3154 ESystemEvents systemEvent = ESystemEvents::None;
3155 ControlId controlID = InvalidControlId;
3156 EntityId entityId = INVALID_ENTITYID;
3158 switch (request.GetData()->requestType)
3160 case ERequestType::SystemRequest:
3162 auto const pBase = static_cast<SSystemRequestDataBase const*>(request.GetData());
3164 switch (pBase->systemRequestType)
3166 case ESystemRequestType::SetImpl:
3168 systemEvent = ESystemEvents::ImplSet;
3170 break;
3172 case ESystemRequestType::ExecuteTrigger:
3174 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecuteTrigger> const*>(pBase);
3175 controlID = pRequestData->triggerId;
3176 systemEvent = ESystemEvents::TriggerExecuted;
3178 break;
3180 case ESystemRequestType::ExecuteTriggerWithCallbacks:
3182 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecuteTriggerWithCallbacks> const*>(pBase);
3183 controlID = pRequestData->data.triggerId;
3184 systemEvent = ESystemEvents::TriggerExecuted;
3186 break;
3188 default:
3190 break;
3194 break;
3196 case ERequestType::CallbackRequest:
3198 auto const pBase = static_cast<SCallbackRequestDataBase const*>(request.GetData());
3200 switch (pBase->callbackRequestType)
3202 case ECallbackRequestType::ReportFinishedTriggerInstance:
3204 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportFinishedTriggerInstance> const*>(pBase);
3205 controlID = pRequestData->triggerId;
3206 entityId = pRequestData->entityId;
3207 systemEvent = ESystemEvents::TriggerFinished;
3209 break;
3211 case ECallbackRequestType::ReportTriggerConnectionInstanceCallback:
3213 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportTriggerConnectionInstanceCallback> const*>(pBase);
3214 systemEvent = pRequestData->events;
3216 break;
3218 case ECallbackRequestType::SendTriggerInstanceCallback:
3220 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::SendTriggerInstanceCallback> const*>(pBase);
3221 controlID = pRequestData->triggerId;
3222 entityId = pRequestData->entityId;
3223 systemEvent = pRequestData->events;
3225 break;
3227 case ECallbackRequestType::ReportContextActivated:
3229 systemEvent = ESystemEvents::ContextActivated;
3231 break;
3233 case ECallbackRequestType::ReportContextDeactivated:
3235 systemEvent = ESystemEvents::ContextDeactivated;
3237 break;
3239 case ECallbackRequestType::ReportFinishedPreload:
3241 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportFinishedPreload> const*>(pBase);
3242 controlID = static_cast<ControlId>(pRequestData->preloadRequestId);
3243 systemEvent = pRequestData->isFullSuccess ? ESystemEvents::PreloadFinishedSuccess : ESystemEvents::PreloadFinishedFailure;
3245 break;
3247 default:
3249 break;
3253 break;
3255 case ERequestType::ObjectRequest:
3257 auto const pBase = static_cast<SObjectRequestDataBase const*>(request.GetData());
3259 switch (pBase->objectRequestType)
3261 case EObjectRequestType::ExecuteTrigger:
3263 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::ExecuteTrigger> const*>(pBase);
3264 controlID = pRequestData->triggerId;
3265 entityId = pRequestData->entityId;
3266 systemEvent = ESystemEvents::TriggerExecuted;
3268 break;
3270 case EObjectRequestType::ExecuteTriggerWithCallbacks:
3272 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::ExecuteTriggerWithCallbacks> const*>(pBase);
3273 controlID = pRequestData->data.triggerId;
3274 entityId = pRequestData->entityId;
3275 systemEvent = ESystemEvents::TriggerExecuted;
3277 break;
3279 default:
3281 break;
3285 break;
3287 case ERequestType::ListenerRequest:
3289 // Nothing to do currently for this type of request.
3291 break;
3293 default:
3295 CryFatalError("Unknown request type during %s!", __FUNCTION__);
3297 break;
3301 ERequestResult result = ERequestResult::Failure;
3303 switch (request.status)
3305 case ERequestStatus::Success:
3307 result = ERequestResult::Success;
3308 break;
3310 case ERequestStatus::Failure: // Intentional fall-through.
3311 case ERequestStatus::PartialSuccess:
3313 result = ERequestResult::Failure;
3314 break;
3316 default:
3318 CRY_ASSERT_MESSAGE(false, "Invalid request status '%u'. Cannot be converted to a request result during %s", request.status, __FUNCTION__);
3319 result = ERequestResult::Failure;
3320 break;
3324 SRequestInfo const requestInfo(
3325 result,
3326 request.pOwner,
3327 request.pUserData,
3328 request.pUserDataOwner,
3329 systemEvent,
3330 controlID,
3331 entityId);
3333 g_eventListenerManager.NotifyListener(&requestInfo);
3336 //////////////////////////////////////////////////////////////////////////
3337 ERequestStatus CSystem::HandleSetImpl(Impl::IImpl* const pIImpl)
3339 ERequestStatus result = ERequestStatus::Failure;
3341 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3342 ContextInfo const tempContextInfo = g_contextInfo;
3343 #endif // CRY_AUDIO_USE_DEBUG_CODE
3345 if ((g_pIImpl != nullptr) && (pIImpl != g_pIImpl))
3347 ReleaseImpl();
3350 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3351 g_contextInfo.clear();
3352 g_contextInfo.insert(tempContextInfo.begin(), tempContextInfo.end());
3353 #endif // CRY_AUDIO_USE_DEBUG_CODE
3355 g_pIImpl = pIImpl;
3357 if (g_pIImpl == nullptr)
3359 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3360 Cry::Audio::Log(ELogType::Warning, "nullptr passed to SetImpl, will run with the null implementation");
3361 #endif // CRY_AUDIO_USE_DEBUG_CODE
3363 MEMSTAT_CONTEXT(EMemStatContextType::AudioSystem, "CryAudio::Impl::Null::CImpl");
3364 auto const pImpl = new Impl::Null::CImpl();
3365 CRY_ASSERT(pImpl != nullptr);
3366 g_pIImpl = static_cast<Impl::IImpl*>(pImpl);
3369 g_xmlProcessor.ParseSystemData();
3371 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3372 if ((g_systemStates& ESystemStates::PoolsAllocated) == ESystemStates::None)
3374 // Don't allocate again after impl switch.
3375 AllocateMemoryPools();
3376 g_systemStates |= ESystemStates::PoolsAllocated;
3378 #else
3379 AllocateMemoryPools();
3380 #endif // CRY_AUDIO_USE_DEBUG_CODE
3382 result = g_pIImpl->Init(m_objectPoolSize);
3384 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3385 // Get impl info again (was done in ParseSystemData) to set the impl name, because
3386 // it's not guaranteed that it already existed in the impl constructor.
3387 g_pIImpl->GetInfo(g_implInfo);
3388 #endif // CRY_AUDIO_USE_DEBUG_CODE
3390 if (result != ERequestStatus::Success)
3392 // The impl failed to initialize, allow it to shut down and release then fall back to the null impl.
3394 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3395 Cry::Audio::Log(ELogType::Error, "Failed to set the AudioImpl %s. Will run with the null implementation.", g_implInfo.name);
3396 #endif // CRY_AUDIO_USE_DEBUG_CODE
3398 // There's no need to call Shutdown when the initialization failed as
3399 // we expect the implementation to clean-up itself if it couldn't be initialized
3401 g_pIImpl->Release(); // Release the engine specific data.
3403 MEMSTAT_CONTEXT(EMemStatContextType::AudioSystem, "CryAudio::Impl::Null::CImpl");
3404 auto const pImpl = new Impl::Null::CImpl();
3405 CRY_ASSERT(pImpl != nullptr);
3406 g_pIImpl = static_cast<Impl::IImpl*>(pImpl);
3409 CRY_ASSERT_MESSAGE(g_defaultListener.GetImplData() == nullptr, "<Audio> The default listeners's impl-data must be nullptr during %s", __FUNCTION__);
3411 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3412 g_defaultListener.SetImplData(g_pIImpl->ConstructListener(g_defaultListener.GetDebugTransformation(), g_szDefaultListenerName));
3413 #else
3414 g_defaultListener.SetImplData(g_pIImpl->ConstructListener(CTransformation::GetEmptyObject(), g_szDefaultListenerName));
3415 #endif // CRY_AUDIO_USE_DEBUG_CODE
3417 CRY_ASSERT_MESSAGE(g_pIObject == nullptr, "<Audio> g_pIObject must be nullptr during %s", __FUNCTION__);
3418 Impl::IListeners const defaultImplListener{ g_defaultListener.GetImplData() };
3420 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3421 g_pIObject = g_pIImpl->ConstructObject(CTransformation::GetEmptyObject(), defaultImplListener, g_szGlobalName);
3422 #else
3423 g_pIObject = g_pIImpl->ConstructObject(CTransformation::GetEmptyObject(), defaultImplListener);
3424 #endif // CRY_AUDIO_USE_DEBUG_CODE
3426 string const listenerNames = g_cvars.m_pListeners->GetString();
3428 if (!listenerNames.empty())
3430 int curPos = 0;
3431 string listenerName = listenerNames.Tokenize(",", curPos);
3433 while (!listenerName.empty())
3435 listenerName.Trim();
3437 if (g_listenerManager.GetListener(StringToId(listenerName.c_str())) == &g_defaultListener)
3439 g_listenerManager.CreateListener(CTransformation::GetEmptyObject(), listenerName.c_str(), false);
3442 listenerName = listenerNames.Tokenize(",", curPos);
3446 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3447 CRY_ASSERT_MESSAGE(g_previewListener.GetImplData() == nullptr, "<Audio> The preview listeners's impl-data must be nullptr during %s", __FUNCTION__);
3448 g_previewListener.SetImplData(g_pIImpl->ConstructListener(CTransformation::GetEmptyObject(), g_szPreviewListenerName));
3450 CRY_ASSERT_MESSAGE(g_previewObject.GetImplData() == nullptr, "<Audio> The preview object's impl-data must be nullptr during %s", __FUNCTION__);
3451 Impl::IListeners const previewImplListener{ g_previewListener.GetImplData() };
3452 g_previewObject.SetImplData(g_pIImpl->ConstructObject(CTransformation::GetEmptyObject(), previewImplListener, g_previewObject.GetName()));
3453 g_previewObject.SetFlag(EObjectFlags::IgnoreDrawDebugInfo);
3455 g_listenerManager.ReconstructImplData();
3457 for (auto const pObject : g_constructedObjects)
3459 CRY_ASSERT_MESSAGE(pObject->GetImplData() == nullptr, "<Audio> The object's impl-data must be nullptr during %s", __FUNCTION__);
3461 Listeners const& listeners = pObject->GetListeners();
3462 Impl::IListeners implListeners;
3464 for (auto const pListener : listeners)
3466 implListeners.push_back(pListener->GetImplData());
3469 pObject->SetImplData(g_pIImpl->ConstructObject(pObject->GetTransformation(), implListeners, pObject->GetName()));
3472 for (auto const& contextPair : g_contextInfo)
3474 ContextId const contextId = contextPair.second.contextId;
3476 if (contextPair.second.isRegistered && contextPair.second.isActive && (contextId != GlobalContextId))
3478 char const* const szContextName = contextPair.first.c_str();
3480 CryFixedStringT<MaxFilePathLength> contextPath = g_configPath;
3481 contextPath += g_szContextsFolderName;
3482 contextPath += "/";
3483 contextPath += szContextName;
3485 g_xmlProcessor.ParseControlsData(contextPath.c_str(), contextId, szContextName);
3486 g_xmlProcessor.ParsePreloadsData(contextPath.c_str(), contextId);
3488 auto const preloadRequestId = static_cast<PreloadRequestId>(contextId);
3489 result = g_fileCacheManager.TryLoadRequest(preloadRequestId, true, true);
3491 if (result != ERequestStatus::Success)
3493 Cry::Audio::Log(ELogType::Warning, R"(No preload request found for context - "%s"!)", szContextName);
3496 AutoLoadSetting(contextId);
3497 ReportContextActivated(contextId);
3501 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager | EDebugUpdateFilter::Contexts);
3502 #endif // CRY_AUDIO_USE_DEBUG_CODE
3504 SetImplLanguage();
3506 return result;
3509 //////////////////////////////////////////////////////////////////////////
3510 void CSystem::SetImplLanguage()
3512 if (ICVar* pCVar = gEnv->pConsole->GetCVar("g_languageAudio"))
3514 g_pIImpl->SetLanguage(pCVar->GetString());
3518 //////////////////////////////////////////////////////////////////////////
3519 void CSystem::HandleActivateContext(ContextId const contextId)
3521 CryFixedStringT<MaxFileNameLength> const contextName = stl::find_in_map(g_contextLookup, contextId, "");
3523 if (!contextName.empty())
3525 CryFixedStringT<MaxFilePathLength> contextPath = g_configPath;
3526 contextPath += g_szContextsFolderName;
3527 contextPath += "/";
3528 contextPath += contextName.c_str();
3530 if (g_xmlProcessor.ParseControlsData(contextPath.c_str(), contextId, contextName.c_str()))
3532 g_xmlProcessor.ParsePreloadsData(contextPath.c_str(), contextId);
3534 for (auto const& preloadPair : g_preloadRequests)
3536 if (preloadPair.second->GetContextId() == contextId)
3538 g_fileCacheManager.TryLoadRequest(preloadPair.second->GetId(), true, true);
3542 AutoLoadSetting(contextId);
3543 ReportContextActivated(contextId);
3546 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3547 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager | EDebugUpdateFilter::Contexts);
3548 #endif // CRY_AUDIO_USE_DEBUG_CODE
3552 //////////////////////////////////////////////////////////////////////////
3553 void CSystem::HandleDeactivateContext(ContextId const contextId)
3555 g_xmlProcessor.ClearControlsData(contextId, false);
3556 g_xmlProcessor.ClearPreloadsData(contextId, false);
3558 for (auto const& preloadPair : g_preloadRequests)
3560 if (preloadPair.second->GetContextId() == contextId)
3562 g_fileCacheManager.TryUnloadRequest(preloadPair.second->GetId());
3566 ReportContextDeactivated(contextId);
3568 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3569 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager | EDebugUpdateFilter::Contexts);
3570 #endif // CRY_AUDIO_USE_DEBUG_CODE
3573 //////////////////////////////////////////////////////////////////////////
3574 void CSystem::ReportContextActivated(ContextId const id)
3576 SCallbackRequestData<ECallbackRequestType::ReportContextActivated> const requestData;
3577 CRequest const request(
3578 &requestData,
3579 ERequestFlags::CallbackOnExternalOrCallingThread,
3580 nullptr,
3581 reinterpret_cast<void*>(static_cast<uintptr_t>(id)));
3582 PushRequest(request);
3585 //////////////////////////////////////////////////////////////////////////
3586 void CSystem::ReportContextDeactivated(ContextId const id)
3588 // Use GlobalContextId when all contexts have been deactivated.
3590 SCallbackRequestData<ECallbackRequestType::ReportContextDeactivated> const requestData;
3591 CRequest const request(
3592 &requestData,
3593 ERequestFlags::CallbackOnExternalOrCallingThread,
3594 nullptr,
3595 reinterpret_cast<void*>(static_cast<uintptr_t>(id)));
3596 PushRequest(request);
3599 //////////////////////////////////////////////////////////////////////////
3600 void CSystem::SetCurrentEnvironmentsOnObject(CObject* const pObject, EntityId const entityToIgnore)
3602 IAreaManager* const pIAreaManager = gEnv->pEntitySystem->GetAreaManager();
3603 size_t numAreas = 0;
3604 static size_t const s_maxAreas = 10;
3605 static SAudioAreaInfo s_areaInfos[s_maxAreas];
3607 if (pIAreaManager->QueryAudioAreas(pObject->GetTransformation().GetPosition(), s_areaInfos, s_maxAreas, numAreas))
3609 for (size_t i = 0; i < numAreas; ++i)
3611 SAudioAreaInfo const& areaInfo = s_areaInfos[i];
3613 if (entityToIgnore == INVALID_ENTITYID || entityToIgnore != areaInfo.envProvidingEntityId)
3615 CEnvironment const* const pEnvironment = stl::find_in_map(g_environmentLookup, areaInfo.audioEnvironmentId, nullptr);
3617 if (pEnvironment != nullptr)
3619 pEnvironment->Set(*pObject, areaInfo.amount);
3626 #if defined(CRY_AUDIO_USE_OCCLUSION)
3627 //////////////////////////////////////////////////////////////////////////
3628 void CSystem::SetOcclusionType(CObject& object, EOcclusionType const occlusionType) const
3630 switch (occlusionType)
3632 case EOcclusionType::Ignore:
3634 object.HandleSetOcclusionType(EOcclusionType::Ignore);
3635 object.SetOcclusion(0.0f);
3637 break;
3639 case EOcclusionType::Adaptive:
3641 object.HandleSetOcclusionType(EOcclusionType::Adaptive);
3643 break;
3645 case EOcclusionType::Low:
3647 object.HandleSetOcclusionType(EOcclusionType::Low);
3649 break;
3651 case EOcclusionType::Medium:
3653 object.HandleSetOcclusionType(EOcclusionType::Medium);
3655 break;
3657 case EOcclusionType::High:
3659 object.HandleSetOcclusionType(EOcclusionType::High);
3661 break;
3663 default:
3665 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3666 Cry::Audio::Log(ELogType::Warning, "Unknown occlusion type during %s: %u", __FUNCTION__, occlusionType);
3667 #endif // CRY_AUDIO_USE_DEBUG_CODE
3669 break;
3673 #endif // CRY_AUDIO_USE_OCCLUSION
3675 //////////////////////////////////////////////////////////////////////////
3676 void CSystem::OnCallback(SRequestInfo const* const pRequestInfo)
3678 if ((gEnv->mMainThreadId == CryGetCurrentThreadId()) && (pRequestInfo->entityId != INVALID_ENTITYID))
3680 IEntity* const pIEntity = gEnv->pEntitySystem->GetEntity(pRequestInfo->entityId);
3682 if (pIEntity != nullptr)
3684 SEntityEvent eventData;
3685 eventData.nParam[0] = reinterpret_cast<intptr_t>(pRequestInfo);
3687 if (pRequestInfo->systemEvent == ESystemEvents::TriggerExecuted)
3689 eventData.event = ENTITY_EVENT_AUDIO_TRIGGER_STARTED;
3690 pIEntity->SendEvent(eventData);
3693 if ((pRequestInfo->systemEvent == ESystemEvents::TriggerFinished) ||
3694 ((pRequestInfo->systemEvent == ESystemEvents::TriggerExecuted) && (pRequestInfo->requestResult != ERequestResult::Success)))
3696 eventData.event = ENTITY_EVENT_AUDIO_TRIGGER_ENDED;
3697 pIEntity->SendEvent(eventData);
3703 //////////////////////////////////////////////////////////////////////////
3704 void CSystem::GetImplInfo(SImplInfo& implInfo)
3706 SSystemRequestData<ESystemRequestType::GetImplInfo> const requestData(implInfo);
3707 CRequest const request(&requestData, ERequestFlags::ExecuteBlocking);
3708 PushRequest(request);
3711 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3712 //////////////////////////////////////////////////////////////////////////
3713 void CSystem::HandleRefresh()
3715 Cry::Audio::Log(ELogType::Warning, "Beginning to refresh the AudioSystem!");
3717 ERequestStatus result = g_pIImpl->StopAllSounds();
3718 CRY_ASSERT(result == ERequestStatus::Success);
3720 for (auto const& contextPair : g_contextInfo)
3722 if (contextPair.second.isRegistered && contextPair.second.isActive)
3724 result = g_fileCacheManager.UnloadDataByContext(contextPair.second.contextId);
3725 CRY_ASSERT(result == ERequestStatus::Success);
3729 result = g_fileCacheManager.UnloadDataByContext(GlobalContextId);
3730 CRY_ASSERT(result == ERequestStatus::Success);
3732 // Store active contexts for reloading after they have been unloaded which empties the map.
3733 ContextInfo const tempContextInfo = g_contextInfo;
3735 g_xmlProcessor.ClearPreloadsData(GlobalContextId, true);
3736 g_xmlProcessor.ClearControlsData(GlobalContextId, true);
3737 ReportContextDeactivated(GlobalContextId);
3738 ResetRequestCount();
3740 g_pIImpl->OnRefresh();
3742 g_xmlProcessor.ParseSystemData();
3743 g_xmlProcessor.ParseControlsData(g_configPath.c_str(), GlobalContextId, g_szGlobalContextName);
3744 g_xmlProcessor.ParsePreloadsData(g_configPath.c_str(), GlobalContextId);
3746 // The global preload might not exist if no preloads have been created, for that reason we don't check the result of this call
3747 g_fileCacheManager.TryLoadRequest(GlobalPreloadRequestId, true, true);
3749 AutoLoadSetting(GlobalContextId);
3751 for (auto const& contextPair : tempContextInfo)
3753 ContextId const contextId = contextPair.second.contextId;
3755 if (contextPair.second.isRegistered && contextPair.second.isActive && (contextId != GlobalContextId))
3757 char const* const szContextName = contextPair.first.c_str();
3759 CryFixedStringT<MaxFilePathLength> contextPath = g_configPath;
3760 contextPath += g_szContextsFolderName;
3761 contextPath += "/";
3762 contextPath += szContextName;
3764 g_xmlProcessor.ParseControlsData(contextPath.c_str(), contextId, szContextName);
3765 g_xmlProcessor.ParsePreloadsData(contextPath.c_str(), contextId);
3767 auto const preloadRequestId = static_cast<PreloadRequestId>(contextId);
3768 result = g_fileCacheManager.TryLoadRequest(preloadRequestId, true, true);
3770 if (result != ERequestStatus::Success)
3772 Cry::Audio::Log(ELogType::Warning, R"(No preload request found for context - "%s"!)", szContextName);
3775 AutoLoadSetting(contextId);
3776 ReportContextActivated(contextId);
3780 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager | EDebugUpdateFilter::Contexts);
3782 Cry::Audio::Log(ELogType::Warning, "Done refreshing the AudioSystem!");
3785 //////////////////////////////////////////////////////////////////////////
3786 void CSystem::ScheduleIRenderAuxGeomForRendering(IRenderAuxGeom* pRenderAuxGeom)
3788 auto oldRenderAuxGeom = m_currentRenderAuxGeom.exchange(pRenderAuxGeom);
3789 CRY_ASSERT(oldRenderAuxGeom != pRenderAuxGeom);
3791 // Kill FIFO entries beyond 1, only the head survives in m_currentRenderAuxGeom
3792 // Throw away all older entries
3793 if (oldRenderAuxGeom && oldRenderAuxGeom != pRenderAuxGeom)
3795 gEnv->pRenderer->DeleteAuxGeom(oldRenderAuxGeom);
3799 //////////////////////////////////////////////////////////////////////////
3800 void CSystem::SubmitLastIRenderAuxGeomForRendering()
3802 if (m_lastDebugRenderSubmitExternalFrame != gEnv->nMainFrameID)
3804 // get auxGeom from "storage"
3805 auto pCurrentRenderAuxGeom = m_currentRenderAuxGeom.exchange(nullptr);
3806 if (pCurrentRenderAuxGeom != nullptr)
3808 gEnv->pRenderer->SubmitAuxGeom(pCurrentRenderAuxGeom, true);
3809 // if another auxGeom was stored in the meantime, we can throw away the current one
3810 // otherwise we keep it around for re-use, to avoid flickering
3811 IRenderAuxGeom* pExpected = nullptr;
3812 if (!m_currentRenderAuxGeom.compare_exchange_strong(pExpected, pCurrentRenderAuxGeom))
3814 gEnv->pRenderer->DeleteAuxGeom(pCurrentRenderAuxGeom);
3816 m_lastDebugRenderSubmitExternalFrame = gEnv->nMainFrameID;
3821 //////////////////////////////////////////////////////////////////////////
3822 void CSystem::DrawDebug()
3824 if (g_cvars.m_drawDebug > 0)
3826 SubmitLastIRenderAuxGeomForRendering();
3828 if (m_canDraw)
3830 m_canDraw = false;
3832 SSystemRequestData<ESystemRequestType::DrawDebugInfo> const requestData;
3833 CRequest const request(&requestData);
3834 PushRequest(request);
3839 //////////////////////////////////////////////////////////////////////////
3840 void CSystem::UpdateDebugInfo()
3842 SSystemRequestData<ESystemRequestType::UpdateDebugInfo> const requestData;
3843 CRequest const request(&requestData);
3844 PushRequest(request);
3847 //////////////////////////////////////////////////////////////////////////
3848 void DrawRequestCategoryInfo(IRenderAuxGeom& auxGeom, float const posX, float& posY, char const* const szType)
3850 auxGeom.Draw2dLabel(posX, posY, Debug::g_systemFontSize, Debug::s_systemColorTextSecondary, false, "%s Request Peak:", szType);
3851 posY += Debug::g_systemLineHeight;
3854 //////////////////////////////////////////////////////////////////////////
3855 void DrawRequestPeakInfo(IRenderAuxGeom& auxGeom, float const posX, float& posY, char const* const szType, uint16 const peak, uint16 poolSize)
3857 bool const poolSizeExceeded = (peak > poolSize) && (poolSize != 0);
3858 CryFixedStringT<MaxInfoStringLength> debugText;
3860 if (poolSizeExceeded)
3862 debugText.Format("%s: %u (Pool Size: %u)", szType, peak, poolSize);
3864 else
3866 debugText.Format("%s: %u", szType, peak);
3869 auxGeom.Draw2dLabel(
3870 posX,
3871 posY,
3872 Debug::g_systemFontSize,
3873 poolSizeExceeded ? Debug::s_globalColorError : Debug::s_systemColorTextPrimary,
3874 false,
3875 "%s", debugText.c_str());
3876 posY += Debug::g_systemLineHeight;
3879 //////////////////////////////////////////////////////////////////////////
3880 void DrawRequestDebugInfo(IRenderAuxGeom& auxGeom, float const posX, float posY)
3882 auxGeom.Draw2dLabel(posX, posY, Debug::g_listHeaderFontSize, Debug::s_globalColorHeader, false, "Audio Requests");
3883 posY += Debug::g_listHeaderLineHeight;
3885 DrawRequestPeakInfo(auxGeom, posX, posY, "Total", g_requestPeaks.requests, 0);
3887 DrawRequestCategoryInfo(auxGeom, posX, posY, "System");
3888 DrawRequestPeakInfo(auxGeom, posX, posY, "ExecuteTrigger", g_requestPeaks.systemExecuteTrigger, g_systemExecuteTriggerPoolSize);
3889 DrawRequestPeakInfo(auxGeom, posX, posY, "ExecuteTriggerEx", g_requestPeaks.systemExecuteTriggerEx, g_systemExecuteTriggerExPoolSize);
3890 DrawRequestPeakInfo(auxGeom, posX, posY, "ExecuteTriggerWithCallbacks", g_requestPeaks.systemExecuteTriggerWithCallbacks, g_systemExecuteTriggerWithCallbacksPoolSize);
3891 DrawRequestPeakInfo(auxGeom, posX, posY, "StopTrigger", g_requestPeaks.systemStopTrigger, g_systemStopTriggerPoolSize);
3892 DrawRequestPeakInfo(auxGeom, posX, posY, "RegisterObject", g_requestPeaks.systemRegisterObject, g_systemRegisterObjectPoolSize);
3893 DrawRequestPeakInfo(auxGeom, posX, posY, "ReleaseObject", g_requestPeaks.systemReleaseObject, g_systemReleaseObjectPoolSize);
3894 DrawRequestPeakInfo(auxGeom, posX, posY, "SetParameter", g_requestPeaks.systemSetParameter, g_systemSetParameterPoolSize);
3895 DrawRequestPeakInfo(auxGeom, posX, posY, "SetSwitchState", g_requestPeaks.systemSetSwitchState, g_systemSetSwitchStatePoolSize);
3897 DrawRequestCategoryInfo(auxGeom, posX, posY, "Object");
3898 DrawRequestPeakInfo(auxGeom, posX, posY, "ExecuteTrigger", g_requestPeaks.objectExecuteTrigger, g_objectExecuteTriggerPoolSize);
3899 DrawRequestPeakInfo(auxGeom, posX, posY, "ExecuteTriggerWithCallbacks", g_requestPeaks.objectExecuteTriggerWithCallbacks, g_objectExecuteTriggerWithCallbacksPoolSize);
3900 DrawRequestPeakInfo(auxGeom, posX, posY, "StopTrigger", g_requestPeaks.objectStopTrigger, g_objectStopTriggerPoolSize);
3901 DrawRequestPeakInfo(auxGeom, posX, posY, "SetTransformation", g_requestPeaks.objectSetTransformation, g_objectSetTransformationPoolSize);
3902 DrawRequestPeakInfo(auxGeom, posX, posY, "SetParameter", g_requestPeaks.objectSetParameter, g_objectSetParameterPoolSize);
3903 DrawRequestPeakInfo(auxGeom, posX, posY, "SetSwitchState", g_requestPeaks.objectSetSwitchState, g_objectSetSwitchStatePoolSize);
3904 DrawRequestPeakInfo(auxGeom, posX, posY, "SetCurrentEnvironments", g_requestPeaks.objectSetCurrentEnvironments, g_objectSetCurrentEnvironmentsPoolSize);
3905 DrawRequestPeakInfo(auxGeom, posX, posY, "SetEnvironment", g_requestPeaks.objectSetEnvironment, g_objectSetEnvironmentPoolSize);
3906 DrawRequestPeakInfo(auxGeom, posX, posY, "ProcessPhysicsRay", g_requestPeaks.objectProcessPhysicsRay, g_objectProcessPhysicsRayPoolSize);
3908 DrawRequestCategoryInfo(auxGeom, posX, posY, "Listener");
3909 DrawRequestPeakInfo(auxGeom, posX, posY, "SetTransformation", g_requestPeaks.listenerSetTransformation, g_listenerSetTransformationPoolSize);
3911 DrawRequestCategoryInfo(auxGeom, posX, posY, "Callback");
3912 DrawRequestPeakInfo(auxGeom, posX, posY, "ReportStartedTriggerConnectionInstance", g_requestPeaks.callbackReportStartedriggerConnectionInstance, g_callbackReportStartedTriggerConnectionInstancePoolSize);
3913 DrawRequestPeakInfo(auxGeom, posX, posY, "ReportFinishedTriggerConnectionInstance", g_requestPeaks.callbackReportFinishedTriggerConnectionInstance, g_callbackReportFinishedTriggerConnectionInstancePoolSize);
3914 DrawRequestPeakInfo(auxGeom, posX, posY, "ReportFinishedTriggerInstance", g_requestPeaks.callbackReportFinishedTriggerInstance, g_callbackReportFinishedTriggerInstancePoolSize);
3915 DrawRequestPeakInfo(auxGeom, posX, posY, "ReportTriggerConnectionInstanceCallback", g_requestPeaks.callbackReportTriggerConnectionInstanceCallback, g_callbackReportTriggerConnectionInstanceCallbackPoolSize);
3916 DrawRequestPeakInfo(auxGeom, posX, posY, "SendTriggerInstanceCallback", g_requestPeaks.callbackSendTriggerInstanceCallback, g_callbackSendTriggerInstanceCallbackPoolSize);
3917 DrawRequestPeakInfo(auxGeom, posX, posY, "ReportPhysicalizedObject", g_requestPeaks.callbackReportPhysicalizedObject, g_callbackReportPhysicalizedObjectPoolSize);
3918 DrawRequestPeakInfo(auxGeom, posX, posY, "ReportVirtualizedObject", g_requestPeaks.callbackReportVirtualizedObject, g_callbackReportVirtualizedObjectPoolSize);
3921 //////////////////////////////////////////////////////////////////////////
3922 void DrawObjectInfo(
3923 IRenderAuxGeom& auxGeom,
3924 float const posX,
3925 float& posY,
3926 Vec3 const& camPos,
3927 CObject const& object,
3928 CryFixedStringT<MaxControlNameLength> const& lowerCaseSearchString,
3929 size_t& numObjects)
3931 Vec3 const& position = object.GetTransformation().GetPosition();
3932 float const distance = position.GetDistance(camPos);
3934 if ((g_cvars.m_debugDistance <= 0.0f) || ((g_cvars.m_debugDistance > 0.0f) && (distance < g_cvars.m_debugDistance)))
3936 char const* const szObjectName = object.GetName();
3937 CryFixedStringT<MaxControlNameLength> lowerCaseObjectName(szObjectName);
3938 lowerCaseObjectName.MakeLower();
3939 bool const hasActiveData = (object.GetFlags() & EObjectFlags::Active) != EObjectFlags::None;
3940 bool const isVirtual = (object.GetFlags() & EObjectFlags::Virtual) != EObjectFlags::None;
3941 bool const stringFound = (lowerCaseSearchString.empty() || (lowerCaseSearchString.compareNoCase("0") == 0)) || (lowerCaseObjectName.find(lowerCaseSearchString) != CryFixedStringT<MaxControlNameLength>::npos);
3942 bool const draw = stringFound && ((g_cvars.m_hideInactiveObjects == 0) || ((g_cvars.m_hideInactiveObjects != 0) && hasActiveData && !isVirtual));
3944 if (draw)
3946 CryFixedStringT<MaxMiscStringLength> debugText;
3948 if ((object.GetFlags() & EObjectFlags::InUse) != EObjectFlags::None)
3950 debugText.Format(szObjectName);
3952 else
3954 debugText.Format("%s [To Be Released]", szObjectName);
3957 auxGeom.Draw2dLabel(
3958 posX,
3959 posY,
3960 Debug::g_listFontSize,
3961 !hasActiveData ? Debug::s_globalColorInactive : (isVirtual ? Debug::s_globalColorVirtual : Debug::s_listColorItemActive),
3962 false,
3963 "%s", debugText.c_str());
3965 posY += Debug::g_listLineHeight;
3966 ++numObjects;
3971 //////////////////////////////////////////////////////////////////////////
3972 void DrawObjectDebugInfo(IRenderAuxGeom& auxGeom, float const posX, float posY)
3974 size_t numObjects = 0;
3975 float const headerPosY = posY;
3976 CryFixedStringT<MaxControlNameLength> lowerCaseSearchString(g_cvars.m_pDebugFilter->GetString());
3977 lowerCaseSearchString.MakeLower();
3979 posY += Debug::g_listHeaderLineHeight;
3980 Vec3 const& camPos = GetISystem()->GetViewCamera().GetPosition();
3982 DrawObjectInfo(auxGeom, posX, posY, camPos, g_previewObject, lowerCaseSearchString, numObjects);
3984 for (auto const pObject : g_constructedObjects)
3986 float const distance = pObject->GetTransformation().GetPosition().GetDistance(camPos);
3988 if ((g_cvars.m_debugDistance <= 0.0f) || ((g_cvars.m_debugDistance > 0.0f) && (distance <= g_cvars.m_debugDistance)))
3990 DrawObjectInfo(auxGeom, posX, posY, camPos, *pObject, lowerCaseSearchString, numObjects);
3994 auxGeom.Draw2dLabel(posX, headerPosY, Debug::g_listHeaderFontSize, Debug::s_globalColorHeader, false, "Audio Objects [%" PRISIZE_T "]", numObjects);
3997 //////////////////////////////////////////////////////////////////////////
3998 void DrawPerActiveObjectDebugInfo(IRenderAuxGeom& auxGeom)
4000 CryFixedStringT<MaxControlNameLength> lowerCaseSearchString(g_cvars.m_pDebugFilter->GetString());
4001 lowerCaseSearchString.MakeLower();
4002 bool const isTextFilterDisabled = (lowerCaseSearchString.empty() || (lowerCaseSearchString.compareNoCase("0") == 0));
4004 for (auto const pObject : g_activeObjects)
4006 if ((pObject->GetFlags() & EObjectFlags::IgnoreDrawDebugInfo) == EObjectFlags::None)
4008 pObject->DrawDebugInfo(auxGeom, isTextFilterDisabled, lowerCaseSearchString);
4013 //////////////////////////////////////////////////////////////////////////
4014 void DrawContextDebugInfo(IRenderAuxGeom& auxGeom, float const posX, float posY)
4016 auxGeom.Draw2dLabel(posX, posY, Debug::g_listHeaderFontSize, Debug::s_globalColorHeader, false, "Contexts [%" PRISIZE_T "]", g_contextLookup.size() + 1);
4017 posY += Debug::g_listHeaderLineHeight;
4019 for (auto const& contextPair : g_contextDebugInfo)
4021 auxGeom.Draw2dLabel(
4022 posX,
4023 posY,
4024 Debug::g_listFontSize,
4025 contextPair.second ? Debug::s_listColorItemActive : Debug::s_globalColorInactive,
4026 false,
4027 "%s", contextPair.first.c_str());
4029 posY += Debug::g_listLineHeight;
4033 ///////////////////////////////////////////////////////////////////////////
4034 void DrawGlobalDataDebugInfo(IRenderAuxGeom& auxGeom, float const posX, float posY)
4036 auxGeom.Draw2dLabel(posX, posY, Debug::g_listHeaderFontSize, Debug::s_globalColorHeader, false, g_szGlobalName);
4037 posY += Debug::g_listHeaderLineHeight;
4039 // Check if text filter is enabled.
4040 CryFixedStringT<MaxControlNameLength> lowerCaseSearchString(g_cvars.m_pDebugFilter->GetString());
4041 lowerCaseSearchString.MakeLower();
4042 bool const isTextFilterDisabled = (lowerCaseSearchString.empty() || (lowerCaseSearchString.compareNoCase("0") == 0));
4043 bool const filterAllObjectInfo = (g_cvars.m_drawDebug & Debug::EDrawFilter::FilterAllObjectInfo) != 0;
4045 // Check if any trigger matches text filter.
4046 bool doesTriggerMatchFilter = false;
4047 std::vector<CryFixedStringT<MaxMiscStringLength>> triggerInfo;
4049 if (!g_triggerInstances.empty() || filterAllObjectInfo)
4051 Debug::TriggerCounts triggerCounts;
4053 for (auto const& triggerInstancePair : g_triggerInstances)
4055 ++(triggerCounts[triggerInstancePair.second->GetTriggerId()]);
4058 for (auto const& triggerCountsPair : triggerCounts)
4060 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, triggerCountsPair.first, nullptr);
4062 if (pTrigger != nullptr)
4064 char const* const szTriggerName = pTrigger->GetName();
4066 if (!isTextFilterDisabled)
4068 CryFixedStringT<MaxControlNameLength> lowerCaseTriggerName(szTriggerName);
4069 lowerCaseTriggerName.MakeLower();
4071 if (lowerCaseTriggerName.find(lowerCaseSearchString) != CryFixedStringT<MaxControlNameLength>::npos)
4073 doesTriggerMatchFilter = true;
4077 CryFixedStringT<MaxMiscStringLength> debugText;
4078 uint8 const numInstances = triggerCountsPair.second;
4080 if (numInstances == 1)
4082 debugText.Format("%s\n", szTriggerName);
4084 else
4086 debugText.Format("%s: %u\n", szTriggerName, numInstances);
4089 triggerInfo.emplace_back(debugText);
4094 // Check if any state or switch matches text filter.
4095 bool doesStateSwitchMatchFilter = false;
4096 std::map<CSwitch const* const, CSwitchState const* const> switchStateInfo;
4098 if (!g_switchStates.empty() || filterAllObjectInfo)
4100 for (auto const& switchStatePair : g_switchStates)
4102 CSwitch const* const pSwitch = stl::find_in_map(g_switchLookup, switchStatePair.first, nullptr);
4104 if (pSwitch != nullptr)
4106 CSwitchState const* const pSwitchState = stl::find_in_map(pSwitch->GetStates(), switchStatePair.second, nullptr);
4108 if (pSwitchState != nullptr)
4110 if (!isTextFilterDisabled)
4112 char const* const szSwitchName = pSwitch->GetName();
4113 CryFixedStringT<MaxControlNameLength> lowerCaseSwitchName(szSwitchName);
4114 lowerCaseSwitchName.MakeLower();
4115 char const* const szStateName = pSwitchState->GetName();
4116 CryFixedStringT<MaxControlNameLength> lowerCaseStateName(szStateName);
4117 lowerCaseStateName.MakeLower();
4119 if ((lowerCaseSwitchName.find(lowerCaseSearchString) != CryFixedStringT<MaxControlNameLength>::npos) ||
4120 (lowerCaseStateName.find(lowerCaseSearchString) != CryFixedStringT<MaxControlNameLength>::npos))
4122 doesStateSwitchMatchFilter = true;
4126 switchStateInfo.emplace(pSwitch, pSwitchState);
4132 // Check if any parameter matches text filter.
4133 bool doesParameterMatchFilter = false;
4134 std::map<char const* const, float const> parameterInfo;
4136 if (!g_parameters.empty() || filterAllObjectInfo)
4138 for (auto const& parameterPair : g_parameters)
4140 CParameter const* const pParameter = stl::find_in_map(g_parameterLookup, parameterPair.first, nullptr);
4142 if (pParameter != nullptr)
4144 char const* const szParameterName = pParameter->GetName();
4146 if (!isTextFilterDisabled)
4148 CryFixedStringT<MaxControlNameLength> lowerCaseParameterName(szParameterName);
4149 lowerCaseParameterName.MakeLower();
4151 if (lowerCaseParameterName.find(lowerCaseSearchString) != CryFixedStringT<MaxControlNameLength>::npos)
4153 doesParameterMatchFilter = true;
4157 parameterInfo.emplace(szParameterName, parameterPair.second);
4162 if (isTextFilterDisabled || doesTriggerMatchFilter)
4164 for (auto const& debugText : triggerInfo)
4166 auxGeom.Draw2dLabel(
4167 posX,
4168 posY,
4169 Debug::g_objectFontSize,
4170 Debug::s_objectColorTrigger,
4171 false,
4172 "%s", debugText.c_str());
4174 posY += Debug::g_objectLineHeight;
4178 if (isTextFilterDisabled || doesStateSwitchMatchFilter)
4180 for (auto const& switchStatePair : switchStateInfo)
4182 auto const pSwitch = switchStatePair.first;
4183 auto const pSwitchState = switchStatePair.second;
4185 Debug::CStateDrawData& drawData = g_stateDrawInfo.emplace(std::piecewise_construct, std::forward_as_tuple(pSwitch->GetId()), std::forward_as_tuple(pSwitchState->GetId())).first->second;
4186 drawData.Update(pSwitchState->GetId());
4187 ColorF const switchTextColor = { 0.8f, drawData.m_currentSwitchColor, 0.6f };
4189 auxGeom.Draw2dLabel(
4190 posX,
4191 posY,
4192 Debug::g_objectFontSize,
4193 switchTextColor,
4194 false,
4195 "%s: %s\n",
4196 pSwitch->GetName(),
4197 pSwitchState->GetName());
4199 posY += Debug::g_objectLineHeight;
4203 if (isTextFilterDisabled || doesParameterMatchFilter)
4205 for (auto const& parameterPair : parameterInfo)
4207 auxGeom.Draw2dLabel(
4208 posX,
4209 posY,
4210 Debug::g_objectFontSize,
4211 Debug::s_objectColorParameter,
4212 false,
4213 "%s: %2.2f\n",
4214 parameterPair.first,
4215 parameterPair.second);
4217 posY += Debug::g_objectLineHeight;
4221 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectImplInfo) != 0)
4223 g_pIObject->DrawDebugInfo(auxGeom, posX, posY, (isTextFilterDisabled ? nullptr : lowerCaseSearchString.c_str()));
4227 //////////////////////////////////////////////////////////////////////////
4228 void CSystem::HandleDrawDebug()
4230 CRY_PROFILE_FUNCTION(PROFILE_AUDIO);
4231 IRenderAuxGeom* const pAuxGeom = gEnv->pRenderer ? gEnv->pRenderer->GetOrCreateIRenderAuxGeom() : nullptr;
4233 if (pAuxGeom != nullptr)
4235 if ((g_cvars.m_drawDebug & Debug::objectMask) != 0)
4237 // Needs to be called first so that the rest of the labels are printed on top.
4238 // (Draw2dLabel doesn't provide a way to set which labels are printed on top)
4239 DrawPerActiveObjectDebugInfo(*pAuxGeom);
4242 float posX = 8.0f;
4243 float posY = 4.0f;
4244 float const headerPosY = posY;
4246 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::HideMemoryInfo) == 0)
4248 posY += Debug::g_systemHeaderLineSpacerHeight;
4250 size_t totalPoolSize = 0;
4251 bool const drawDetailedMemInfo = (g_cvars.m_drawDebug & Debug::EDrawFilter::DetailedMemoryInfo) != 0;
4254 auto& allocator = CObject::GetAllocator();
4255 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4256 totalPoolSize += memAlloc;
4258 if (drawDetailedMemInfo)
4260 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Objects", m_objectPoolSize);
4264 #if defined(CRY_AUDIO_USE_OCCLUSION)
4266 auto& allocator = SOcclusionInfo::GetAllocator();
4267 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4268 totalPoolSize += memAlloc;
4270 if (drawDetailedMemInfo)
4272 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Occlusion Infos", m_objectPoolSize);
4275 #endif // CRY_AUDIO_USE_OCCLUSION
4278 auto& allocator = CTriggerInstance::GetAllocator();
4279 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4280 totalPoolSize += memAlloc;
4282 if (drawDetailedMemInfo)
4284 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Trigger Instances", static_cast<uint16>(g_cvars.m_triggerInstancePoolSize));
4288 if (g_debugPoolSizes.triggers > 0)
4290 auto& allocator = CTrigger::GetAllocator();
4291 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4292 totalPoolSize += memAlloc;
4294 if (drawDetailedMemInfo)
4296 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Triggers", g_poolSizes.triggers);
4300 if (g_debugPoolSizes.parameters > 0)
4302 auto& allocator = CParameter::GetAllocator();
4303 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4304 totalPoolSize += memAlloc;
4306 if (drawDetailedMemInfo)
4308 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Parameters", g_poolSizes.parameters);
4312 if (g_debugPoolSizes.switches > 0)
4314 auto& allocator = CSwitch::GetAllocator();
4315 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4316 totalPoolSize += memAlloc;
4318 if (drawDetailedMemInfo)
4320 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Switches", g_poolSizes.switches);
4324 if (g_debugPoolSizes.states > 0)
4326 auto& allocator = CSwitchState::GetAllocator();
4327 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4328 totalPoolSize += memAlloc;
4330 if (drawDetailedMemInfo)
4332 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "SwitchStates", g_poolSizes.states);
4336 if (g_debugPoolSizes.environments > 0)
4338 auto& allocator = CEnvironment::GetAllocator();
4339 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4340 totalPoolSize += memAlloc;
4342 if (drawDetailedMemInfo)
4344 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Environments", g_poolSizes.environments);
4348 if (g_debugPoolSizes.preloads > 0)
4350 auto& allocator = CPreloadRequest::GetAllocator();
4351 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4352 totalPoolSize += memAlloc;
4354 if (drawDetailedMemInfo)
4356 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Preloads", g_poolSizes.preloads);
4360 if (g_debugPoolSizes.settings > 0)
4362 auto& allocator = CSetting::GetAllocator();
4363 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4364 totalPoolSize += memAlloc;
4366 if (drawDetailedMemInfo)
4368 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Settings", g_poolSizes.settings);
4372 if (g_debugPoolSizes.files > 0)
4374 auto& allocator = CFile::GetAllocator();
4375 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4376 totalPoolSize += memAlloc;
4378 if (drawDetailedMemInfo)
4380 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Files", g_poolSizes.files);
4384 CryModuleMemoryInfo memInfo;
4385 ZeroStruct(memInfo);
4386 CryGetMemoryInfoForModule(&memInfo);
4388 CryFixedStringT<Debug::MaxMemInfoStringLength> memAllocSizeString;
4389 auto const memAllocSize = static_cast<size_t>(memInfo.allocated - memInfo.freed);
4390 Debug::FormatMemoryString(memAllocSizeString, memAllocSize - totalPoolSize);
4392 CryFixedStringT<Debug::MaxMemInfoStringLength> totalPoolSizeString;
4393 Debug::FormatMemoryString(totalPoolSizeString, totalPoolSize);
4395 size_t const totalFileSize = g_fileCacheManager.GetTotalCachedFileSize();
4397 CryFixedStringT<Debug::MaxMemInfoStringLength> totalMemSizeString;
4398 size_t const totalMemSize = memAllocSize + totalFileSize;
4399 Debug::FormatMemoryString(totalMemSizeString, totalMemSize);
4401 char const* const szMuted = ((g_systemStates& ESystemStates::IsMuted) != ESystemStates::None) ? " - Muted" : "";
4402 char const* const szPaused = ((g_systemStates& ESystemStates::IsPaused) != ESystemStates::None) ? " - Paused" : "";
4404 if (totalFileSize > 0)
4406 CryFixedStringT<Debug::MaxMemInfoStringLength> totalFileSizeString;
4407 Debug::FormatMemoryString(totalFileSizeString, totalFileSize);
4409 pAuxGeom->Draw2dLabel(posX, headerPosY, Debug::g_systemHeaderFontSize, Debug::s_globalColorHeader, false,
4410 "Audio (System: %s | Pools: %s | Assets: %s | Total: %s)%s%s",
4411 memAllocSizeString.c_str(), totalPoolSizeString.c_str(), totalFileSizeString.c_str(), totalMemSizeString.c_str(), szMuted, szPaused);
4413 else
4415 pAuxGeom->Draw2dLabel(posX, headerPosY, Debug::g_systemHeaderFontSize, Debug::s_globalColorHeader, false,
4416 "Audio (System: %s | Pools: %s | Total: %s)%s%s",
4417 memAllocSizeString.c_str(), totalPoolSizeString.c_str(), totalMemSizeString.c_str(), szMuted, szPaused);
4420 size_t const numObjects = g_constructedObjects.size();
4421 size_t const numActiveObjects = g_activeObjects.size();
4422 size_t const numListeners = g_listenerManager.GetNumListeners();
4423 size_t const numEventListeners = g_eventListenerManager.GetNumEventListeners();
4425 #if defined(CRY_AUDIO_USE_OCCLUSION)
4426 static float const SMOOTHING_ALPHA = 0.2f;
4427 static float syncRays = 0;
4428 static float asyncRays = 0;
4429 syncRays += (CPropagationProcessor::s_totalSyncPhysRays - syncRays) * SMOOTHING_ALPHA;
4430 asyncRays += (CPropagationProcessor::s_totalAsyncPhysRays - asyncRays) * SMOOTHING_ALPHA * 0.1f;
4432 posY += Debug::g_systemLineHeight;
4433 pAuxGeom->Draw2dLabel(posX, posY, Debug::g_systemFontSize, Debug::s_systemColorTextSecondary, false,
4434 "Objects: %3" PRISIZE_T "/%3" PRISIZE_T " | EventListeners %3" PRISIZE_T " | Listeners: %" PRISIZE_T " | SyncRays: %3.1f AsyncRays: %3.1f",
4435 numActiveObjects, numObjects, numEventListeners, numListeners, syncRays, asyncRays);
4436 #else
4437 posY += Debug::g_systemLineHeight;
4438 pAuxGeom->Draw2dLabel(posX, posY, Debug::g_systemFontSize, Debug::s_systemColorTextSecondary, false,
4439 "Objects: %3" PRISIZE_T "/%3" PRISIZE_T " | EventListeners %3" PRISIZE_T " | Listeners: %" PRISIZE_T,
4440 numActiveObjects, numObjects, numEventListeners, numListeners);
4441 #endif // CRY_AUDIO_USE_OCCLUSION
4443 if (g_pIImpl != nullptr)
4445 posY += Debug::g_systemHeaderLineHeight;
4446 g_pIImpl->DrawDebugMemoryInfo(*pAuxGeom, posX, posY, (g_cvars.m_drawDebug & Debug::EDrawFilter::DetailedMemoryInfo) != 0);
4449 posY += Debug::g_systemHeaderLineHeight;
4452 string debugFilter = g_cvars.m_pDebugFilter->GetString();
4454 if (debugFilter.IsEmpty() || debugFilter == "0")
4456 debugFilter = "<none>";
4459 string debugDistance = ToString(g_cvars.m_debugDistance) + " m";
4461 if (g_cvars.m_debugDistance <= 0)
4463 debugDistance = "<infinite>";
4466 string debugDraw = "";
4468 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::Spheres) != 0)
4470 debugDraw += "Spheres, ";
4473 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectLabel) != 0)
4475 debugDraw += "Labels, ";
4478 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectTriggers) != 0)
4480 debugDraw += "Triggers, ";
4483 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectStates) != 0)
4485 debugDraw += "States, ";
4488 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectParameters) != 0)
4490 debugDraw += "Parameters, ";
4493 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectEnvironments) != 0)
4495 debugDraw += "Environments, ";
4498 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectDistance) != 0)
4500 debugDraw += "Distances, ";
4503 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::OcclusionRayLabels) != 0)
4505 debugDraw += "Occlusion Ray Labels, ";
4508 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::OcclusionRays) != 0)
4510 debugDraw += "Occlusion Rays, ";
4513 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::OcclusionRayOffset) != 0)
4515 debugDraw += "Occlusion Ray Offset, ";
4518 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::OcclusionListenerPlane) != 0)
4520 debugDraw += "Occlusion Listener Plane, ";
4523 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::OcclusionCollisionSpheres) != 0)
4525 debugDraw += "Occlusion Collision Spheres, ";
4528 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::GlobalPlaybackInfo) != 0)
4530 debugDraw += "Default Object Info, ";
4533 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectImplInfo) != 0)
4535 debugDraw += "Object Middleware Info, ";
4538 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::Contexts) != 0)
4540 debugDraw += "Active Contexts, ";
4543 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ImplList) != 0)
4545 debugDraw += "Implementation List, ";
4548 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ActiveObjects) != 0)
4550 debugDraw += "Active Objects, ";
4553 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::FileCacheManagerInfo) != 0)
4555 debugDraw += "File Cache Manager, ";
4558 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::RequestInfo) != 0)
4560 debugDraw += "Requests, ";
4563 if (!debugDraw.IsEmpty())
4565 debugDraw.erase(debugDraw.length() - 2, 2);
4566 pAuxGeom->Draw2dLabel(posX, posY, Debug::g_systemFontSize, Debug::s_systemColorTextPrimary, false, "Debug Draw: %s", debugDraw.c_str());
4567 posY += Debug::g_systemLineHeight;
4568 pAuxGeom->Draw2dLabel(posX, posY, Debug::g_systemFontSize, Debug::s_systemColorTextPrimary, false, "Debug Filter: %s | Debug Distance: %s", debugFilter.c_str(), debugDistance.c_str());
4570 posY += Debug::g_systemHeaderLineHeight;
4573 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::FileCacheManagerInfo) != 0)
4575 g_fileCacheManager.DrawDebugInfo(*pAuxGeom, posX, posY);
4576 posX += 600.0f;
4579 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::GlobalPlaybackInfo) != 0)
4581 DrawGlobalDataDebugInfo(*pAuxGeom, posX, posY);
4582 posX += 400.0f;
4585 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::Contexts) != 0)
4587 DrawContextDebugInfo(*pAuxGeom, posX, posY);
4588 posX += 200.0f;
4591 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ActiveObjects) != 0)
4593 DrawObjectDebugInfo(*pAuxGeom, posX, posY);
4594 posX += 300.0f;
4597 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ImplList) != 0)
4599 if (g_pIImpl != nullptr)
4601 Vec3 const& camPos = GetISystem()->GetViewCamera().GetPosition();
4603 g_pIImpl->DrawDebugInfoList(*pAuxGeom, posX, posY, camPos, g_cvars.m_debugDistance, g_cvars.m_pDebugFilter->GetString());
4604 // The impl is responsible for increasing posX.
4608 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::RequestInfo) != 0)
4610 DrawRequestDebugInfo(*pAuxGeom, posX, posY);
4611 posX += 600.0f;
4615 g_system.ScheduleIRenderAuxGeomForRendering(pAuxGeom);
4618 //////////////////////////////////////////////////////////////////////////
4619 void CSystem::HandleRetriggerControls()
4621 for (auto const pObject : g_constructedObjects)
4623 pObject->ForceImplementationRefresh();
4626 ForceGlobalDataImplRefresh();
4627 g_previewObject.ForceImplementationRefresh();
4629 if ((g_systemStates& ESystemStates::IsMuted) != ESystemStates::None)
4631 ExecuteDefaultTrigger(EDefaultTriggerType::MuteAll);
4634 if ((g_systemStates& ESystemStates::IsPaused) != ESystemStates::None)
4636 ExecuteDefaultTrigger(EDefaultTriggerType::PauseAll);
4639 #endif // CRY_AUDIO_USE_DEBUG_CODE
4640 } // namespace CryAudio