update audio + switch to wwise
This commit is contained in:
@@ -0,0 +1,755 @@
|
||||
#if UNITY_EDITOR
|
||||
/*******************************************************************************
|
||||
The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
|
||||
Technology released in source code form as part of the game integration package.
|
||||
The content of this file may not be used without valid licenses to the
|
||||
AUDIOKINETIC Wwise Technology.
|
||||
Note that the use of the game engine is subject to the Unity(R) Terms of
|
||||
Service at https://unity3d.com/legal/terms-of-service
|
||||
|
||||
License Usage
|
||||
|
||||
Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
|
||||
this file in accordance with the end user license agreement provided with the
|
||||
software or, alternatively, in accordance with the terms contained
|
||||
in a written agreement between you and Audiokinetic Inc.
|
||||
Copyright (c) 2024 Audiokinetic Inc.
|
||||
*******************************************************************************/
|
||||
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.ObjectModel;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// This class communicates with Wwise Authoring via AkWaapiUtilities to keep track of the Wwise object hierarchy in the project.
|
||||
/// This hierarchy information is stored in a tree structure and is used by the Wwise Picker when it is in WAAPI mode.
|
||||
/// Changes to the project are received via WAAPI subscriptions.
|
||||
/// </summary>
|
||||
public class AkWwiseTreeWAAPIDataSource : AkWwiseTreeDataSource
|
||||
{
|
||||
|
||||
private System.Timers.Timer selectTimer;
|
||||
private System.Timers.Timer searchTimer;
|
||||
|
||||
private ReturnOptions waapiWwiseObjectOptions =
|
||||
new ReturnOptions(new string[] { "id", "name", "type", "childrenCount", "path", "workunitType", "parent" });
|
||||
|
||||
|
||||
public bool AutoSyncSelection;
|
||||
public bool WaitingForSearchResults;
|
||||
|
||||
public AkWwiseTreeWAAPIDataSource() : base()
|
||||
{
|
||||
Connect();
|
||||
|
||||
selectTimer = new System.Timers.Timer();
|
||||
selectTimer.Interval = 200;
|
||||
selectTimer.AutoReset = false;
|
||||
selectTimer.Elapsed += FireSelect;
|
||||
|
||||
searchTimer = new System.Timers.Timer();
|
||||
searchTimer.Interval = 200;
|
||||
searchTimer.AutoReset = false;
|
||||
searchTimer.Elapsed += FireSearch;
|
||||
}
|
||||
|
||||
public override void FetchData()
|
||||
{
|
||||
Data.Clear();
|
||||
m_MaxID = 0;
|
||||
ProjectRoot = CreateProjectRootItem();
|
||||
|
||||
foreach (var type in FolderNames.Keys)
|
||||
{
|
||||
AkWaapiUtilities.GetResultListDelegate<WwiseObjectInfoJsonObject> callback = (List<WwiseObjectInfoJsonObject> items) =>
|
||||
{
|
||||
AddBaseFolder(AkWaapiUtilities.ParseObjectInfo(items), type);
|
||||
};
|
||||
AkWaapiUtilities.GetWwiseObjectAndDescendants(FolderNames[type], waapiWwiseObjectOptions, 2, callback);
|
||||
}
|
||||
Changed();
|
||||
}
|
||||
|
||||
public override AkWwiseTreeViewItem GetComponentDataRoot(WwiseObjectType objectType)
|
||||
{
|
||||
var tempProjectRoot = new AkWwiseTreeViewItem(ProjectRoot);
|
||||
if (!wwiseObjectFolders.ContainsKey(objectType))
|
||||
{
|
||||
return tempProjectRoot;
|
||||
}
|
||||
|
||||
tempProjectRoot.AddWwiseItemChild(wwiseObjectFolders[objectType]);
|
||||
return tempProjectRoot;
|
||||
}
|
||||
|
||||
WwiseObjectType componentObjectType;
|
||||
public override void LoadComponentData(WwiseObjectType objectType)
|
||||
{
|
||||
componentObjectType = objectType;
|
||||
LoadComponentDataDelayed();
|
||||
}
|
||||
|
||||
public void LoadComponentDataDelayed()
|
||||
{
|
||||
//Delay call until data has been fetched
|
||||
if (!wwiseObjectFolders.ContainsKey(componentObjectType))
|
||||
{
|
||||
UnityEditor.EditorApplication.delayCall += LoadComponentDataDelayed;
|
||||
}
|
||||
else
|
||||
{
|
||||
AkWaapiUtilities.GetResultListDelegate<WwiseObjectInfoJsonObject> callback = (List<WwiseObjectInfoJsonObject> items) =>
|
||||
{
|
||||
AddItems(AkWaapiUtilities.ParseObjectInfo(items));
|
||||
};
|
||||
AkWaapiUtilities.GetWwiseObjectAndDescendants(wwiseObjectFolders[componentObjectType].objectGuid,
|
||||
waapiWwiseObjectOptions, -1, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string searchString;
|
||||
private WwiseObjectType searchObjectTypeFilter;
|
||||
public override void UpdateSearchResults(string searchFilter, WwiseObjectType objectType = WwiseObjectType.None)
|
||||
{
|
||||
searchTimer.Stop();
|
||||
searchString = searchFilter;
|
||||
searchObjectTypeFilter = objectType;
|
||||
searchTimer.Enabled = true;
|
||||
searchTimer.Start();
|
||||
}
|
||||
|
||||
private void FireSearch(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
if (WaitingForSearchResults) return;
|
||||
if (SearchRoot == null)
|
||||
{
|
||||
SearchRoot = new AkWwiseTreeViewItem(ProjectRoot);
|
||||
}
|
||||
|
||||
SearchRoot.children.Clear();
|
||||
SearchData = new TreeItems();
|
||||
TreeUtility.TreeToList(SearchRoot, ref SearchData);
|
||||
AkWaapiUtilities.GetResultListDelegate<WwiseObjectInfoJsonObject> callback = (List<WwiseObjectInfoJsonObject> items) =>
|
||||
{
|
||||
AddSearchResults(AkWaapiUtilities.ParseObjectInfo(items));
|
||||
treeviewCommandQueue.Enqueue(new TreeViewCommand(() => Expand(SearchRoot.objectGuid, false)));
|
||||
WaitingForSearchResults = false;
|
||||
};
|
||||
AkWaapiUtilities.Search(searchString, searchObjectTypeFilter, waapiWwiseObjectOptions, callback);
|
||||
WaitingForSearchResults = true;
|
||||
}
|
||||
|
||||
public override AkWwiseTreeViewItem GetSearchResults()
|
||||
{
|
||||
if (SearchRoot == null)
|
||||
{
|
||||
SearchRoot = new AkWwiseTreeViewItem(ProjectRoot);
|
||||
}
|
||||
|
||||
return SearchRoot;
|
||||
}
|
||||
|
||||
public void AddSearchResults(IEnumerable<WwiseObjectInfo> matchList)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var info in matchList)
|
||||
{
|
||||
if (!FilterPath(info.path))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var match = FindInSearchResults(info.objectGUID);
|
||||
if (match != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var matchItem = FindByGuid(info.objectGUID);
|
||||
if (matchItem == null)
|
||||
{
|
||||
AkWaapiUtilities.GetResultListDelegate<WwiseObjectInfoJsonObject> callback = (List<WwiseObjectInfoJsonObject> items) =>
|
||||
{
|
||||
AddItemWithAncestorsToSearch(AkWaapiUtilities.ParseObjectInfo(items));
|
||||
};
|
||||
AkWaapiUtilities.GetWwiseObjectAndAncestors(info.objectGUID, waapiWwiseObjectOptions, callback);
|
||||
continue;
|
||||
}
|
||||
|
||||
AddItemToSearch(matchItem);
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogError("Search died");
|
||||
UnityEngine.Debug.LogError(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddItemToSearch(AkWwiseTreeViewItem sourceItem)
|
||||
{
|
||||
var matchItem = new AkWwiseTreeViewItem(sourceItem);
|
||||
SearchData.Add(matchItem);
|
||||
|
||||
var sourceParent = sourceItem.parent as AkWwiseTreeViewItem;
|
||||
var parentCopy = FindInSearchResults(sourceParent.objectGuid);
|
||||
if (parentCopy != null)
|
||||
{
|
||||
parentCopy.AddWwiseItemChild(matchItem);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
parentCopy = new AkWwiseTreeViewItem(sourceParent);
|
||||
parentCopy.AddWwiseItemChild(matchItem);
|
||||
SearchData.Add(parentCopy);
|
||||
var nextParent = sourceParent.parent as AkWwiseTreeViewItem;
|
||||
while (nextParent != null)
|
||||
{
|
||||
var parentInSearchItems = FindInSearchResults(nextParent.objectGuid);
|
||||
if (parentInSearchItems != null)
|
||||
{
|
||||
parentInSearchItems.AddWwiseItemChild(parentCopy);
|
||||
break;
|
||||
}
|
||||
parentInSearchItems = new AkWwiseTreeViewItem(nextParent);
|
||||
parentInSearchItems.AddWwiseItemChild(parentCopy);
|
||||
SearchData.Add(parentInSearchItems);
|
||||
parentCopy = parentInSearchItems;
|
||||
nextParent = nextParent.parent as AkWwiseTreeViewItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddItemWithAncestors(List<WwiseObjectInfo> infoItems, bool selectAfterCreated = false)
|
||||
{
|
||||
var parent = ProjectRoot;
|
||||
//Items obtained from the WAAPI call are sorted by path so we can simply iterate over them
|
||||
foreach (var infoItem in infoItems)
|
||||
{
|
||||
var newItem = FindByGuid(infoItem.objectGUID);
|
||||
if (newItem == null)
|
||||
{
|
||||
newItem = new AkWwiseTreeViewItem(infoItem, GenerateUniqueID(), parent.depth + 1);
|
||||
Data.Add(newItem);
|
||||
parent.AddWwiseItemChild(newItem);
|
||||
}
|
||||
|
||||
if (!CheckIfFullyLoaded(parent))
|
||||
{
|
||||
System.Guid guid = new System.Guid(parent.objectGuid.ToString());
|
||||
AkWaapiUtilities.GetResultListDelegate<WwiseObjectInfoJsonObject> callback = (List<WwiseObjectInfoJsonObject> items) =>
|
||||
{
|
||||
UpdateParentWithLoadedChildren(guid, AkWaapiUtilities.ParseObjectInfo(items));
|
||||
};
|
||||
AkWaapiUtilities.GetChildren(parent.objectGuid, waapiWwiseObjectOptions, callback);
|
||||
}
|
||||
parent = newItem;
|
||||
}
|
||||
|
||||
if (selectAfterCreated)
|
||||
{
|
||||
treeviewCommandQueue.Enqueue(new TreeViewCommand(() => Expand(parent.objectGuid, true)));
|
||||
}
|
||||
}
|
||||
|
||||
public void AddItemWithAncestorsToSearch(List<WwiseObjectInfo> infoItems)
|
||||
{
|
||||
AddItemWithAncestors(infoItems, false);
|
||||
var item = FindByGuid(infoItems.Last().objectGUID);
|
||||
AddItemToSearch(item);
|
||||
}
|
||||
|
||||
public void AddItems(List<WwiseObjectInfo> infoItems)
|
||||
{
|
||||
foreach (var infoItem in infoItems)
|
||||
{
|
||||
if (infoItem.type == WwiseObjectType.None)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var tParent = FindByGuid(infoItem.parentID);
|
||||
if (tParent == null || tParent == ProjectRoot)
|
||||
{
|
||||
tParent = ProjectRoot;
|
||||
}
|
||||
|
||||
var tChild = FindByGuid(infoItem.objectGUID);
|
||||
if (tChild == null)
|
||||
{
|
||||
tChild = new AkWwiseTreeViewItem(infoItem, GenerateUniqueID(), tParent.depth + 1);
|
||||
Data.Add(tChild);
|
||||
tParent.AddWwiseItemChild(tChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddBaseFolder(List<WwiseObjectInfo> infoItems, WwiseObjectType oType)
|
||||
{
|
||||
if (infoItems != null && infoItems.Count > 0)
|
||||
{
|
||||
AddItems(infoItems);
|
||||
var folder = FindByGuid(infoItems[0].objectGUID);
|
||||
wwiseObjectFolders[oType] = folder;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateParentWithLoadedChildren(System.Guid parentGuid, List<WwiseObjectInfo> children)
|
||||
{
|
||||
if (children == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var parent = FindByGuid(parentGuid);
|
||||
if (parent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
parent.children.Remove(null);
|
||||
|
||||
parent.numChildren = children.Count;
|
||||
if (parent.children.Count > children.Count)
|
||||
{
|
||||
parent.children.Clear();
|
||||
}
|
||||
|
||||
foreach (var child in children)
|
||||
{
|
||||
if (parent.children.Any(c => ((AkWwiseTreeViewItem)c).objectGuid == child.objectGUID))
|
||||
continue;
|
||||
else
|
||||
parent.AddWwiseItemChild(new AkWwiseTreeViewItem(child, GenerateUniqueID(), parent.depth + 1));
|
||||
}
|
||||
}
|
||||
|
||||
public void SetChildren(System.Guid parentGuid, List<WwiseObjectInfo> children)
|
||||
{
|
||||
if (children == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var parent = FindByGuid(parentGuid);
|
||||
parent.children.Clear();
|
||||
parent.children.Remove(null);
|
||||
|
||||
parent.numChildren = children.Count;
|
||||
|
||||
foreach (var child in children)
|
||||
{
|
||||
parent.AddWwiseItemChild(new AkWwiseTreeViewItem(child, GenerateUniqueID(), parent.depth + 1));
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckIfFullyLoaded(AkWwiseTreeViewItem item)
|
||||
{
|
||||
if (item == ProjectRoot)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (item.objectType == WwiseObjectType.Event)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (item.numChildren != item.children.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (item.children.Contains(null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ReadOnlyDictionary<WwiseObjectType, string> FolderNames = new ReadOnlyDictionary<WwiseObjectType, string>(new Dictionary<WwiseObjectType, string>()
|
||||
{
|
||||
{ WwiseObjectType.AuxBus , @"\Master-Mixer Hierarchy" },
|
||||
{ WwiseObjectType.Event , @"\Events" },
|
||||
{ WwiseObjectType.State, @"\States"},
|
||||
{ WwiseObjectType.StateGroup, @"\States"},
|
||||
{ WwiseObjectType.Soundbank, @"\SoundBanks"},
|
||||
{ WwiseObjectType.Switch, @"\Switches"},
|
||||
{ WwiseObjectType.SwitchGroup, @"\Switches"},
|
||||
{ WwiseObjectType.AcousticTexture, @"\Virtual Acoustics" },
|
||||
{ WwiseObjectType.Trigger, @"\Triggers" },
|
||||
{ WwiseObjectType.GameParameter, @"\Game Parameters" },
|
||||
});
|
||||
|
||||
|
||||
static List<AkWaapiUtilities.SubscriptionInfo> subscriptions = new List<AkWaapiUtilities.SubscriptionInfo>();
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes to nameChanged, childAdded, childRemoved, and selectionChanged WAAPI events in order to keep the picker in sync with the Wwise project explorer.
|
||||
/// </summary>
|
||||
public void SubscribeTopics()
|
||||
{
|
||||
AkWaapiUtilities.Subscribe(ak.wwise.core.@object.nameChanged, OnWaapiRenamed, SubscriptionHandshake);
|
||||
AkWaapiUtilities.Subscribe(ak.wwise.core.@object.childAdded, OnWaapiChildAdded, SubscriptionHandshake);
|
||||
AkWaapiUtilities.Subscribe(ak.wwise.core.@object.childRemoved, OnWaapiChildRemoved, SubscriptionHandshake);
|
||||
AkWaapiUtilities.Subscribe(ak.wwise.ui.selectionChanged, OnWwiseSelectionChanged, SubscriptionHandshake);
|
||||
}
|
||||
|
||||
public void SubscriptionHandshake(AkWaapiUtilities.SubscriptionInfo sub)
|
||||
{
|
||||
subscriptions.Add(sub);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes from currently active subscriptions.
|
||||
/// </summary>
|
||||
void UnsubscribeTopics()
|
||||
{
|
||||
var tSubs = subscriptions;
|
||||
foreach (var sub in tSubs)
|
||||
{
|
||||
if (sub.SubscriptionId != 0)
|
||||
{
|
||||
AkWaapiUtilities.Unsubscribe(sub.SubscriptionId);
|
||||
}
|
||||
}
|
||||
subscriptions.Clear();
|
||||
}
|
||||
|
||||
void OnWaapiRenamed(string json)
|
||||
{
|
||||
var renamedItem = AkWaapiUtilities.ParseRenameObject(json);
|
||||
treeviewCommandQueue.Enqueue(new TreeViewCommand(() => Rename(renamedItem.objectInfo.objectGUID, renamedItem.newName)));
|
||||
}
|
||||
|
||||
void OnWaapiChildAdded(string json)
|
||||
{
|
||||
var added = AkWaapiUtilities.ParseChildAddedOrRemoved(json);
|
||||
|
||||
if (added.childInfo.type == WwiseObjectType.None)
|
||||
return;
|
||||
|
||||
var parent = FindByGuid(added.parentInfo.objectGUID);
|
||||
|
||||
// New object created, but parent is not loaded yet, so we can ignore it
|
||||
if (parent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var child = FindByGuid(added.childInfo.objectGUID);
|
||||
if (child == null)
|
||||
{
|
||||
child = new AkWwiseTreeViewItem(added.childInfo, GenerateUniqueID(), parent.depth + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
child.numChildren = added.childInfo.childrenCount;
|
||||
child.displayName = added.childInfo.name;
|
||||
}
|
||||
|
||||
parent.AddWwiseItemChild(child);
|
||||
Data.Add(child);
|
||||
parent.numChildren = added.parentInfo.childrenCount;
|
||||
child.depth = parent.depth + 1;
|
||||
|
||||
if (!CheckIfFullyLoaded(parent))
|
||||
{
|
||||
AkWaapiUtilities.GetResultListDelegate<WwiseObjectInfoJsonObject> callback = (List<WwiseObjectInfoJsonObject> items) =>
|
||||
{
|
||||
UpdateParentWithLoadedChildren(parent.objectGuid, AkWaapiUtilities.ParseObjectInfo(items));
|
||||
};
|
||||
AkWaapiUtilities.GetChildren(parent.objectGuid, waapiWwiseObjectOptions, callback);
|
||||
}
|
||||
|
||||
if (!CheckIfFullyLoaded(child))
|
||||
{
|
||||
AkWaapiUtilities.GetResultListDelegate<WwiseObjectInfoJsonObject> callback = (List<WwiseObjectInfoJsonObject> items) =>
|
||||
{
|
||||
UpdateParentWithLoadedChildren(child.objectGuid, AkWaapiUtilities.ParseObjectInfo(items));
|
||||
};
|
||||
AkWaapiUtilities.GetChildren(child.objectGuid, waapiWwiseObjectOptions, callback);
|
||||
}
|
||||
ScheduleRebuild();
|
||||
}
|
||||
|
||||
void OnWaapiChildRemoved(string json)
|
||||
{
|
||||
var removed = AkWaapiUtilities.ParseChildAddedOrRemoved(json);
|
||||
toRequeue.Enqueue(new TreeViewCommand(() => Remove(removed.parentInfo, removed.childInfo)));
|
||||
}
|
||||
|
||||
void OnWwiseSelectionChanged(string json)
|
||||
{
|
||||
if (AutoSyncSelection)
|
||||
{
|
||||
var objects = AkWaapiUtilities.ParseSelectedObjects(json);
|
||||
if (objects.Count > 0)
|
||||
{
|
||||
if (FilterPath(objects[0].path))
|
||||
{
|
||||
treeviewCommandQueue.Enqueue(new TreeViewCommand(() => SelectItem(objects[0].objectGUID)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Rename(System.Guid objectGuid, string newName)
|
||||
{
|
||||
var item = FindByGuid(objectGuid);
|
||||
if (item != null)
|
||||
{
|
||||
item.name = newName;
|
||||
}
|
||||
else
|
||||
{
|
||||
toRequeue.Enqueue(new TreeViewCommand(() => Rename(objectGuid, newName)));
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove(WwiseObjectInfo parentInfo, WwiseObjectInfo childInfo)
|
||||
{
|
||||
var parent = FindByGuid(parentInfo.objectGUID);
|
||||
|
||||
//Object removed, but it was never loaded so we can ignore it
|
||||
if (parent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
parent.numChildren = parentInfo.childrenCount;
|
||||
var index = parent.children.FindIndex(el => ((AkWwiseTreeViewItem)el).objectGuid == childInfo.objectGUID);
|
||||
if (index != -1)
|
||||
{
|
||||
parent.children.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
public void Expand(System.Guid objectGuid, bool select)
|
||||
{
|
||||
if (TreeView == null || !TreeView.ExpandItem(objectGuid, select))
|
||||
{
|
||||
toRequeue.Enqueue(new TreeViewCommand(() => Expand(objectGuid, select)));
|
||||
}
|
||||
}
|
||||
|
||||
public override void SelectItem(System.Guid itemGuid)
|
||||
{
|
||||
if (TreeView == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (TreeView.m_storedSearchString != string.Empty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TreeView.ExpandItem(itemGuid, true))
|
||||
{
|
||||
var item = FindByGuid(itemGuid);
|
||||
treeviewCommandQueue.Enqueue(new TreeViewCommand(() => Expand(itemGuid, true)));
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
AkWaapiUtilities.GetResultListDelegate<WwiseObjectInfoJsonObject> callback = (List<WwiseObjectInfoJsonObject> items) =>
|
||||
{
|
||||
AddItemWithAncestors(AkWaapiUtilities.ParseObjectInfo(items));
|
||||
};
|
||||
AkWaapiUtilities.GetWwiseObjectAndAncestors(itemGuid, waapiWwiseObjectOptions, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool FilterPath(string path)
|
||||
{
|
||||
var splitpath = path.Split('\\');
|
||||
if (splitpath.Length > 1)
|
||||
{
|
||||
var folder = @"\" + splitpath[1];
|
||||
if (FolderNames.Values.Contains(folder) || WaapiKeywords.FolderDisplaynames.Values.Contains(folder))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void ItemSelected(AkWwiseTreeViewItem item)
|
||||
{
|
||||
if (AutoSyncSelection)
|
||||
{
|
||||
SelectObjectInAuthoring(item.objectGuid);
|
||||
}
|
||||
}
|
||||
|
||||
private System.Guid guidToSelect;
|
||||
public override void SelectObjectInAuthoring(System.Guid objectGuid)
|
||||
{
|
||||
selectTimer.Stop();
|
||||
guidToSelect = objectGuid;
|
||||
selectTimer.Enabled = true;
|
||||
selectTimer.Start();
|
||||
}
|
||||
|
||||
private void FireSelect(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
AkWaapiUtilities.SelectObjectInAuthoring(guidToSelect);
|
||||
}
|
||||
|
||||
//Make a single command queue
|
||||
private ConcurrentQueue<TreeViewCommand> treeviewCommandQueue = new ConcurrentQueue<TreeViewCommand>();
|
||||
private Queue<TreeViewCommand> toRequeue = new Queue<TreeViewCommand>();
|
||||
|
||||
public class TreeViewCommand
|
||||
{
|
||||
public System.Action payload;
|
||||
|
||||
public TreeViewCommand(System.Action payload)
|
||||
{
|
||||
this.payload = payload;
|
||||
}
|
||||
public void Execute()
|
||||
{
|
||||
payload.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public override void ScheduleRebuild()
|
||||
{
|
||||
rebuildFlag = true;
|
||||
}
|
||||
|
||||
private bool rebuildFlag = false;
|
||||
private bool refreshFlag = false;
|
||||
|
||||
public void Update()
|
||||
{
|
||||
while (treeviewCommandQueue.Count > 0)
|
||||
{
|
||||
if (treeviewCommandQueue.TryDequeue(out TreeViewCommand cmd))
|
||||
{
|
||||
cmd.Execute();
|
||||
refreshFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
while (toRequeue.Count > 0)
|
||||
{
|
||||
treeviewCommandQueue.Enqueue(toRequeue.Dequeue());
|
||||
}
|
||||
|
||||
//Preemptively load items in hierarchy that are close to being exposed ( up to grandchildren of unexpanded items)
|
||||
if (rebuildFlag)
|
||||
{
|
||||
TreeUtility.TreeToList(ProjectRoot, ref Data);
|
||||
if (TreeView != null)
|
||||
{
|
||||
Preload(ProjectRoot, TreeView.state);
|
||||
}
|
||||
refreshFlag = true;
|
||||
rebuildFlag = false;
|
||||
}
|
||||
|
||||
|
||||
//Updates treeView data and sets repaint flag
|
||||
if (refreshFlag)
|
||||
{
|
||||
Changed();
|
||||
refreshFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Preload(AkWwiseTreeViewItem parent, TreeViewState treeState)
|
||||
{
|
||||
if (parent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CheckIfFullyLoaded(parent))
|
||||
{
|
||||
AkWaapiUtilities.GetResultListDelegate<WwiseObjectInfoJsonObject> callback = (List<WwiseObjectInfoJsonObject> items) =>
|
||||
{
|
||||
UpdateParentWithLoadedChildren(parent.objectGuid, AkWaapiUtilities.ParseObjectInfo(items));
|
||||
};
|
||||
AkWaapiUtilities.GetChildren(parent.objectGuid, waapiWwiseObjectOptions, callback);
|
||||
}
|
||||
|
||||
//Preload one level of hidden items.
|
||||
if (IsExpanded(treeState, parent.id) || (parent.parent != null && IsExpanded(treeState, parent.parent.id)) ||
|
||||
parent.id == ProjectRoot.id )
|
||||
{
|
||||
foreach (AkWwiseTreeViewItem childItem in parent.children)
|
||||
{
|
||||
|
||||
Preload(childItem, treeState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetExpanded(IEnumerable<System.Guid> ids)
|
||||
{
|
||||
if (TreeView != null)
|
||||
{
|
||||
foreach (var id in ids)
|
||||
{
|
||||
treeviewCommandQueue.Enqueue(new TreeViewCommand(() => Expand(id, false)));
|
||||
}
|
||||
TreeView.state.expandedIDs.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void Connect()
|
||||
{
|
||||
AkWaapiUtilities.Connected += OnConnection;
|
||||
AkWaapiUtilities.QueueConsumed += ScheduleRebuild;
|
||||
AkWaapiUtilities.Disconnecting += Disconnect;
|
||||
}
|
||||
|
||||
public void OnConnection()
|
||||
{
|
||||
SubscribeTopics();
|
||||
FetchData();
|
||||
}
|
||||
|
||||
public void Disconnect(bool still_connected)
|
||||
{
|
||||
this.treeviewCommandQueue = new ConcurrentQueue<TreeViewCommand>();
|
||||
if (ProjectRoot != null)
|
||||
ProjectRoot.children = new List<TreeViewItem>();
|
||||
if (still_connected)
|
||||
{
|
||||
UnsubscribeTopics();
|
||||
}
|
||||
else
|
||||
{
|
||||
subscriptions.Clear();
|
||||
}
|
||||
Changed();
|
||||
}
|
||||
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
subscriptions.Clear();
|
||||
}
|
||||
|
||||
|
||||
~AkWwiseTreeWAAPIDataSource()
|
||||
{
|
||||
Disconnect(true);
|
||||
}
|
||||
|
||||
public override void SaveExpansionStatus(List<int> expandedItems)
|
||||
{
|
||||
AkWwiseProjectInfo.GetData().ExpandedWaapiItemIds = expandedItems;
|
||||
}
|
||||
|
||||
public override List<int> LoadExpansionSatus()
|
||||
{
|
||||
return AkWwiseProjectInfo.GetData().ExpandedWaapiItemIds;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user