WwiseResourceLoader.cpp 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162
  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. #include "Wwise/WwiseResourceLoader.h"
  16. #include "Wwise/CookedData/WwiseInitBankCookedData.h"
  17. #include "Wwise/CookedData/WwiseLanguageCookedData.h"
  18. #include "Wwise/CookedData/WwiseLocalizedAuxBusCookedData.h"
  19. #include "Wwise/CookedData/WwiseLocalizedEventCookedData.h"
  20. #include "Wwise/CookedData/WwiseLocalizedShareSetCookedData.h"
  21. #include "Wwise/CookedData/WwiseLocalizedSoundBankCookedData.h"
  22. #include "Async/Async.h"
  23. #if WITH_EDITORONLY_DATA && PLATFORM_WINDOWS
  24. static const auto DefaultPlatform = MakeShared<FWwisePlatformId>(FGuid(0x6E0CB257, 0xC6C84C5C, 0x83662740, 0xDFC441EC), TEXT("Windows"), TEXT("Windows"));
  25. #elif WITH_EDITORONLY_DATA && PLATFORM_MAC
  26. static const auto DefaultPlatform = MakeShared<FWwisePlatformId>(FGuid(0x02DC7702, 0x6E7B4AE4, 0xBAE464D2, 0xB1057150), TEXT("Mac"), TEXT("Mac"));
  27. #elif WITH_EDITORONLY_DATA && PLATFORM_LINUX
  28. static const auto DefaultPlatform = MakeShared<FWwisePlatformId>(FGuid(0xBD0BDF13, 0x3125454F, 0x8BFD3195, 0x37169F81), TEXT("Linux"), TEXT("Linux"));
  29. #else
  30. static const auto DefaultPlatform = MakeShared<FWwisePlatformId>(FGuid(0x6E0CB257, 0xC6C84C5C, 0x83662740, 0xDFC441EC), TEXT("Windows"));
  31. #endif
  32. static const FWwiseLanguageCookedData DefaultLanguage(684519430, TEXT("English(US)"), EWwiseLanguageRequirement::IsDefault);
  33. bool FWwiseResourceLoader::IsEnabled() const
  34. {
  35. if (UNLIKELY(!ResourceLoaderImpl))
  36. {
  37. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  38. return false;
  39. }
  40. return ResourceLoaderImpl->IsEnabled();
  41. }
  42. void FWwiseResourceLoader::Enable()
  43. {
  44. UE_LOG(LogWwiseResourceLoader, Verbose, TEXT("Enabling ResourceLoaderImpl..."));
  45. ResourceLoaderImpl->Enable();
  46. }
  47. void FWwiseResourceLoader::Disable()
  48. {
  49. UE_LOG(LogWwiseResourceLoader, Verbose, TEXT("Disabling ResourceLoaderImpl..."));
  50. ResourceLoaderImpl->Disable();
  51. }
  52. FWwiseResourceLoader::FWwiseResourceLoader() :
  53. ResourceLoaderImpl(FWwiseResourceLoaderImpl::Instantiate())
  54. {
  55. ResourceLoaderImpl->CurrentLanguage = SystemLanguage();
  56. ResourceLoaderImpl->CurrentPlatform = SystemPlatform();
  57. }
  58. void FWwiseResourceLoader::SetLanguage(FWwiseLanguageCookedData InLanguage, EWwiseReloadLanguage InReloadLanguage)
  59. {
  60. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("SetLanguage"));
  61. SetLanguageAsync(InLanguage, InReloadLanguage).Wait();
  62. }
  63. void FWwiseResourceLoader::SetPlatform(const FWwiseSharedPlatformId& InPlatform)
  64. {
  65. if (UNLIKELY(!ResourceLoaderImpl))
  66. {
  67. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  68. return;
  69. }
  70. ResourceLoaderImpl->SetPlatform(InPlatform);
  71. }
  72. FWwiseLanguageCookedData FWwiseResourceLoader::GetCurrentLanguage() const
  73. {
  74. if (UNLIKELY(!ResourceLoaderImpl))
  75. {
  76. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  77. return {};
  78. }
  79. return ResourceLoaderImpl->CurrentLanguage;
  80. }
  81. FWwiseSharedPlatformId FWwiseResourceLoader::GetCurrentPlatform() const
  82. {
  83. if (UNLIKELY(!ResourceLoaderImpl))
  84. {
  85. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  86. return {};
  87. }
  88. return ResourceLoaderImpl->CurrentPlatform;
  89. }
  90. FString FWwiseResourceLoader::GetUnrealPath(const FString& InPath) const
  91. {
  92. if (UNLIKELY(!ResourceLoaderImpl))
  93. {
  94. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  95. return {};
  96. }
  97. return ResourceLoaderImpl->GetUnrealPath(InPath);
  98. }
  99. FName FWwiseResourceLoader::GetUnrealExternalSourcePath() const
  100. {
  101. if (UNLIKELY(!ResourceLoaderImpl))
  102. {
  103. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  104. return {};
  105. }
  106. return ResourceLoaderImpl->GetUnrealExternalSourcePath();
  107. }
  108. FString FWwiseResourceLoader::GetUnrealStagePath(const FString& InPath) const
  109. {
  110. if (UNLIKELY(!ResourceLoaderImpl))
  111. {
  112. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  113. return {};
  114. }
  115. return ResourceLoaderImpl->GetUnrealStagePath(InPath);
  116. }
  117. #if WITH_EDITORONLY_DATA
  118. FString FWwiseResourceLoader::GetUnrealGeneratedSoundBanksPath(const FString& InPath) const
  119. {
  120. if (UNLIKELY(!ResourceLoaderImpl))
  121. {
  122. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  123. return {};
  124. }
  125. return ResourceLoaderImpl->GetUnrealGeneratedSoundBanksPath(InPath);
  126. }
  127. void FWwiseResourceLoader::SetUnrealGeneratedSoundBanksPath(const FDirectoryPath& DirectoryPath)
  128. {
  129. if (UNLIKELY(!ResourceLoaderImpl))
  130. {
  131. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  132. return;
  133. }
  134. ResourceLoaderImpl->GeneratedSoundBanksPath = DirectoryPath;
  135. }
  136. const FDirectoryPath& FWwiseResourceLoader::GetUnrealGeneratedSoundBanksPath()
  137. {
  138. if (UNLIKELY(!ResourceLoaderImpl))
  139. {
  140. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  141. static const FDirectoryPath Empty;
  142. return Empty;
  143. }
  144. return ResourceLoaderImpl->GeneratedSoundBanksPath;
  145. }
  146. #endif
  147. //
  148. // User-facing loading and unloading operations
  149. //
  150. FWwiseLoadedAuxBus FWwiseResourceLoader::LoadAuxBus(const FWwiseLocalizedAuxBusCookedData& InAuxBusCookedData,
  151. const FWwiseLanguageCookedData* InLanguageOverride)
  152. {
  153. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("LoadAuxBus"));
  154. return LoadAuxBusAsync(InAuxBusCookedData, InLanguageOverride).Get();
  155. }
  156. void FWwiseResourceLoader::UnloadAuxBus(FWwiseLoadedAuxBus&& InAuxBus)
  157. {
  158. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("UnloadAuxBus"));
  159. FWwiseLoadedAuxBusPromise Promise;
  160. Promise.EmplaceValue(MoveTemp(InAuxBus));
  161. UnloadAuxBusAsync(Promise.GetFuture()).Wait();
  162. }
  163. FWwiseLoadedEvent FWwiseResourceLoader::LoadEvent(const FWwiseLocalizedEventCookedData& InEventCookedData,
  164. const FWwiseLanguageCookedData* InLanguageOverride)
  165. {
  166. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("LoadEvent"));
  167. return LoadEventAsync(InEventCookedData, InLanguageOverride).Get();
  168. }
  169. void FWwiseResourceLoader::UnloadEvent(FWwiseLoadedEvent&& InEvent)
  170. {
  171. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("UnloadEvent"));
  172. FWwiseLoadedEventPromise Promise;
  173. Promise.EmplaceValue(MoveTemp(InEvent));
  174. UnloadEventAsync(Promise.GetFuture()).Wait();
  175. }
  176. FWwiseLoadedExternalSource FWwiseResourceLoader::LoadExternalSource(
  177. const FWwiseExternalSourceCookedData& InExternalSourceCookedData)
  178. {
  179. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("LoadExternalSource"));
  180. return LoadExternalSourceAsync(InExternalSourceCookedData).Get();
  181. }
  182. void FWwiseResourceLoader::UnloadExternalSource(FWwiseLoadedExternalSource&& InExternalSource)
  183. {
  184. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("UnloadExternalSource"));
  185. FWwiseLoadedExternalSourcePromise Promise;
  186. Promise.EmplaceValue(MoveTemp(InExternalSource));
  187. UnloadExternalSourceAsync(Promise.GetFuture()).Wait();
  188. }
  189. FWwiseLoadedGroupValue FWwiseResourceLoader::LoadGroupValue(const FWwiseGroupValueCookedData& InGroupValueCookedData)
  190. {
  191. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("LoadGroupValue"));
  192. return LoadGroupValueAsync(InGroupValueCookedData).Get();
  193. }
  194. void FWwiseResourceLoader::UnloadGroupValue(FWwiseLoadedGroupValue&& InGroupValue)
  195. {
  196. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("UnloadGroupValue"));
  197. FWwiseLoadedGroupValuePromise Promise;
  198. Promise.EmplaceValue(MoveTemp(InGroupValue));
  199. UnloadGroupValueAsync(Promise.GetFuture()).Wait();
  200. }
  201. FWwiseLoadedInitBank FWwiseResourceLoader::LoadInitBank(const FWwiseInitBankCookedData& InInitBankCookedData)
  202. {
  203. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("LoadInitBank"));
  204. return LoadInitBankAsync(InInitBankCookedData).Get();
  205. }
  206. void FWwiseResourceLoader::UnloadInitBank(FWwiseLoadedInitBank&& InInitBank)
  207. {
  208. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("UnloadInitBank"));
  209. FWwiseLoadedInitBankPromise Promise;
  210. Promise.EmplaceValue(MoveTemp(InInitBank));
  211. UnloadInitBankAsync(Promise.GetFuture()).Wait();
  212. }
  213. FWwiseLoadedMedia FWwiseResourceLoader::LoadMedia(const FWwiseMediaCookedData& InMediaCookedData)
  214. {
  215. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("LoadMedia"));
  216. return LoadMediaAsync(InMediaCookedData).Get();
  217. }
  218. void FWwiseResourceLoader::UnloadMedia(FWwiseLoadedMedia&& InMedia)
  219. {
  220. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("UnloadMedia"));
  221. FWwiseLoadedMediaPromise Promise;
  222. Promise.EmplaceValue(MoveTemp(InMedia));
  223. UnloadMediaAsync(Promise.GetFuture()).Wait();
  224. }
  225. FWwiseLoadedShareSet FWwiseResourceLoader::LoadShareSet(const FWwiseLocalizedShareSetCookedData& InShareSetCookedData,
  226. const FWwiseLanguageCookedData* InLanguageOverride)
  227. {
  228. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("LoadShareSet"));
  229. return LoadShareSetAsync(InShareSetCookedData, InLanguageOverride).Get();
  230. }
  231. void FWwiseResourceLoader::UnloadShareSet(FWwiseLoadedShareSet&& InShareSet)
  232. {
  233. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("UnloadShareSet"));
  234. FWwiseLoadedShareSetPromise Promise;
  235. Promise.EmplaceValue(MoveTemp(InShareSet));
  236. UnloadShareSetAsync(Promise.GetFuture()).Wait();
  237. }
  238. FWwiseLoadedSoundBank FWwiseResourceLoader::LoadSoundBank(
  239. const FWwiseLocalizedSoundBankCookedData& InSoundBankCookedData, const FWwiseLanguageCookedData* InLanguageOverride)
  240. {
  241. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("LoadSoundBank"));
  242. return LoadSoundBankAsync(InSoundBankCookedData, InLanguageOverride).Get();
  243. }
  244. void FWwiseResourceLoader::UnloadSoundBank(FWwiseLoadedSoundBank&& InSoundBank)
  245. {
  246. SCOPED_WWISERESOURCELOADER_EVENT_4(TEXT("UnloadSoundBank"));
  247. FWwiseLoadedSoundBankPromise Promise;
  248. Promise.EmplaceValue(MoveTemp(InSoundBank));
  249. UnloadSoundBankAsync(Promise.GetFuture()).Wait();
  250. }
  251. FWwiseResourceLoader::FWwiseSetLanguageFuture FWwiseResourceLoader::SetLanguageAsync(
  252. FWwiseLanguageCookedData InLanguage, EWwiseReloadLanguage InReloadLanguage)
  253. {
  254. FWwiseSetLanguagePromise Promise;
  255. auto Future = Promise.GetFuture();
  256. if (UNLIKELY(!ResourceLoaderImpl))
  257. {
  258. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  259. Promise.EmplaceValue();
  260. return Future;
  261. }
  262. ResourceLoaderImpl->SetLanguageAsync(MoveTemp(Promise), InLanguage, InReloadLanguage);
  263. return Future;
  264. }
  265. FWwiseLoadedAuxBusFuture FWwiseResourceLoader::LoadAuxBusAsync(const FWwiseLocalizedAuxBusCookedData& InAuxBusCookedData,
  266. const FWwiseLanguageCookedData* InLanguageOverride)
  267. {
  268. FWwiseLoadedAuxBusPromise Promise;
  269. auto Future = Promise.GetFuture();
  270. if (UNLIKELY(!ResourceLoaderImpl))
  271. {
  272. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  273. Promise.EmplaceValue(nullptr);
  274. }
  275. else if (!IsEnabled())
  276. {
  277. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  278. Promise.EmplaceValue(nullptr);
  279. }
  280. else
  281. {
  282. auto* AuxBusNode = ResourceLoaderImpl->CreateAuxBusNode(InAuxBusCookedData, InLanguageOverride);
  283. if (UNLIKELY(!AuxBusNode))
  284. {
  285. Promise.EmplaceValue(nullptr);
  286. }
  287. else
  288. {
  289. ResourceLoaderImpl->LoadAuxBusAsync(MoveTemp(Promise), MoveTemp(AuxBusNode));
  290. }
  291. }
  292. return Future;
  293. }
  294. FWwiseResourceUnloadFuture FWwiseResourceLoader::UnloadAuxBusAsync(FWwiseLoadedAuxBusFuture&& InAuxBus)
  295. {
  296. FWwiseResourceUnloadPromise Promise;
  297. auto Future = Promise.GetFuture();
  298. if (UNLIKELY(!ResourceLoaderImpl))
  299. {
  300. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  301. Promise.EmplaceValue();
  302. }
  303. else if (!IsEnabled())
  304. {
  305. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  306. Promise.EmplaceValue();
  307. }
  308. else if (UNLIKELY(InAuxBus.IsReady() && InAuxBus.Get() == nullptr))
  309. {
  310. Promise.EmplaceValue();
  311. }
  312. else if (LIKELY(InAuxBus.IsReady()))
  313. {
  314. auto* AuxBus = InAuxBus.Get();
  315. ResourceLoaderImpl->UnloadAuxBusAsync(MoveTemp(Promise), MoveTemp(AuxBus));
  316. }
  317. else
  318. {
  319. AsyncTask(ResourceLoaderImpl->TaskThread, [this, InAuxBus = MoveTemp(InAuxBus), Promise = MoveTemp(Promise)]() mutable
  320. {
  321. {
  322. int WaitCount = 0;
  323. while (!InAuxBus.WaitFor(FTimespan::FromSeconds(1.0)))
  324. {
  325. if (IsEngineExitRequested())
  326. {
  327. UE_LOG(LogWwiseResourceLoader, Verbose, TEXT("Giving up on waiting for Aux Bus load since we are exiting. Gave up on count [%d]"), WaitCount);
  328. Promise.EmplaceValue();
  329. return;
  330. }
  331. else
  332. {
  333. UE_CLOG(WaitCount != 10, LogWwiseResourceLoader, Verbose, TEXT("Waiting for an Aux Bus to be fully loaded so we can unload it [%d]"), WaitCount);
  334. UE_CLOG(WaitCount == 10, LogWwiseResourceLoader, Warning, TEXT("Waited 10 seconds for an Aux Bus to be loaded so we can unload it."));
  335. ++WaitCount;
  336. }
  337. }
  338. }
  339. auto* AuxBus = InAuxBus.Get();
  340. if (UNLIKELY(!ResourceLoaderImpl))
  341. {
  342. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  343. Promise.EmplaceValue();
  344. }
  345. else if (!IsEnabled())
  346. {
  347. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  348. Promise.EmplaceValue();
  349. }
  350. else if (UNLIKELY(!AuxBus))
  351. {
  352. Promise.EmplaceValue();
  353. }
  354. else
  355. {
  356. ResourceLoaderImpl->UnloadAuxBusAsync(MoveTemp(Promise), MoveTemp(AuxBus));
  357. }
  358. });
  359. }
  360. return Future;
  361. }
  362. FWwiseLoadedEventFuture FWwiseResourceLoader::LoadEventAsync(const FWwiseLocalizedEventCookedData& InEventCookedData,
  363. const FWwiseLanguageCookedData* InLanguageOverride)
  364. {
  365. FWwiseLoadedEventPromise Promise;
  366. auto Future = Promise.GetFuture();
  367. if (UNLIKELY(!ResourceLoaderImpl))
  368. {
  369. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  370. Promise.EmplaceValue(nullptr);
  371. }
  372. else if (!IsEnabled())
  373. {
  374. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  375. Promise.EmplaceValue(nullptr);
  376. }
  377. else
  378. {
  379. auto* EventNode = ResourceLoaderImpl->CreateEventNode(InEventCookedData, InLanguageOverride);
  380. if (UNLIKELY(!EventNode))
  381. {
  382. Promise.EmplaceValue(nullptr);
  383. }
  384. else
  385. {
  386. ResourceLoaderImpl->LoadEventAsync(MoveTemp(Promise), MoveTemp(EventNode));
  387. }
  388. }
  389. return Future;
  390. }
  391. FWwiseResourceUnloadFuture FWwiseResourceLoader::UnloadEventAsync(FWwiseLoadedEventFuture&& InEvent)
  392. {
  393. FWwiseResourceUnloadPromise Promise;
  394. auto Future = Promise.GetFuture();
  395. if (UNLIKELY(!ResourceLoaderImpl))
  396. {
  397. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  398. Promise.EmplaceValue();
  399. }
  400. else if (!IsEnabled())
  401. {
  402. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  403. Promise.EmplaceValue();
  404. }
  405. else if (UNLIKELY(InEvent.IsReady() && InEvent.Get() == nullptr))
  406. {
  407. Promise.EmplaceValue();
  408. }
  409. else if (LIKELY(InEvent.IsReady()))
  410. {
  411. auto* Event = InEvent.Get();
  412. ResourceLoaderImpl->UnloadEventAsync(MoveTemp(Promise), MoveTemp(Event));
  413. }
  414. else
  415. {
  416. AsyncTask(ResourceLoaderImpl->TaskThread, [this, InEvent = MoveTemp(InEvent), Promise = MoveTemp(Promise)]() mutable
  417. {
  418. {
  419. int WaitCount = 0;
  420. while (!InEvent.WaitFor(FTimespan::FromSeconds(1.0)))
  421. {
  422. if (IsEngineExitRequested())
  423. {
  424. UE_LOG(LogWwiseResourceLoader, Verbose, TEXT("Giving up on waiting for Event load since we are exiting. Gave up on count [%d]"), WaitCount);
  425. Promise.EmplaceValue();
  426. return;
  427. }
  428. else
  429. {
  430. UE_CLOG(WaitCount != 10, LogWwiseResourceLoader, Verbose, TEXT("Waiting for a Event to be fully loaded so we can unload it [%d]"), WaitCount);
  431. UE_CLOG(WaitCount == 10, LogWwiseResourceLoader, Warning, TEXT("Waited 10 seconds for a Event to be loaded so we can unload it."));
  432. ++WaitCount;
  433. }
  434. }
  435. }
  436. auto* Event = InEvent.Get();
  437. if (UNLIKELY(!ResourceLoaderImpl))
  438. {
  439. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  440. Promise.EmplaceValue();
  441. }
  442. else if (!IsEnabled())
  443. {
  444. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  445. Promise.EmplaceValue();
  446. }
  447. else if (UNLIKELY(!Event))
  448. {
  449. Promise.EmplaceValue();
  450. }
  451. else
  452. {
  453. ResourceLoaderImpl->UnloadEventAsync(MoveTemp(Promise), MoveTemp(Event));
  454. }
  455. });
  456. }
  457. return Future;
  458. }
  459. FWwiseLoadedExternalSourceFuture FWwiseResourceLoader::LoadExternalSourceAsync(
  460. const FWwiseExternalSourceCookedData& InExternalSourceCookedData)
  461. {
  462. FWwiseLoadedExternalSourcePromise Promise;
  463. auto Future = Promise.GetFuture();
  464. if (UNLIKELY(!ResourceLoaderImpl))
  465. {
  466. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  467. Promise.EmplaceValue(nullptr);
  468. }
  469. else if (!IsEnabled())
  470. {
  471. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  472. Promise.EmplaceValue(nullptr);
  473. }
  474. else
  475. {
  476. auto* ExternalSourceNode = ResourceLoaderImpl->CreateExternalSourceNode(InExternalSourceCookedData);
  477. if (UNLIKELY(!ExternalSourceNode))
  478. {
  479. Promise.EmplaceValue(nullptr);
  480. }
  481. else
  482. {
  483. ResourceLoaderImpl->LoadExternalSourceAsync(MoveTemp(Promise), MoveTemp(ExternalSourceNode));
  484. }
  485. }
  486. return Future;
  487. }
  488. FWwiseResourceUnloadFuture FWwiseResourceLoader::UnloadExternalSourceAsync(FWwiseLoadedExternalSourceFuture&& InExternalSource)
  489. {
  490. FWwiseResourceUnloadPromise Promise;
  491. auto Future = Promise.GetFuture();
  492. if (UNLIKELY(!ResourceLoaderImpl))
  493. {
  494. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  495. Promise.EmplaceValue();
  496. }
  497. else if (!IsEnabled())
  498. {
  499. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  500. Promise.EmplaceValue();
  501. }
  502. else if (UNLIKELY(InExternalSource.IsReady() && InExternalSource.Get() == nullptr))
  503. {
  504. Promise.EmplaceValue();
  505. }
  506. else if (LIKELY(InExternalSource.IsReady()))
  507. {
  508. auto* ExternalSource = InExternalSource.Get();
  509. ResourceLoaderImpl->UnloadExternalSourceAsync(MoveTemp(Promise), MoveTemp(ExternalSource));
  510. }
  511. else
  512. {
  513. AsyncTask(ResourceLoaderImpl->TaskThread, [this, InExternalSource = MoveTemp(InExternalSource), Promise = MoveTemp(Promise)]() mutable
  514. {
  515. {
  516. int WaitCount = 0;
  517. while (!InExternalSource.WaitFor(FTimespan::FromSeconds(1.0)))
  518. {
  519. if (IsEngineExitRequested())
  520. {
  521. UE_LOG(LogWwiseResourceLoader, Verbose, TEXT("Giving up on waiting for External Source load since we are exiting. Gave up on count [%d]"), WaitCount);
  522. Promise.EmplaceValue();
  523. return;
  524. }
  525. else
  526. {
  527. UE_CLOG(WaitCount != 10, LogWwiseResourceLoader, Verbose, TEXT("Waiting for a External Source to be fully loaded so we can unload it [%d]"), WaitCount);
  528. UE_CLOG(WaitCount == 10, LogWwiseResourceLoader, Warning, TEXT("Waited 10 seconds for a External Source to be loaded so we can unload it."));
  529. ++WaitCount;
  530. }
  531. }
  532. }
  533. auto* ExternalSource = InExternalSource.Get();
  534. if (UNLIKELY(!ResourceLoaderImpl))
  535. {
  536. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  537. Promise.EmplaceValue();
  538. }
  539. else if (!IsEnabled())
  540. {
  541. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  542. Promise.EmplaceValue();
  543. }
  544. else if (UNLIKELY(!ExternalSource))
  545. {
  546. Promise.EmplaceValue();
  547. }
  548. else
  549. {
  550. ResourceLoaderImpl->UnloadExternalSourceAsync(MoveTemp(Promise), MoveTemp(ExternalSource));
  551. }
  552. });
  553. }
  554. return Future;
  555. }
  556. FWwiseLoadedGroupValueFuture FWwiseResourceLoader::LoadGroupValueAsync(const FWwiseGroupValueCookedData& InGroupValueCookedData)
  557. {
  558. FWwiseLoadedGroupValuePromise Promise;
  559. auto Future = Promise.GetFuture();
  560. if (UNLIKELY(!ResourceLoaderImpl))
  561. {
  562. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  563. Promise.EmplaceValue(nullptr);
  564. }
  565. else if (!IsEnabled())
  566. {
  567. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  568. Promise.EmplaceValue(nullptr);
  569. }
  570. else
  571. {
  572. auto* GroupValueNode = ResourceLoaderImpl->CreateGroupValueNode(InGroupValueCookedData);
  573. if (UNLIKELY(!GroupValueNode))
  574. {
  575. Promise.EmplaceValue(nullptr);
  576. }
  577. else
  578. {
  579. ResourceLoaderImpl->LoadGroupValueAsync(MoveTemp(Promise), MoveTemp(GroupValueNode));
  580. }
  581. }
  582. return Future;
  583. }
  584. FWwiseResourceUnloadFuture FWwiseResourceLoader::UnloadGroupValueAsync(FWwiseLoadedGroupValueFuture&& InGroupValue)
  585. {
  586. FWwiseResourceUnloadPromise Promise;
  587. auto Future = Promise.GetFuture();
  588. if (UNLIKELY(!ResourceLoaderImpl))
  589. {
  590. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  591. Promise.EmplaceValue();
  592. }
  593. else if (!IsEnabled())
  594. {
  595. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  596. Promise.EmplaceValue();
  597. }
  598. else if (UNLIKELY(InGroupValue.IsReady() && InGroupValue.Get() == nullptr))
  599. {
  600. Promise.EmplaceValue();
  601. }
  602. else if (LIKELY(InGroupValue.IsReady()))
  603. {
  604. auto* GroupValue = InGroupValue.Get();
  605. ResourceLoaderImpl->UnloadGroupValueAsync(MoveTemp(Promise), MoveTemp(GroupValue));
  606. }
  607. else
  608. {
  609. AsyncTask(ResourceLoaderImpl->TaskThread, [this, InGroupValue = MoveTemp(InGroupValue), Promise = MoveTemp(Promise)]() mutable
  610. {
  611. {
  612. int WaitCount = 0;
  613. while (!InGroupValue.WaitFor(FTimespan::FromSeconds(1.0)))
  614. {
  615. if (IsEngineExitRequested())
  616. {
  617. UE_LOG(LogWwiseResourceLoader, Verbose, TEXT("Giving up on waiting for Group Value load since we are exiting. Gave up on count [%d]"), WaitCount);
  618. Promise.EmplaceValue();
  619. return;
  620. }
  621. else
  622. {
  623. UE_CLOG(WaitCount != 10, LogWwiseResourceLoader, Verbose, TEXT("Waiting for a Group Value to be fully loaded so we can unload it [%d]"), WaitCount);
  624. UE_CLOG(WaitCount == 10, LogWwiseResourceLoader, Warning, TEXT("Waited 10 seconds for a Group Value to be loaded so we can unload it."));
  625. ++WaitCount;
  626. }
  627. }
  628. }
  629. auto* GroupValue = InGroupValue.Get();
  630. if (UNLIKELY(!ResourceLoaderImpl))
  631. {
  632. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  633. Promise.EmplaceValue();
  634. }
  635. else if (!IsEnabled())
  636. {
  637. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  638. Promise.EmplaceValue();
  639. }
  640. else if (UNLIKELY(!GroupValue))
  641. {
  642. Promise.EmplaceValue();
  643. }
  644. else
  645. {
  646. ResourceLoaderImpl->UnloadGroupValueAsync(MoveTemp(Promise), MoveTemp(GroupValue));
  647. }
  648. });
  649. }
  650. return Future;
  651. }
  652. FWwiseLoadedInitBankFuture FWwiseResourceLoader::LoadInitBankAsync(const FWwiseInitBankCookedData& InInitBankCookedData)
  653. {
  654. FWwiseLoadedInitBankPromise Promise;
  655. auto Future = Promise.GetFuture();
  656. if (UNLIKELY(!ResourceLoaderImpl))
  657. {
  658. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  659. Promise.EmplaceValue(nullptr);
  660. }
  661. else if (!IsEnabled())
  662. {
  663. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  664. Promise.EmplaceValue(nullptr);
  665. }
  666. else
  667. {
  668. auto* InitBankNode = ResourceLoaderImpl->CreateInitBankNode(InInitBankCookedData);
  669. if (UNLIKELY(!InitBankNode))
  670. {
  671. Promise.EmplaceValue(nullptr);
  672. }
  673. else
  674. {
  675. ResourceLoaderImpl->LoadInitBankAsync(MoveTemp(Promise), MoveTemp(InitBankNode));
  676. }
  677. }
  678. return Future;
  679. }
  680. FWwiseResourceUnloadFuture FWwiseResourceLoader::UnloadInitBankAsync(FWwiseLoadedInitBankFuture&& InInitBank)
  681. {
  682. FWwiseResourceUnloadPromise Promise;
  683. auto Future = Promise.GetFuture();
  684. if (UNLIKELY(!ResourceLoaderImpl))
  685. {
  686. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  687. Promise.EmplaceValue();
  688. }
  689. else if (!IsEnabled())
  690. {
  691. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  692. Promise.EmplaceValue();
  693. }
  694. else if (UNLIKELY(InInitBank.IsReady() && InInitBank.Get() == nullptr))
  695. {
  696. Promise.EmplaceValue();
  697. }
  698. else if (LIKELY(InInitBank.IsReady()))
  699. {
  700. auto* InitBank = InInitBank.Get();
  701. ResourceLoaderImpl->UnloadInitBankAsync(MoveTemp(Promise), MoveTemp(InitBank));
  702. }
  703. else
  704. {
  705. AsyncTask(ResourceLoaderImpl->TaskThread, [this, InInitBank = MoveTemp(InInitBank), Promise = MoveTemp(Promise)]() mutable
  706. {
  707. {
  708. int WaitCount = 0;
  709. while (!InInitBank.WaitFor(FTimespan::FromSeconds(1.0)))
  710. {
  711. if (IsEngineExitRequested())
  712. {
  713. UE_LOG(LogWwiseResourceLoader, Verbose, TEXT("Giving up on waiting for Init Bank load since we are exiting. Gave up on count [%d]"), WaitCount);
  714. Promise.EmplaceValue();
  715. return;
  716. }
  717. else
  718. {
  719. UE_CLOG(WaitCount != 10, LogWwiseResourceLoader, Verbose, TEXT("Waiting for a Init Bank to be fully loaded so we can unload it [%d]"), WaitCount);
  720. UE_CLOG(WaitCount == 10, LogWwiseResourceLoader, Warning, TEXT("Waited 10 seconds for a Init Bank to be loaded so we can unload it."));
  721. ++WaitCount;
  722. }
  723. }
  724. }
  725. auto* InitBank = InInitBank.Get();
  726. if (UNLIKELY(!ResourceLoaderImpl))
  727. {
  728. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  729. Promise.EmplaceValue();
  730. }
  731. else if (!IsEnabled())
  732. {
  733. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  734. Promise.EmplaceValue();
  735. }
  736. else if (UNLIKELY(!InitBank))
  737. {
  738. Promise.EmplaceValue();
  739. }
  740. else
  741. {
  742. ResourceLoaderImpl->UnloadInitBankAsync(MoveTemp(Promise), MoveTemp(InitBank));
  743. }
  744. });
  745. }
  746. return Future;
  747. }
  748. FWwiseLoadedMediaFuture FWwiseResourceLoader::LoadMediaAsync(const FWwiseMediaCookedData& InMediaCookedData)
  749. {
  750. FWwiseLoadedMediaPromise Promise;
  751. auto Future = Promise.GetFuture();
  752. if (UNLIKELY(!ResourceLoaderImpl))
  753. {
  754. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  755. Promise.EmplaceValue(nullptr);
  756. }
  757. else if (!IsEnabled())
  758. {
  759. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  760. Promise.EmplaceValue(nullptr);
  761. }
  762. else
  763. {
  764. auto* MediaNode = ResourceLoaderImpl->CreateMediaNode(InMediaCookedData);
  765. if (UNLIKELY(!MediaNode))
  766. {
  767. Promise.EmplaceValue(nullptr);
  768. }
  769. else
  770. {
  771. ResourceLoaderImpl->LoadMediaAsync(MoveTemp(Promise), MoveTemp(MediaNode));
  772. }
  773. }
  774. return Future;
  775. }
  776. FWwiseResourceUnloadFuture FWwiseResourceLoader::UnloadMediaAsync(FWwiseLoadedMediaFuture&& InMedia)
  777. {
  778. FWwiseResourceUnloadPromise Promise;
  779. auto Future = Promise.GetFuture();
  780. if (UNLIKELY(!ResourceLoaderImpl))
  781. {
  782. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  783. Promise.EmplaceValue();
  784. }
  785. else if (!IsEnabled())
  786. {
  787. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  788. Promise.EmplaceValue();
  789. }
  790. else if (UNLIKELY(InMedia.IsReady() && InMedia.Get() == nullptr))
  791. {
  792. Promise.EmplaceValue();
  793. }
  794. else if (LIKELY(InMedia.IsReady()))
  795. {
  796. auto* Media = InMedia.Get();
  797. ResourceLoaderImpl->UnloadMediaAsync(MoveTemp(Promise), MoveTemp(Media));
  798. }
  799. else
  800. {
  801. AsyncTask(ResourceLoaderImpl->TaskThread, [this, InMedia = MoveTemp(InMedia), Promise = MoveTemp(Promise)]() mutable
  802. {
  803. {
  804. int WaitCount = 0;
  805. while (!InMedia.WaitFor(FTimespan::FromSeconds(1.0)))
  806. {
  807. if (IsEngineExitRequested())
  808. {
  809. UE_LOG(LogWwiseResourceLoader, Verbose, TEXT("Giving up on waiting for Media load since we are exiting. Gave up on count [%d]"), WaitCount);
  810. Promise.EmplaceValue();
  811. return;
  812. }
  813. else
  814. {
  815. UE_CLOG(WaitCount != 10, LogWwiseResourceLoader, Verbose, TEXT("Waiting for a Media to be fully loaded so we can unload it [%d]"), WaitCount);
  816. UE_CLOG(WaitCount == 10, LogWwiseResourceLoader, Warning, TEXT("Waited 10 seconds for a Media to be loaded so we can unload it."));
  817. ++WaitCount;
  818. }
  819. }
  820. }
  821. auto* Media = InMedia.Get();
  822. if (UNLIKELY(!ResourceLoaderImpl))
  823. {
  824. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  825. Promise.EmplaceValue();
  826. }
  827. else if (!IsEnabled())
  828. {
  829. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  830. Promise.EmplaceValue();
  831. }
  832. else if (UNLIKELY(!Media))
  833. {
  834. Promise.EmplaceValue();
  835. }
  836. else
  837. {
  838. ResourceLoaderImpl->UnloadMediaAsync(MoveTemp(Promise), MoveTemp(Media));
  839. }
  840. });
  841. }
  842. return Future;
  843. }
  844. FWwiseLoadedShareSetFuture FWwiseResourceLoader::LoadShareSetAsync(
  845. const FWwiseLocalizedShareSetCookedData& InShareSetCookedData, const FWwiseLanguageCookedData* InLanguageOverride)
  846. {
  847. FWwiseLoadedShareSetPromise Promise;
  848. auto Future = Promise.GetFuture();
  849. if (UNLIKELY(!ResourceLoaderImpl))
  850. {
  851. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  852. Promise.EmplaceValue(nullptr);
  853. }
  854. else if (!IsEnabled())
  855. {
  856. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  857. Promise.EmplaceValue(nullptr);
  858. }
  859. else
  860. {
  861. auto* ShareSetNode = ResourceLoaderImpl->CreateShareSetNode(InShareSetCookedData, InLanguageOverride);
  862. if (UNLIKELY(!ShareSetNode))
  863. {
  864. Promise.EmplaceValue(nullptr);
  865. }
  866. else
  867. {
  868. ResourceLoaderImpl->LoadShareSetAsync(MoveTemp(Promise), MoveTemp(ShareSetNode));
  869. }
  870. }
  871. return Future;
  872. }
  873. FWwiseResourceUnloadFuture FWwiseResourceLoader::UnloadShareSetAsync(FWwiseLoadedShareSetFuture&& InShareSet)
  874. {
  875. FWwiseResourceUnloadPromise Promise;
  876. auto Future = Promise.GetFuture();
  877. if (UNLIKELY(!ResourceLoaderImpl))
  878. {
  879. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  880. Promise.EmplaceValue();
  881. }
  882. else if (!IsEnabled())
  883. {
  884. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  885. Promise.EmplaceValue();
  886. }
  887. else if (UNLIKELY(InShareSet.IsReady() && InShareSet.Get() == nullptr))
  888. {
  889. Promise.EmplaceValue();
  890. }
  891. else if (LIKELY(InShareSet.IsReady()))
  892. {
  893. auto* ShareSet = InShareSet.Get();
  894. ResourceLoaderImpl->UnloadShareSetAsync(MoveTemp(Promise), MoveTemp(ShareSet));
  895. }
  896. else
  897. {
  898. AsyncTask(ResourceLoaderImpl->TaskThread, [this, InShareSet = MoveTemp(InShareSet), Promise = MoveTemp(Promise)]() mutable
  899. {
  900. {
  901. int WaitCount = 0;
  902. while (!InShareSet.WaitFor(FTimespan::FromSeconds(1.0)))
  903. {
  904. if (IsEngineExitRequested())
  905. {
  906. UE_LOG(LogWwiseResourceLoader, Verbose, TEXT("Giving up on waiting for ShareSet load since we are exiting. Gave up on count [%d]"), WaitCount);
  907. Promise.EmplaceValue();
  908. return;
  909. }
  910. else
  911. {
  912. UE_CLOG(WaitCount != 10, LogWwiseResourceLoader, Verbose, TEXT("Waiting for a ShareSet to be fully loaded so we can unload it [%d]"), WaitCount);
  913. UE_CLOG(WaitCount == 10, LogWwiseResourceLoader, Warning, TEXT("Waited 10 seconds for a ShareSet to be loaded so we can unload it."));
  914. ++WaitCount;
  915. }
  916. }
  917. }
  918. auto* ShareSet = InShareSet.Get();
  919. if (UNLIKELY(!ResourceLoaderImpl))
  920. {
  921. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  922. Promise.EmplaceValue();
  923. }
  924. else if (!IsEnabled())
  925. {
  926. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  927. Promise.EmplaceValue();
  928. }
  929. else if (UNLIKELY(!ShareSet))
  930. {
  931. Promise.EmplaceValue();
  932. }
  933. else
  934. {
  935. ResourceLoaderImpl->UnloadShareSetAsync(MoveTemp(Promise), MoveTemp(ShareSet));
  936. }
  937. });
  938. }
  939. return Future;
  940. }
  941. FWwiseLoadedSoundBankFuture FWwiseResourceLoader::LoadSoundBankAsync(
  942. const FWwiseLocalizedSoundBankCookedData& InSoundBankCookedData, const FWwiseLanguageCookedData* InLanguageOverride)
  943. {
  944. FWwiseLoadedSoundBankPromise Promise;
  945. auto Future = Promise.GetFuture();
  946. if (UNLIKELY(!ResourceLoaderImpl))
  947. {
  948. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  949. Promise.EmplaceValue(nullptr);
  950. }
  951. else if (!IsEnabled())
  952. {
  953. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  954. Promise.EmplaceValue(nullptr);
  955. }
  956. else
  957. {
  958. auto* SoundBankNode = ResourceLoaderImpl->CreateSoundBankNode(InSoundBankCookedData, InLanguageOverride);
  959. if (UNLIKELY(!SoundBankNode))
  960. {
  961. Promise.EmplaceValue(nullptr);
  962. }
  963. else
  964. {
  965. ResourceLoaderImpl->LoadSoundBankAsync(MoveTemp(Promise), MoveTemp(SoundBankNode));
  966. }
  967. }
  968. return Future;
  969. }
  970. FWwiseResourceUnloadFuture FWwiseResourceLoader::UnloadSoundBankAsync(FWwiseLoadedSoundBankFuture&& InSoundBank)
  971. {
  972. FWwiseResourceUnloadPromise Promise;
  973. auto Future = Promise.GetFuture();
  974. if (UNLIKELY(!ResourceLoaderImpl))
  975. {
  976. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  977. Promise.EmplaceValue();
  978. }
  979. else if (!IsEnabled())
  980. {
  981. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  982. Promise.EmplaceValue();
  983. }
  984. else if (UNLIKELY(InSoundBank.IsReady() && InSoundBank.Get() == nullptr))
  985. {
  986. Promise.EmplaceValue();
  987. }
  988. else if (LIKELY(InSoundBank.IsReady()))
  989. {
  990. auto* SoundBank = InSoundBank.Get();
  991. ResourceLoaderImpl->UnloadSoundBankAsync(MoveTemp(Promise), MoveTemp(SoundBank));
  992. }
  993. else
  994. {
  995. AsyncTask(ResourceLoaderImpl->TaskThread, [this, InSoundBank = MoveTemp(InSoundBank), Promise = MoveTemp(Promise)]() mutable
  996. {
  997. {
  998. int WaitCount = 0;
  999. while (!InSoundBank.WaitFor(FTimespan::FromSeconds(1.0)))
  1000. {
  1001. if (IsEngineExitRequested())
  1002. {
  1003. UE_LOG(LogWwiseResourceLoader, Verbose, TEXT("Giving up on waiting for SoundBank load since we are exiting. Gave up on count [%d]"), WaitCount);
  1004. Promise.EmplaceValue();
  1005. return;
  1006. }
  1007. else
  1008. {
  1009. UE_CLOG(WaitCount != 10, LogWwiseResourceLoader, Verbose, TEXT("Waiting for a SoundBank to be fully loaded so we can unload it [%d]"), WaitCount);
  1010. UE_CLOG(WaitCount == 10, LogWwiseResourceLoader, Warning, TEXT("Waited 10 seconds for a SoundBank to be loaded so we can unload it."));
  1011. ++WaitCount;
  1012. }
  1013. }
  1014. }
  1015. auto* SoundBank = InSoundBank.Get();
  1016. if (UNLIKELY(!ResourceLoaderImpl))
  1017. {
  1018. UE_LOG(LogWwiseResourceLoader, Error, TEXT("No ResourceLoaderImpl"));
  1019. Promise.EmplaceValue();
  1020. }
  1021. else if (!IsEnabled())
  1022. {
  1023. UE_LOG(LogWwiseResourceLoader, Warning, TEXT("ResourceLoaderImpl is disabled"));
  1024. Promise.EmplaceValue();
  1025. }
  1026. else if (UNLIKELY(!SoundBank))
  1027. {
  1028. Promise.EmplaceValue();
  1029. }
  1030. else
  1031. {
  1032. ResourceLoaderImpl->UnloadSoundBankAsync(MoveTemp(Promise), MoveTemp(SoundBank));
  1033. }
  1034. });
  1035. }
  1036. return Future;
  1037. }
  1038. //
  1039. // Basic info
  1040. //
  1041. FWwiseSharedPlatformId FWwiseResourceLoader::SystemPlatform() const
  1042. {
  1043. auto Result = FWwiseSharedPlatformId();
  1044. Result.Platform = DefaultPlatform;
  1045. return Result;
  1046. }
  1047. FWwiseLanguageCookedData FWwiseResourceLoader::SystemLanguage() const
  1048. {
  1049. return DefaultLanguage;
  1050. }