WwiseDataStructure.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. /*******************************************************************************
  2. The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
  3. Technology released in source code form as part of the game integration package.
  4. The content of this file may not be used without valid licenses to the
  5. AUDIOKINETIC Wwise Technology.
  6. Note that the use of the game engine is subject to the Unreal(R) Engine End User
  7. License Agreement at https://www.unrealengine.com/en-US/eula/unreal
  8. License Usage
  9. Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
  10. this file in accordance with the end user license agreement provided with the
  11. software or, alternatively, in accordance with the terms contained
  12. in a written agreement between you and Audiokinetic Inc.
  13. Copyright (c) 2023 Audiokinetic Inc.
  14. *******************************************************************************/
  15. #pragma once
  16. #include "Wwise/WwiseGeneratedFiles.h"
  17. #include "Wwise/Stats/ProjectDatabase.h"
  18. #include "Wwise/WwiseSharedLanguageId.h"
  19. #include "Wwise/Info/WwiseObjectInfo.h"
  20. #include "Wwise/Info/WwiseEventInfo.h"
  21. #include "Wwise/Info/WwiseGroupValueInfo.h"
  22. #include "Wwise/Metadata/WwiseMetadataSoundBank.h"
  23. #include "Wwise/Ref/WwiseRefAcousticTexture.h"
  24. #include "Wwise/Ref/WwiseAnyRef.h"
  25. #include "Wwise/Ref/WwiseRefAudioDevice.h"
  26. #include "Wwise/Ref/WwiseRefAuxBus.h"
  27. #include "Wwise/Ref/WwiseRefBus.h"
  28. #include "Wwise/Ref/WwiseRefCustomPlugin.h"
  29. #include "Wwise/Ref/WwiseRefDialogueArgument.h"
  30. #include "Wwise/Ref/WwiseRefExternalSource.h"
  31. #include "Wwise/Ref/WwiseRefGameParameter.h"
  32. #include "Wwise/Ref/WwiseRefLanguage.h"
  33. #include "Wwise/Ref/WwiseRefMedia.h"
  34. #include "Wwise/Ref/WwiseRefPlatform.h"
  35. #include "Wwise/Ref/WwiseRefPluginLib.h"
  36. #include "Wwise/Ref/WwiseRefPluginShareSet.h"
  37. #include "Wwise/Ref/WwiseRefSoundBank.h"
  38. #include "Wwise/Ref/WwiseRefState.h"
  39. #include "Wwise/Ref/WwiseRefSwitch.h"
  40. #include "Wwise/Ref/WwiseRefSwitchContainer.h"
  41. #include "Wwise/Ref/WwiseRefTrigger.h"
  42. #include "Engine/EngineTypes.h"
  43. #include "UObject/SoftObjectPath.h"
  44. #include <inttypes.h>
  45. struct WWISEPROJECTDATABASE_API FWwiseRootDataStructure
  46. {
  47. FWwiseGeneratedFiles::FGeneratedRootFiles GeneratedRootFiles;
  48. WwiseMetadataFileMap JsonFiles;
  49. WwiseLanguageNamesMap LanguageNames;
  50. WwiseLanguageIdsMap LanguageIds;
  51. WwisePlatformNamesMap PlatformNames;
  52. WwisePlatformGuidsMap PlatformGuids;
  53. TSet<FWwiseSharedLanguageId> Languages;
  54. TSet<FWwiseSharedPlatformId> Platforms;
  55. FWwiseRootDataStructure() {}
  56. FWwiseRootDataStructure(WwiseMetadataFileMap&& JsonFiles);
  57. FWwiseRootDataStructure& operator+=(FWwiseRootDataStructure&& Rhs);
  58. uint32 GetLanguageId(const FName& Name) const
  59. {
  60. if (const auto* Language = LanguageNames.Find(Name))
  61. {
  62. return Language->LanguageId();
  63. }
  64. return FWwiseDatabaseLocalizableIdKey::GENERIC_LANGUAGE;
  65. }
  66. };
  67. struct WWISEPROJECTDATABASE_API FWwisePlatformDataStructure :
  68. private FWwiseRefAcousticTexture::FGlobalIdsMap,
  69. private FWwiseRefAudioDevice::FGlobalIdsMap,
  70. private FWwiseRefAuxBus::FGlobalIdsMap,
  71. private FWwiseRefBus::FGlobalIdsMap,
  72. private FWwiseRefCustomPlugin::FGlobalIdsMap,
  73. private FWwiseRefDialogueArgument::FGlobalIdsMap,
  74. private FWwiseRefDialogueEvent::FGlobalIdsMap,
  75. private FWwiseRefEvent::FGlobalIdsMap,
  76. private FWwiseRefExternalSource::FGlobalIdsMap,
  77. private FWwiseRefGameParameter::FGlobalIdsMap,
  78. private FWwiseRefMedia::FGlobalIdsMap,
  79. private FWwiseRefPluginLib::FGlobalIdsMap,
  80. private FWwiseRefPluginShareSet::FGlobalIdsMap,
  81. private FWwiseRefSoundBank::FGlobalIdsMap,
  82. private FWwiseRefState::FGlobalIdsMap,
  83. private FWwiseRefStateGroup::FGlobalIdsMap,
  84. private FWwiseRefSwitch::FGlobalIdsMap,
  85. private FWwiseRefSwitchGroup::FGlobalIdsMap,
  86. private FWwiseRefTrigger::FGlobalIdsMap
  87. {
  88. FWwiseSharedPlatformId Platform;
  89. FWwiseRefPlatform PlatformRef;
  90. FWwiseGeneratedFiles::FPlatformFiles GeneratedPlatformFiles;
  91. WwiseMetadataFileMap JsonFiles;
  92. WwiseAcousticTextureGlobalIdsMap& AcousticTextures;
  93. WwiseAudioDeviceGlobalIdsMap& AudioDevices;
  94. WwiseAuxBusGlobalIdsMap& AuxBusses;
  95. WwiseBusGlobalIdsMap& Busses;
  96. WwiseCustomPluginGlobalIdsMap& CustomPlugins;
  97. WwiseDialogueArgumentGlobalIdsMap& DialogueArguments;
  98. WwiseDialogueEventGlobalIdsMap& DialogueEvents;
  99. WwiseEventGlobalIdsMap& Events;
  100. WwiseExternalSourceGlobalIdsMap& ExternalSources;
  101. WwiseGameParameterGlobalIdsMap& GameParameters;
  102. WwiseMediaGlobalIdsMap& MediaFiles;
  103. WwisePluginLibGlobalIdsMap& PluginLibs;
  104. WwisePluginShareSetGlobalIdsMap& PluginShareSets;
  105. WwiseSoundBankGlobalIdsMap& SoundBanks;
  106. WwiseStateGlobalIdsMap& States;
  107. WwiseStateGroupGlobalIdsMap& StateGroups;
  108. WwiseSwitchGlobalIdsMap& Switches;
  109. WwiseSwitchGroupGlobalIdsMap& SwitchGroups;
  110. WwiseTriggerGlobalIdsMap& Triggers;
  111. WwisePluginLibNamesMap PluginLibNames;
  112. WwiseSwitchContainersByEvent SwitchContainersByEvent;
  113. WwiseGuidMap Guids;
  114. WwiseNameMap Names;
  115. FWwisePlatformDataStructure();
  116. FWwisePlatformDataStructure(const FWwiseSharedPlatformId& InPlatform, FWwiseRootDataStructure& InRootData, WwiseMetadataFileMap&& InJsonFiles);
  117. FWwisePlatformDataStructure(const FWwisePlatformDataStructure& Rhs);
  118. FWwisePlatformDataStructure(FWwisePlatformDataStructure&& Rhs);
  119. FWwisePlatformDataStructure& operator+=(FWwisePlatformDataStructure&& Rhs);
  120. template <typename RequiredRef>
  121. void GetRefMap(TMap<FWwiseSharedLanguageId, RequiredRef>& OutRefMap, const TSet<FWwiseSharedLanguageId>& InLanguages, const FWwiseObjectInfo& InInfo) const;
  122. template <typename RequiredRef>
  123. void GetRefMap(TMap<FWwiseSharedLanguageId, TSet<RequiredRef>>& OutRefMap, const TSet<FWwiseSharedLanguageId>& InLanguages, const FWwiseObjectInfo& InInfo) const;
  124. template <typename RequiredRef>
  125. bool GetRef(TSet<RequiredRef>& OutRef, const FWwiseSharedLanguageId& InLanguage, const FWwiseObjectInfo& InInfo) const;
  126. template <typename RequiredRef>
  127. bool GetRef(RequiredRef& OutRef, const FWwiseSharedLanguageId& InLanguage, const FWwiseObjectInfo& InInfo) const;
  128. template <typename RequiredRef>
  129. bool GetRef(RequiredRef& OutRef, const FWwiseSharedLanguageId& InLanguage, const FWwiseGroupValueInfo& InInfo) const;
  130. template <typename RequiredRef>
  131. static bool GetLocalizableRef(RequiredRef& OutRef, const TMap<FWwiseDatabaseLocalizableIdKey, RequiredRef>& InGlobalMap,
  132. uint32 InShortId, uint32 InLanguageId, uint32 InSoundBankId, const TCHAR* InDebugName);
  133. template <typename RequiredRef>
  134. static bool GetLocalizableGroupRef(RequiredRef& OutRef, const TMap<FWwiseDatabaseLocalizableGroupValueKey, RequiredRef>& InGlobalMap,
  135. FWwiseDatabaseGroupValueKey InGroupValue, uint32 InLanguageId, uint32 InSoundBankId, const TCHAR* InDebugName);
  136. template <typename RequiredRef>
  137. static void GetLocalizableRefs(TArray<RequiredRef>& OutRefs, const TMap<FWwiseDatabaseLocalizableIdKey, RequiredRef>& InGlobalMap,
  138. uint32 InShortId, uint32 InLanguageId, uint32 InSoundBankId, const TCHAR* InDebugName);
  139. template <typename RefType>
  140. bool GetFromId(RefType& OutRef, uint32 InId, uint32 InLanguageId = 0, uint32 InSoundBankId = 0) const
  141. {
  142. return GetLocalizableRef(OutRef, RefType::FGlobalIdsMap::GlobalIdsMap, InId, InLanguageId, InSoundBankId, RefType::NAME);
  143. }
  144. template <typename RefType>
  145. bool GetFromId(RefType& OutRef, FWwiseDatabaseGroupValueKey InId, uint32 InLanguageId = 0, uint32 InSoundBankId = 0) const
  146. {
  147. return GetLocalizableGroupRef(OutRef, RefType::FGlobalIdsMap::GlobalIdsMap, InId, InLanguageId, InSoundBankId, RefType::NAME);
  148. }
  149. template <typename RefType>
  150. bool GetFromId(TSet<RefType>& OutRef, uint32 InId, uint32 InLanguageId, uint32 InSoundBankId) const;
  151. bool GetFromId(FWwiseRefMedia& OutRef, uint32 InShortId, uint32 InLanguageId, uint32 InSoundBankId) const;
  152. template <typename RequiredRef>
  153. void AddBasicRefToMap(TMap<FWwiseDatabaseLocalizableIdKey, RequiredRef>& OutMap, const RequiredRef& InRef, const FWwiseMetadataBasicReference& InObject);
  154. template <typename RequiredRef>
  155. void AddEventRefToMap(TMap<FWwiseDatabaseLocalizableIdKey, RequiredRef>& OutMap, const RequiredRef& InRef, const FWwiseMetadataBasicReference& InObject);
  156. template <typename RequiredRef>
  157. void AddRefToMap(TMap<FWwiseDatabaseLocalizableIdKey, RequiredRef>& OutMap, const RequiredRef& InRef, const uint32& InId, const FName* InName, const FName* InObjectPath, const FGuid* InGuid);
  158. private:
  159. FWwisePlatformDataStructure& operator=(const FWwisePlatformDataStructure& Rhs) = delete;
  160. };
  161. struct WWISEPROJECTDATABASE_API FWwiseDataStructure
  162. {
  163. FRWLock Lock;
  164. FWwiseRootDataStructure RootData;
  165. TMap<FWwiseSharedPlatformId, FWwisePlatformDataStructure> Platforms;
  166. FWwiseDataStructure() {}
  167. FWwiseDataStructure(const FDirectoryPath& InDirectoryPath, const FName* InPlatform = nullptr, const FGuid* InBasePlatformGuid = nullptr);
  168. ~FWwiseDataStructure();
  169. FWwiseDataStructure& operator+=(FWwiseDataStructure&& Rhs);
  170. FWwiseDataStructure& operator=(FWwiseDataStructure&& Rhs)
  171. {
  172. RootData = MoveTemp(Rhs.RootData);
  173. Platforms = MoveTemp(Rhs.Platforms);
  174. return *this;
  175. }
  176. private:
  177. FWwiseDataStructure(const FWwiseDataStructure& other) = delete;
  178. FWwiseDataStructure& operator=(const FWwiseDataStructure& other) = delete;
  179. void LoadDataStructure(FWwiseGeneratedFiles&& Directory);
  180. };
  181. template<typename RequiredRef>
  182. inline void FWwisePlatformDataStructure::GetRefMap(TMap<FWwiseSharedLanguageId, RequiredRef>& OutRefMap, const TSet<FWwiseSharedLanguageId>& InLanguages, const FWwiseObjectInfo& InInfo) const
  183. {
  184. OutRefMap.Empty(InLanguages.Num());
  185. for (const auto& Language : InLanguages)
  186. {
  187. RequiredRef Ref;
  188. if (GetRef(Ref, Language, InInfo))
  189. {
  190. OutRefMap.Add(Language, Ref);
  191. }
  192. }
  193. }
  194. template<typename RequiredRef>
  195. inline void FWwisePlatformDataStructure::GetRefMap(TMap<FWwiseSharedLanguageId, TSet<RequiredRef>>& OutRefMap, const TSet<FWwiseSharedLanguageId>& InLanguages, const FWwiseObjectInfo& InInfo) const
  196. {
  197. OutRefMap.Empty(InLanguages.Num());
  198. for (const auto& Language : InLanguages)
  199. {
  200. TSet<RequiredRef> Refs;
  201. if (GetRef(Refs, Language, InInfo))
  202. {
  203. if (Refs.Num() > 1)
  204. {
  205. UE_LOG(LogWwiseProjectDatabase,Log, TEXT("More than one ref per language found in %s (%s %" PRIu32 ")"), RequiredRef::NAME, *InInfo.WwiseName.ToString(), InInfo.WwiseShortId);
  206. }
  207. OutRefMap.Add(Language, Refs);
  208. }
  209. }
  210. }
  211. template <typename RequiredRef>
  212. bool FWwisePlatformDataStructure::GetRef(TSet<RequiredRef>& OutRef, const FWwiseSharedLanguageId& InLanguage, const FWwiseObjectInfo& InInfo) const
  213. {
  214. const auto LanguageId = InLanguage.GetLanguageId();
  215. // Get from GUID
  216. bool bResult = false;
  217. if (InInfo.WwiseGuid.IsValid())
  218. {
  219. TArray<const FWwiseAnyRef*> Results;
  220. if (LanguageId != 0)
  221. {
  222. Guids.MultiFindPointer(FWwiseDatabaseLocalizableGuidKey(InInfo.WwiseGuid, LanguageId), Results, false);
  223. }
  224. Guids.MultiFindPointer(FWwiseDatabaseLocalizableGuidKey(InInfo.WwiseGuid, 0), Results, false);
  225. if (LIKELY(Results.Num() > 0))
  226. {
  227. for (const auto* Any : Results)
  228. {
  229. RequiredRef Result;
  230. if (LIKELY(Any->GetRef(Result)))
  231. {
  232. bool bAlreadyInSet = OutRef.Find(Result) != nullptr;
  233. if (LIKELY(!bAlreadyInSet))
  234. {
  235. if (InInfo.HardCodedSoundBankShortId == 0 || InInfo.HardCodedSoundBankShortId == Result.SoundBankId())
  236. {
  237. OutRef.Add(Result, &bAlreadyInSet);
  238. if (UNLIKELY(InInfo.WwiseName.IsNone()))
  239. {
  240. UE_LOG(LogWwiseProjectDatabase, Verbose, TEXT("Name not set while retrieving Wwise Object GUID %s: Should be %s or %s."),
  241. *InInfo.WwiseGuid.ToString(), *Any->GetName().ToString(), *Any->GetObjectPath().ToString());
  242. }
  243. else if (UNLIKELY(InInfo.WwiseName != Any->GetName() && InInfo.WwiseName != Any->GetObjectPath()))
  244. {
  245. UE_LOG(LogWwiseProjectDatabase, Log, TEXT("Different name while retrieving Wwise Object GUID %s (%s): Should be %s or %s."),
  246. *InInfo.WwiseGuid.ToString(), *InInfo.WwiseName.ToString(), *Any->GetName().ToString(), *Any->GetObjectPath().ToString());
  247. }
  248. if (UNLIKELY(InInfo.WwiseShortId == 0))
  249. {
  250. UE_LOG(LogWwiseProjectDatabase, Log, TEXT("Id not set while retrieving Wwise Object GUID %s: Should be %" PRIu32 "."),
  251. *InInfo.WwiseGuid.ToString(), Any->GetId());
  252. }
  253. else if (UNLIKELY(InInfo.WwiseShortId != Any->GetId()))
  254. {
  255. UE_LOG(LogWwiseProjectDatabase, Log, TEXT("Different Id while retrieving Wwise Object GUID %s (%" PRIu32 "): Should be %" PRIu32 "."),
  256. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, Any->GetId());
  257. }
  258. }
  259. }
  260. bResult |= !bAlreadyInSet;
  261. }
  262. }
  263. return bResult;
  264. }
  265. }
  266. // Get from Short ID
  267. if (InInfo.WwiseShortId != 0)
  268. {
  269. auto OldOutRefNum = OutRef.Num();
  270. if (GetFromId(OutRef, InInfo.WwiseShortId, InLanguage.GetLanguageId(), InInfo.HardCodedSoundBankShortId))
  271. {
  272. return OldOutRefNum != OutRef.Num();
  273. }
  274. }
  275. // Get from Name. Try all found assets with such name until we get one
  276. if (!InInfo.WwiseName.IsNone())
  277. {
  278. FWwiseDatabaseLocalizableNameKey LocalizableName(InInfo.WwiseName, InLanguage.GetLanguageId());
  279. TArray<const FWwiseAnyRef *> Results;
  280. if (LanguageId != 0)
  281. {
  282. Names.MultiFindPointer(FWwiseDatabaseLocalizableNameKey(InInfo.WwiseName, 0), Results);
  283. }
  284. Names.MultiFindPointer(FWwiseDatabaseLocalizableNameKey(InInfo.WwiseName, LanguageId), Results);
  285. for (const auto *Any : Results)
  286. {
  287. RequiredRef Result;
  288. if (LIKELY(Any->GetRef(Result)))
  289. {
  290. bool bAlreadyInSet = OutRef.Find(Result) != nullptr;
  291. if (LIKELY(!bAlreadyInSet))
  292. {
  293. OutRef.Add(Result, &bAlreadyInSet);
  294. if (UNLIKELY(InInfo.WwiseName.IsNone()))
  295. {
  296. UE_LOG(LogWwiseProjectDatabase, Verbose, TEXT("Name not set while retrieving Wwise Object GUID %s: Should be %s or %s."),
  297. *InInfo.WwiseGuid.ToString(), *Any->GetName().ToString(), *Any->GetObjectPath().ToString());
  298. }
  299. else if (UNLIKELY(InInfo.WwiseName != Any->GetName() && InInfo.WwiseName != Any->GetObjectPath()))
  300. {
  301. UE_LOG(LogWwiseProjectDatabase, Log, TEXT("Different name while retrieving Wwise Object GUID %s (%s): Should be %s or %s."),
  302. *InInfo.WwiseGuid.ToString(), *InInfo.WwiseName.ToString(), *Any->GetName().ToString(), *Any->GetObjectPath().ToString());
  303. }
  304. if (UNLIKELY(InInfo.WwiseShortId == 0))
  305. {
  306. UE_LOG(LogWwiseProjectDatabase, Log, TEXT("Id not set while retrieving Wwise Object GUID %s: Should be %" PRIu32 "."),
  307. *InInfo.WwiseGuid.ToString(), Any->GetId());
  308. }
  309. else if (UNLIKELY(InInfo.WwiseShortId != Any->GetId()))
  310. {
  311. UE_LOG(LogWwiseProjectDatabase, Log, TEXT("Different Id while retrieving Wwise Object GUID %s (%" PRIu32 "): Should be %" PRIu32 "."),
  312. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, Any->GetId());
  313. }
  314. }
  315. bResult |= !bAlreadyInSet;
  316. }
  317. return bResult;
  318. }
  319. }
  320. return false;
  321. }
  322. template <typename RequiredRef>
  323. inline bool FWwisePlatformDataStructure::GetRef(RequiredRef& OutRef, const FWwiseSharedLanguageId& InLanguage, const FWwiseObjectInfo& InInfo) const
  324. {
  325. const auto LanguageId = InLanguage.GetLanguageId();
  326. // Get from GUID
  327. if (InInfo.WwiseGuid.IsValid())
  328. {
  329. FWwiseDatabaseLocalizableGuidKey LocalizableGuid(InInfo.WwiseGuid, LanguageId);
  330. const auto *AssetFromGuid = Guids.Find(LocalizableGuid);
  331. if (LIKELY(AssetFromGuid))
  332. {
  333. return AssetFromGuid->GetRef(OutRef);
  334. }
  335. if (LIKELY(LanguageId != 0))
  336. {
  337. LocalizableGuid = FWwiseDatabaseLocalizableGuidKey(InInfo.WwiseGuid, 0);
  338. AssetFromGuid = Guids.Find(LocalizableGuid);
  339. if (LIKELY(AssetFromGuid))
  340. {
  341. return AssetFromGuid->GetRef(OutRef);
  342. }
  343. }
  344. }
  345. // Get from Short ID
  346. if (InInfo.WwiseShortId != 0)
  347. {
  348. if (GetFromId(OutRef, InInfo.WwiseShortId, LanguageId, InInfo.HardCodedSoundBankShortId))
  349. {
  350. return true;
  351. }
  352. }
  353. // Get from Name. Try all found assets with such name until we get one
  354. if (!InInfo.WwiseName.IsNone())
  355. {
  356. TArray<const FWwiseAnyRef*> FoundAssets;
  357. Names.MultiFindPointer(FWwiseDatabaseLocalizableNameKey(InInfo.WwiseName, LanguageId), FoundAssets);
  358. if (LIKELY(LanguageId != 0))
  359. {
  360. Names.MultiFindPointer(FWwiseDatabaseLocalizableNameKey(InInfo.WwiseName, 0), FoundAssets);
  361. }
  362. for (const auto* Asset : FoundAssets)
  363. {
  364. if (Asset->GetRef(OutRef))
  365. {
  366. return true;
  367. }
  368. }
  369. }
  370. return false;
  371. }
  372. template <typename RequiredRef>
  373. inline bool FWwisePlatformDataStructure::GetRef(RequiredRef& OutRef, const FWwiseSharedLanguageId& InLanguage, const FWwiseGroupValueInfo& InInfo) const
  374. {
  375. const auto LanguageId = InLanguage.GetLanguageId();
  376. // Get from GUID
  377. if (InInfo.WwiseGuid.IsValid())
  378. {
  379. FWwiseDatabaseLocalizableGuidKey LocalizableGuid(InInfo.WwiseGuid, LanguageId);
  380. const auto *AssetFromGuid = Guids.Find(LocalizableGuid);
  381. if (LIKELY(AssetFromGuid))
  382. {
  383. return AssetFromGuid->GetRef(OutRef);
  384. }
  385. if (LIKELY(LanguageId != 0))
  386. {
  387. LocalizableGuid = FWwiseDatabaseLocalizableGuidKey(InInfo.WwiseGuid, 0);
  388. AssetFromGuid = Guids.Find(LocalizableGuid);
  389. if (LIKELY(AssetFromGuid))
  390. {
  391. return AssetFromGuid->GetRef(OutRef);
  392. }
  393. }
  394. }
  395. // Get from Short ID
  396. if (InInfo.WwiseShortId != 0)
  397. {
  398. if (GetFromId(OutRef, FWwiseDatabaseGroupValueKey(InInfo.GroupShortId, InInfo.WwiseShortId), InLanguage.GetLanguageId(), 0))
  399. {
  400. return true;
  401. }
  402. }
  403. // Get from Name. Try all found assets with such name until we get one
  404. if (!InInfo.WwiseName.IsNone())
  405. {
  406. FWwiseDatabaseLocalizableNameKey LocalizableName(InInfo.WwiseName, InLanguage.GetLanguageId());
  407. TArray<const FWwiseAnyRef *> FoundAssets;
  408. Names.MultiFindPointer(FWwiseDatabaseLocalizableNameKey(InInfo.WwiseName, LanguageId), FoundAssets);
  409. if (LIKELY(LanguageId != 0))
  410. {
  411. Names.MultiFindPointer(FWwiseDatabaseLocalizableNameKey(InInfo.WwiseName, 0), FoundAssets);
  412. }
  413. for (const auto *Asset : FoundAssets)
  414. {
  415. if (Asset->GetRef(OutRef))
  416. {
  417. return true;
  418. }
  419. }
  420. }
  421. return false;
  422. }
  423. template <typename RequiredRef>
  424. inline bool FWwisePlatformDataStructure::GetLocalizableRef(RequiredRef & OutRef, const TMap<FWwiseDatabaseLocalizableIdKey, RequiredRef> &InGlobalMap,
  425. uint32 InShortId, uint32 InLanguageId, uint32 InSoundBankId, const TCHAR *InDebugName)
  426. {
  427. const RequiredRef* Result = nullptr;
  428. if (LIKELY(InLanguageId != 0))
  429. {
  430. FWwiseDatabaseLocalizableIdKey LocalizableId(InShortId, InLanguageId);
  431. Result = InGlobalMap.Find(LocalizableId);
  432. if (!Result)
  433. {
  434. FWwiseDatabaseLocalizableIdKey NoLanguageId(InShortId, FWwiseDatabaseLocalizableIdKey::GENERIC_LANGUAGE);
  435. Result = InGlobalMap.Find(NoLanguageId);
  436. }
  437. }
  438. else
  439. {
  440. for (const auto& Elem : InGlobalMap)
  441. {
  442. if (Elem.Key.Id == InShortId)
  443. {
  444. Result = &Elem.Value;
  445. break;
  446. }
  447. }
  448. }
  449. if (UNLIKELY(!Result))
  450. {
  451. return false;
  452. }
  453. if (InSoundBankId != 0)
  454. {
  455. const FWwiseMetadataSoundBank* SoundBank = Result->GetSoundBank();
  456. if (UNLIKELY(!SoundBank))
  457. {
  458. UE_LOG(LogWwiseProjectDatabase, Error, TEXT("Could not retrieve SoundBank for %s %" PRIu32 " (Lang=%" PRIu32 "; SB=%" PRIu32 ")"), InDebugName, InShortId, InLanguageId, InSoundBankId);
  459. return false;
  460. }
  461. if (UNLIKELY(SoundBank->Id != InSoundBankId))
  462. {
  463. UE_LOG(LogWwiseProjectDatabase, Error, TEXT("Get incorrect SoundBank %" PRIu32 " for %s %" PRIu32 " (Lang = %" PRIu32 "; SB = %" PRIu32 ")"), SoundBank->Id, InDebugName, InShortId, InLanguageId, InSoundBankId);
  464. return false;
  465. }
  466. }
  467. OutRef = *Result;
  468. return true;
  469. }
  470. template <typename RequiredRef>
  471. void FWwisePlatformDataStructure::GetLocalizableRefs(TArray<RequiredRef>& OutRefs,
  472. const TMap<FWwiseDatabaseLocalizableIdKey, RequiredRef>& InGlobalMap, uint32 InShortId, uint32 InLanguageId,
  473. uint32 InSoundBankId, const TCHAR* InDebugName)
  474. {
  475. if (LIKELY(InLanguageId != 0 && InSoundBankId != 0))
  476. {
  477. const RequiredRef* Result = nullptr;
  478. FWwiseDatabaseLocalizableIdKey RefId(InShortId, InLanguageId, InSoundBankId);
  479. Result = InGlobalMap.Find(RefId);
  480. if (!Result)
  481. {
  482. FWwiseDatabaseLocalizableIdKey NoLanguageId(InShortId, FWwiseDatabaseLocalizableIdKey::GENERIC_LANGUAGE, InSoundBankId);
  483. Result = InGlobalMap.Find(NoLanguageId);
  484. }
  485. if (Result)
  486. {
  487. OutRefs.Add(*Result);
  488. }
  489. }
  490. else
  491. {
  492. for (const auto& Elem : InGlobalMap)
  493. {
  494. if (UNLIKELY(Elem.Key.Id == InShortId)
  495. && (InLanguageId == 0 || Elem.Key.LanguageId == InLanguageId || Elem.Key.LanguageId == 0)
  496. && (InSoundBankId == 0 || Elem.Key.SoundBankId == InSoundBankId))
  497. {
  498. OutRefs.Add(Elem.Value);
  499. }
  500. }
  501. }
  502. }
  503. template <>
  504. inline bool FWwisePlatformDataStructure::GetLocalizableRef<FWwiseRefPluginLib>(FWwiseRefPluginLib& OutRef, const TMap<FWwiseDatabaseLocalizableIdKey, FWwiseRefPluginLib>& InGlobalMap,
  505. uint32 InShortId, uint32 InLanguageId, uint32 InSoundBankId, const TCHAR* InDebugName)
  506. {
  507. const FWwiseRefPluginLib* Result = nullptr;
  508. if (LIKELY(InLanguageId != 0))
  509. {
  510. FWwiseDatabaseLocalizableIdKey LocalizableId(InShortId, InLanguageId);
  511. Result = InGlobalMap.Find(LocalizableId);
  512. if (!Result)
  513. {
  514. FWwiseDatabaseLocalizableIdKey NoLanguageId(InShortId, FWwiseDatabaseLocalizableIdKey::GENERIC_LANGUAGE);
  515. Result = InGlobalMap.Find(NoLanguageId);
  516. }
  517. }
  518. else
  519. {
  520. for (const auto& Elem : InGlobalMap)
  521. {
  522. if (Elem.Key.Id == InShortId)
  523. {
  524. Result = &Elem.Value;
  525. break;
  526. }
  527. }
  528. }
  529. if (UNLIKELY(!Result))
  530. {
  531. return false;
  532. }
  533. OutRef = *Result;
  534. return true;
  535. }
  536. template <typename RequiredRef>
  537. inline bool FWwisePlatformDataStructure::GetLocalizableGroupRef(RequiredRef& OutRef, const TMap<FWwiseDatabaseLocalizableGroupValueKey, RequiredRef>& InGlobalMap,
  538. FWwiseDatabaseGroupValueKey InGroupValue, uint32 InLanguageId, uint32 InSoundBankId, const TCHAR* InDebugName)
  539. {
  540. const RequiredRef* Result = nullptr;
  541. if (LIKELY(InLanguageId != 0))
  542. {
  543. FWwiseDatabaseLocalizableGroupValueKey LocalizableGroupValue(InGroupValue, InLanguageId);
  544. Result = InGlobalMap.Find(LocalizableGroupValue);
  545. if (!Result)
  546. {
  547. FWwiseDatabaseLocalizableGroupValueKey NoLanguageId(InGroupValue, FWwiseDatabaseLocalizableIdKey::GENERIC_LANGUAGE);
  548. Result = InGlobalMap.Find(NoLanguageId);
  549. }
  550. }
  551. else
  552. {
  553. for (const auto& Elem : InGlobalMap)
  554. {
  555. if (Elem.Key.GroupValue == InGroupValue)
  556. {
  557. Result = &Elem.Value;
  558. break;
  559. }
  560. }
  561. }
  562. if (UNLIKELY(!Result))
  563. {
  564. return false;
  565. }
  566. if (InSoundBankId != 0)
  567. {
  568. const FWwiseMetadataSoundBank* SoundBank = Result->GetSoundBank();
  569. if (UNLIKELY(!SoundBank))
  570. {
  571. UE_LOG(LogWwiseProjectDatabase, Error, TEXT("Could not retrieve SoundBank for %s %" PRIu32 " %" PRIu32 " (Lang = %" PRIu32 "; SB = %" PRIu32 ")"), InDebugName, InGroupValue.GroupId, InGroupValue.Id, InLanguageId, InSoundBankId);
  572. return false;
  573. }
  574. if (UNLIKELY(SoundBank->Id != InSoundBankId))
  575. {
  576. UE_LOG(LogWwiseProjectDatabase, Error, TEXT("Get incorrect SoundBank %" PRIu32 " for %s %" PRIu32 " %" PRIu32 " (Lang = %" PRIu32 "; SB = %" PRIu32 ")"), SoundBank->Id, InDebugName, InGroupValue.GroupId, InGroupValue.Id, InLanguageId, InSoundBankId);
  577. return false;
  578. }
  579. }
  580. OutRef = *Result;
  581. return true;
  582. }
  583. template <typename RefType>
  584. inline bool FWwisePlatformDataStructure::GetFromId(TSet<RefType>& OutRef, uint32 InId, uint32 InLanguageId, uint32 InSoundBankId) const
  585. {
  586. TArray<RefType> Refs;
  587. GetLocalizableRefs(Refs, RefType::FGlobalIdsMap::GlobalIdsMap, InId, InLanguageId, InSoundBankId, RefType::NAME);
  588. if (LIKELY(Refs.Num() > 0))
  589. {
  590. OutRef.Append(Refs);
  591. return true;
  592. }
  593. return false;
  594. }
  595. template<typename RequiredRef>
  596. inline void FWwisePlatformDataStructure::AddBasicRefToMap(TMap<FWwiseDatabaseLocalizableIdKey, RequiredRef>& OutMap, const RequiredRef& InRef, const FWwiseMetadataBasicReference& InObject)
  597. {
  598. AddRefToMap(OutMap, InRef, InObject.Id, &InObject.Name, &InObject.ObjectPath, &InObject.GUID);
  599. }
  600. template<typename RequiredRef>
  601. inline void FWwisePlatformDataStructure::AddEventRefToMap(TMap<FWwiseDatabaseLocalizableIdKey, RequiredRef>& OutMap, const RequiredRef& InRef, const FWwiseMetadataBasicReference& InObject)
  602. {
  603. AddRefToMap(OutMap, InRef, InObject.Id, &InObject.Name, &InObject.ObjectPath, &InObject.GUID);
  604. }
  605. template<typename RequiredRef>
  606. void FWwisePlatformDataStructure::AddRefToMap(TMap<FWwiseDatabaseLocalizableIdKey, RequiredRef>& OutMap, const RequiredRef& InRef, const uint32& InId, const FName* InName, const FName* InObjectPath, const FGuid* InGuid)
  607. {
  608. const auto AnyRef = FWwiseAnyRef::Create(InRef);
  609. if (InName && !InName->IsNone())
  610. {
  611. Names.Add(FWwiseDatabaseLocalizableNameKey(*InName, InRef.LanguageId), AnyRef);
  612. }
  613. if (InObjectPath && !InObjectPath->IsNone())
  614. {
  615. Names.Add(FWwiseDatabaseLocalizableNameKey(*InObjectPath, InRef.LanguageId), AnyRef);
  616. }
  617. if (InGuid && InGuid->IsValid())
  618. {
  619. Guids.Add(FWwiseDatabaseLocalizableGuidKey(*InGuid, InRef.LanguageId), AnyRef);
  620. }
  621. OutMap.Add(FWwiseDatabaseLocalizableIdKey(InId, InRef.LanguageId), InRef);
  622. }
  623. template<>
  624. inline void FWwisePlatformDataStructure::AddRefToMap<FWwiseRefPluginLib>(TMap<FWwiseDatabaseLocalizableIdKey, FWwiseRefPluginLib>& OutMap, const FWwiseRefPluginLib& InRef, const uint32& InId, const FName* InName, const FName* InObjectPath, const FGuid* InGuid)
  625. {
  626. const auto AnyRef = FWwiseAnyRef::Create(InRef);
  627. if (InName && !InName->IsNone())
  628. {
  629. Names.Add(FWwiseDatabaseLocalizableNameKey(*InName, 0), AnyRef);
  630. }
  631. if (InObjectPath && !InObjectPath->IsNone())
  632. {
  633. Names.Add(FWwiseDatabaseLocalizableNameKey(*InObjectPath, 0), AnyRef);
  634. }
  635. if (InGuid && InGuid->IsValid())
  636. {
  637. Guids.Add(FWwiseDatabaseLocalizableGuidKey(*InGuid, 0), AnyRef);
  638. }
  639. OutMap.Add(FWwiseDatabaseLocalizableIdKey(InId, 0), InRef);
  640. }