WwiseBrowserDataSource.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  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 "WwiseBrowserDataSource.h"
  16. #include "AkUnrealAssetDataHelper.h"
  17. #include "AkWaapiUtils.h"
  18. #include "WaapiDataSource.h"
  19. #include "WwiseProjectDatabaseSource.h"
  20. #include "Templates/SharedPointer.h"
  21. #include "WaapiPicker/WwiseTreeItem.h"
  22. #include "IAudiokineticTools.h"
  23. #include "AssetManagement/AkAssetDatabase.h"
  24. #include "AssetRegistry/AssetRegistryModule.h"
  25. #include "Editor.h"
  26. bool FSoundBankStatusFilter::IsKeptInBrowser(FWwiseTreeItemPtr& Item) const
  27. {
  28. if (AreFiltersOff())
  29. {
  30. return true;
  31. }
  32. if (bFilters[NotInWwise] && Item->IsNotInWwiseOrSoundBank())
  33. {
  34. return true;
  35. }
  36. if (bFilters[DeletedInWwise] && Item->IsDeletedInWwise())
  37. {
  38. return true;
  39. }
  40. if (bFilters[NewInWwise] && Item->IsNewInWwise())
  41. {
  42. return true;
  43. }
  44. if (bFilters[RenamedInWwise] && Item->IsRenamedInWwise())
  45. {
  46. return true;
  47. }
  48. if (bFilters[MovedInWwise] && Item->IsMovedInWwise())
  49. {
  50. return true;
  51. }
  52. if (bFilters[UpToDate] && Item->IsSoundBankUpToDate())
  53. {
  54. return true;
  55. }
  56. return false;
  57. }
  58. bool FSoundBankStatusFilter::AreFiltersOff() const
  59. {
  60. for (auto filter : bFilters)
  61. {
  62. if (filter)
  63. {
  64. return false;
  65. }
  66. }
  67. return true;
  68. }
  69. bool FUAssetStatusFilter::IsKeptInBrowser(FWwiseTreeItemPtr& Item) const
  70. {
  71. if (AreFiltersOff())
  72. {
  73. return true;
  74. }
  75. if(bFilters[UAssetMissing] && Item->IsUAssetMissing())
  76. {
  77. return true;
  78. }
  79. if(bFilters[UAssetOrphaned] && Item->IsUAssetOrphaned())
  80. {
  81. return true;
  82. }
  83. if(bFilters[NotInSoundBankOrUnreal] && Item->IsNotInSoundBankOrUnreal())
  84. {
  85. return true;
  86. }
  87. if(bFilters[MultipleUAssets] && Item->HasMultipleUAssets())
  88. {
  89. return true;
  90. }
  91. if (bFilters[RenamedInSoundBank] && Item->IsRenamedInSoundBank())
  92. {
  93. return true;
  94. }
  95. if (bFilters[UAssetNeedsUpdate] && Item->IsUAssetOutOfDate())
  96. {
  97. return true;
  98. }
  99. if(bFilters[UAssetUpToDate] && Item->IsUAssetUpToDate())
  100. {
  101. return true;
  102. }
  103. return false;
  104. }
  105. bool FUAssetStatusFilter::AreFiltersOff() const
  106. {
  107. for (auto filter : bFilters)
  108. {
  109. if (filter)
  110. {
  111. return false;
  112. }
  113. }
  114. return true;
  115. }
  116. bool FWwiseTypeFilter::IsKeptInBrowser(FWwiseTreeItemPtr& Item) const
  117. {
  118. if(AreFiltersOff())
  119. {
  120. return true;
  121. }
  122. for(int i = 0; i < NumberOfWwiseTypes; i++)
  123. {
  124. if(bFilters[i] && Item->ItemType == GetExpectedType((EWwiseTypeFilter)i))
  125. {
  126. return true;
  127. }
  128. }
  129. return false;
  130. }
  131. bool FWwiseTypeFilter::AreFiltersOff() const
  132. {
  133. for(auto bFilter : bFilters)
  134. {
  135. if(bFilter)
  136. {
  137. return false;
  138. }
  139. }
  140. return true;
  141. }
  142. EWwiseItemType::Type FWwiseTypeFilter::GetExpectedType(EWwiseTypeFilter Filter) const
  143. {
  144. switch(Filter)
  145. {
  146. case AcousticTexture:
  147. return EWwiseItemType::AcousticTexture;
  148. case Effects:
  149. return EWwiseItemType::EffectShareSet;
  150. case Events:
  151. return EWwiseItemType::Event;
  152. case GameParameters:
  153. return EWwiseItemType::GameParameter;
  154. case MasterMixerHierarchy:
  155. return EWwiseItemType::Bus;
  156. case State:
  157. return EWwiseItemType::State;
  158. case Switch:
  159. return EWwiseItemType::Switch;
  160. case Trigger:
  161. return EWwiseItemType::Trigger;
  162. default:
  163. break;
  164. }
  165. return EWwiseItemType::None;
  166. }
  167. FWwiseBrowserDataSource::FWwiseBrowserDataSource()
  168. {
  169. WaapiDataSource = MakeUnique<FWaapiDataSource>();
  170. ProjectDBDataSource = MakeUnique<FWwiseProjectDatabaseDataSource>();
  171. UAssetDataSource = MakeUnique<FUAssetDataSource>();
  172. WaapiDataSource->Init();
  173. WaapiDataSource->WaapiDataSourceRefreshed.BindRaw(this, &FWwiseBrowserDataSource::OnWaapiDataSourceRefreshed);
  174. WaapiDataSource->WwiseSelectionChange.BindRaw(this, &FWwiseBrowserDataSource::OnWwiseSelectionChange);
  175. WaapiDataSource->WwiseExpansionChange.BindRaw(this, &FWwiseBrowserDataSource::OnWwiseExpansionChange);
  176. ProjectDBDataSource->Init();
  177. ProjectDBDataSource->ProjectDatabaseDataSourceRefreshed.BindRaw(this, &FWwiseBrowserDataSource::OnProjectDBDataSourceRefreshed);
  178. FAssetRegistryModule* AssetRegistryModule = &FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
  179. auto& AssetRegistry = AssetRegistryModule->Get();
  180. if (AssetRegistry.IsLoadingAssets())
  181. {
  182. OnFilesLoaded = AssetRegistry.OnFilesLoaded().AddRaw(this, &FWwiseBrowserDataSource::OnFilesFullyLoaded);
  183. }
  184. else
  185. {
  186. SetupAssetCallbacks();
  187. }
  188. }
  189. FWwiseBrowserDataSource::~FWwiseBrowserDataSource()
  190. {
  191. WaapiDataSource->WaapiDataSourceRefreshed.Unbind();
  192. WaapiDataSource->WwiseSelectionChange.Unbind();
  193. WaapiDataSource->WwiseExpansionChange.Unbind();
  194. ProjectDBDataSource->ProjectDatabaseDataSourceRefreshed.Unbind();
  195. FAssetRegistryModule* AssetRegistryModule = &FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
  196. auto& AssetRegistry = AssetRegistryModule->Get();
  197. AssetRegistry.OnAssetAdded().Remove(OnAssetAdded);
  198. AssetRegistry.OnAssetRemoved().Remove(OnAssetRemoved);
  199. AssetRegistry.OnAssetRenamed().Remove(OnAssetRenamed);
  200. AssetRegistry.OnAssetUpdated().Remove(OnAssetUpdated);
  201. if(PostEditorTickHandle.IsValid())
  202. {
  203. GEditor->OnPostEditorTick().Remove(PostEditorTickHandle);
  204. }
  205. }
  206. void FWwiseBrowserDataSource::ConstructTree()
  207. {
  208. UAssetDataSource->ConstructItems();
  209. ProjectDBDataSource->ConstructTree(false);
  210. WaapiDataSource->ConstructTree(false);
  211. MergeDataSources(false);
  212. }
  213. bool FWwiseBrowserDataSource::AreFiltersOff()
  214. {
  215. return WwiseTypeFilter.AreFiltersOff() &&
  216. UAssetStatusFilter.AreFiltersOff() &&
  217. SoundBankStatusFilter.AreFiltersOff();
  218. }
  219. void FWwiseBrowserDataSource::ApplyTextFilter(TSharedPtr<StringFilter> FilterText)
  220. {
  221. CurrentFilterText = FilterText;
  222. ConstructTree();
  223. if (!AreFiltersOff())
  224. {
  225. ApplyFilter(SoundBankStatusFilter, UAssetStatusFilter, WwiseTypeFilter);
  226. }
  227. }
  228. void FWwiseBrowserDataSource::ApplyFilter(FSoundBankStatusFilter SoundBankStatus,
  229. FUAssetStatusFilter UAssetStatus,
  230. FWwiseTypeFilter WwiseType)
  231. {
  232. SoundBankStatusFilter = SoundBankStatus;
  233. UAssetStatusFilter = UAssetStatus;
  234. WwiseTypeFilter = WwiseType;
  235. RootItems.Empty();
  236. for (auto& RootItem : RootItemsUnfiltered)
  237. {
  238. FWwiseTreeItemPtr RootItemFiltered;
  239. ApplyFilter(RootItem, RootItemFiltered);
  240. RootItems.Add(RootItemFiltered);
  241. }
  242. }
  243. void FWwiseBrowserDataSource::ApplyFilter(FWwiseTreeItemPtr Item, FWwiseTreeItemPtr& OutItem)
  244. {
  245. OutItem = MakeShared<FWwiseTreeItem>(*Item.Get());
  246. OutItem->EmptyChildren();
  247. for (auto CurrItem : Item->GetChildren())
  248. {
  249. if (!IsKeptInBrowser(CurrItem))
  250. {
  251. continue;
  252. }
  253. if (CurrItem->IsFolder())
  254. {
  255. FWwiseTreeItemPtr Children;
  256. ApplyFilter(CurrItem, Children);
  257. OutItem->AddChild(Children);
  258. }
  259. else
  260. {
  261. FWwiseTreeItemPtr Children = MakeShared<FWwiseTreeItem>(*CurrItem.Get());
  262. OutItem->AddChild(Children);
  263. }
  264. }
  265. }
  266. void FWwiseBrowserDataSource::ClearFilter()
  267. {
  268. CurrentFilterText = {};
  269. }
  270. bool FWwiseBrowserDataSource::IsKeptInBrowser(FWwiseTreeItemPtr Item)
  271. {
  272. if(AreFiltersOff())
  273. {
  274. return true;
  275. }
  276. if (Item->IsFolder())
  277. {
  278. for (auto Children : Item->GetChildren())
  279. {
  280. if (IsKeptInBrowser(Children))
  281. {
  282. return true;
  283. }
  284. }
  285. return false;
  286. }
  287. bool bWwiseFilterResult = true;
  288. if (GetWaapiConnectionStatus() == EWwiseConnectionStatus::Connected)
  289. {
  290. bWwiseFilterResult = SoundBankStatusFilter.IsKeptInBrowser(Item);
  291. }
  292. return bWwiseFilterResult &&
  293. UAssetStatusFilter.IsKeptInBrowser(Item) &&
  294. WwiseTypeFilter.IsKeptInBrowser(Item);
  295. }
  296. FWwiseTreeItemPtr FWwiseBrowserDataSource::GetTreeRootForType(EWwiseItemType::Type ItemType, const FString& FilterText)
  297. {
  298. FScopeLock AutoLock(&RootItemsLock);
  299. if (RootItemsUnfiltered.Num() < ItemType + 1)
  300. {
  301. UE_LOG(LogAudiokineticTools, Error, TEXT("Failed to get Item Type. Index out of range."));
  302. return MakeShared<FWwiseTreeItem>("", "", nullptr, EWwiseItemType::Type::None, FGuid());
  303. }
  304. if (AreFiltersOff())
  305. {
  306. return RootItemsUnfiltered[ItemType];
  307. }
  308. return RootItems[ItemType];
  309. }
  310. FText FWwiseBrowserDataSource::GetProjectName()
  311. {
  312. if (ProjectDBDataSource.IsValid())
  313. {
  314. return ProjectDBDataSource->GetProjectName();
  315. }
  316. return {};
  317. }
  318. FText FWwiseBrowserDataSource::GetConnectedWwiseProjectName()
  319. {
  320. return FText::FromString(WaapiDataSource->LoadProjectName());
  321. }
  322. int32 FWwiseBrowserDataSource::LoadChildren(FWwiseTreeItemPtr TreeItem, TArray<FWwiseTreeItemPtr>& OutChildren)
  323. {
  324. UE_LOG(LogAudiokineticTools, VeryVerbose, TEXT("Loading children for %s"), *TreeItem->FolderPath )
  325. TArray<FWwiseTreeItemPtr> WaapiChildren;
  326. TArray<FWwiseTreeItemPtr> SoundBanksChildren;
  327. FWwiseTreeItemPtr WaapiParent = WaapiDataSource->FindItemFromPath(TreeItem->FolderPath);
  328. FWwiseTreeItemPtr SoundBanksParent = ProjectDBDataSource->FindItemFromPath(TreeItem->FolderPath);
  329. WaapiDataSource->LoadChildren(WaapiParent);
  330. ProjectDBDataSource->LoadChildren(SoundBanksParent);
  331. //In this case, it is an orphaned uasset.
  332. if(!WaapiParent && !SoundBanksParent)
  333. {
  334. return TreeItem->GetChildren().Num();
  335. }
  336. TreeItem->EmptyChildren();
  337. if(SoundBanksParent || WaapiParent)
  338. {
  339. CreateUnifiedTree(SoundBanksParent, WaapiParent, TreeItem);
  340. TreeItem->SortChildren();
  341. return TreeItem->GetChildren().Num();
  342. }
  343. return 0;
  344. }
  345. void FWwiseBrowserDataSource::ClearEmptyChildren(FWwiseTreeItemPtr TreeItem)
  346. {
  347. TArray<FWwiseTreeItemPtr> ChildrenToRemove;
  348. for (auto Child : *TreeItem->GetChildrenMutable())
  349. {
  350. if (Child->IsOfType({EWwiseItemType::None}))
  351. {
  352. ChildrenToRemove.Add(Child);
  353. }
  354. }
  355. TreeItem->RemoveChildren(ChildrenToRemove);
  356. }
  357. EWwiseConnectionStatus FWwiseBrowserDataSource::GetWaapiConnectionStatus() const
  358. {
  359. if(!WaapiDataSource.IsValid())
  360. {
  361. return EWwiseConnectionStatus::WwiseNotOpen;
  362. }
  363. return WaapiDataSource->IsProjectLoaded();
  364. }
  365. FString FWwiseBrowserDataSource::GetItemWorkUnitPath(FWwiseTreeItemPtr InTreeItem)
  366. {
  367. if (WaapiDataSource.IsValid())
  368. {
  369. return WaapiDataSource->GetItemWorkUnitPath(InTreeItem);
  370. }
  371. return {};
  372. }
  373. void FWwiseBrowserDataSource::SelectInWwiseProjectExplorer(TArray<FWwiseTreeItemPtr>& InTreeItem)
  374. {
  375. if (WaapiDataSource.IsValid())
  376. {
  377. WaapiDataSource->SelectInProjectExplorer(InTreeItem);
  378. }
  379. }
  380. void FWwiseBrowserDataSource::HandleFindWwiseItemInProjectExplorerCommandExecute(
  381. const TArray<FWwiseTreeItemPtr>& SelectedItems) const
  382. {
  383. WaapiDataSource->HandleFindWwiseItemInProjectExplorerCommandExecute(SelectedItems);
  384. }
  385. void FWwiseBrowserDataSource::MergeDataSources(bool bGenerateUAssetsInfo)
  386. {
  387. FWwiseTreeItemPtr WaapiRootItem;
  388. FWwiseTreeItemPtr SoundBanksRootItem;
  389. if (bGenerateUAssetsInfo)
  390. {
  391. UAssetDataSource->ConstructItems();
  392. }
  393. {
  394. FScopeLock AutoLock(&RootItemsLock);
  395. RootItemsUnfiltered.Empty();
  396. }
  397. for (int i = EWwiseItemType::Event; i <= EWwiseItemType::LastWwiseBrowserType; ++i)
  398. {
  399. if (!CurrentFilterText.IsValid() || CurrentFilterText->GetRawFilterText().IsEmpty())
  400. {
  401. SoundBanksRootItem = ProjectDBDataSource->GetRootItem(static_cast<EWwiseItemType::Type>(i));
  402. }
  403. else
  404. {
  405. SoundBanksRootItem = ProjectDBDataSource->LoadFilteredRootItem(static_cast<EWwiseItemType::Type>(i), CurrentFilterText);
  406. }
  407. FWwiseTreeItemPtr NewRootItem;
  408. if (SoundBanksRootItem)
  409. {
  410. NewRootItem = MakeShared<FWwiseTreeItem>(SoundBanksRootItem->DisplayName, SoundBanksRootItem->FolderPath, nullptr, SoundBanksRootItem->ItemType, SoundBanksRootItem->ItemId);
  411. NewRootItem->WwiseItemRef = SoundBanksRootItem->WwiseItemRef;
  412. NewRootItem->ShortId = SoundBanksRootItem->ShortId;
  413. UE_LOG(LogAudiokineticTools, VeryVerbose, TEXT("Creating Tree for %s "), *SoundBanksRootItem->FolderPath)
  414. }
  415. if (!CurrentFilterText.IsValid() || CurrentFilterText->GetRawFilterText().IsEmpty())
  416. {
  417. WaapiRootItem = WaapiDataSource->GetRootItem(static_cast<EWwiseItemType::Type>(i));
  418. }
  419. else
  420. {
  421. WaapiRootItem = WaapiDataSource->LoadFilteredRootItem(static_cast<EWwiseItemType::Type>(i), CurrentFilterText);
  422. }
  423. if (WaapiRootItem)
  424. {
  425. if (!NewRootItem)
  426. {
  427. NewRootItem = MakeShared<FWwiseTreeItem>(WaapiRootItem->DisplayName, WaapiRootItem->FolderPath, nullptr, WaapiRootItem->ItemType, WaapiRootItem->ItemId);
  428. NewRootItem->WwiseItemRef = WaapiRootItem->WwiseItemRef;
  429. }
  430. NewRootItem->ItemId = WaapiRootItem->ItemId;
  431. }
  432. if(SoundBanksRootItem || WaapiRootItem)
  433. {
  434. CreateUnifiedTree(SoundBanksRootItem, WaapiRootItem, NewRootItem);
  435. UE_LOG(LogAudiokineticTools, VeryVerbose, TEXT("Merging Tree for %s "), *NewRootItem->FolderPath);
  436. FScopeLock AutoLock(&RootItemsLock);
  437. RootItemsUnfiltered.Add(NewRootItem);
  438. }
  439. }
  440. // Add the Orphan UAssets
  441. {
  442. FScopeLock AutoLock(&RootItemsLock);
  443. FWwiseTreeItemPtr RootItem = MakeShared<FWwiseTreeItem>(FString("Orphaned UAssets"), FString("\\Orphaned UAssets"), nullptr, EWwiseItemType::Folder, FGuid());
  444. TArray<UAssetDataSourceInformation> OrphanAssets;
  445. UAssetDataSource->GetOrphanAssets(OrphanAssets);
  446. for(auto& OrphanAsset : OrphanAssets)
  447. {
  448. //Check if they should be filtered out by the text
  449. if (CurrentFilterText.IsValid() && !CurrentFilterText->GetRawFilterText().IsEmpty())
  450. {
  451. if (!OrphanAsset.Id.Name.ToString().Contains(CurrentFilterText->GetRawFilterText().ToString()))
  452. {
  453. continue;
  454. }
  455. }
  456. FWwiseTreeItemPtr NewItem = MakeShared<FWwiseTreeItem>(OrphanAsset.Id.Name.ToString(), FString(), RootItem, OrphanAsset.Type, FGuid());
  457. NewItem->Assets = OrphanAsset.AssetsData;
  458. NewItem->UAssetName = OrphanAsset.Id.Name;
  459. NewItem->ShortId = OrphanAsset.Id.ShortId;
  460. RootItem->AddChild(NewItem);
  461. }
  462. RootItemsUnfiltered.Add(RootItem);
  463. }
  464. WwiseBrowserDataSourceRefreshed.ExecuteIfBound();
  465. }
  466. void FWwiseBrowserDataSource::CreateUnifiedTree(const FWwiseTreeItemPtr& TreeItemRootSoundBank, const FWwiseTreeItemPtr& TreeItemRootWaapi, FWwiseTreeItemPtr& TreeItemRootDst)
  467. {
  468. if (TreeItemRootSoundBank)
  469. {
  470. CreateProjectDBItem(TreeItemRootSoundBank, TreeItemRootDst);
  471. }
  472. if (TreeItemRootWaapi)
  473. {
  474. CreateWaapiItem(TreeItemRootWaapi, TreeItemRootDst);
  475. }
  476. }
  477. void FWwiseBrowserDataSource::CreateProjectDBItem(const FWwiseTreeItemPtr& TreeItemRootSoundBank, FWwiseTreeItemPtr& TreeItemRootDst)
  478. {
  479. FString DefaultAssetName = TreeItemRootSoundBank->GetDefaultAssetName();
  480. TreeItemRootDst = MakeShared<FWwiseTreeItem>(TreeItemRootSoundBank->DisplayName, TreeItemRootSoundBank->FolderPath, nullptr, TreeItemRootSoundBank->ItemType, TreeItemRootSoundBank->ItemId);
  481. if(TreeItemRootSoundBank->ShouldDisplayInfo())
  482. {
  483. TArray<FAssetData> Assets;
  484. EWwiseItemType::Type Type;
  485. FName UAssetName;
  486. UAssetDataSource->GetAssetsInfo(TreeItemRootSoundBank->ItemId, TreeItemRootSoundBank->ShortId, DefaultAssetName, Type, UAssetName, Assets);
  487. TreeItemRootDst->Assets = Assets;
  488. TreeItemRootDst->UAssetName = UAssetName;
  489. }
  490. TreeItemRootDst->WwiseItemRef = TreeItemRootSoundBank->WwiseItemRef;
  491. TreeItemRootDst->ShortId = TreeItemRootSoundBank->ShortId;
  492. //State Groups have a None State that does not appear in Wwise. Set the Ref to true to avoid "Deleted in Wwise".
  493. if(TreeItemRootDst->ItemType == EWwiseItemType::State && TreeItemRootDst->DisplayName == FString("None"))
  494. {
  495. TreeItemRootDst->WaapiName = TreeItemRootDst->DisplayName;
  496. TreeItemRootDst->bWaapiRefExists = true;
  497. }
  498. for (auto& Child : TreeItemRootSoundBank->GetChildren())
  499. {
  500. FWwiseTreeItemPtr NewItem;
  501. CreateProjectDBItem(Child, NewItem);
  502. TreeItemRootDst->AddChild(NewItem);
  503. }
  504. TreeItemRootDst->SortChildren();
  505. }
  506. void FWwiseBrowserDataSource::CreateWaapiExclusiveItem(const FWwiseTreeItemPtr& WaapiItem, FWwiseTreeItemPtr& TreeItemRootDst)
  507. {
  508. FWwiseTreeItemPtr CurrItem = MakeShared<FWwiseTreeItem>(WaapiItem->DisplayName, WaapiItem->FolderPath, nullptr, WaapiItem->ItemType, WaapiItem->ItemId);
  509. if(WaapiItem->ShouldDisplayInfo())
  510. {
  511. FString DefaultAssetName = WaapiItem->GetDefaultAssetName();
  512. TArray<FAssetData> Assets;
  513. FName AssetName;
  514. EWwiseItemType::Type ItemType;
  515. UAssetDataSource->GetAssetsInfo(WaapiItem->ItemId, WaapiItem->ShortId, DefaultAssetName, ItemType, AssetName, Assets);
  516. CurrItem->UAssetName = AssetName;
  517. CurrItem->Assets = Assets;
  518. }
  519. CurrItem->WaapiName = WaapiItem->DisplayName;
  520. CurrItem->bWaapiRefExists = true;
  521. CurrItem->ChildCountInWwise = WaapiItem->ChildCountInWwise;
  522. TreeItemRootDst->AddChild(CurrItem);
  523. }
  524. void FWwiseBrowserDataSource::CreateWaapiItem(const FWwiseTreeItemPtr& TreeItemRootWaapi, FWwiseTreeItemPtr& TreeItemRootDst)
  525. {
  526. FWwiseTreeItemPtr NewItem;
  527. for (const auto& WaapiItem : TreeItemRootWaapi->GetChildren())
  528. {
  529. NewItem = TreeItemRootDst->GetChild(WaapiItem->ItemId, WaapiItem->ShortId, WaapiItem->DisplayName);
  530. if (NewItem)
  531. {
  532. NewItem->WaapiName = WaapiItem->DisplayName;
  533. NewItem->bWaapiRefExists = true;
  534. if(NewItem->IsFolder())
  535. {
  536. NewItem->ItemId = WaapiItem->ItemId;
  537. }
  538. continue;
  539. }
  540. if (WaapiItem->IsFolder())
  541. {
  542. NewItem = MakeShared<FWwiseTreeItem>(WaapiItem->DisplayName, WaapiItem->FolderPath, nullptr, WaapiItem->ItemType, WaapiItem->ItemId);
  543. TreeItemRootDst->AddChild(NewItem);
  544. continue;
  545. }
  546. auto SoundBankItem = ProjectDBDataSource->FindItem(WaapiItem);
  547. //The item was moved in Wwise
  548. if (SoundBankItem)
  549. {
  550. auto Root = TreeItemRootDst->GetRoot();
  551. NewItem = Root->FindItemRecursive(WaapiItem);
  552. if (NewItem)
  553. {
  554. NewItem->WaapiName = WaapiItem->DisplayName;
  555. NewItem->bWaapiRefExists = true;
  556. NewItem->bSameLocation = false;
  557. }
  558. }
  559. else
  560. {
  561. CreateWaapiExclusiveItem(WaapiItem, TreeItemRootDst);
  562. }
  563. }
  564. TreeItemRootDst->SortChildren();
  565. for (auto CurrItem : TreeItemRootDst->GetChildren())
  566. {
  567. if (TreeItemRootWaapi)
  568. {
  569. if (FWwiseTreeItemPtr WaapiItem = TreeItemRootWaapi->GetChild(CurrItem->ItemId, CurrItem->ShortId, CurrItem->DisplayName))
  570. {
  571. CreateWaapiItem(WaapiItem, CurrItem);
  572. }
  573. }
  574. }
  575. }
  576. void FWwiseBrowserDataSource::OnWaapiDataSourceRefreshed()
  577. {
  578. MergeDataSources(false);
  579. }
  580. void FWwiseBrowserDataSource::OnProjectDBDataSourceRefreshed()
  581. {
  582. MergeDataSources();
  583. }
  584. void FWwiseBrowserDataSource::SetupAssetCallbacks()
  585. {
  586. FAssetRegistryModule* AssetRegistryModule = &FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
  587. if (AssetRegistryModule)
  588. {
  589. auto& AssetRegistry = AssetRegistryModule->Get();
  590. OnAssetAdded = AssetRegistry.OnAssetAdded().AddRaw(this, &FWwiseBrowserDataSource::OnUAssetSourceRefresh);
  591. OnAssetRemoved = AssetRegistry.OnAssetRemoved().AddRaw(this, &FWwiseBrowserDataSource::OnUAssetSourceRefresh);
  592. OnAssetRenamed = AssetRegistry.OnAssetRenamed().AddRaw(this, &FWwiseBrowserDataSource::OnUAssetSourceRefresh);
  593. OnAssetUpdated = AssetRegistry.OnAssetUpdated().AddRaw(this, &FWwiseBrowserDataSource::OnUAssetSourceRefresh);
  594. }
  595. }
  596. void FWwiseBrowserDataSource::OnFilesFullyLoaded()
  597. {
  598. if (OnFilesLoaded.IsValid())
  599. {
  600. FAssetRegistryModule* AssetRegistryModule = &FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
  601. if (AssetRegistryModule)
  602. {
  603. auto& AssetRegistry = AssetRegistryModule->Get();
  604. AssetRegistry.OnFilesLoaded().Remove(OnFilesLoaded);
  605. }
  606. }
  607. SetupAssetCallbacks();
  608. MergeDataSources();
  609. }
  610. void FWwiseBrowserDataSource::OnTimerTick(float DeltaSeconds)
  611. {
  612. AssetUpdateTimer -= DeltaSeconds;
  613. if(AssetUpdateTimer <= 0.f)
  614. {
  615. MergeDataSources();
  616. if(PostEditorTickHandle.IsValid())
  617. {
  618. GEngine->OnPostEditorTick().Remove(PostEditorTickHandle);
  619. PostEditorTickHandle.Reset();
  620. }
  621. }
  622. }
  623. void FWwiseBrowserDataSource::OnUAssetSourceRefresh(const FAssetData& AssetData)
  624. {
  625. if(AkUnrealAssetDataHelper::IsAssetAkAudioType(AssetData) && !AkUnrealAssetDataHelper::IsAssetTransient(AssetData))
  626. {
  627. if(!PostEditorTickHandle.IsValid())
  628. {
  629. PostEditorTickHandle = GEngine->OnPostEditorTick().AddRaw(this, &FWwiseBrowserDataSource::OnTimerTick);
  630. }
  631. AssetUpdateTimer = AssetTimerRefresh;
  632. }
  633. }
  634. void FWwiseBrowserDataSource::OnUAssetSourceRefresh(const FAssetData& AssetData, const FString& OldPath)
  635. {
  636. if (AkUnrealAssetDataHelper::IsAssetAkAudioType(AssetData) && !AkUnrealAssetDataHelper::IsAssetTransient(AssetData))
  637. {
  638. if(!PostEditorTickHandle.IsValid())
  639. {
  640. PostEditorTickHandle = GEngine->OnPostEditorTick().AddRaw(this, &FWwiseBrowserDataSource::OnTimerTick);
  641. }
  642. AssetUpdateTimer = AssetTimerRefresh;
  643. }
  644. }
  645. void FWwiseBrowserDataSource::OnWwiseSelectionChange(const TArray<TSharedPtr<FWwiseTreeItem>>& Items)
  646. {
  647. WwiseSelectionChange.ExecuteIfBound(Items);
  648. }
  649. void FWwiseBrowserDataSource::OnWwiseExpansionChange(const TArray<TSharedPtr<FWwiseTreeItem>>& Items)
  650. {
  651. WwiseExpansionChange.ExecuteIfBound(Items);
  652. }