Merge remote-tracking branch 'public/release_candidate' into release
[CRYENGINE.git] / Code / CryEngine / CryAudioSystem / System.cpp
blob7f47690bfe899558354db05ed469bc060d06a26a
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 case ESYSTEM_EVENT_AUDIO_RELOAD_CONTROLS_DATA:
1085 SSystemRequestData<ESystemRequestType::ReloadControlsData> const requestData;
1086 CRequest const request(&requestData);
1087 PushRequest(request);
1089 break;
1091 #endif // CRY_AUDIO_USE_DEBUG_CODE
1092 default:
1094 break;
1099 //////////////////////////////////////////////////////////////////////////
1100 bool CSystem::OnInputEvent(SInputEvent const& event)
1102 if (event.state == eIS_Changed && event.deviceType == eIDT_Gamepad)
1104 if (event.keyId == eKI_SYS_ConnectDevice)
1106 g_pIImpl->GamepadConnected(event.deviceUniqueID);
1108 else if (event.keyId == eKI_SYS_DisconnectDevice)
1110 g_pIImpl->GamepadDisconnected(event.deviceUniqueID);
1114 // Do not consume event
1115 return false;
1118 //////////////////////////////////////////////////////////////////////////
1119 void CSystem::InternalUpdate()
1121 CRY_PROFILE_SECTION(PROFILE_AUDIO, "Audio: Internal Update");
1123 if (m_lastExternalThreadFrameId != m_externalThreadFrameId)
1125 if (g_pIImpl != nullptr)
1127 g_listenerManager.Update(m_accumulatedFrameTime);
1128 UpdateActiveObjects(m_accumulatedFrameTime);
1129 g_pIImpl->Update();
1132 ProcessRequests(m_requestQueue);
1133 m_lastExternalThreadFrameId = m_externalThreadFrameId;
1134 m_accumulatedFrameTime = 0.0f;
1135 m_didThreadWait = false;
1137 else if (m_didThreadWait)
1139 // Effectively no time has passed for the external thread as it didn't progress.
1140 // Consequently 0.0f is passed for deltaTime.
1141 if (g_pIImpl != nullptr)
1143 g_listenerManager.Update(0.0f);
1144 UpdateActiveObjects(0.0f);
1145 g_pIImpl->Update();
1148 ProcessRequests(m_requestQueue);
1149 m_didThreadWait = false;
1151 else
1153 // If we're faster than the external thread let's wait to make room for other threads.
1154 CRY_PROFILE_SECTION_WAITING(PROFILE_AUDIO, "Wait - Audio Update");
1156 // The external thread will wake the audio thread up effectively syncing it to itself.
1157 // If not however, the audio thread will execute at a minimum of roughly 30 fps.
1158 if (m_audioThreadWakeupEvent.Wait(30))
1160 // Only reset if the event was signaled, not timed-out!
1161 m_audioThreadWakeupEvent.Reset();
1164 m_didThreadWait = true;
1168 ///////////////////////////////////////////////////////////////////////////
1169 bool CSystem::Initialize()
1171 if (!m_isInitialized)
1173 g_cvars.RegisterVariables();
1175 if (g_cvars.m_objectPoolSize < 1)
1177 g_cvars.m_objectPoolSize = 1;
1179 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1180 Cry::Audio::Log(ELogType::Warning, R"(Audio Object pool size must be at least 1. Forcing the cvar "s_AudioObjectPoolSize" to 1!)");
1181 #endif // CRY_AUDIO_USE_DEBUG_CODE
1184 CObject::CreateAllocator(static_cast<uint16>(g_cvars.m_objectPoolSize));
1186 #if defined(CRY_AUDIO_USE_OCCLUSION)
1187 SOcclusionInfo::CreateAllocator(static_cast<uint16>(g_cvars.m_objectPoolSize));
1188 #endif // CRY_AUDIO_USE_OCCLUSION
1190 if (g_cvars.m_triggerInstancePoolSize < 1)
1192 g_cvars.m_triggerInstancePoolSize = 1;
1194 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1195 Cry::Audio::Log(ELogType::Warning, R"(Trigger instance pool size must be at least 1. Forcing the cvar "s_TriggerInstancePoolSize" to 1!)");
1196 #endif // CRY_AUDIO_USE_DEBUG_CODE
1199 CTriggerInstance::CreateAllocator(static_cast<uint16>(g_cvars.m_triggerInstancePoolSize));
1201 #if defined(CRY_AUDIO_USE_OCCLUSION)
1202 // Add the callback for the obstruction calculation.
1203 gEnv->pPhysicalWorld->AddEventClient(
1204 EventPhysRWIResult::id,
1205 &CPropagationProcessor::OnObstructionTest,
1208 CPropagationProcessor::UpdateOcclusionRayFlags();
1209 CPropagationProcessor::UpdateOcclusionPlanes();
1210 #endif // CRY_AUDIO_USE_OCCLUSION
1212 m_objectPoolSize = static_cast<uint16>(g_cvars.m_objectPoolSize);
1214 g_activeObjects.reserve(static_cast<size_t>(m_objectPoolSize));
1216 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1217 g_constructedObjects.reserve(static_cast<size_t>(m_objectPoolSize));
1219 g_contextInfo.emplace(
1220 std::piecewise_construct,
1221 std::forward_as_tuple(g_szGlobalContextName),
1222 std::forward_as_tuple(SContextInfo(GlobalContextId, true, true)));
1223 #endif // CRY_AUDIO_USE_DEBUG_CODE
1225 g_listenerManager.Initialize();
1226 g_fileCacheManager.Initialize();
1228 CRY_ASSERT_MESSAGE(!m_mainThread.IsActive(), "AudioSystem thread active before initialization during %s", __FUNCTION__);
1229 m_mainThread.Activate();
1230 AddRequestListener(&CSystem::OnCallback, nullptr, ESystemEvents::TriggerExecuted | ESystemEvents::TriggerFinished);
1231 m_isInitialized = true;
1233 else
1235 CRY_ASSERT_MESSAGE(false, "AudioSystem has already been initialized during %s", __FUNCTION__);
1238 return m_isInitialized;
1241 ///////////////////////////////////////////////////////////////////////////
1242 void CSystem::Release()
1244 if (m_isInitialized)
1246 RemoveRequestListener(&CSystem::OnCallback, nullptr);
1248 SSystemRequestData<ESystemRequestType::ReleaseImpl> const requestData;
1249 CRequest const request(&requestData, ERequestFlags::ExecuteBlocking);
1250 PushRequest(request);
1252 m_mainThread.Deactivate();
1254 #if defined(CRY_AUDIO_USE_OCCLUSION)
1255 if (gEnv->pPhysicalWorld != nullptr)
1257 // remove the callback for the obstruction calculation
1258 gEnv->pPhysicalWorld->RemoveEventClient(
1259 EventPhysRWIResult::id,
1260 &CPropagationProcessor::OnObstructionTest,
1263 #endif // CRY_AUDIO_USE_OCCLUSION
1265 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1266 for (auto const pObject : g_constructedObjects)
1268 CRY_ASSERT_MESSAGE(pObject->GetImplData() == nullptr, "An object cannot have valid impl data during %s", __FUNCTION__);
1269 delete pObject;
1272 g_constructedObjects.clear();
1273 #endif // CRY_AUDIO_USE_DEBUG_CODE
1275 g_listenerManager.Terminate();
1276 g_cvars.UnregisterVariables();
1278 CObject::FreeMemoryPool();
1279 CTriggerInstance::FreeMemoryPool();
1281 #if defined(CRY_AUDIO_USE_OCCLUSION)
1282 SOcclusionInfo::FreeMemoryPool();
1283 #endif // CRY_AUDIO_USE_OCCLUSION
1285 m_isInitialized = false;
1287 else
1289 CRY_ASSERT_MESSAGE(false, "AudioSystem has already been released or was never properly initialized during %s", __FUNCTION__);
1293 //////////////////////////////////////////////////////////////////////////
1294 void CSystem::SetImpl(Impl::IImpl* const pIImpl, SRequestUserData const& userData /*= SAudioRequestUserData::GetEmptyObject()*/)
1296 SSystemRequestData<ESystemRequestType::SetImpl> const requestData(pIImpl);
1297 CRequest const request(&requestData, userData);
1298 PushRequest(request);
1301 //////////////////////////////////////////////////////////////////////////
1302 void CSystem::ExecuteTriggerEx(SExecuteTriggerData const& triggerData, SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1304 SSystemRequestData<ESystemRequestType::ExecuteTriggerEx> const requestData(triggerData);
1305 CRequest const request(&requestData, userData);
1306 PushRequest(request);
1309 //////////////////////////////////////////////////////////////////////////
1310 void CSystem::ExecuteDefaultTrigger(EDefaultTriggerType const type, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1312 SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const requestData(type);
1313 CRequest const request(&requestData, userData);
1314 PushRequest(request);
1317 //////////////////////////////////////////////////////////////////////////
1318 void CSystem::SetParameter(ControlId const parameterId, float const value, SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1320 SSystemRequestData<ESystemRequestType::SetParameter> const requestData(parameterId, value);
1321 CRequest const request(&requestData, userData);
1322 PushRequest(request);
1325 //////////////////////////////////////////////////////////////////////////
1326 void CSystem::SetParameterGlobally(ControlId const parameterId, float const value, SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1328 SSystemRequestData<ESystemRequestType::SetParameterGlobally> const requestData(parameterId, value);
1329 CRequest const request(&requestData, userData);
1330 PushRequest(request);
1333 //////////////////////////////////////////////////////////////////////////
1334 void CSystem::SetSwitchState(ControlId const switchId, SwitchStateId const switchStateId, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1336 SSystemRequestData<ESystemRequestType::SetSwitchState> const requestData(switchId, switchStateId);
1337 CRequest const request(&requestData, userData);
1338 PushRequest(request);
1341 //////////////////////////////////////////////////////////////////////////
1342 void CSystem::SetSwitchStateGlobally(ControlId const switchId, SwitchStateId const switchStateId, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1344 SSystemRequestData<ESystemRequestType::SetSwitchStateGlobally> const requestData(switchId, switchStateId);
1345 CRequest const request(&requestData, userData);
1346 PushRequest(request);
1349 //////////////////////////////////////////////////////////////////////////
1350 void CSystem::ExecuteTrigger(ControlId const triggerId, SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1352 SSystemRequestData<ESystemRequestType::ExecuteTrigger> const requestData(triggerId);
1353 CRequest const request(&requestData, userData);
1354 PushRequest(request);
1357 //////////////////////////////////////////////////////////////////////////
1358 void CSystem::ExecuteTriggerWithCallbacks(STriggerCallbackData const& callbackData, SRequestUserData const& userData /* = SRequestUserData::GetEmptyObject() */)
1360 SSystemRequestData<ESystemRequestType::ExecuteTriggerWithCallbacks> const requestData(callbackData);
1361 CRequest const request(&requestData, userData);
1362 PushRequest(request);
1365 //////////////////////////////////////////////////////////////////////////
1366 void CSystem::StopTrigger(ControlId const triggerId /* = CryAudio::InvalidControlId */, SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1368 if (triggerId != InvalidControlId)
1370 SSystemRequestData<ESystemRequestType::StopTrigger> const requestData(triggerId);
1371 CRequest const request(&requestData, userData);
1372 PushRequest(request);
1374 else
1376 SSystemRequestData<ESystemRequestType::StopAllTriggers> const requestData;
1377 CRequest const request(&requestData, userData);
1378 PushRequest(request);
1382 //////////////////////////////////////////////////////////////////////////
1383 void CSystem::ExecutePreviewTrigger(ControlId const triggerId)
1385 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1386 switch (triggerId)
1388 case g_loseFocusTriggerId:
1390 SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const requestData(EDefaultTriggerType::LoseFocus);
1391 CRequest const request(&requestData);
1392 PushRequest(request);
1394 break;
1396 case g_getFocusTriggerId:
1398 SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const requestData(EDefaultTriggerType::GetFocus);
1399 CRequest const request(&requestData);
1400 PushRequest(request);
1402 break;
1404 case g_muteAllTriggerId:
1406 SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const requestData(EDefaultTriggerType::MuteAll);
1407 CRequest const request(&requestData);
1408 PushRequest(request);
1410 break;
1412 case g_unmuteAllTriggerId:
1414 SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const requestData(EDefaultTriggerType::UnmuteAll);
1415 CRequest const request(&requestData);
1416 PushRequest(request);
1418 break;
1420 case g_pauseAllTriggerId:
1422 SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const requestData(EDefaultTriggerType::PauseAll);
1423 CRequest const request(&requestData);
1424 PushRequest(request);
1426 break;
1428 case g_resumeAllTriggerId:
1430 SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const requestData(EDefaultTriggerType::ResumeAll);
1431 CRequest const request(&requestData);
1432 PushRequest(request);
1434 break;
1436 default:
1438 SSystemRequestData<ESystemRequestType::ExecutePreviewTrigger> const requestData(triggerId);
1439 CRequest const request(&requestData);
1440 PushRequest(request);
1442 break;
1445 #endif // CRY_AUDIO_USE_DEBUG_CODE
1448 //////////////////////////////////////////////////////////////////////////
1449 void CSystem::ExecutePreviewTriggerEx(Impl::ITriggerInfo const& triggerInfo)
1451 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1452 SSystemRequestData<ESystemRequestType::ExecutePreviewTriggerEx> const requestData(triggerInfo);
1453 CRequest const request(&requestData);
1454 PushRequest(request);
1455 #endif // CRY_AUDIO_USE_DEBUG_CODE
1458 //////////////////////////////////////////////////////////////////////////
1459 void CSystem::ExecutePreviewTriggerEx(XmlNodeRef const& node)
1461 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1462 SSystemRequestData<ESystemRequestType::ExecutePreviewTriggerExNode> const requestData(node);
1463 CRequest const request(&requestData);
1464 PushRequest(request);
1465 #endif // CRY_AUDIO_USE_DEBUG_CODE
1468 //////////////////////////////////////////////////////////////////////////
1469 void CSystem::StopPreviewTrigger()
1471 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1472 SSystemRequestData<ESystemRequestType::StopPreviewTrigger> const requestData;
1473 CRequest const request(&requestData);
1474 PushRequest(request);
1475 #endif // CRY_AUDIO_USE_DEBUG_CODE
1478 //////////////////////////////////////////////////////////////////////////
1479 void CSystem::RefreshObject(Impl::IObject* const pIObject)
1481 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1482 SSystemRequestData<ESystemRequestType::RefreshObject> const requestData(pIObject);
1483 CRequest const request(&requestData);
1484 PushRequest(request);
1485 #endif // CRY_AUDIO_USE_DEBUG_CODE
1488 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1489 //////////////////////////////////////////////////////////////////////////
1490 void CSystem::ResetRequestCount()
1492 SSystemRequestData<ESystemRequestType::ResetRequestCount> const requestData;
1493 CRequest const request(&requestData);
1494 PushRequest(request);
1496 #endif // CRY_AUDIO_USE_DEBUG_CODE
1498 //////////////////////////////////////////////////////////////////////////
1499 void CSystem::ReportStartedTriggerConnectionInstance(TriggerInstanceId const triggerInstanceId, ETriggerResult const result, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1501 SCallbackRequestData<ECallbackRequestType::ReportStartedTriggerConnectionInstance> const requestData(triggerInstanceId, result);
1502 CRequest const request(&requestData, userData);
1503 PushRequest(request);
1506 //////////////////////////////////////////////////////////////////////////
1507 void CSystem::ReportFinishedTriggerConnectionInstance(TriggerInstanceId const triggerInstanceId, ETriggerResult const result, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1509 SCallbackRequestData<ECallbackRequestType::ReportFinishedTriggerConnectionInstance> const requestData(triggerInstanceId, result);
1510 CRequest const request(&requestData, userData);
1511 PushRequest(request);
1514 //////////////////////////////////////////////////////////////////////////
1515 void CSystem::ReportTriggerConnectionInstanceCallback(TriggerInstanceId const triggerInstanceId, ESystemEvents const systemEvent, SRequestUserData const& userData /* = SRequestUserData::GetEmptyObject() */)
1517 SCallbackRequestData<ECallbackRequestType::ReportTriggerConnectionInstanceCallback> const requestData(triggerInstanceId, systemEvent);
1518 CRequest const request(&requestData, userData);
1519 PushRequest(request);
1522 //////////////////////////////////////////////////////////////////////////
1523 void CSystem::ReportPhysicalizedObject(Impl::IObject* const pIObject, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1525 SCallbackRequestData<ECallbackRequestType::ReportPhysicalizedObject> const requestData(pIObject);
1526 CRequest const request(&requestData, userData);
1527 PushRequest(request);
1530 //////////////////////////////////////////////////////////////////////////
1531 void CSystem::ReportVirtualizedObject(Impl::IObject* const pIObject, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1533 SCallbackRequestData<ECallbackRequestType::ReportVirtualizedObject> const requestData(pIObject);
1534 CRequest const request(&requestData, userData);
1535 PushRequest(request);
1538 //////////////////////////////////////////////////////////////////////////
1539 void CSystem::StopAllSounds(SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1541 SSystemRequestData<ESystemRequestType::StopAllSounds> const requestData;
1542 CRequest const request(&requestData, userData);
1543 PushRequest(request);
1546 //////////////////////////////////////////////////////////////////////////
1547 void CSystem::ParseControlsData(
1548 char const* const szFolderPath,
1549 char const* const szContextName,
1550 ContextId const contextId,
1551 SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1553 SSystemRequestData<ESystemRequestType::ParseControlsData> const requestData(szFolderPath, szContextName, contextId);
1554 CRequest const request(&requestData, userData);
1555 PushRequest(request);
1558 //////////////////////////////////////////////////////////////////////////
1559 void CSystem::ParsePreloadsData(
1560 char const* const szFolderPath,
1561 ContextId const contextId,
1562 SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1564 SSystemRequestData<ESystemRequestType::ParsePreloadsData> const requestData(szFolderPath, contextId);
1565 CRequest const request(&requestData, userData);
1566 PushRequest(request);
1569 //////////////////////////////////////////////////////////////////////////
1570 void CSystem::PreloadSingleRequest(PreloadRequestId const id, bool const bAutoLoadOnly, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1572 SSystemRequestData<ESystemRequestType::PreloadSingleRequest> const requestData(id, bAutoLoadOnly);
1573 CRequest const request(&requestData, userData);
1574 PushRequest(request);
1577 //////////////////////////////////////////////////////////////////////////
1578 void CSystem::UnloadSingleRequest(PreloadRequestId const id, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1580 SSystemRequestData<ESystemRequestType::UnloadSingleRequest> const requestData(id);
1581 CRequest const request(&requestData, userData);
1582 PushRequest(request);
1585 //////////////////////////////////////////////////////////////////////////
1586 void CSystem::ActivateContext(ContextId const contextId)
1588 if ((contextId != InvalidContextId) && (contextId != GlobalContextId))
1590 SSystemRequestData<ESystemRequestType::ActivateContext> const requestData(contextId);
1591 CRequest const request(&requestData);
1592 PushRequest(request);
1594 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1595 else
1597 if (contextId == InvalidContextId)
1599 Cry::Audio::Log(ELogType::Warning, "Invalid context id passed in %s", __FUNCTION__);
1601 else
1603 Cry::Audio::Log(ELogType::Warning, "The global context cannot get activated manually.");
1606 #endif // CRY_AUDIO_USE_DEBUG_CODE
1609 //////////////////////////////////////////////////////////////////////////
1610 void CSystem::DeactivateContext(ContextId const contextId)
1612 if ((contextId != InvalidContextId) && (contextId != GlobalContextId))
1614 SSystemRequestData<ESystemRequestType::DeactivateContext> const requestData(contextId);
1615 CRequest const request(&requestData);
1616 PushRequest(request);
1618 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1619 else
1621 if (contextId == InvalidContextId)
1623 Cry::Audio::Log(ELogType::Warning, "Invalid context id passed in %s", __FUNCTION__);
1625 else
1627 Cry::Audio::Log(ELogType::Warning, "The global context cannot get deactivated manually.");
1630 #endif // CRY_AUDIO_USE_DEBUG_CODE
1633 //////////////////////////////////////////////////////////////////////////
1634 void CSystem::AutoLoadSetting(ContextId const contextId, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1636 SSystemRequestData<ESystemRequestType::AutoLoadSetting> const requestData(contextId);
1637 CRequest const request(&requestData, userData);
1638 PushRequest(request);
1641 //////////////////////////////////////////////////////////////////////////
1642 void CSystem::LoadSetting(ControlId const id, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1644 SSystemRequestData<ESystemRequestType::LoadSetting> const requestData(id);
1645 CRequest const request(&requestData, userData);
1646 PushRequest(request);
1649 //////////////////////////////////////////////////////////////////////////
1650 void CSystem::UnloadSetting(ControlId const id, SRequestUserData const& userData /*= SRequestUserData::GetEmptyObject()*/)
1652 SSystemRequestData<ESystemRequestType::UnloadSetting> const requestData(id);
1653 CRequest const request(&requestData, userData);
1654 PushRequest(request);
1657 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1658 //////////////////////////////////////////////////////////////////////////
1659 void CSystem::RetriggerControls(SRequestUserData const& userData /* = SAudioRequestUserData::GetEmptyObject() */)
1661 SSystemRequestData<ESystemRequestType::RetriggerControls> const requestData;
1662 CRequest const request(&requestData, userData);
1663 PushRequest(request);
1665 #endif // CRY_AUDIO_USE_DEBUG_CODE
1667 ///////////////////////////////////////////////////////////////////////////
1668 char const* CSystem::GetConfigPath() const
1670 return g_configPath.c_str();
1673 ///////////////////////////////////////////////////////////////////////////
1674 CryAudio::IListener* CSystem::CreateListener(CTransformation const& transformation, char const* const szName)
1676 CListener* pListener = nullptr;
1677 SSystemRequestData<ESystemRequestType::RegisterListener> const requestData(&pListener, transformation, szName);
1678 CRequest const request(&requestData, ERequestFlags::ExecuteBlocking);
1679 PushRequest(request);
1681 return static_cast<CryAudio::IListener*>(pListener);
1684 ///////////////////////////////////////////////////////////////////////////
1685 void CSystem::ReleaseListener(CryAudio::IListener* const pIListener)
1687 if (static_cast<CListener*>(pIListener)->IsUserCreated())
1689 SSystemRequestData<ESystemRequestType::ReleaseListener> const requestData(static_cast<CListener*>(pIListener));
1690 CRequest const request(&requestData);
1691 PushRequest(request);
1693 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1694 else
1696 Cry::Audio::Log(ELogType::Error, "Non-user-created listener cannot get released during %s", __FUNCTION__);
1698 #endif // CRY_AUDIO_USE_DEBUG_CODE
1701 //////////////////////////////////////////////////////////////////////////
1702 IListener* CSystem::GetListener(ListenerId const id /*= DefaultListenerId*/)
1704 CListener* pListener = &g_defaultListener;
1706 if ((id != DefaultListenerId) && (id != InvalidListenerId))
1708 SSystemRequestData<ESystemRequestType::GetListener> const requestData(&pListener, id);
1709 CRequest const request(&requestData, ERequestFlags::ExecuteBlocking);
1710 PushRequest(request);
1713 return static_cast<CryAudio::IListener*>(pListener);
1716 //////////////////////////////////////////////////////////////////////////
1717 CryAudio::IObject* CSystem::CreateObject(SCreateObjectData const& objectData /*= SCreateObjectData::GetEmptyObject()*/)
1719 CObject* pObject = nullptr;
1720 SSystemRequestData<ESystemRequestType::RegisterObject> const requestData(&pObject, objectData);
1721 CRequest const request(&requestData, ERequestFlags::ExecuteBlocking);
1722 PushRequest(request);
1724 return static_cast<CryAudio::IObject*>(pObject);
1727 //////////////////////////////////////////////////////////////////////////
1728 void CSystem::ReleaseObject(CryAudio::IObject* const pIObject)
1730 CRY_ASSERT_MESSAGE(pIObject != nullptr, "pIObject is nullptr during %s", __FUNCTION__);
1731 SSystemRequestData<ESystemRequestType::ReleaseObject> const requestData(static_cast<CObject*>(pIObject));
1732 CRequest const request(&requestData);
1733 PushRequest(request);
1736 //////////////////////////////////////////////////////////////////////////
1737 void CSystem::GetTriggerData(ControlId const triggerId, STriggerData& triggerData)
1739 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1740 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, triggerId, nullptr);
1742 if (pTrigger != nullptr)
1744 triggerData.radius = pTrigger->GetRadius();
1746 #endif // CRY_AUDIO_USE_DEBUG_CODE
1749 //////////////////////////////////////////////////////////////////////////
1750 void CSystem::ReleaseImpl()
1752 // Reject new requests during shutdown.
1753 g_systemStates |= ESystemStates::ImplShuttingDown;
1755 g_pIImpl->OnBeforeRelease();
1757 // Release middleware specific data before its shutdown.
1758 g_listenerManager.ReleaseImplData();
1760 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1761 // Don't delete objects here as we need them to survive a middleware switch!
1762 for (auto const pObject : g_constructedObjects)
1764 g_pIImpl->DestructObject(pObject->GetImplData());
1765 pObject->Release();
1767 #endif // CRY_AUDIO_USE_DEBUG_CODE
1769 g_pIImpl->DestructObject(g_pIObject);
1770 ReleaseGlobalData();
1772 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1773 g_pIImpl->DestructObject(g_previewObject.GetImplData());
1774 g_previewObject.Release();
1775 ResetRequestCount();
1776 #endif // CRY_AUDIO_USE_DEBUG_CODE
1778 g_xmlProcessor.ClearPreloadsData(GlobalContextId, true);
1779 g_xmlProcessor.ClearControlsData(GlobalContextId, true);
1781 ReportContextDeactivated(GlobalContextId);
1783 g_pIImpl->ShutDown();
1784 g_pIImpl->Release();
1785 g_pIImpl = nullptr;
1787 FreeMemoryPools();
1789 g_systemStates &= ~ESystemStates::ImplShuttingDown;
1792 //////////////////////////////////////////////////////////////////////////
1793 void CSystem::OnLanguageChanged()
1795 SSystemRequestData<ESystemRequestType::ChangeLanguage> const requestData;
1796 CRequest const request(&requestData);
1797 PushRequest(request);
1800 //////////////////////////////////////////////////////////////////////////
1801 void CSystem::Log(ELogType const type, char const* const szFormat, ...)
1803 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1804 if (szFormat != nullptr && szFormat[0] != '\0' && gEnv->pLog->GetVerbosityLevel() != -1)
1806 CRY_PROFILE_SECTION(PROFILE_AUDIO, "CSystem::Log");
1808 char buffer[256];
1809 va_list ArgList;
1810 va_start(ArgList, szFormat);
1811 cry_vsprintf(buffer, szFormat, ArgList);
1812 va_end(ArgList);
1814 auto const loggingOptions = static_cast<ELoggingOptions>(g_cvars.m_loggingOptions);
1816 switch (type)
1818 case ELogType::Warning:
1820 if ((loggingOptions& ELoggingOptions::Warnings) != ELoggingOptions::None)
1822 gEnv->pSystem->Warning(VALIDATOR_MODULE_AUDIO, VALIDATOR_WARNING, VALIDATOR_FLAG_AUDIO, nullptr, "<Audio>: %s", buffer);
1825 break;
1827 case ELogType::Error:
1829 if ((loggingOptions& ELoggingOptions::Errors) != ELoggingOptions::None)
1831 gEnv->pSystem->Warning(VALIDATOR_MODULE_AUDIO, VALIDATOR_ERROR, VALIDATOR_FLAG_AUDIO, nullptr, "<Audio>: %s", buffer);
1834 break;
1836 case ELogType::Comment:
1838 if ((gEnv->pLog != nullptr) && (gEnv->pLog->GetVerbosityLevel() >= 4) && ((loggingOptions& ELoggingOptions::Comments) != ELoggingOptions::None))
1840 CryLogAlways("<Audio>: %s", buffer);
1843 break;
1845 case ELogType::Always:
1847 CryLogAlways("<Audio>: %s", buffer);
1849 break;
1851 default:
1853 CRY_ASSERT(false);
1855 break;
1859 #endif // CRY_AUDIO_USE_DEBUG_CODE
1862 //////////////////////////////////////////////////////////////////////////
1863 void CSystem::ProcessRequests(Requests& requestQueue)
1865 CRequest request;
1867 while (requestQueue.dequeue(request))
1869 if (request.status == ERequestStatus::None)
1871 request.status = ERequestStatus::Pending;
1872 ProcessRequest(request);
1874 else
1876 // TODO: handle pending requests!
1879 if (request.status != ERequestStatus::Pending)
1881 if ((request.flags & ERequestFlags::CallbackOnAudioThread) != ERequestFlags::None)
1883 NotifyListener(request);
1885 if ((request.flags & ERequestFlags::ExecuteBlocking) != ERequestFlags::None)
1887 m_mainEvent.Set();
1890 else if ((request.flags & ERequestFlags::CallbackOnExternalOrCallingThread) != ERequestFlags::None)
1892 if ((request.flags & ERequestFlags::ExecuteBlocking) != ERequestFlags::None)
1894 m_syncRequest = request;
1895 m_mainEvent.Set();
1897 else
1899 if (request.GetData()->requestType == ERequestType::ObjectRequest)
1901 auto const pBase = static_cast<SObjectRequestDataBase const*>(request.GetData());
1902 pBase->pObject->IncrementSyncCallbackCounter();
1903 // No sync callback counting for default object, because it gets released on unloading of the audio system dll.
1906 m_syncCallbacks.enqueue(request);
1909 else if ((request.flags & ERequestFlags::ExecuteBlocking) != ERequestFlags::None)
1911 m_mainEvent.Set();
1916 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1917 SetRequestCountPeak();
1918 #endif // CRY_AUDIO_USE_DEBUG_CODE
1921 //////////////////////////////////////////////////////////////////////////
1922 void CSystem::ProcessRequest(CRequest& request)
1924 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
1925 CountRequestPerUpdate(request);
1926 #endif // CRY_AUDIO_USE_DEBUG_CODE
1928 ERequestStatus result = ERequestStatus::None;
1930 if (request.GetData())
1932 switch (request.GetData()->requestType)
1934 case ERequestType::ObjectRequest:
1936 result = ProcessObjectRequest(request);
1938 break;
1940 case ERequestType::ListenerRequest:
1942 result = ProcessListenerRequest(request.GetData());
1944 break;
1946 case ERequestType::CallbackRequest:
1948 result = ProcessCallbackRequest(request);
1950 break;
1952 case ERequestType::SystemRequest:
1954 result = ProcessSystemRequest(request);
1956 break;
1958 default:
1960 CRY_ASSERT_MESSAGE(false, "Unknown request type: %u during %s", request.GetData()->requestType, __FUNCTION__);
1962 break;
1967 request.status = result;
1970 //////////////////////////////////////////////////////////////////////////
1971 ERequestStatus CSystem::ProcessSystemRequest(CRequest const& request)
1973 ERequestStatus result = ERequestStatus::Failure;
1974 auto const pBase = static_cast<SSystemRequestDataBase const*>(request.GetData());
1976 switch (pBase->systemRequestType)
1978 case ESystemRequestType::AddRequestListener:
1980 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::AddRequestListener> const*>(request.GetData());
1981 g_eventListenerManager.AddRequestListener(pRequestData);
1982 result = ERequestStatus::Success;
1984 break;
1986 case ESystemRequestType::RemoveRequestListener:
1988 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::RemoveRequestListener> const*>(request.GetData());
1989 g_eventListenerManager.RemoveRequestListener(pRequestData->func, pRequestData->pObjectToListenTo);
1990 result = ERequestStatus::Success;
1992 break;
1994 case ESystemRequestType::SetImpl:
1996 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::SetImpl> const*>(request.GetData());
1997 result = HandleSetImpl(pRequestData->pIImpl) ? ERequestStatus::Success : ERequestStatus::Failure;
1999 break;
2001 case ESystemRequestType::ExecuteTrigger:
2003 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecuteTrigger> const* const>(request.GetData());
2005 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->triggerId, nullptr);
2007 if (pTrigger != nullptr)
2009 pTrigger->Execute(request.pOwner, request.pUserData, request.pUserDataOwner, request.flags);
2010 result = ERequestStatus::Success;
2013 break;
2015 case ESystemRequestType::ExecuteTriggerWithCallbacks:
2017 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecuteTriggerWithCallbacks> const* const>(request.GetData());
2019 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->data.triggerId, nullptr);
2021 if (pTrigger != nullptr)
2023 pTrigger->ExecuteWithCallbacks(pRequestData->data, request.pOwner, request.pUserData, request.pUserDataOwner, request.flags);
2024 result = ERequestStatus::Success;
2027 break;
2029 case ESystemRequestType::StopTrigger:
2031 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::StopTrigger> const* const>(request.GetData());
2033 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->triggerId, nullptr);
2035 if (pTrigger != nullptr)
2037 pTrigger->Stop(g_pIObject);
2038 result = ERequestStatus::Success;
2041 break;
2043 case ESystemRequestType::StopAllTriggers:
2045 g_pIObject->StopAllTriggers();
2046 result = ERequestStatus::Success;
2048 break;
2050 case ESystemRequestType::ExecuteTriggerEx:
2052 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecuteTriggerEx> const*>(request.GetData());
2054 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->triggerId, nullptr);
2056 if (pTrigger != nullptr)
2058 Listeners listeners;
2060 for (auto const id : pRequestData->listenerIds)
2062 listeners.push_back(g_listenerManager.GetListener(id));
2065 Impl::IListeners implListeners;
2067 for (auto const pListener : listeners)
2069 implListeners.push_back(pListener->GetImplData());
2072 MEMSTAT_CONTEXT(EMemStatContextType::AudioSystem, "CryAudio::CObject");
2074 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2075 auto const pNewObject = new CObject(pRequestData->transformation, pRequestData->name.c_str());
2076 pNewObject->Init(g_pIImpl->ConstructObject(pRequestData->transformation, implListeners, pNewObject->GetName()), listeners);
2077 g_constructedObjects.push_back(pNewObject);
2078 #else
2079 auto const pNewObject = new CObject(pRequestData->transformation);
2080 pNewObject->Init(g_pIImpl->ConstructObject(pRequestData->transformation, implListeners), listeners);
2081 #endif // CRY_AUDIO_USE_DEBUG_CODE
2083 if (pRequestData->setCurrentEnvironments)
2085 SetCurrentEnvironmentsOnObject(pNewObject, INVALID_ENTITYID);
2088 #if defined(CRY_AUDIO_USE_OCCLUSION)
2089 SetOcclusionType(*pNewObject, pRequestData->occlusionType);
2090 #endif // CRY_AUDIO_USE_OCCLUSION
2091 pTrigger->Execute(*pNewObject, request.pOwner, request.pUserData, request.pUserDataOwner, request.flags, pRequestData->entityId);
2092 pNewObject->RemoveFlag(EObjectFlags::InUse);
2094 if ((pNewObject->GetFlags() & EObjectFlags::Active) == EObjectFlags::None)
2096 pNewObject->Destruct();
2099 result = ERequestStatus::Success;
2102 break;
2104 case ESystemRequestType::ExecuteDefaultTrigger:
2106 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecuteDefaultTrigger> const*>(request.GetData());
2108 switch (pRequestData->triggerType)
2110 case EDefaultTriggerType::LoseFocus:
2112 if ((g_systemStates& ESystemStates::IsMuted) == ESystemStates::None)
2114 g_loseFocusTrigger.Execute();
2117 result = ERequestStatus::Success;
2119 break;
2121 case EDefaultTriggerType::GetFocus:
2123 if ((g_systemStates& ESystemStates::IsMuted) == ESystemStates::None)
2125 g_getFocusTrigger.Execute();
2128 result = ERequestStatus::Success;
2130 break;
2132 case EDefaultTriggerType::MuteAll:
2134 g_muteAllTrigger.Execute();
2135 result = ERequestStatus::Success;
2136 g_systemStates |= ESystemStates::IsMuted;
2138 break;
2140 case EDefaultTriggerType::UnmuteAll:
2142 g_unmuteAllTrigger.Execute();
2143 result = ERequestStatus::Success;
2144 g_systemStates &= ~ESystemStates::IsMuted;
2146 break;
2148 case EDefaultTriggerType::PauseAll:
2150 g_pauseAllTrigger.Execute();
2151 result = ERequestStatus::Success;
2153 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2154 g_systemStates |= ESystemStates::IsPaused;
2155 #endif // CRY_AUDIO_USE_DEBUG_CODE
2157 break;
2159 case EDefaultTriggerType::ResumeAll:
2161 g_resumeAllTrigger.Execute();
2162 result = ERequestStatus::Success;
2164 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2165 g_systemStates &= ~ESystemStates::IsPaused;
2166 #endif // CRY_AUDIO_USE_DEBUG_CODE
2168 break;
2170 default:
2172 break;
2176 break;
2178 case ESystemRequestType::StopAllSounds:
2180 g_pIImpl->StopAllSounds();
2181 result = ERequestStatus::Success;
2183 break;
2185 case ESystemRequestType::ParseControlsData:
2187 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ParseControlsData> const*>(request.GetData());
2188 g_xmlProcessor.ParseControlsData(pRequestData->folderPath.c_str(), pRequestData->contextId, pRequestData->contextName.c_str());
2190 if (pRequestData->contextId != GlobalContextId)
2192 ReportContextActivated(pRequestData->contextId);
2195 result = ERequestStatus::Success;
2197 break;
2199 case ESystemRequestType::ParsePreloadsData:
2201 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ParsePreloadsData> const*>(request.GetData());
2202 g_xmlProcessor.ParsePreloadsData(pRequestData->folderPath.c_str(), pRequestData->contextId);
2204 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2205 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager | EDebugUpdateFilter::Contexts);
2206 #endif // CRY_AUDIO_USE_DEBUG_CODE
2208 result = ERequestStatus::Success;
2210 break;
2212 case ESystemRequestType::ClearControlsData:
2214 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ClearControlsData> const*>(request.GetData());
2215 g_xmlProcessor.ClearControlsData(pRequestData->contextId, false);
2217 ContextId const id = pRequestData->contextId;
2219 if ((id != GlobalContextId) && (id != InvalidContextId))
2221 ReportContextDeactivated(id);
2224 result = ERequestStatus::Success;
2226 break;
2228 case ESystemRequestType::ClearPreloadsData:
2230 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ClearPreloadsData> const*>(request.GetData());
2231 g_xmlProcessor.ClearPreloadsData(pRequestData->contextId, false);
2233 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2234 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager | EDebugUpdateFilter::Contexts);
2235 #endif // CRY_AUDIO_USE_DEBUG_CODE
2237 result = ERequestStatus::Success;
2239 break;
2241 case ESystemRequestType::PreloadSingleRequest:
2243 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::PreloadSingleRequest> const*>(request.GetData());
2244 result = g_fileCacheManager.TryLoadRequest(
2245 pRequestData->preloadRequestId,
2246 ((request.flags & ERequestFlags::ExecuteBlocking) != ERequestFlags::None),
2247 pRequestData->bAutoLoadOnly,
2248 request.flags,
2249 request.pOwner,
2250 request.pUserData,
2251 request.pUserDataOwner);
2253 break;
2255 case ESystemRequestType::UnloadSingleRequest:
2257 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::UnloadSingleRequest> const*>(request.GetData());
2258 result = g_fileCacheManager.TryUnloadRequest(pRequestData->preloadRequestId);
2260 break;
2262 case ESystemRequestType::ActivateContext:
2264 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ActivateContext> const*>(request.GetData());
2266 HandleActivateContext(pRequestData->contextId);
2267 result = ERequestStatus::Success;
2269 break;
2271 case ESystemRequestType::DeactivateContext:
2273 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::DeactivateContext> const*>(request.GetData());
2275 HandleDeactivateContext(pRequestData->contextId);
2276 result = ERequestStatus::Success;
2278 break;
2280 case ESystemRequestType::SetParameter:
2282 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::SetParameter> const*>(request.GetData());
2284 CParameter const* const pParameter = stl::find_in_map(g_parameterLookup, pRequestData->parameterId, nullptr);
2286 if (pParameter != nullptr)
2288 pParameter->Set(pRequestData->value);
2289 result = ERequestStatus::Success;
2292 break;
2294 case ESystemRequestType::SetParameterGlobally:
2296 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::SetParameterGlobally> const*>(request.GetData());
2298 CParameter const* const pParameter = stl::find_in_map(g_parameterLookup, pRequestData->parameterId, nullptr);
2300 if (pParameter != nullptr)
2302 pParameter->SetGlobally(pRequestData->value);
2303 result = ERequestStatus::Success;
2306 break;
2308 case ESystemRequestType::SetSwitchState:
2310 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::SetSwitchState> const*>(request.GetData());
2312 CSwitch const* const pSwitch = stl::find_in_map(g_switchLookup, pRequestData->switchId, nullptr);
2314 if (pSwitch != nullptr)
2316 CSwitchState const* const pState = stl::find_in_map(pSwitch->GetStates(), pRequestData->switchStateId, nullptr);
2318 if (pState != nullptr)
2320 pState->Set();
2321 result = ERequestStatus::Success;
2325 break;
2327 case ESystemRequestType::SetSwitchStateGlobally:
2329 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::SetSwitchStateGlobally> const*>(request.GetData());
2331 CSwitch const* const pSwitch = stl::find_in_map(g_switchLookup, pRequestData->switchId, nullptr);
2333 if (pSwitch != nullptr)
2335 CSwitchState const* const pState = stl::find_in_map(pSwitch->GetStates(), pRequestData->switchStateId, nullptr);
2337 if (pState != nullptr)
2339 pState->SetGlobally();
2340 result = ERequestStatus::Success;
2344 break;
2346 case ESystemRequestType::AutoLoadSetting:
2348 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::AutoLoadSetting> const*>(request.GetData());
2350 for (auto const& settingPair : g_settingLookup)
2352 CSetting const* const pSetting = settingPair.second;
2354 if (pSetting->IsAutoLoad() && (pSetting->GetContextId() == pRequestData->contextId))
2356 pSetting->Load();
2357 break;
2361 result = ERequestStatus::Success;
2363 break;
2365 case ESystemRequestType::LoadSetting:
2367 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::LoadSetting> const*>(request.GetData());
2369 CSetting const* const pSetting = stl::find_in_map(g_settingLookup, pRequestData->id, nullptr);
2371 if (pSetting != nullptr)
2373 pSetting->Load();
2374 result = ERequestStatus::Success;
2377 break;
2379 case ESystemRequestType::UnloadSetting:
2381 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::UnloadSetting> const*>(request.GetData());
2383 CSetting const* const pSetting = stl::find_in_map(g_settingLookup, pRequestData->id, nullptr);
2385 if (pSetting != nullptr)
2387 pSetting->Unload();
2388 result = ERequestStatus::Success;
2391 break;
2393 case ESystemRequestType::UnloadAFCMDataByContext:
2395 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::UnloadAFCMDataByContext> const*>(request.GetData());
2396 g_fileCacheManager.UnloadDataByContext(pRequestData->contextId);
2397 result = ERequestStatus::Success;
2399 break;
2401 case ESystemRequestType::ReleaseImpl:
2403 ReleaseImpl();
2404 result = ERequestStatus::Success;
2406 break;
2408 case ESystemRequestType::ChangeLanguage:
2410 SetImplLanguage();
2412 g_fileCacheManager.UpdateLocalizedFileCacheEntries();
2414 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2415 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager);
2416 #endif // CRY_AUDIO_USE_DEBUG_CODE
2418 result = ERequestStatus::Success;
2420 break;
2422 #if defined(CRY_AUDIO_USE_OCCLUSION)
2423 case ESystemRequestType::ReleasePendingRays:
2425 for (auto const pObject : g_activeObjects)
2427 pObject->ReleasePendingRays();
2430 result = ERequestStatus::Success;
2432 break;
2434 #endif // CRY_AUDIO_USE_OCCLUSION
2435 case ESystemRequestType::GetImplInfo:
2437 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::GetImplInfo> const*>(request.GetData());
2438 g_pIImpl->GetInfo(pRequestData->implInfo);
2439 result = ERequestStatus::Success;
2441 break;
2443 case ESystemRequestType::RegisterListener:
2445 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::RegisterListener> const*>(request.GetData());
2446 *pRequestData->ppListener = g_listenerManager.CreateListener(pRequestData->transformation, pRequestData->name.c_str(), true);
2447 result = ERequestStatus::Success;
2449 break;
2451 case ESystemRequestType::ReleaseListener:
2453 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ReleaseListener> const*>(request.GetData());
2455 CRY_ASSERT(pRequestData->pListener != nullptr);
2457 if (pRequestData->pListener != nullptr)
2459 g_listenerManager.ReleaseListener(pRequestData->pListener);
2460 result = ERequestStatus::Success;
2463 break;
2465 case ESystemRequestType::GetListener:
2467 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::GetListener> const*>(request.GetData());
2468 *pRequestData->ppListener = g_listenerManager.GetListener(pRequestData->id);
2469 result = ERequestStatus::Success;
2471 break;
2473 case ESystemRequestType::RegisterObject:
2475 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::RegisterObject> const*>(request.GetData());
2477 Listeners listeners;
2479 for (auto const id : pRequestData->listenerIds)
2481 listeners.push_back(g_listenerManager.GetListener(id));
2484 Impl::IListeners implListeners;
2485 implListeners.reserve(listeners.size());
2487 for (auto const pListener : listeners)
2489 implListeners.push_back(pListener->GetImplData());
2492 MEMSTAT_CONTEXT(EMemStatContextType::AudioSystem, "CryAudio::CObject");
2494 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2495 auto const pNewObject = new CObject(pRequestData->transformation, pRequestData->name.c_str());
2496 pNewObject->Init(g_pIImpl->ConstructObject(pRequestData->transformation, implListeners, pNewObject->GetName()), listeners);
2497 g_constructedObjects.push_back(pNewObject);
2498 #else
2499 auto const pNewObject = new CObject(pRequestData->transformation);
2500 pNewObject->Init(g_pIImpl->ConstructObject(pRequestData->transformation, implListeners), listeners);
2501 #endif // CRY_AUDIO_USE_DEBUG_CODE
2503 if (pRequestData->setCurrentEnvironments)
2505 SetCurrentEnvironmentsOnObject(pNewObject, INVALID_ENTITYID);
2508 #if defined(CRY_AUDIO_USE_OCCLUSION)
2509 SetOcclusionType(*pNewObject, pRequestData->occlusionType);
2510 #endif // CRY_AUDIO_USE_OCCLUSION
2511 *pRequestData->ppObject = pNewObject;
2512 result = ERequestStatus::Success;
2514 break;
2516 case ESystemRequestType::ReleaseObject:
2518 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ReleaseObject> const*>(request.GetData());
2520 pRequestData->pObject->RemoveFlag(EObjectFlags::InUse);
2522 if ((pRequestData->pObject->GetFlags() & EObjectFlags::Active) == EObjectFlags::None)
2524 pRequestData->pObject->Destruct();
2527 result = ERequestStatus::Success;
2529 break;
2531 case ESystemRequestType::None:
2533 result = ERequestStatus::Success;
2535 break;
2537 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2538 case ESystemRequestType::RefreshSystem:
2540 HandleRefresh();
2541 HandleRetriggerControls();
2542 result = ERequestStatus::Success;
2544 break;
2546 case ESystemRequestType::ExecutePreviewTrigger:
2548 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecutePreviewTrigger> const*>(request.GetData());
2550 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->triggerId, nullptr);
2552 if (pTrigger != nullptr)
2554 pTrigger->Execute(g_previewObject, request.pOwner, request.pUserData, request.pUserDataOwner, request.flags);
2555 result = ERequestStatus::Success;
2558 break;
2560 case ESystemRequestType::ExecutePreviewTriggerEx:
2562 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecutePreviewTriggerEx> const*>(request.GetData());
2564 g_previewTrigger.Execute(pRequestData->triggerInfo);
2565 result = ERequestStatus::Success;
2567 break;
2569 case ESystemRequestType::ExecutePreviewTriggerExNode:
2571 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecutePreviewTriggerExNode> const*>(request.GetData());
2573 g_previewTrigger.Execute(pRequestData->node);
2574 result = ERequestStatus::Success;
2576 break;
2578 case ESystemRequestType::StopPreviewTrigger:
2580 g_previewObject.StopAllTriggers();
2581 result = ERequestStatus::Success;
2583 break;
2585 case ESystemRequestType::RefreshObject:
2587 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::RefreshObject> const*>(request.GetData());
2589 for (auto const pObject : g_constructedObjects)
2591 if (pObject->GetImplData() == pRequestData->pIObject)
2593 pObject->ForceImplementationRefresh();
2594 break;
2598 result = ERequestStatus::Success;
2600 break;
2602 case ESystemRequestType::ResetRequestCount:
2604 ZeroStruct(g_requestsPerUpdate);
2605 ZeroStruct(g_requestPeaks);
2606 result = ERequestStatus::Success;
2608 break;
2610 case ESystemRequestType::RetriggerControls:
2612 HandleRetriggerControls();
2613 result = ERequestStatus::Success;
2615 break;
2617 case ESystemRequestType::ReloadControlsData:
2619 for (auto const pObject : g_activeObjects)
2621 pObject->StopAllTriggers();
2624 g_pIObject->StopAllTriggers();
2625 g_previewObject.StopAllTriggers();
2627 // Store active contexts for reloading after they have been unloaded which empties the map.
2628 ContextInfo const tempContextInfo = g_contextInfo;
2630 g_xmlProcessor.ClearControlsData(GlobalContextId, true);
2631 ReportContextDeactivated(GlobalContextId);
2633 g_xmlProcessor.ParseSystemData();
2634 g_xmlProcessor.ParseControlsData(g_configPath.c_str(), GlobalContextId, g_szGlobalContextName);
2636 for (auto const& contextPair : tempContextInfo)
2638 ContextId const contextId = contextPair.second.contextId;
2640 if (contextPair.second.isRegistered && contextPair.second.isActive && (contextId != GlobalContextId))
2642 char const* const szContextName = contextPair.first.c_str();
2644 CryFixedStringT<MaxFilePathLength> contextPath = g_configPath;
2645 contextPath += g_szContextsFolderName;
2646 contextPath += "/";
2647 contextPath += szContextName;
2649 g_xmlProcessor.ParseControlsData(contextPath.c_str(), contextId, szContextName);
2651 ReportContextActivated(contextId);
2655 HandleRetriggerControls();
2657 result = ERequestStatus::Success;
2659 break;
2661 case ESystemRequestType::DrawDebugInfo:
2663 HandleDrawDebug();
2664 m_canDraw = true;
2665 result = ERequestStatus::Success;
2667 break;
2669 case ESystemRequestType::UpdateDebugInfo:
2671 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager | EDebugUpdateFilter::Contexts);
2672 result = ERequestStatus::Success;
2674 break;
2676 #endif // CRY_AUDIO_USE_DEBUG_CODE
2677 default:
2679 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2680 Cry::Audio::Log(ELogType::Warning, "Unknown manager request type: %u", pBase->systemRequestType);
2681 #endif // CRY_AUDIO_USE_DEBUG_CODE
2683 break;
2687 return result;
2690 //////////////////////////////////////////////////////////////////////////
2691 ERequestStatus CSystem::ProcessCallbackRequest(CRequest& request)
2693 ERequestStatus result = ERequestStatus::Failure;
2694 auto const pBase = static_cast<SCallbackRequestDataBase const*>(request.GetData());
2696 switch (pBase->callbackRequestType)
2698 case ECallbackRequestType::ReportStartedTriggerConnectionInstance:
2700 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportStartedTriggerConnectionInstance> 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->ReportStartedTriggerInstance(pRequestData->triggerInstanceId, pRequestData->result);
2712 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2713 objectFound = true;
2714 #endif // CRY_AUDIO_USE_DEBUG_CODE
2716 else if (std::find(g_triggerInstanceIds.begin(), g_triggerInstanceIds.end(), pRequestData->triggerInstanceId) != g_triggerInstanceIds.end())
2718 ReportStartedGlobalTriggerInstance(pRequestData->triggerInstanceId, pRequestData->result);
2720 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2721 objectFound = true;
2722 #endif // CRY_AUDIO_USE_DEBUG_CODE
2725 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2726 CRY_ASSERT_MESSAGE(objectFound, "TriggerInstanceId %u is not mapped to an object during %s", pRequestData->triggerInstanceId, __FUNCTION__);
2727 #endif // CRY_AUDIO_USE_DEBUG_CODE
2729 result = ERequestStatus::Success;
2731 break;
2733 case ECallbackRequestType::ReportFinishedTriggerConnectionInstance:
2735 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportFinishedTriggerConnectionInstance> const*>(request.GetData());
2737 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2738 bool objectFound = false;
2739 #endif // CRY_AUDIO_USE_DEBUG_CODE
2741 CObject* const pObject = stl::find_in_map(g_triggerInstanceIdLookup, pRequestData->triggerInstanceId, nullptr);
2743 if (pObject != nullptr)
2745 pObject->ReportFinishedTriggerInstance(pRequestData->triggerInstanceId, pRequestData->result);
2747 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2748 objectFound = true;
2749 #endif // CRY_AUDIO_USE_DEBUG_CODE
2752 else if (std::find(g_triggerInstanceIds.begin(), g_triggerInstanceIds.end(), pRequestData->triggerInstanceId) != g_triggerInstanceIds.end())
2754 ReportFinishedTriggerInstance(pRequestData->triggerInstanceId, pRequestData->result);
2756 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2757 objectFound = true;
2758 #endif // CRY_AUDIO_USE_DEBUG_CODE
2761 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2762 CRY_ASSERT_MESSAGE(objectFound, "TriggerInstanceId %u is not mapped to an object during %s", pRequestData->triggerInstanceId, __FUNCTION__);
2763 #endif // CRY_AUDIO_USE_DEBUG_CODE
2765 result = ERequestStatus::Success;
2767 break;
2769 case ECallbackRequestType::ReportTriggerConnectionInstanceCallback:
2771 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportTriggerConnectionInstanceCallback> const*>(request.GetData());
2773 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2774 bool objectFound = false;
2775 #endif // CRY_AUDIO_USE_DEBUG_CODE
2777 CObject* const pObject = stl::find_in_map(g_triggerInstanceIdLookup, pRequestData->triggerInstanceId, nullptr);
2779 if (pObject != nullptr)
2781 pObject->ReportTriggerInstanceCallback(pRequestData->triggerInstanceId, pRequestData->events);
2783 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2784 objectFound = true;
2785 #endif // CRY_AUDIO_USE_DEBUG_CODE
2788 else if (std::find(g_triggerInstanceIds.begin(), g_triggerInstanceIds.end(), pRequestData->triggerInstanceId) != g_triggerInstanceIds.end())
2790 ReportTriggerInstanceCallback(pRequestData->triggerInstanceId, pRequestData->events);
2792 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2793 objectFound = true;
2794 #endif // CRY_AUDIO_USE_DEBUG_CODE
2797 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2798 CRY_ASSERT_MESSAGE(objectFound, "TriggerInstanceId %u is not mapped to an object during %s", pRequestData->triggerInstanceId, __FUNCTION__);
2799 #endif // CRY_AUDIO_USE_DEBUG_CODE
2801 result = ERequestStatus::Success;
2803 break;
2805 case ECallbackRequestType::ReportPhysicalizedObject:
2807 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportPhysicalizedObject> const*>(request.GetData());
2809 for (auto const pObject : g_activeObjects)
2811 if (pObject->GetImplData() == pRequestData->pIObject)
2813 pObject->RemoveFlag(EObjectFlags::Virtual);
2815 #if defined(CRY_AUDIO_USE_DEBUG_CODE) && defined(CRY_AUDIO_USE_OCCLUSION)
2816 pObject->ResetObstructionRays();
2817 #endif // CRY_AUDIO_USE_DEBUG_CODE && CRY_AUDIO_USE_OCCLUSION
2819 break;
2823 result = ERequestStatus::Success;
2825 break;
2827 case ECallbackRequestType::ReportVirtualizedObject:
2829 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportVirtualizedObject> const*>(request.GetData());
2831 for (auto const pObject : g_activeObjects)
2833 if (pObject->GetImplData() == pRequestData->pIObject)
2835 pObject->SetFlag(EObjectFlags::Virtual);
2836 break;
2840 result = ERequestStatus::Success;
2842 break;
2844 case ECallbackRequestType::ReportFinishedTriggerInstance: // Intentional fall-through.
2845 case ECallbackRequestType::ReportContextActivated: // Intentional fall-through.
2846 case ECallbackRequestType::ReportContextDeactivated: // Intentional fall-through.
2847 case ECallbackRequestType::ReportFinishedPreload: // Intentional fall-through.
2848 case ECallbackRequestType::None:
2850 result = ERequestStatus::Success;
2852 break;
2854 default:
2856 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2857 Cry::Audio::Log(ELogType::Warning, "Unknown callback manager request type: %u", pBase->callbackRequestType);
2858 #endif // CRY_AUDIO_USE_DEBUG_CODE
2860 break;
2864 return result;
2867 //////////////////////////////////////////////////////////////////////////
2868 ERequestStatus CSystem::ProcessObjectRequest(CRequest const& request)
2870 ERequestStatus result = ERequestStatus::Failure;
2872 auto const pBase = static_cast<SObjectRequestDataBase const*>(request.GetData());
2873 CObject* const pObject = pBase->pObject;
2875 switch (pBase->objectRequestType)
2877 case EObjectRequestType::ExecuteTrigger:
2879 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::ExecuteTrigger> const*>(request.GetData());
2881 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->triggerId, nullptr);
2883 if (pTrigger != nullptr)
2885 pTrigger->Execute(*pObject, request.pOwner, request.pUserData, request.pUserDataOwner, request.flags, pRequestData->entityId);
2886 result = ERequestStatus::Success;
2889 break;
2891 case EObjectRequestType::ExecuteTriggerWithCallbacks:
2893 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::ExecuteTriggerWithCallbacks> const*>(request.GetData());
2895 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->data.triggerId, nullptr);
2897 if (pTrigger != nullptr)
2899 pTrigger->ExecuteWithCallbacks(*pObject, pRequestData->data, request.pOwner, request.pUserData, request.pUserDataOwner, request.flags, pRequestData->entityId);
2900 result = ERequestStatus::Success;
2903 break;
2905 case EObjectRequestType::StopTrigger:
2907 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::StopTrigger> const*>(request.GetData());
2909 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, pRequestData->triggerId, nullptr);
2911 if (pTrigger != nullptr)
2913 pTrigger->Stop(pObject->GetImplData());
2914 result = ERequestStatus::Success;
2917 break;
2919 case EObjectRequestType::StopAllTriggers:
2921 pObject->StopAllTriggers();
2922 result = ERequestStatus::Success;
2924 break;
2926 case EObjectRequestType::SetTransformation:
2928 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetTransformation> const*>(request.GetData());
2930 pObject->HandleSetTransformation(pRequestData->transformation);
2931 result = ERequestStatus::Success;
2933 break;
2935 case EObjectRequestType::SetParameter:
2937 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetParameter> const*>(request.GetData());
2939 CParameter const* const pParameter = stl::find_in_map(g_parameterLookup, pRequestData->parameterId, nullptr);
2941 if (pParameter != nullptr)
2943 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2944 pParameter->Set(*pObject, pRequestData->value);
2945 #else
2946 pParameter->Set(pObject->GetImplData(), pRequestData->value);
2947 #endif // CRY_AUDIO_USE_DEBUG_CODE
2949 result = ERequestStatus::Success;
2952 break;
2954 case EObjectRequestType::SetSwitchState:
2956 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetSwitchState> const*>(request.GetData());
2958 CSwitch const* const pSwitch = stl::find_in_map(g_switchLookup, pRequestData->switchId, nullptr);
2960 if (pSwitch != nullptr)
2962 CSwitchState const* const pState = stl::find_in_map(pSwitch->GetStates(), pRequestData->switchStateId, nullptr);
2964 if (pState != nullptr)
2966 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
2967 pState->Set(*pObject);
2968 #else
2969 pState->Set(pObject->GetImplData());
2970 #endif // CRY_AUDIO_USE_DEBUG_CODE
2972 result = ERequestStatus::Success;
2976 break;
2978 #if defined(CRY_AUDIO_USE_OCCLUSION)
2979 case EObjectRequestType::SetOcclusionType:
2981 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetOcclusionType> const*>(request.GetData());
2983 SetOcclusionType(*pObject, pRequestData->occlusionType);
2984 result = ERequestStatus::Success;
2986 break;
2988 case EObjectRequestType::SetOcclusionRayOffset:
2990 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetOcclusionRayOffset> const*>(request.GetData());
2992 pObject->HandleSetOcclusionRayOffset(pRequestData->occlusionRayOffset);
2993 result = ERequestStatus::Success;
2995 break;
2997 #endif // CRY_AUDIO_USE_OCCLUSION
2998 case EObjectRequestType::SetCurrentEnvironments:
3000 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetCurrentEnvironments> const*>(request.GetData());
3002 SetCurrentEnvironmentsOnObject(pObject, pRequestData->entityToIgnore);
3004 break;
3006 case EObjectRequestType::SetEnvironment:
3008 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetEnvironment> const*>(request.GetData());
3010 CEnvironment const* const pEnvironment = stl::find_in_map(g_environmentLookup, pRequestData->environmentId, nullptr);
3012 if (pEnvironment != nullptr)
3014 pEnvironment->Set(*pObject, pRequestData->amount);
3015 result = ERequestStatus::Success;
3018 break;
3020 #if defined(CRY_AUDIO_USE_OCCLUSION)
3021 case EObjectRequestType::ProcessPhysicsRay:
3023 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::ProcessPhysicsRay> const*>(request.GetData());
3025 pObject->ProcessPhysicsRay(pRequestData->rayInfo);
3026 result = ERequestStatus::Success;
3028 break;
3030 #endif // CRY_AUDIO_USE_OCCLUSION
3031 case EObjectRequestType::AddListener:
3033 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::AddListener> const*>(request.GetData());
3035 pObject->HandleAddListener(pRequestData->listenerId);
3036 result = ERequestStatus::Success;
3038 break;
3040 case EObjectRequestType::RemoveListener:
3042 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::RemoveListener> const*>(request.GetData());
3044 pObject->HandleRemoveListener(pRequestData->listenerId);
3045 result = ERequestStatus::Success;
3047 break;
3049 case EObjectRequestType::ToggleAbsoluteVelocityTracking:
3051 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::ToggleAbsoluteVelocityTracking> const*>(request.GetData());
3053 if (pRequestData->isEnabled)
3055 pObject->GetImplData()->ToggleFunctionality(EObjectFunctionality::TrackAbsoluteVelocity, true);
3057 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3058 pObject->SetFlag(EObjectFlags::TrackAbsoluteVelocity);
3059 #endif // CRY_AUDIO_USE_DEBUG_CODE
3061 else
3063 pObject->GetImplData()->ToggleFunctionality(EObjectFunctionality::TrackAbsoluteVelocity, false);
3065 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3066 pObject->RemoveFlag(EObjectFlags::TrackAbsoluteVelocity);
3067 #endif // CRY_AUDIO_USE_DEBUG_CODE
3070 result = ERequestStatus::Success;
3071 break;
3073 case EObjectRequestType::ToggleRelativeVelocityTracking:
3075 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::ToggleRelativeVelocityTracking> const*>(request.GetData());
3077 if (pRequestData->isEnabled)
3079 pObject->GetImplData()->ToggleFunctionality(EObjectFunctionality::TrackRelativeVelocity, true);
3081 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3082 pObject->SetFlag(EObjectFlags::TrackRelativeVelocity);
3083 #endif // CRY_AUDIO_USE_DEBUG_CODE
3085 else
3087 pObject->GetImplData()->ToggleFunctionality(EObjectFunctionality::TrackRelativeVelocity, false);
3089 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3090 pObject->RemoveFlag(EObjectFlags::TrackRelativeVelocity);
3091 #endif // CRY_AUDIO_USE_DEBUG_CODE
3094 result = ERequestStatus::Success;
3095 break;
3097 case EObjectRequestType::None:
3099 result = ERequestStatus::Success;
3100 break;
3102 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3103 case EObjectRequestType::SetName:
3105 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::SetName> const*>(request.GetData());
3107 pObject->HandleSetName(pRequestData->name.c_str());
3108 result = ERequestStatus::Success;
3110 break;
3112 #endif // CRY_AUDIO_USE_DEBUG_CODE
3113 default:
3115 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3116 Cry::Audio::Log(ELogType::Warning, "Unknown object request type: %u", pBase->objectRequestType);
3117 #endif // CRY_AUDIO_USE_DEBUG_CODE
3119 break;
3123 return result;
3126 //////////////////////////////////////////////////////////////////////////
3127 ERequestStatus CSystem::ProcessListenerRequest(SRequestData const* const pPassedRequestData)
3129 ERequestStatus result = ERequestStatus::Failure;
3130 auto const pBase = static_cast<SListenerRequestDataBase const*>(pPassedRequestData);
3132 switch (pBase->listenerRequestType)
3134 case EListenerRequestType::SetTransformation:
3136 auto const pRequestData = static_cast<SListenerRequestData<EListenerRequestType::SetTransformation> const* const>(pPassedRequestData);
3138 CRY_ASSERT(pRequestData->pListener != nullptr);
3140 if (pRequestData->pListener != nullptr)
3142 pRequestData->pListener->HandleSetTransformation(pRequestData->transformation);
3145 result = ERequestStatus::Success;
3147 break;
3150 case EListenerRequestType::None:
3152 result = ERequestStatus::Success;
3154 break;
3157 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3158 case EListenerRequestType::SetName:
3160 auto const pRequestData = static_cast<SListenerRequestData<EListenerRequestType::SetName> const*>(pPassedRequestData);
3162 pRequestData->pListener->HandleSetName(pRequestData->name.c_str());
3163 result = ERequestStatus::Success;
3165 break;
3167 #endif // CRY_AUDIO_USE_DEBUG_CODE
3168 default:
3170 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3171 Cry::Audio::Log(ELogType::Warning, "Unknown listener request type: %u", pBase->listenerRequestType);
3172 #endif // CRY_AUDIO_USE_DEBUG_CODE
3174 break;
3178 return result;
3181 //////////////////////////////////////////////////////////////////////////
3182 void CSystem::NotifyListener(CRequest const& request)
3184 ESystemEvents systemEvent = ESystemEvents::None;
3185 ControlId controlID = InvalidControlId;
3186 EntityId entityId = INVALID_ENTITYID;
3188 switch (request.GetData()->requestType)
3190 case ERequestType::SystemRequest:
3192 auto const pBase = static_cast<SSystemRequestDataBase const*>(request.GetData());
3194 switch (pBase->systemRequestType)
3196 case ESystemRequestType::SetImpl:
3198 systemEvent = ESystemEvents::ImplSet;
3200 break;
3202 case ESystemRequestType::ExecuteTrigger:
3204 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecuteTrigger> const*>(pBase);
3205 controlID = pRequestData->triggerId;
3206 systemEvent = ESystemEvents::TriggerExecuted;
3208 break;
3210 case ESystemRequestType::ExecuteTriggerWithCallbacks:
3212 auto const pRequestData = static_cast<SSystemRequestData<ESystemRequestType::ExecuteTriggerWithCallbacks> const*>(pBase);
3213 controlID = pRequestData->data.triggerId;
3214 systemEvent = ESystemEvents::TriggerExecuted;
3216 break;
3218 default:
3220 break;
3224 break;
3226 case ERequestType::CallbackRequest:
3228 auto const pBase = static_cast<SCallbackRequestDataBase const*>(request.GetData());
3230 switch (pBase->callbackRequestType)
3232 case ECallbackRequestType::ReportFinishedTriggerInstance:
3234 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportFinishedTriggerInstance> const*>(pBase);
3235 controlID = pRequestData->triggerId;
3236 entityId = pRequestData->entityId;
3237 systemEvent = ESystemEvents::TriggerFinished;
3239 break;
3241 case ECallbackRequestType::ReportTriggerConnectionInstanceCallback:
3243 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportTriggerConnectionInstanceCallback> const*>(pBase);
3244 systemEvent = pRequestData->events;
3246 break;
3248 case ECallbackRequestType::SendTriggerInstanceCallback:
3250 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::SendTriggerInstanceCallback> const*>(pBase);
3251 controlID = pRequestData->triggerId;
3252 entityId = pRequestData->entityId;
3253 systemEvent = pRequestData->events;
3255 break;
3257 case ECallbackRequestType::ReportContextActivated:
3259 systemEvent = ESystemEvents::ContextActivated;
3261 break;
3263 case ECallbackRequestType::ReportContextDeactivated:
3265 systemEvent = ESystemEvents::ContextDeactivated;
3267 break;
3269 case ECallbackRequestType::ReportFinishedPreload:
3271 auto const pRequestData = static_cast<SCallbackRequestData<ECallbackRequestType::ReportFinishedPreload> const*>(pBase);
3272 controlID = static_cast<ControlId>(pRequestData->preloadRequestId);
3273 systemEvent = pRequestData->isFullSuccess ? ESystemEvents::PreloadFinishedSuccess : ESystemEvents::PreloadFinishedFailure;
3275 break;
3277 default:
3279 break;
3283 break;
3285 case ERequestType::ObjectRequest:
3287 auto const pBase = static_cast<SObjectRequestDataBase const*>(request.GetData());
3289 switch (pBase->objectRequestType)
3291 case EObjectRequestType::ExecuteTrigger:
3293 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::ExecuteTrigger> const*>(pBase);
3294 controlID = pRequestData->triggerId;
3295 entityId = pRequestData->entityId;
3296 systemEvent = ESystemEvents::TriggerExecuted;
3298 break;
3300 case EObjectRequestType::ExecuteTriggerWithCallbacks:
3302 auto const pRequestData = static_cast<SObjectRequestData<EObjectRequestType::ExecuteTriggerWithCallbacks> const*>(pBase);
3303 controlID = pRequestData->data.triggerId;
3304 entityId = pRequestData->entityId;
3305 systemEvent = ESystemEvents::TriggerExecuted;
3307 break;
3309 default:
3311 break;
3315 break;
3317 case ERequestType::ListenerRequest:
3319 // Nothing to do currently for this type of request.
3321 break;
3323 default:
3325 CryFatalError("Unknown request type during %s!", __FUNCTION__);
3327 break;
3331 ERequestResult result = ERequestResult::Failure;
3333 switch (request.status)
3335 case ERequestStatus::Success:
3337 result = ERequestResult::Success;
3338 break;
3340 case ERequestStatus::Failure:
3342 result = ERequestResult::Failure;
3343 break;
3345 default:
3347 CRY_ASSERT_MESSAGE(false, "Invalid request status '%u'. Cannot be converted to a request result during %s", request.status, __FUNCTION__);
3348 result = ERequestResult::Failure;
3349 break;
3353 SRequestInfo const requestInfo(
3354 result,
3355 request.pOwner,
3356 request.pUserData,
3357 request.pUserDataOwner,
3358 systemEvent,
3359 controlID,
3360 entityId);
3362 g_eventListenerManager.NotifyListener(&requestInfo);
3365 //////////////////////////////////////////////////////////////////////////
3366 bool CSystem::HandleSetImpl(Impl::IImpl* const pIImpl)
3368 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3369 ContextInfo const tempContextInfo = g_contextInfo;
3370 #endif // CRY_AUDIO_USE_DEBUG_CODE
3372 if ((g_pIImpl != nullptr) && (pIImpl != g_pIImpl))
3374 ReleaseImpl();
3377 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3378 g_contextInfo.clear();
3379 g_contextInfo.insert(tempContextInfo.begin(), tempContextInfo.end());
3380 #endif // CRY_AUDIO_USE_DEBUG_CODE
3382 g_pIImpl = pIImpl;
3384 if (g_pIImpl == nullptr)
3386 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3387 Cry::Audio::Log(ELogType::Warning, "nullptr passed to SetImpl, will run with the null implementation");
3388 #endif // CRY_AUDIO_USE_DEBUG_CODE
3390 MEMSTAT_CONTEXT(EMemStatContextType::AudioSystem, "CryAudio::Impl::Null::CImpl");
3391 auto const pImpl = new Impl::Null::CImpl();
3392 CRY_ASSERT(pImpl != nullptr);
3393 g_pIImpl = static_cast<Impl::IImpl*>(pImpl);
3396 g_xmlProcessor.ParseSystemData();
3398 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3399 if ((g_systemStates& ESystemStates::PoolsAllocated) == ESystemStates::None)
3401 // Don't allocate again after impl switch.
3402 AllocateMemoryPools();
3403 g_systemStates |= ESystemStates::PoolsAllocated;
3405 #else
3406 AllocateMemoryPools();
3407 #endif // CRY_AUDIO_USE_DEBUG_CODE
3409 bool const isInitialized = g_pIImpl->Init(m_objectPoolSize);
3411 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3412 // Get impl info again (was done in ParseSystemData) to set the impl name, because
3413 // it's not guaranteed that it already existed in the impl constructor.
3414 g_pIImpl->GetInfo(g_implInfo);
3415 #endif // CRY_AUDIO_USE_DEBUG_CODE
3417 if (!isInitialized)
3419 // The impl failed to initialize, allow it to shut down and release then fall back to the null impl.
3421 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3422 Cry::Audio::Log(ELogType::Error, "Failed to set the AudioImpl %s. Will run with the null implementation.", g_implInfo.name);
3423 #endif // CRY_AUDIO_USE_DEBUG_CODE
3425 // There's no need to call Shutdown when the initialization failed as
3426 // we expect the implementation to clean-up itself if it couldn't be initialized
3428 g_pIImpl->Release(); // Release the engine specific data.
3430 MEMSTAT_CONTEXT(EMemStatContextType::AudioSystem, "CryAudio::Impl::Null::CImpl");
3431 auto const pImpl = new Impl::Null::CImpl();
3432 CRY_ASSERT(pImpl != nullptr);
3433 g_pIImpl = static_cast<Impl::IImpl*>(pImpl);
3436 CRY_ASSERT_MESSAGE(g_defaultListener.GetImplData() == nullptr, "<Audio> The default listeners's impl-data must be nullptr during %s", __FUNCTION__);
3438 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3439 g_defaultListener.SetImplData(g_pIImpl->ConstructListener(g_defaultListener.GetDebugTransformation(), g_szDefaultListenerName));
3440 #else
3441 g_defaultListener.SetImplData(g_pIImpl->ConstructListener(CTransformation::GetEmptyObject(), g_szDefaultListenerName));
3442 #endif // CRY_AUDIO_USE_DEBUG_CODE
3444 CRY_ASSERT_MESSAGE(g_pIObject == nullptr, "<Audio> g_pIObject must be nullptr during %s", __FUNCTION__);
3445 Impl::IListeners const defaultImplListener{ g_defaultListener.GetImplData() };
3447 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3448 g_pIObject = g_pIImpl->ConstructObject(CTransformation::GetEmptyObject(), defaultImplListener, g_szGlobalName);
3449 #else
3450 g_pIObject = g_pIImpl->ConstructObject(CTransformation::GetEmptyObject(), defaultImplListener);
3451 #endif // CRY_AUDIO_USE_DEBUG_CODE
3453 string const listenerNames = g_cvars.m_pListeners->GetString();
3455 if (!listenerNames.empty())
3457 int curPos = 0;
3458 string listenerName = listenerNames.Tokenize(",", curPos);
3460 while (!listenerName.empty())
3462 listenerName.Trim();
3464 if (g_listenerManager.GetListener(StringToId(listenerName.c_str())) == &g_defaultListener)
3466 g_listenerManager.CreateListener(CTransformation::GetEmptyObject(), listenerName.c_str(), false);
3469 listenerName = listenerNames.Tokenize(",", curPos);
3473 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3474 CRY_ASSERT_MESSAGE(g_previewListener.GetImplData() == nullptr, "<Audio> The preview listeners's impl-data must be nullptr during %s", __FUNCTION__);
3475 g_previewListener.SetImplData(g_pIImpl->ConstructListener(CTransformation::GetEmptyObject(), g_szPreviewListenerName));
3477 CRY_ASSERT_MESSAGE(g_previewObject.GetImplData() == nullptr, "<Audio> The preview object's impl-data must be nullptr during %s", __FUNCTION__);
3478 Impl::IListeners const previewImplListener{ g_previewListener.GetImplData() };
3479 g_previewObject.SetImplData(g_pIImpl->ConstructObject(CTransformation::GetEmptyObject(), previewImplListener, g_previewObject.GetName()));
3480 g_previewObject.SetFlag(EObjectFlags::IgnoreDrawDebugInfo);
3482 g_listenerManager.ReconstructImplData();
3484 for (auto const pObject : g_constructedObjects)
3486 CRY_ASSERT_MESSAGE(pObject->GetImplData() == nullptr, "<Audio> The object's impl-data must be nullptr during %s", __FUNCTION__);
3488 Listeners const& listeners = pObject->GetListeners();
3489 Impl::IListeners implListeners;
3491 for (auto const pListener : listeners)
3493 implListeners.push_back(pListener->GetImplData());
3496 pObject->SetImplData(g_pIImpl->ConstructObject(pObject->GetTransformation(), implListeners, pObject->GetName()));
3499 for (auto const& contextPair : g_contextInfo)
3501 ContextId const contextId = contextPair.second.contextId;
3503 if (contextPair.second.isRegistered && contextPair.second.isActive && (contextId != GlobalContextId))
3505 char const* const szContextName = contextPair.first.c_str();
3507 CryFixedStringT<MaxFilePathLength> contextPath = g_configPath;
3508 contextPath += g_szContextsFolderName;
3509 contextPath += "/";
3510 contextPath += szContextName;
3512 g_xmlProcessor.ParseControlsData(contextPath.c_str(), contextId, szContextName);
3513 g_xmlProcessor.ParsePreloadsData(contextPath.c_str(), contextId);
3515 auto const preloadRequestId = static_cast<PreloadRequestId>(contextId);
3517 if (g_fileCacheManager.TryLoadRequest(preloadRequestId, true, true) != ERequestStatus::Success)
3519 Cry::Audio::Log(ELogType::Warning, R"(No preload request found for context - "%s"!)", szContextName);
3522 AutoLoadSetting(contextId);
3523 ReportContextActivated(contextId);
3527 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager | EDebugUpdateFilter::Contexts);
3528 #endif // CRY_AUDIO_USE_DEBUG_CODE
3530 SetImplLanguage();
3532 return isInitialized;
3535 //////////////////////////////////////////////////////////////////////////
3536 void CSystem::SetImplLanguage()
3538 if (ICVar* pCVar = gEnv->pConsole->GetCVar("g_languageAudio"))
3540 g_pIImpl->SetLanguage(pCVar->GetString());
3544 //////////////////////////////////////////////////////////////////////////
3545 void CSystem::HandleActivateContext(ContextId const contextId)
3547 CryFixedStringT<MaxFileNameLength> const contextName = stl::find_in_map(g_contextLookup, contextId, "");
3549 if (!contextName.empty())
3551 CryFixedStringT<MaxFilePathLength> contextPath = g_configPath;
3552 contextPath += g_szContextsFolderName;
3553 contextPath += "/";
3554 contextPath += contextName.c_str();
3556 if (g_xmlProcessor.ParseControlsData(contextPath.c_str(), contextId, contextName.c_str()))
3558 g_xmlProcessor.ParsePreloadsData(contextPath.c_str(), contextId);
3560 for (auto const& preloadPair : g_preloadRequests)
3562 if (preloadPair.second->GetContextId() == contextId)
3564 g_fileCacheManager.TryLoadRequest(preloadPair.second->GetId(), true, true);
3568 AutoLoadSetting(contextId);
3569 ReportContextActivated(contextId);
3572 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3573 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager | EDebugUpdateFilter::Contexts);
3574 #endif // CRY_AUDIO_USE_DEBUG_CODE
3578 //////////////////////////////////////////////////////////////////////////
3579 void CSystem::HandleDeactivateContext(ContextId const contextId)
3581 g_xmlProcessor.ClearControlsData(contextId, false);
3582 g_xmlProcessor.ClearPreloadsData(contextId, false);
3584 for (auto const& preloadPair : g_preloadRequests)
3586 if (preloadPair.second->GetContextId() == contextId)
3588 g_fileCacheManager.TryUnloadRequest(preloadPair.second->GetId());
3592 ReportContextDeactivated(contextId);
3594 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3595 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager | EDebugUpdateFilter::Contexts);
3596 #endif // CRY_AUDIO_USE_DEBUG_CODE
3599 //////////////////////////////////////////////////////////////////////////
3600 void CSystem::ReportContextActivated(ContextId const id)
3602 SCallbackRequestData<ECallbackRequestType::ReportContextActivated> const requestData;
3603 CRequest const request(
3604 &requestData,
3605 ERequestFlags::CallbackOnExternalOrCallingThread,
3606 nullptr,
3607 reinterpret_cast<void*>(static_cast<uintptr_t>(id)));
3608 PushRequest(request);
3611 //////////////////////////////////////////////////////////////////////////
3612 void CSystem::ReportContextDeactivated(ContextId const id)
3614 // Use GlobalContextId when all contexts have been deactivated.
3616 SCallbackRequestData<ECallbackRequestType::ReportContextDeactivated> const requestData;
3617 CRequest const request(
3618 &requestData,
3619 ERequestFlags::CallbackOnExternalOrCallingThread,
3620 nullptr,
3621 reinterpret_cast<void*>(static_cast<uintptr_t>(id)));
3622 PushRequest(request);
3625 //////////////////////////////////////////////////////////////////////////
3626 void CSystem::SetCurrentEnvironmentsOnObject(CObject* const pObject, EntityId const entityToIgnore)
3628 IAreaManager* const pIAreaManager = gEnv->pEntitySystem->GetAreaManager();
3629 size_t numAreas = 0;
3630 static size_t const s_maxAreas = 10;
3631 static SAudioAreaInfo s_areaInfos[s_maxAreas];
3633 if (pIAreaManager->QueryAudioAreas(pObject->GetTransformation().GetPosition(), s_areaInfos, s_maxAreas, numAreas))
3635 for (size_t i = 0; i < numAreas; ++i)
3637 SAudioAreaInfo const& areaInfo = s_areaInfos[i];
3639 if (entityToIgnore == INVALID_ENTITYID || entityToIgnore != areaInfo.envProvidingEntityId)
3641 CEnvironment const* const pEnvironment = stl::find_in_map(g_environmentLookup, areaInfo.audioEnvironmentId, nullptr);
3643 if (pEnvironment != nullptr)
3645 pEnvironment->Set(*pObject, areaInfo.amount);
3652 #if defined(CRY_AUDIO_USE_OCCLUSION)
3653 //////////////////////////////////////////////////////////////////////////
3654 void CSystem::SetOcclusionType(CObject& object, EOcclusionType const occlusionType) const
3656 switch (occlusionType)
3658 case EOcclusionType::Ignore:
3660 object.HandleSetOcclusionType(EOcclusionType::Ignore);
3661 object.SetOcclusion(0.0f);
3663 break;
3665 case EOcclusionType::Adaptive:
3667 object.HandleSetOcclusionType(EOcclusionType::Adaptive);
3669 break;
3671 case EOcclusionType::Low:
3673 object.HandleSetOcclusionType(EOcclusionType::Low);
3675 break;
3677 case EOcclusionType::Medium:
3679 object.HandleSetOcclusionType(EOcclusionType::Medium);
3681 break;
3683 case EOcclusionType::High:
3685 object.HandleSetOcclusionType(EOcclusionType::High);
3687 break;
3689 default:
3691 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3692 Cry::Audio::Log(ELogType::Warning, "Unknown occlusion type during %s: %u", __FUNCTION__, occlusionType);
3693 #endif // CRY_AUDIO_USE_DEBUG_CODE
3695 break;
3699 #endif // CRY_AUDIO_USE_OCCLUSION
3701 //////////////////////////////////////////////////////////////////////////
3702 void CSystem::OnCallback(SRequestInfo const* const pRequestInfo)
3704 if ((gEnv->mMainThreadId == CryGetCurrentThreadId()) && (pRequestInfo->entityId != INVALID_ENTITYID))
3706 IEntity* const pIEntity = gEnv->pEntitySystem->GetEntity(pRequestInfo->entityId);
3708 if (pIEntity != nullptr)
3710 SEntityEvent eventData;
3711 eventData.nParam[0] = reinterpret_cast<intptr_t>(pRequestInfo);
3713 if (pRequestInfo->systemEvent == ESystemEvents::TriggerExecuted)
3715 eventData.event = ENTITY_EVENT_AUDIO_TRIGGER_STARTED;
3716 pIEntity->SendEvent(eventData);
3719 if ((pRequestInfo->systemEvent == ESystemEvents::TriggerFinished) ||
3720 ((pRequestInfo->systemEvent == ESystemEvents::TriggerExecuted) && (pRequestInfo->requestResult != ERequestResult::Success)))
3722 eventData.event = ENTITY_EVENT_AUDIO_TRIGGER_ENDED;
3723 pIEntity->SendEvent(eventData);
3729 //////////////////////////////////////////////////////////////////////////
3730 void CSystem::GetImplInfo(SImplInfo& implInfo)
3732 SSystemRequestData<ESystemRequestType::GetImplInfo> const requestData(implInfo);
3733 CRequest const request(&requestData, ERequestFlags::ExecuteBlocking);
3734 PushRequest(request);
3737 #if defined(CRY_AUDIO_USE_DEBUG_CODE)
3738 //////////////////////////////////////////////////////////////////////////
3739 void CSystem::HandleRefresh()
3741 Cry::Audio::Log(ELogType::Warning, "Beginning to refresh the AudioSystem!");
3743 g_pIImpl->StopAllSounds();
3745 for (auto const& contextPair : g_contextInfo)
3747 if (contextPair.second.isRegistered && contextPair.second.isActive)
3749 g_fileCacheManager.UnloadDataByContext(contextPair.second.contextId);
3753 g_fileCacheManager.UnloadDataByContext(GlobalContextId);
3755 // Store active contexts for reloading after they have been unloaded which empties the map.
3756 ContextInfo const tempContextInfo = g_contextInfo;
3758 g_xmlProcessor.ClearPreloadsData(GlobalContextId, true);
3759 g_xmlProcessor.ClearControlsData(GlobalContextId, true);
3760 ReportContextDeactivated(GlobalContextId);
3761 ResetRequestCount();
3763 g_pIImpl->OnRefresh();
3765 g_xmlProcessor.ParseSystemData();
3766 g_xmlProcessor.ParseControlsData(g_configPath.c_str(), GlobalContextId, g_szGlobalContextName);
3767 g_xmlProcessor.ParsePreloadsData(g_configPath.c_str(), GlobalContextId);
3769 // The global preload might not exist if no preloads have been created, for that reason we don't check the result of this call
3770 g_fileCacheManager.TryLoadRequest(GlobalPreloadRequestId, true, true);
3772 AutoLoadSetting(GlobalContextId);
3774 for (auto const& contextPair : tempContextInfo)
3776 ContextId const contextId = contextPair.second.contextId;
3778 if (contextPair.second.isRegistered && contextPair.second.isActive && (contextId != GlobalContextId))
3780 char const* const szContextName = contextPair.first.c_str();
3782 CryFixedStringT<MaxFilePathLength> contextPath = g_configPath;
3783 contextPath += g_szContextsFolderName;
3784 contextPath += "/";
3785 contextPath += szContextName;
3787 g_xmlProcessor.ParseControlsData(contextPath.c_str(), contextId, szContextName);
3788 g_xmlProcessor.ParsePreloadsData(contextPath.c_str(), contextId);
3790 auto const preloadRequestId = static_cast<PreloadRequestId>(contextId);
3792 if (g_fileCacheManager.TryLoadRequest(preloadRequestId, true, true) != ERequestStatus::Success)
3794 Cry::Audio::Log(ELogType::Warning, R"(No preload request found for context - "%s"!)", szContextName);
3797 AutoLoadSetting(contextId);
3798 ReportContextActivated(contextId);
3802 HandleUpdateDebugInfo(EDebugUpdateFilter::FileCacheManager | EDebugUpdateFilter::Contexts);
3804 Cry::Audio::Log(ELogType::Warning, "Done refreshing the AudioSystem!");
3807 //////////////////////////////////////////////////////////////////////////
3808 void CSystem::ScheduleIRenderAuxGeomForRendering(IRenderAuxGeom* pRenderAuxGeom)
3810 auto oldRenderAuxGeom = m_currentRenderAuxGeom.exchange(pRenderAuxGeom);
3811 CRY_ASSERT(oldRenderAuxGeom != pRenderAuxGeom);
3813 // Kill FIFO entries beyond 1, only the head survives in m_currentRenderAuxGeom
3814 // Throw away all older entries
3815 if (oldRenderAuxGeom && oldRenderAuxGeom != pRenderAuxGeom)
3817 gEnv->pRenderer->DeleteAuxGeom(oldRenderAuxGeom);
3821 //////////////////////////////////////////////////////////////////////////
3822 void CSystem::SubmitLastIRenderAuxGeomForRendering()
3824 if (m_lastDebugRenderSubmitExternalFrame != gEnv->nMainFrameID)
3826 // get auxGeom from "storage"
3827 auto pCurrentRenderAuxGeom = m_currentRenderAuxGeom.exchange(nullptr);
3828 if (pCurrentRenderAuxGeom != nullptr)
3830 gEnv->pRenderer->SubmitAuxGeom(pCurrentRenderAuxGeom, true);
3831 // if another auxGeom was stored in the meantime, we can throw away the current one
3832 // otherwise we keep it around for re-use, to avoid flickering
3833 IRenderAuxGeom* pExpected = nullptr;
3834 if (!m_currentRenderAuxGeom.compare_exchange_strong(pExpected, pCurrentRenderAuxGeom))
3836 gEnv->pRenderer->DeleteAuxGeom(pCurrentRenderAuxGeom);
3838 m_lastDebugRenderSubmitExternalFrame = gEnv->nMainFrameID;
3843 //////////////////////////////////////////////////////////////////////////
3844 void CSystem::DrawDebug()
3846 if (g_cvars.m_drawDebug > 0)
3848 SubmitLastIRenderAuxGeomForRendering();
3850 if (m_canDraw)
3852 m_canDraw = false;
3854 SSystemRequestData<ESystemRequestType::DrawDebugInfo> const requestData;
3855 CRequest const request(&requestData);
3856 PushRequest(request);
3861 //////////////////////////////////////////////////////////////////////////
3862 void CSystem::UpdateDebugInfo()
3864 SSystemRequestData<ESystemRequestType::UpdateDebugInfo> const requestData;
3865 CRequest const request(&requestData);
3866 PushRequest(request);
3869 //////////////////////////////////////////////////////////////////////////
3870 void DrawRequestCategoryInfo(IRenderAuxGeom& auxGeom, float const posX, float& posY, char const* const szType)
3872 auxGeom.Draw2dLabel(posX, posY, Debug::g_systemFontSize, Debug::s_systemColorTextSecondary, false, "%s Request Peak:", szType);
3873 posY += Debug::g_systemLineHeight;
3876 //////////////////////////////////////////////////////////////////////////
3877 void DrawRequestPeakInfo(IRenderAuxGeom& auxGeom, float const posX, float& posY, char const* const szType, uint16 const peak, uint16 poolSize)
3879 bool const poolSizeExceeded = (peak > poolSize) && (poolSize != 0);
3880 CryFixedStringT<MaxInfoStringLength> debugText;
3882 if (poolSizeExceeded)
3884 debugText.Format("%s: %u (Pool Size: %u)", szType, peak, poolSize);
3886 else
3888 debugText.Format("%s: %u", szType, peak);
3891 auxGeom.Draw2dLabel(
3892 posX,
3893 posY,
3894 Debug::g_systemFontSize,
3895 poolSizeExceeded ? Debug::s_globalColorError : Debug::s_systemColorTextPrimary,
3896 false,
3897 "%s", debugText.c_str());
3898 posY += Debug::g_systemLineHeight;
3901 //////////////////////////////////////////////////////////////////////////
3902 void DrawRequestDebugInfo(IRenderAuxGeom& auxGeom, float const posX, float posY)
3904 auxGeom.Draw2dLabel(posX, posY, Debug::g_listHeaderFontSize, Debug::s_globalColorHeader, false, "Audio Requests");
3905 posY += Debug::g_listHeaderLineHeight;
3907 DrawRequestPeakInfo(auxGeom, posX, posY, "Total", g_requestPeaks.requests, 0);
3909 DrawRequestCategoryInfo(auxGeom, posX, posY, "System");
3910 DrawRequestPeakInfo(auxGeom, posX, posY, "ExecuteTrigger", g_requestPeaks.systemExecuteTrigger, g_systemExecuteTriggerPoolSize);
3911 DrawRequestPeakInfo(auxGeom, posX, posY, "ExecuteTriggerEx", g_requestPeaks.systemExecuteTriggerEx, g_systemExecuteTriggerExPoolSize);
3912 DrawRequestPeakInfo(auxGeom, posX, posY, "ExecuteTriggerWithCallbacks", g_requestPeaks.systemExecuteTriggerWithCallbacks, g_systemExecuteTriggerWithCallbacksPoolSize);
3913 DrawRequestPeakInfo(auxGeom, posX, posY, "StopTrigger", g_requestPeaks.systemStopTrigger, g_systemStopTriggerPoolSize);
3914 DrawRequestPeakInfo(auxGeom, posX, posY, "RegisterObject", g_requestPeaks.systemRegisterObject, g_systemRegisterObjectPoolSize);
3915 DrawRequestPeakInfo(auxGeom, posX, posY, "ReleaseObject", g_requestPeaks.systemReleaseObject, g_systemReleaseObjectPoolSize);
3916 DrawRequestPeakInfo(auxGeom, posX, posY, "SetParameter", g_requestPeaks.systemSetParameter, g_systemSetParameterPoolSize);
3917 DrawRequestPeakInfo(auxGeom, posX, posY, "SetSwitchState", g_requestPeaks.systemSetSwitchState, g_systemSetSwitchStatePoolSize);
3919 DrawRequestCategoryInfo(auxGeom, posX, posY, "Object");
3920 DrawRequestPeakInfo(auxGeom, posX, posY, "ExecuteTrigger", g_requestPeaks.objectExecuteTrigger, g_objectExecuteTriggerPoolSize);
3921 DrawRequestPeakInfo(auxGeom, posX, posY, "ExecuteTriggerWithCallbacks", g_requestPeaks.objectExecuteTriggerWithCallbacks, g_objectExecuteTriggerWithCallbacksPoolSize);
3922 DrawRequestPeakInfo(auxGeom, posX, posY, "StopTrigger", g_requestPeaks.objectStopTrigger, g_objectStopTriggerPoolSize);
3923 DrawRequestPeakInfo(auxGeom, posX, posY, "SetTransformation", g_requestPeaks.objectSetTransformation, g_objectSetTransformationPoolSize);
3924 DrawRequestPeakInfo(auxGeom, posX, posY, "SetParameter", g_requestPeaks.objectSetParameter, g_objectSetParameterPoolSize);
3925 DrawRequestPeakInfo(auxGeom, posX, posY, "SetSwitchState", g_requestPeaks.objectSetSwitchState, g_objectSetSwitchStatePoolSize);
3926 DrawRequestPeakInfo(auxGeom, posX, posY, "SetCurrentEnvironments", g_requestPeaks.objectSetCurrentEnvironments, g_objectSetCurrentEnvironmentsPoolSize);
3927 DrawRequestPeakInfo(auxGeom, posX, posY, "SetEnvironment", g_requestPeaks.objectSetEnvironment, g_objectSetEnvironmentPoolSize);
3928 DrawRequestPeakInfo(auxGeom, posX, posY, "ProcessPhysicsRay", g_requestPeaks.objectProcessPhysicsRay, g_objectProcessPhysicsRayPoolSize);
3930 DrawRequestCategoryInfo(auxGeom, posX, posY, "Listener");
3931 DrawRequestPeakInfo(auxGeom, posX, posY, "SetTransformation", g_requestPeaks.listenerSetTransformation, g_listenerSetTransformationPoolSize);
3933 DrawRequestCategoryInfo(auxGeom, posX, posY, "Callback");
3934 DrawRequestPeakInfo(auxGeom, posX, posY, "ReportStartedTriggerConnectionInstance", g_requestPeaks.callbackReportStartedriggerConnectionInstance, g_callbackReportStartedTriggerConnectionInstancePoolSize);
3935 DrawRequestPeakInfo(auxGeom, posX, posY, "ReportFinishedTriggerConnectionInstance", g_requestPeaks.callbackReportFinishedTriggerConnectionInstance, g_callbackReportFinishedTriggerConnectionInstancePoolSize);
3936 DrawRequestPeakInfo(auxGeom, posX, posY, "ReportFinishedTriggerInstance", g_requestPeaks.callbackReportFinishedTriggerInstance, g_callbackReportFinishedTriggerInstancePoolSize);
3937 DrawRequestPeakInfo(auxGeom, posX, posY, "ReportTriggerConnectionInstanceCallback", g_requestPeaks.callbackReportTriggerConnectionInstanceCallback, g_callbackReportTriggerConnectionInstanceCallbackPoolSize);
3938 DrawRequestPeakInfo(auxGeom, posX, posY, "SendTriggerInstanceCallback", g_requestPeaks.callbackSendTriggerInstanceCallback, g_callbackSendTriggerInstanceCallbackPoolSize);
3939 DrawRequestPeakInfo(auxGeom, posX, posY, "ReportPhysicalizedObject", g_requestPeaks.callbackReportPhysicalizedObject, g_callbackReportPhysicalizedObjectPoolSize);
3940 DrawRequestPeakInfo(auxGeom, posX, posY, "ReportVirtualizedObject", g_requestPeaks.callbackReportVirtualizedObject, g_callbackReportVirtualizedObjectPoolSize);
3943 //////////////////////////////////////////////////////////////////////////
3944 void DrawObjectInfo(
3945 IRenderAuxGeom& auxGeom,
3946 float const posX,
3947 float& posY,
3948 Vec3 const& camPos,
3949 CObject const& object,
3950 CryFixedStringT<MaxControlNameLength> const& lowerCaseSearchString,
3951 size_t& numObjects)
3953 Vec3 const& position = object.GetTransformation().GetPosition();
3954 float const distance = position.GetDistance(camPos);
3956 if ((g_cvars.m_debugDistance <= 0.0f) || ((g_cvars.m_debugDistance > 0.0f) && (distance < g_cvars.m_debugDistance)))
3958 char const* const szObjectName = object.GetName();
3959 CryFixedStringT<MaxControlNameLength> lowerCaseObjectName(szObjectName);
3960 lowerCaseObjectName.MakeLower();
3961 bool const hasActiveData = (object.GetFlags() & EObjectFlags::Active) != EObjectFlags::None;
3962 bool const isVirtual = (object.GetFlags() & EObjectFlags::Virtual) != EObjectFlags::None;
3963 bool const stringFound = (lowerCaseSearchString.empty() || (lowerCaseSearchString.compareNoCase("0") == 0)) || (lowerCaseObjectName.find(lowerCaseSearchString) != CryFixedStringT<MaxControlNameLength>::npos);
3964 bool const draw = stringFound && ((g_cvars.m_hideInactiveObjects == 0) || ((g_cvars.m_hideInactiveObjects != 0) && hasActiveData && !isVirtual));
3966 if (draw)
3968 CryFixedStringT<MaxMiscStringLength> debugText;
3970 if ((object.GetFlags() & EObjectFlags::InUse) != EObjectFlags::None)
3972 debugText.Format(szObjectName);
3974 else
3976 debugText.Format("%s [To Be Released]", szObjectName);
3979 auxGeom.Draw2dLabel(
3980 posX,
3981 posY,
3982 Debug::g_listFontSize,
3983 !hasActiveData ? Debug::s_globalColorInactive : (isVirtual ? Debug::s_globalColorVirtual : Debug::s_listColorItemActive),
3984 false,
3985 "%s", debugText.c_str());
3987 posY += Debug::g_listLineHeight;
3988 ++numObjects;
3993 //////////////////////////////////////////////////////////////////////////
3994 void DrawObjectDebugInfo(IRenderAuxGeom& auxGeom, float const posX, float posY)
3996 size_t numObjects = 0;
3997 float const headerPosY = posY;
3998 CryFixedStringT<MaxControlNameLength> lowerCaseSearchString(g_cvars.m_pDebugFilter->GetString());
3999 lowerCaseSearchString.MakeLower();
4001 posY += Debug::g_listHeaderLineHeight;
4002 Vec3 const& camPos = GetISystem()->GetViewCamera().GetPosition();
4004 DrawObjectInfo(auxGeom, posX, posY, camPos, g_previewObject, lowerCaseSearchString, numObjects);
4006 for (auto const pObject : g_constructedObjects)
4008 float const distance = pObject->GetTransformation().GetPosition().GetDistance(camPos);
4010 if ((g_cvars.m_debugDistance <= 0.0f) || ((g_cvars.m_debugDistance > 0.0f) && (distance <= g_cvars.m_debugDistance)))
4012 DrawObjectInfo(auxGeom, posX, posY, camPos, *pObject, lowerCaseSearchString, numObjects);
4016 auxGeom.Draw2dLabel(posX, headerPosY, Debug::g_listHeaderFontSize, Debug::s_globalColorHeader, false, "Audio Objects [%" PRISIZE_T "]", numObjects);
4019 //////////////////////////////////////////////////////////////////////////
4020 void DrawPerActiveObjectDebugInfo(IRenderAuxGeom& auxGeom)
4022 CryFixedStringT<MaxControlNameLength> lowerCaseSearchString(g_cvars.m_pDebugFilter->GetString());
4023 lowerCaseSearchString.MakeLower();
4024 bool const isTextFilterDisabled = (lowerCaseSearchString.empty() || (lowerCaseSearchString.compareNoCase("0") == 0));
4026 for (auto const pObject : g_activeObjects)
4028 if ((pObject->GetFlags() & EObjectFlags::IgnoreDrawDebugInfo) == EObjectFlags::None)
4030 pObject->DrawDebugInfo(auxGeom, isTextFilterDisabled, lowerCaseSearchString);
4035 //////////////////////////////////////////////////////////////////////////
4036 void DrawContextDebugInfo(IRenderAuxGeom& auxGeom, float const posX, float posY)
4038 auxGeom.Draw2dLabel(posX, posY, Debug::g_listHeaderFontSize, Debug::s_globalColorHeader, false, "Contexts [%" PRISIZE_T "]", g_contextLookup.size() + 1);
4039 posY += Debug::g_listHeaderLineHeight;
4041 for (auto const& contextPair : g_contextDebugInfo)
4043 auxGeom.Draw2dLabel(
4044 posX,
4045 posY,
4046 Debug::g_listFontSize,
4047 contextPair.second ? Debug::s_listColorItemActive : Debug::s_globalColorInactive,
4048 false,
4049 "%s", contextPair.first.c_str());
4051 posY += Debug::g_listLineHeight;
4055 ///////////////////////////////////////////////////////////////////////////
4056 void DrawGlobalDataDebugInfo(IRenderAuxGeom& auxGeom, float const posX, float posY)
4058 auxGeom.Draw2dLabel(posX, posY, Debug::g_listHeaderFontSize, Debug::s_globalColorHeader, false, g_szGlobalName);
4059 posY += Debug::g_listHeaderLineHeight;
4061 // Check if text filter is enabled.
4062 CryFixedStringT<MaxControlNameLength> lowerCaseSearchString(g_cvars.m_pDebugFilter->GetString());
4063 lowerCaseSearchString.MakeLower();
4064 bool const isTextFilterDisabled = (lowerCaseSearchString.empty() || (lowerCaseSearchString.compareNoCase("0") == 0));
4065 bool const filterAllObjectInfo = (g_cvars.m_drawDebug & Debug::EDrawFilter::FilterAllObjectInfo) != 0;
4067 // Check if any trigger matches text filter.
4068 bool doesTriggerMatchFilter = false;
4069 std::vector<CryFixedStringT<MaxMiscStringLength>> triggerInfo;
4071 if (!g_triggerInstances.empty() || filterAllObjectInfo)
4073 Debug::TriggerCounts triggerCounts;
4075 for (auto const& triggerInstancePair : g_triggerInstances)
4077 ++(triggerCounts[triggerInstancePair.second->GetTriggerId()]);
4080 for (auto const& triggerCountsPair : triggerCounts)
4082 CTrigger const* const pTrigger = stl::find_in_map(g_triggerLookup, triggerCountsPair.first, nullptr);
4084 if (pTrigger != nullptr)
4086 char const* const szTriggerName = pTrigger->GetName();
4088 if (!isTextFilterDisabled)
4090 CryFixedStringT<MaxControlNameLength> lowerCaseTriggerName(szTriggerName);
4091 lowerCaseTriggerName.MakeLower();
4093 if (lowerCaseTriggerName.find(lowerCaseSearchString) != CryFixedStringT<MaxControlNameLength>::npos)
4095 doesTriggerMatchFilter = true;
4099 CryFixedStringT<MaxMiscStringLength> debugText;
4100 uint8 const numInstances = triggerCountsPair.second;
4102 if (numInstances == 1)
4104 debugText.Format("%s\n", szTriggerName);
4106 else
4108 debugText.Format("%s: %u\n", szTriggerName, numInstances);
4111 triggerInfo.emplace_back(debugText);
4116 // Check if any state or switch matches text filter.
4117 bool doesStateSwitchMatchFilter = false;
4118 std::map<CSwitch const* const, CSwitchState const* const> switchStateInfo;
4120 if (!g_switchStates.empty() || filterAllObjectInfo)
4122 for (auto const& switchStatePair : g_switchStates)
4124 CSwitch const* const pSwitch = stl::find_in_map(g_switchLookup, switchStatePair.first, nullptr);
4126 if (pSwitch != nullptr)
4128 CSwitchState const* const pSwitchState = stl::find_in_map(pSwitch->GetStates(), switchStatePair.second, nullptr);
4130 if (pSwitchState != nullptr)
4132 if (!isTextFilterDisabled)
4134 char const* const szSwitchName = pSwitch->GetName();
4135 CryFixedStringT<MaxControlNameLength> lowerCaseSwitchName(szSwitchName);
4136 lowerCaseSwitchName.MakeLower();
4137 char const* const szStateName = pSwitchState->GetName();
4138 CryFixedStringT<MaxControlNameLength> lowerCaseStateName(szStateName);
4139 lowerCaseStateName.MakeLower();
4141 if ((lowerCaseSwitchName.find(lowerCaseSearchString) != CryFixedStringT<MaxControlNameLength>::npos) ||
4142 (lowerCaseStateName.find(lowerCaseSearchString) != CryFixedStringT<MaxControlNameLength>::npos))
4144 doesStateSwitchMatchFilter = true;
4148 switchStateInfo.emplace(pSwitch, pSwitchState);
4154 // Check if any parameter matches text filter.
4155 bool doesParameterMatchFilter = false;
4156 std::map<char const* const, float const> parameterInfo;
4158 if (!g_parameters.empty() || filterAllObjectInfo)
4160 for (auto const& parameterPair : g_parameters)
4162 CParameter const* const pParameter = stl::find_in_map(g_parameterLookup, parameterPair.first, nullptr);
4164 if (pParameter != nullptr)
4166 char const* const szParameterName = pParameter->GetName();
4168 if (!isTextFilterDisabled)
4170 CryFixedStringT<MaxControlNameLength> lowerCaseParameterName(szParameterName);
4171 lowerCaseParameterName.MakeLower();
4173 if (lowerCaseParameterName.find(lowerCaseSearchString) != CryFixedStringT<MaxControlNameLength>::npos)
4175 doesParameterMatchFilter = true;
4179 parameterInfo.emplace(szParameterName, parameterPair.second);
4184 if (isTextFilterDisabled || doesTriggerMatchFilter)
4186 for (auto const& debugText : triggerInfo)
4188 auxGeom.Draw2dLabel(
4189 posX,
4190 posY,
4191 Debug::g_objectFontSize,
4192 Debug::s_objectColorTrigger,
4193 false,
4194 "%s", debugText.c_str());
4196 posY += Debug::g_objectLineHeight;
4200 if (isTextFilterDisabled || doesStateSwitchMatchFilter)
4202 for (auto const& switchStatePair : switchStateInfo)
4204 auto const pSwitch = switchStatePair.first;
4205 auto const pSwitchState = switchStatePair.second;
4207 Debug::CStateDrawData& drawData = g_stateDrawInfo.emplace(std::piecewise_construct, std::forward_as_tuple(pSwitch->GetId()), std::forward_as_tuple(pSwitchState->GetId())).first->second;
4208 drawData.Update(pSwitchState->GetId());
4209 ColorF const switchTextColor = { 0.8f, drawData.m_currentSwitchColor, 0.6f };
4211 auxGeom.Draw2dLabel(
4212 posX,
4213 posY,
4214 Debug::g_objectFontSize,
4215 switchTextColor,
4216 false,
4217 "%s: %s\n",
4218 pSwitch->GetName(),
4219 pSwitchState->GetName());
4221 posY += Debug::g_objectLineHeight;
4225 if (isTextFilterDisabled || doesParameterMatchFilter)
4227 for (auto const& parameterPair : parameterInfo)
4229 auxGeom.Draw2dLabel(
4230 posX,
4231 posY,
4232 Debug::g_objectFontSize,
4233 Debug::s_objectColorParameter,
4234 false,
4235 "%s: %2.2f\n",
4236 parameterPair.first,
4237 parameterPair.second);
4239 posY += Debug::g_objectLineHeight;
4243 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectImplInfo) != 0)
4245 g_pIObject->DrawDebugInfo(auxGeom, posX, posY, (isTextFilterDisabled ? nullptr : lowerCaseSearchString.c_str()));
4249 //////////////////////////////////////////////////////////////////////////
4250 void CSystem::HandleDrawDebug()
4252 CRY_PROFILE_FUNCTION(PROFILE_AUDIO);
4253 IRenderAuxGeom* const pAuxGeom = gEnv->pRenderer ? gEnv->pRenderer->GetOrCreateIRenderAuxGeom() : nullptr;
4255 if (pAuxGeom != nullptr)
4257 if ((g_cvars.m_drawDebug & Debug::objectMask) != 0)
4259 // Needs to be called first so that the rest of the labels are printed on top.
4260 // (Draw2dLabel doesn't provide a way to set which labels are printed on top)
4261 DrawPerActiveObjectDebugInfo(*pAuxGeom);
4264 float posX = 8.0f;
4265 float posY = 4.0f;
4266 float const headerPosY = posY;
4268 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::HideMemoryInfo) == 0)
4270 posY += Debug::g_systemHeaderLineSpacerHeight;
4272 size_t totalPoolSize = 0;
4273 bool const drawDetailedMemInfo = (g_cvars.m_drawDebug & Debug::EDrawFilter::DetailedMemoryInfo) != 0;
4276 auto& allocator = CObject::GetAllocator();
4277 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4278 totalPoolSize += memAlloc;
4280 if (drawDetailedMemInfo)
4282 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Objects", m_objectPoolSize);
4286 #if defined(CRY_AUDIO_USE_OCCLUSION)
4288 auto& allocator = SOcclusionInfo::GetAllocator();
4289 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4290 totalPoolSize += memAlloc;
4292 if (drawDetailedMemInfo)
4294 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Occlusion Infos", m_objectPoolSize);
4297 #endif // CRY_AUDIO_USE_OCCLUSION
4300 auto& allocator = CTriggerInstance::GetAllocator();
4301 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4302 totalPoolSize += memAlloc;
4304 if (drawDetailedMemInfo)
4306 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Trigger Instances", static_cast<uint16>(g_cvars.m_triggerInstancePoolSize));
4310 if (g_debugPoolSizes.triggers > 0)
4312 auto& allocator = CTrigger::GetAllocator();
4313 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4314 totalPoolSize += memAlloc;
4316 if (drawDetailedMemInfo)
4318 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Triggers", g_poolSizes.triggers);
4322 if (g_debugPoolSizes.parameters > 0)
4324 auto& allocator = CParameter::GetAllocator();
4325 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4326 totalPoolSize += memAlloc;
4328 if (drawDetailedMemInfo)
4330 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Parameters", g_poolSizes.parameters);
4334 if (g_debugPoolSizes.switches > 0)
4336 auto& allocator = CSwitch::GetAllocator();
4337 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4338 totalPoolSize += memAlloc;
4340 if (drawDetailedMemInfo)
4342 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Switches", g_poolSizes.switches);
4346 if (g_debugPoolSizes.states > 0)
4348 auto& allocator = CSwitchState::GetAllocator();
4349 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4350 totalPoolSize += memAlloc;
4352 if (drawDetailedMemInfo)
4354 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "SwitchStates", g_poolSizes.states);
4358 if (g_debugPoolSizes.environments > 0)
4360 auto& allocator = CEnvironment::GetAllocator();
4361 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4362 totalPoolSize += memAlloc;
4364 if (drawDetailedMemInfo)
4366 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Environments", g_poolSizes.environments);
4370 if (g_debugPoolSizes.preloads > 0)
4372 auto& allocator = CPreloadRequest::GetAllocator();
4373 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4374 totalPoolSize += memAlloc;
4376 if (drawDetailedMemInfo)
4378 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Preloads", g_poolSizes.preloads);
4382 if (g_debugPoolSizes.settings > 0)
4384 auto& allocator = CSetting::GetAllocator();
4385 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4386 totalPoolSize += memAlloc;
4388 if (drawDetailedMemInfo)
4390 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Settings", g_poolSizes.settings);
4394 if (g_debugPoolSizes.files > 0)
4396 auto& allocator = CFile::GetAllocator();
4397 size_t const memAlloc = allocator.GetTotalMemory().nAlloc;
4398 totalPoolSize += memAlloc;
4400 if (drawDetailedMemInfo)
4402 Debug::DrawMemoryPoolInfo(*pAuxGeom, posX, posY, memAlloc, allocator.GetCounts(), "Files", g_poolSizes.files);
4406 CryModuleMemoryInfo memInfo;
4407 ZeroStruct(memInfo);
4409 #if !defined(_LIB)
4410 // This works differently in monolithic builds and therefore doesn't cater to our needs.
4411 CryGetMemoryInfoForModule(&memInfo);
4412 #endif // _LIB
4414 CryFixedStringT<Debug::MaxMemInfoStringLength> memAllocSizeString;
4415 auto const memAllocSize = static_cast<size_t>(memInfo.allocated - memInfo.freed);
4416 Debug::FormatMemoryString(memAllocSizeString, memAllocSize);
4418 CryFixedStringT<Debug::MaxMemInfoStringLength> totalPoolSizeString;
4419 Debug::FormatMemoryString(totalPoolSizeString, totalPoolSize);
4421 size_t const totalFileSize = g_fileCacheManager.GetTotalCachedFileSize();
4423 CryFixedStringT<Debug::MaxMemInfoStringLength> totalMemSizeString;
4424 size_t const totalMemSize = memAllocSize + totalPoolSize + totalFileSize;
4425 Debug::FormatMemoryString(totalMemSizeString, totalMemSize);
4427 char const* const szMuted = ((g_systemStates& ESystemStates::IsMuted) != ESystemStates::None) ? " - Muted" : "";
4428 char const* const szPaused = ((g_systemStates& ESystemStates::IsPaused) != ESystemStates::None) ? " - Paused" : "";
4430 if (totalFileSize > 0)
4432 CryFixedStringT<Debug::MaxMemInfoStringLength> totalFileSizeString;
4433 Debug::FormatMemoryString(totalFileSizeString, totalFileSize);
4435 pAuxGeom->Draw2dLabel(posX, headerPosY, Debug::g_systemHeaderFontSize, Debug::s_globalColorHeader, false,
4436 "Audio (System: %s | Pools: %s | Assets: %s | Total: %s)%s%s",
4437 memAllocSizeString.c_str(), totalPoolSizeString.c_str(), totalFileSizeString.c_str(), totalMemSizeString.c_str(), szMuted, szPaused);
4439 else
4441 pAuxGeom->Draw2dLabel(posX, headerPosY, Debug::g_systemHeaderFontSize, Debug::s_globalColorHeader, false,
4442 "Audio (System: %s | Pools: %s | Total: %s)%s%s",
4443 memAllocSizeString.c_str(), totalPoolSizeString.c_str(), totalMemSizeString.c_str(), szMuted, szPaused);
4446 size_t const numObjects = g_constructedObjects.size();
4447 size_t const numActiveObjects = g_activeObjects.size();
4448 size_t const numListeners = g_listenerManager.GetNumListeners();
4449 size_t const numEventListeners = g_eventListenerManager.GetNumEventListeners();
4451 #if defined(CRY_AUDIO_USE_OCCLUSION)
4452 static float const SMOOTHING_ALPHA = 0.2f;
4453 static float syncRays = 0;
4454 static float asyncRays = 0;
4455 syncRays += (CPropagationProcessor::s_totalSyncPhysRays - syncRays) * SMOOTHING_ALPHA;
4456 asyncRays += (CPropagationProcessor::s_totalAsyncPhysRays - asyncRays) * SMOOTHING_ALPHA * 0.1f;
4458 posY += Debug::g_systemLineHeight;
4459 pAuxGeom->Draw2dLabel(posX, posY, Debug::g_systemFontSize, Debug::s_systemColorTextSecondary, false,
4460 "Objects: %3" PRISIZE_T "/%3" PRISIZE_T " | EventListeners %3" PRISIZE_T " | Listeners: %" PRISIZE_T " | SyncRays: %3.1f AsyncRays: %3.1f",
4461 numActiveObjects, numObjects, numEventListeners, numListeners, syncRays, asyncRays);
4462 #else
4463 posY += Debug::g_systemLineHeight;
4464 pAuxGeom->Draw2dLabel(posX, posY, Debug::g_systemFontSize, Debug::s_systemColorTextSecondary, false,
4465 "Objects: %3" PRISIZE_T "/%3" PRISIZE_T " | EventListeners %3" PRISIZE_T " | Listeners: %" PRISIZE_T,
4466 numActiveObjects, numObjects, numEventListeners, numListeners);
4467 #endif // CRY_AUDIO_USE_OCCLUSION
4469 if (g_pIImpl != nullptr)
4471 posY += Debug::g_systemHeaderLineHeight;
4472 g_pIImpl->DrawDebugMemoryInfo(*pAuxGeom, posX, posY, (g_cvars.m_drawDebug & Debug::EDrawFilter::DetailedMemoryInfo) != 0);
4475 posY += Debug::g_systemHeaderLineHeight;
4478 string debugFilter = g_cvars.m_pDebugFilter->GetString();
4480 if (debugFilter.IsEmpty() || debugFilter == "0")
4482 debugFilter = "<none>";
4485 string debugDistance = ToString(g_cvars.m_debugDistance) + " m";
4487 if (g_cvars.m_debugDistance <= 0)
4489 debugDistance = "<infinite>";
4492 string debugDraw = "";
4494 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::Spheres) != 0)
4496 debugDraw += "Spheres, ";
4499 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectLabel) != 0)
4501 debugDraw += "Labels, ";
4504 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectTriggers) != 0)
4506 debugDraw += "Triggers, ";
4509 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectStates) != 0)
4511 debugDraw += "States, ";
4514 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectParameters) != 0)
4516 debugDraw += "Parameters, ";
4519 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectEnvironments) != 0)
4521 debugDraw += "Environments, ";
4524 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectDistance) != 0)
4526 debugDraw += "Distances, ";
4529 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::OcclusionRayLabels) != 0)
4531 debugDraw += "Occlusion Ray Labels, ";
4534 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::OcclusionRays) != 0)
4536 debugDraw += "Occlusion Rays, ";
4539 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::OcclusionRayOffset) != 0)
4541 debugDraw += "Occlusion Ray Offset, ";
4544 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::OcclusionListenerPlane) != 0)
4546 debugDraw += "Occlusion Listener Plane, ";
4549 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::OcclusionCollisionSpheres) != 0)
4551 debugDraw += "Occlusion Collision Spheres, ";
4554 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::GlobalPlaybackInfo) != 0)
4556 debugDraw += "Default Object Info, ";
4559 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ObjectImplInfo) != 0)
4561 debugDraw += "Object Middleware Info, ";
4564 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::Contexts) != 0)
4566 debugDraw += "Active Contexts, ";
4569 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ImplList) != 0)
4571 debugDraw += "Implementation List, ";
4574 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ActiveObjects) != 0)
4576 debugDraw += "Active Objects, ";
4579 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::FileCacheManagerInfo) != 0)
4581 debugDraw += "File Cache Manager, ";
4584 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::RequestInfo) != 0)
4586 debugDraw += "Requests, ";
4589 if (!debugDraw.IsEmpty())
4591 debugDraw.erase(debugDraw.length() - 2, 2);
4592 pAuxGeom->Draw2dLabel(posX, posY, Debug::g_systemFontSize, Debug::s_systemColorTextPrimary, false, "Debug Draw: %s", debugDraw.c_str());
4593 posY += Debug::g_systemLineHeight;
4594 pAuxGeom->Draw2dLabel(posX, posY, Debug::g_systemFontSize, Debug::s_systemColorTextPrimary, false, "Debug Filter: %s | Debug Distance: %s", debugFilter.c_str(), debugDistance.c_str());
4596 posY += Debug::g_systemHeaderLineHeight;
4599 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::FileCacheManagerInfo) != 0)
4601 g_fileCacheManager.DrawDebugInfo(*pAuxGeom, posX, posY);
4602 posX += 600.0f;
4605 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::GlobalPlaybackInfo) != 0)
4607 DrawGlobalDataDebugInfo(*pAuxGeom, posX, posY);
4608 posX += 400.0f;
4611 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::Contexts) != 0)
4613 DrawContextDebugInfo(*pAuxGeom, posX, posY);
4614 posX += 200.0f;
4617 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ActiveObjects) != 0)
4619 DrawObjectDebugInfo(*pAuxGeom, posX, posY);
4620 posX += 300.0f;
4623 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::ImplList) != 0)
4625 if (g_pIImpl != nullptr)
4627 Vec3 const& camPos = GetISystem()->GetViewCamera().GetPosition();
4629 g_pIImpl->DrawDebugInfoList(*pAuxGeom, posX, posY, camPos, g_cvars.m_debugDistance, g_cvars.m_pDebugFilter->GetString());
4630 // The impl is responsible for increasing posX.
4634 if ((g_cvars.m_drawDebug & Debug::EDrawFilter::RequestInfo) != 0)
4636 DrawRequestDebugInfo(*pAuxGeom, posX, posY);
4637 posX += 600.0f;
4641 g_system.ScheduleIRenderAuxGeomForRendering(pAuxGeom);
4644 //////////////////////////////////////////////////////////////////////////
4645 void CSystem::HandleRetriggerControls()
4647 for (auto const pObject : g_constructedObjects)
4649 pObject->ForceImplementationRefresh();
4652 ForceGlobalDataImplRefresh();
4653 g_previewObject.ForceImplementationRefresh();
4655 if ((g_systemStates& ESystemStates::IsMuted) != ESystemStates::None)
4657 ExecuteDefaultTrigger(EDefaultTriggerType::MuteAll);
4660 if ((g_systemStates& ESystemStates::IsPaused) != ESystemStates::None)
4662 ExecuteDefaultTrigger(EDefaultTriggerType::PauseAll);
4665 #endif // CRY_AUDIO_USE_DEBUG_CODE
4666 } // namespace CryAudio