Feat : Wwise Integration
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "Ak.Wwise.Api.WAAPI",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"AK.Wwise.Unity.API.WwiseTypes",
|
||||
"AK.Wwise.Unity.API",
|
||||
"AK.Wwise.Unity.Utilities",
|
||||
"AK.Wwise.Unity.Logging"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [
|
||||
"Lumin",
|
||||
"Stadia"
|
||||
],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [
|
||||
"!UNITY_SERVER"
|
||||
],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb0dcd37a0eb0aa4bbeb9c8d634123b2
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,136 @@
|
||||
/*******************************************************************************
|
||||
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) 2026 Audiokinetic Inc.
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The Waapi Client provides a core interface to Waapi using strings only. You will need to provide your own JSON serialization.
|
||||
/// </summary>
|
||||
internal class AkWaapiClient
|
||||
{
|
||||
public Wamp wamp;
|
||||
|
||||
public event Wamp.DisconnectedHandler Disconnected;
|
||||
|
||||
/// <summary>Connect to a running instance of Wwise Authoring.</summary>
|
||||
/// <param name="uri">URI to connect. Usually the WebSocket protocol (ws:) followed by the hostname and port, followed by waapi.</param>
|
||||
/// <example>Connect("ws://localhost:8080/waapi")</example>
|
||||
/// <param name="timeout">The maximum timeout in milliseconds for the function to execute. Will raise Waapi.TimeoutException when timeout is reached.</param>
|
||||
public async System.Threading.Tasks.Task Connect(
|
||||
string uri = "ws://localhost:8080/waapi",
|
||||
int timeout = System.Int32.MaxValue)
|
||||
{
|
||||
if (wamp == null)
|
||||
wamp = new Wamp();
|
||||
wamp.Disconnected += Wamp_Disconnected;
|
||||
await wamp.Connect(uri, timeout);
|
||||
}
|
||||
|
||||
public void CancelConnectionAttempt()
|
||||
{
|
||||
wamp.CancelCurrentConnection();
|
||||
}
|
||||
|
||||
private void Wamp_Disconnected()
|
||||
{
|
||||
if (Disconnected != null)
|
||||
{
|
||||
Disconnected();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Close the connection.</summary>
|
||||
/// <param name="timeout">The maximum timeout in milliseconds for the function to execute. Will raise Waapi.TimeoutException when timeout is reached.</param>
|
||||
public async System.Threading.Tasks.Task Close(
|
||||
int timeout = System.Int32.MaxValue)
|
||||
{
|
||||
if (wamp == null)
|
||||
throw new Wamp.WampNotConnectedException("WAMP connection is not established");
|
||||
|
||||
await wamp.Close(timeout);
|
||||
|
||||
wamp.Disconnected -= Wamp_Disconnected;
|
||||
wamp = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return true if the client is connected and ready for operations.
|
||||
/// </summary>
|
||||
public bool IsConnected()
|
||||
{
|
||||
if (wamp == null)
|
||||
return false;
|
||||
|
||||
return wamp.IsConnected();
|
||||
}
|
||||
|
||||
/// <summary>Call a WAAPI remote procedure. Refer to WAAPI reference documentation for a list of URIs and their arguments and options.</summary>
|
||||
/// <param name="uri">The URI of the remote procedure.</param>
|
||||
/// <param name="args">The arguments of the remote procedure.</param>
|
||||
/// <param name="options">The options the remote procedure.</param>
|
||||
/// <param name="timeout">The maximum timeout in milliseconds for the function to execute. Will raise Waapi.TimeoutException when timeout is reached.</param>
|
||||
/// <returns>A JSON string with the result of the Remote Procedure Call.</returns>
|
||||
public async System.Threading.Tasks.Task<string> Call(
|
||||
string uri,
|
||||
string args = "{}",
|
||||
string options = "{}",
|
||||
int timeout = System.Int32.MaxValue)
|
||||
{
|
||||
if (wamp == null)
|
||||
throw new Wamp.WampNotConnectedException("WAMP connection is not established");
|
||||
|
||||
if (args == null)
|
||||
args = "{}";
|
||||
if (options == null)
|
||||
options = "{}";
|
||||
|
||||
return await wamp.Call(uri, args, options, timeout);
|
||||
}
|
||||
|
||||
/// <summary>Subscribe to WAAPI topic. Refer to WAAPI reference documentation for a list of topics and their options.</summary>
|
||||
/// <param name="topic">The topic to which subscribe.</param>
|
||||
/// <param name="options">The options the subscription.</param>
|
||||
/// <param name="publishHandler/// ">The delegate function to call when the topic is published.</param>
|
||||
/// <param name="timeout">The maximum timeout in milliseconds for the function to execute. Will raise Waapi.TimeoutException when timeout is reached.</param>
|
||||
/// <returns>Subscription id, that you can use to unsubscribe.</returns>
|
||||
public async System.Threading.Tasks.Task<uint> Subscribe(
|
||||
string topic,
|
||||
string options,
|
||||
Wamp.PublishHandler publishHandler,
|
||||
int timeout = System.Int32.MaxValue)
|
||||
{
|
||||
if (wamp == null)
|
||||
throw new Wamp.WampNotConnectedException("WAMP connection is not established");
|
||||
|
||||
if (options == null)
|
||||
options = "{}";
|
||||
|
||||
return await wamp.Subscribe(topic, options, publishHandler, timeout);
|
||||
}
|
||||
|
||||
/// <summary>Unsubscribe from a subscription.</summary>
|
||||
/// <param name="subscriptionId">The subscription id received from the initial subscription.</param>
|
||||
/// <param name="timeout">The maximum timeout in milliseconds for the function to execute. Will raise Waapi.TimeoutException when timeout is reached.</param>
|
||||
public async System.Threading.Tasks.Task Unsubscribe(
|
||||
uint subscriptionId,
|
||||
int timeout = System.Int32.MaxValue)
|
||||
{
|
||||
if (wamp == null)
|
||||
throw new Wamp.WampNotConnectedException("WAMP connection is not established");
|
||||
|
||||
await wamp.Unsubscribe(subscriptionId, timeout);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c99a7e15178a14418317de1b1951076
|
||||
@@ -0,0 +1,590 @@
|
||||
/*******************************************************************************
|
||||
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) 2026 Audiokinetic Inc.
|
||||
*******************************************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for Json serializable objects.
|
||||
/// Implements implicit cast to string using UnityEngine.JsonUtility.ToJson.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class JsonSerializable
|
||||
{
|
||||
public static implicit operator string(JsonSerializable o) => UnityEngine.JsonUtility.ToJson(o);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Abstract base class for WAAPI command arguments.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public abstract class Args : JsonSerializable
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WAAPI arguments containing a WAQL string.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class WaqlArgs : Args
|
||||
{
|
||||
public string waql;
|
||||
public WaqlArgs(string query)
|
||||
{
|
||||
waql = query;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WAAPI arguments containing an object identfier.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class ArgsObject : Args
|
||||
{
|
||||
public string @object;
|
||||
|
||||
public ArgsObject(string objectId)
|
||||
{
|
||||
@object = objectId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// WAAPI arguments containing an object identfier and new value used when renaming an object.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class ArgsRename : Args
|
||||
{
|
||||
public string @object;
|
||||
public string value;
|
||||
|
||||
public ArgsRename(string objectId, string value)
|
||||
{
|
||||
@object = objectId;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WAAPI arguments containing an object identfier and name used when deleting an object.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class ArgsDisplayName : Args
|
||||
{
|
||||
public string displayName;
|
||||
|
||||
public ArgsDisplayName(string displayName)
|
||||
{
|
||||
this.displayName = displayName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WAAPI arguments containing an object identfier and command field.
|
||||
/// Used by AkWaapiUtilities.SelectObjectInAuthoringAsync().
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class ArgsCommand : Args
|
||||
{
|
||||
public string[] @objects;
|
||||
public string command;
|
||||
public ArgsCommand(string c, string[] objectIds)
|
||||
{
|
||||
command = c;
|
||||
objects = objectIds;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WAAPI arguments containing an Event identfier and transport ID.
|
||||
/// Used to toggle Event playback.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class ArgsPlay : Args
|
||||
{
|
||||
public string action;
|
||||
public int transport;
|
||||
public ArgsPlay(string a, int t) { action = a; transport = t; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WAAPI arguments containing a transport ID.
|
||||
/// Used to specify transports in transport-specific commands.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class ArgsTransport : Args
|
||||
{
|
||||
public int transport;
|
||||
public ArgsTransport(int t) { transport = t; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Abstract base class for WAAPI command options.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class Options : JsonSerializable
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WAAPI options to specify the names of fields to return in a WAAPI request returning WwiseObjects.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class ReturnOptions : Options
|
||||
{
|
||||
public string[] @return;
|
||||
|
||||
public ReturnOptions(string [] infokeys)
|
||||
{
|
||||
@return = infokeys;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WAAPI options used to specify the transport ID when subscribing.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class TransportOptions : Options
|
||||
{
|
||||
public int transport;
|
||||
public TransportOptions(int id)
|
||||
{
|
||||
transport = id;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to deserialize the response from an ak.wwise.core.transport.create command.
|
||||
/// Contains the transport ID.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class ReturnTransport : JsonSerializable
|
||||
{
|
||||
public int transport;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to deserialize transport-state information receieved from the transport.stateChanged topic.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class TransportState : JsonSerializable
|
||||
{
|
||||
public string gameObject;
|
||||
public string state;
|
||||
public string @object;
|
||||
public int transport;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to deserialize WAAPI error messages.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class ErrorMessage : JsonSerializable
|
||||
{
|
||||
public string message;
|
||||
public ErrorDetails details;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to deserialize details in WAAPI error messages.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class ErrorDetails : JsonSerializable
|
||||
{
|
||||
public string [] reasons;
|
||||
public string procedureUri;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class used to deserialize a WAAPI response containing Wwise objects.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class ReturnWwiseObjects : JsonSerializable
|
||||
{
|
||||
public List<WwiseObjectInfoJsonObject> @return;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class PingWwiseObject : JsonSerializable
|
||||
{
|
||||
public bool isAvailable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generic class to deserialize a WAAPI response containing Wwise objects with custom return options.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class ReturnWwiseObjects<T> : JsonSerializable
|
||||
{
|
||||
public List<T> @return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class used to deserialize selected Wwise objects published on the ak.wwise.ui.selectionChanged topic.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class SelectedWwiseObjects : JsonSerializable
|
||||
{
|
||||
public List<WwiseObjectInfoJsonObject> objects;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to deserialize information published on the ak.wwise.core.@object.nameChanged topic.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class WwiseRenameInfo : JsonSerializable
|
||||
{
|
||||
public WwiseObjectInfoJsonObject @object;
|
||||
public string newName;
|
||||
public string oldName;
|
||||
|
||||
public WwiseObjectInfo objectInfo;
|
||||
public void ParseInfo()
|
||||
{
|
||||
objectInfo = @object;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Used to deserialize information published on the ak.wwise.core.@object.childAdded and ak.wwise.core.@object.childRemoved topics.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class WwiseChildModifiedInfo : JsonSerializable
|
||||
{
|
||||
public WwiseObjectInfoJsonObject parent;
|
||||
public WwiseObjectInfoJsonObject child;
|
||||
|
||||
public WwiseObjectInfo parentInfo;
|
||||
public WwiseObjectInfo childInfo;
|
||||
|
||||
public void ParseInfo()
|
||||
{
|
||||
parentInfo = parent;
|
||||
childInfo = child;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to deserialize information from a request for a Wwise object.
|
||||
/// Implements an implicit cast to WwiseObjectInfo.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class WwiseObjectInfoJsonObject : System.IComparable
|
||||
{
|
||||
public string id;
|
||||
public WwiseObjectInfoParent parent;
|
||||
public string name;
|
||||
public string type;
|
||||
public int childrenCount;
|
||||
public string path;
|
||||
public string filePath;
|
||||
public string workunitType;
|
||||
public string soundbankBnkFilePath;
|
||||
|
||||
public static implicit operator WwiseObjectInfo(WwiseObjectInfoJsonObject info)
|
||||
{
|
||||
return ToObjectInfo(info);
|
||||
}
|
||||
|
||||
public static WwiseObjectInfo ToObjectInfo(WwiseObjectInfoJsonObject info)
|
||||
{
|
||||
var type = info.type == null ? "" : info.type;
|
||||
var wutype = info.workunitType == null ? "" : info.workunitType;
|
||||
var objectType = WaapiHelper.GetWwiseObjectTypeFromString(type.ToLower(), wutype.ToLower());
|
||||
var parentID = info.parent.id == null ? System.Guid.Empty : System.Guid.Parse(info.parent.id);
|
||||
var objectGuid = info.id == null ? System.Guid.Empty : System.Guid.Parse(info.id);
|
||||
|
||||
return new WwiseObjectInfo
|
||||
{
|
||||
objectGUID = objectGuid,
|
||||
name = info.name,
|
||||
type = objectType,
|
||||
childrenCount = info.childrenCount,
|
||||
path = info.path,
|
||||
workUnitType = wutype,
|
||||
parentID = parentID,
|
||||
filePath = info.filePath,
|
||||
soundbankBnkFilePath = info.soundbankBnkFilePath
|
||||
};
|
||||
}
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
if (obj is WwiseObjectInfoJsonObject)
|
||||
{
|
||||
string objPath = (obj as WwiseObjectInfoJsonObject).path;
|
||||
if (objPath.Contains(path))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (path.Contains(objPath))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return path.Length < objPath.Length ? -1 : 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains the GUID of the returned object's parent.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class WwiseObjectInfoParent
|
||||
{
|
||||
public string id;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Class containing the information returned by a WAAPI request for an object.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public struct WwiseObjectInfo
|
||||
{
|
||||
public System.Guid objectGUID;
|
||||
public System.Guid parentID;
|
||||
public string name;
|
||||
public WwiseObjectType type;
|
||||
public int childrenCount;
|
||||
public string path;
|
||||
public string workUnitType;
|
||||
public string filePath;
|
||||
public string soundbankBnkFilePath;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct WwiseStructureChangeParentChange
|
||||
{
|
||||
public WwiseObjectInfoJsonObject newParent;
|
||||
public WwiseObjectInfoJsonObject oldParent;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct WwiseStructureChangeNameChange
|
||||
{
|
||||
public string newName;
|
||||
public string oldName;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct WwiseStructureChangeChange
|
||||
{
|
||||
public string type;
|
||||
public WwiseStructureChangeNameChange nameChange;
|
||||
public WwiseStructureChangeParentChange parentChange;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct WwiseStructureChanged
|
||||
{
|
||||
public WwiseObjectInfoJsonObject @object;
|
||||
public List<WwiseStructureChangeChange> changes;
|
||||
|
||||
void ParseInfo()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct WwiseStructureObjects
|
||||
{
|
||||
public List<WwiseStructureChanged>objects;
|
||||
|
||||
void ParseInfo()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains a helper function GetWwiseObjectTypeFromString.
|
||||
/// </summary>
|
||||
public static class WaapiHelper
|
||||
{
|
||||
public static WwiseObjectType GetWwiseObjectTypeFromString(string typeString, string workUnitType)
|
||||
{
|
||||
if (!WaapiKeywords.typeStringDict.ContainsKey(typeString))
|
||||
return WwiseObjectType.None;
|
||||
|
||||
if (workUnitType != string.Empty)
|
||||
{
|
||||
if (workUnitType == "folder")
|
||||
{
|
||||
return WaapiKeywords.typeStringDict["physicalfolder"];
|
||||
}
|
||||
|
||||
return WaapiKeywords.typeStringDict[typeString];
|
||||
}
|
||||
return WaapiKeywords.typeStringDict[typeString];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains fields for specific WAAPI keywords.
|
||||
/// </summary>
|
||||
public class WaapiKeywords
|
||||
{
|
||||
public const string ACTION = "action";
|
||||
public const string ANCESTORS = "ancestors";
|
||||
public const string AT = "@";
|
||||
public const string AUX_BUSSES = "auxBusses";
|
||||
public const string BACK_SLASH = "\\";
|
||||
public const string BANK_DATA = "bankData";
|
||||
public const string BANK_INFO = "bankInfo";
|
||||
public const string CHILD = "child";
|
||||
public const string CHILDREN = "children";
|
||||
public const string CHILDREN_COUNT = "childrenCount";
|
||||
public const string CLASSID = "classId";
|
||||
public const string COMMAND = "command";
|
||||
public const string DATA = "data";
|
||||
public const string DELETE_ITEMS = "Delete Items";
|
||||
public const string DESCENDANTS = "descendants";
|
||||
public const string DISPLAY_NAME = "displayName";
|
||||
public const string DRAG_DROP_ITEMS = "Drag Drop Items";
|
||||
public const string EVENT = "event";
|
||||
public const string EVENTS = "events";
|
||||
public const string FILEPATH = "filePath";
|
||||
public const string FIND_IN_PROJECT_EXPLORER = "FindInProjectExplorerSyncGroup1";
|
||||
public const string FOLDER = "Folder";
|
||||
public const string FROM = "from";
|
||||
public const string ID = "id";
|
||||
public const string INCLUSIONS = "inclusions";
|
||||
public const string INFO_FILE = "infoFile";
|
||||
public const string IS_CONNECTED = "isConnected";
|
||||
public const string LANGUAGE = "language";
|
||||
public const string LANGUAGES = "languages";
|
||||
public const string MAX = "max";
|
||||
public const string MAX_RADIUS_ATTENUATION = "audioSource:maxRadiusAttenuation";
|
||||
public const string MESSSAGE = "message";
|
||||
public const string MIN = "min";
|
||||
public const string NAME = "name";
|
||||
public const string NAMECONTAINS = "name:contains";
|
||||
public const string NEW = "new";
|
||||
public const string NEW_NAME = "newName";
|
||||
public const string NOTES = "notes";
|
||||
public const string OBJECT = "object";
|
||||
public const string OBJECTS = "objects";
|
||||
public const string OF_TYPE = "ofType";
|
||||
public const string OLD_NAME = "oldName";
|
||||
public const string PARENT = "parent";
|
||||
public const string PATH = "path";
|
||||
public const string PHYSICAL_FOLDER = "PhysicalFolder";
|
||||
public const string PLATFORM = "platform";
|
||||
public const string PLATFORMS = "platforms";
|
||||
public const string PLAY = "play";
|
||||
public const string PLAYING = "playing";
|
||||
public const string PLAYSTOP = "playStop";
|
||||
public const string PLUGININFO_OPTIONS = "pluginInfo";
|
||||
public const string PLUGININFO_RESPONSE = "PluginInfo";
|
||||
public const string PROJECT = "Project";
|
||||
public const string PROPERTY = "property";
|
||||
public const string RADIUS = "radius";
|
||||
public const string RANGE = "range";
|
||||
public const string REBUILD = "rebuild";
|
||||
public const string REBUILDINITBANK = "rebuildInitBank";
|
||||
public const string REDO = "Redo";
|
||||
public const string RESTRICTION = "restriction";
|
||||
public const string RETURN = "return";
|
||||
public const string SEARCH = "search";
|
||||
public const string SELECT = "select";
|
||||
public const string SIZE = "size";
|
||||
public const string SKIP_LANGUAGES = "skipLanguages";
|
||||
public const string SOUNDBANK = "soundbank";
|
||||
public const string SOUNDBANKS = "soundbanks";
|
||||
public const string STATE = "state";
|
||||
public const string STOP = "stop";
|
||||
public const string STOPPED = "stopped";
|
||||
public const string STRUCTURE = "structure";
|
||||
public const string TRANSFORM = "transform";
|
||||
public const string TRANSPORT = "transport";
|
||||
public const string TYPE = "type";
|
||||
public const string UI = "ui";
|
||||
public const string UNDO = "Undo";
|
||||
public const string VALUE = "value";
|
||||
public const string VOLUME = "Volume";
|
||||
public const string WHERE = "where";
|
||||
public const string WORKUNIT_TYPE = "workunit:type";
|
||||
public const string WRITETODISK = "writeToDisk";
|
||||
public const string OPEN_SOUNDBANK_FOLDER = "OpenContainingFolderSoundbank";
|
||||
public const string OPEN_WORKUNIT_FOLDER = "OpenContainingFolderWorkUnit";
|
||||
public const string OPEN_WAV_FOLDER = "OpenContainingFolderWAV";
|
||||
|
||||
/// <summary>
|
||||
/// Maps WwiseObjectType to strings.
|
||||
/// </summary>
|
||||
public static ReadOnlyDictionary<WwiseObjectType, string> WwiseObjectTypeStrings = new ReadOnlyDictionary<WwiseObjectType, string>(new Dictionary<WwiseObjectType, string>()
|
||||
{
|
||||
{WwiseObjectType.None, "None"},
|
||||
{WwiseObjectType.AuxBus, "AuxiliaryBus"},
|
||||
{WwiseObjectType.Bus, "Bus"},
|
||||
{WwiseObjectType.Event, "Event"},
|
||||
{WwiseObjectType.Folder, "Folder"},
|
||||
{WwiseObjectType.PhysicalFolder, "PhysicalFolder"},
|
||||
{WwiseObjectType.Project, "Project"},
|
||||
{WwiseObjectType.Soundbank, "SoundBank"},
|
||||
{WwiseObjectType.State, "State"},
|
||||
{WwiseObjectType.StateGroup, "StateGroup"},
|
||||
{WwiseObjectType.Switch, "Switch"},
|
||||
{WwiseObjectType.SwitchGroup, "SwitchGroup"},
|
||||
{WwiseObjectType.WorkUnit, "WorkUnit"},
|
||||
{WwiseObjectType.GameParameter, "Game Parametr"},
|
||||
{WwiseObjectType.Trigger, "Trigger"},
|
||||
{WwiseObjectType.AcousticTexture, "AcousticTexture"}
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Maps root folder names to displayed strings.
|
||||
/// </summary>
|
||||
public static ReadOnlyDictionary<string, string> FolderDisplaynames = new ReadOnlyDictionary<string, string>(new Dictionary<string, string>()
|
||||
{
|
||||
{"Busses", "Auxiliary Busses" },
|
||||
{ "Events", "Events"},
|
||||
{ "States", "States"},
|
||||
{ "SoundBanks", "SoundBanks"},
|
||||
{ "Switches", "Switches"},
|
||||
{ "Triggers", "Triggers"},
|
||||
{ "Virtual Acoustics", "Virtual Acoustics"},
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Maps strings to WwiseObjectType.
|
||||
/// </summary>
|
||||
public static ReadOnlyDictionary<string, WwiseObjectType> typeStringDict = new ReadOnlyDictionary<string, WwiseObjectType>(new Dictionary<string, WwiseObjectType>()
|
||||
{
|
||||
["auxbus"] = WwiseObjectType.AuxBus,
|
||||
["bus"] = WwiseObjectType.Bus,
|
||||
["event"] = WwiseObjectType.Event,
|
||||
["folder"] = WwiseObjectType.Folder,
|
||||
["physicalfolder"] = WwiseObjectType.PhysicalFolder,
|
||||
["soundbank"] = WwiseObjectType.Soundbank,
|
||||
["project"] = WwiseObjectType.Project,
|
||||
["state"] = WwiseObjectType.State,
|
||||
["stategroup"] = WwiseObjectType.StateGroup,
|
||||
["switch"] = WwiseObjectType.Switch,
|
||||
["switchgroup"] = WwiseObjectType.SwitchGroup,
|
||||
["workunit"] = WwiseObjectType.WorkUnit,
|
||||
["gameparameter"] = WwiseObjectType.GameParameter,
|
||||
["trigger"] = WwiseObjectType.Trigger,
|
||||
["acoustictexture"] = WwiseObjectType.AcousticTexture
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1824479e8e1c3f46b22c405d767ebec
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61263ded45bd05548bbc41e8cb595283
|
||||
@@ -0,0 +1,330 @@
|
||||
/*******************************************************************************
|
||||
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) 2026 Audiokinetic Inc.
|
||||
*******************************************************************************/
|
||||
|
||||
/// <summary>URI strings to use in WAAPI calls. For a complete description, refer to the official Wwise SDK documentation.</summary>
|
||||
public class ak
|
||||
{
|
||||
public class soundengine
|
||||
{
|
||||
/// <summary>Set multiple positions for a single game object. Setting multiple positions for a single game object is a way to simulate multiple emission sources while using the resources of only one voice. This can be used to simulate wall openings, area sounds, or multiple objects emitting the same sound in the same area. See <tt>AK::SoundEngine::SetMultiplePositions</tt>.</summary>
|
||||
public const string setMultiplePositions = "ak.soundengine.setMultiplePositions";
|
||||
/// <summary>Set the scaling factor of a game object. Modify the attenuation computations on this game object to simulate sounds with a larger or smaller area of effect. See <tt>AK::SoundEngine::SetScalingFactor</tt>.</summary>
|
||||
public const string setScalingFactor = "ak.soundengine.setScalingFactor";
|
||||
/// <summary>Asynchronously post an Event to the sound engine (by event ID). See <tt>AK::SoundEngine::PostEvent</tt>.</summary>
|
||||
public const string postEvent = "ak.soundengine.postEvent";
|
||||
/// <summary>Set the value of a real-time parameter control. See <tt>AK::SoundEngine::SetRTPCValue</tt>.</summary>
|
||||
public const string setRTPCValue = "ak.soundengine.setRTPCValue";
|
||||
/// <summary>Set a game object's obstruction and occlusion levels. This function is used to affect how an object should be heard by a specific listener. See <tt>AK::SoundEngine::SetObjectObstructionAndOcclusion</tt>.</summary>
|
||||
public const string setObjectObstructionAndOcclusion = "ak.soundengine.setObjectObstructionAndOcclusion";
|
||||
/// <summary>Set a single game object's active listeners. By default, all new game objects have no listeners active, but this behavior can be overridden with <tt>SetDefaultListeners()</tt>. Inactive listeners are not computed. See <tt>AK::SoundEngine::SetListeners</tt>.</summary>
|
||||
public const string setListeners = "ak.soundengine.setListeners";
|
||||
/// <summary>Execute an action on all nodes that are referenced in the specified event in an action of type play. See <tt>AK::SoundEngine::ExecuteActionOnEvent</tt>.</summary>
|
||||
public const string executeActionOnEvent = "ak.soundengine.executeActionOnEvent";
|
||||
/// <summary>Set a listener's spatialization parameters. This lets you define listener-specific volume offsets for each audio channel. See <tt>AK::SoundEngine::SetListenerSpatialization</tt>.</summary>
|
||||
public const string setListenerSpatialization = "ak.soundengine.setListenerSpatialization";
|
||||
/// <summary>Reset the value of a real-time parameter control to its default value, as specified in the Wwise project. See <tt>AK::SoundEngine::ResetRTPCValue</tt>.</summary>
|
||||
public const string resetRTPCValue = "ak.soundengine.resetRTPCValue";
|
||||
/// <summary>Unregister a game object. Registering a game object twice does nothing. Unregistering it once unregisters it no matter how many times it has been registered. Unregistering a game object while it is in use is allowed, but the control over the parameters of this game object is lost. For example, say a sound associated with this game object is a 3D moving sound. It will stop moving when the game object is unregistered, and there will be no way to regain control over the game object. See <tt>AK::SoundEngine::UnregisterGameObj</tt>.</summary>
|
||||
public const string unregisterGameObj = "ak.soundengine.unregisterGameObj";
|
||||
/// <summary>Stop the current content, associated to the specified playing ID, from playing. See <tt>AK::SoundEngine::StopPlayingID</tt>.</summary>
|
||||
public const string stopPlayingID = "ak.soundengine.stopPlayingID";
|
||||
/// <summary>Set the Auxiliary Busses to route the specified game object. See <tt>AK::SoundEngine::SetGameObjectAuxSendValues</tt>.</summary>
|
||||
public const string setGameObjectAuxSendValues = "ak.soundengine.setGameObjectAuxSendValues";
|
||||
/// <summary>Seek inside all playing objects that are referenced in Play Actions of the specified Event. See <tt>AK::SoundEngine::SeekOnEvent</tt>.</summary>
|
||||
public const string seekOnEvent = "ak.soundengine.seekOnEvent";
|
||||
/// <summary>Register a game object. Registering a game object twice does nothing. Unregistering it once unregisters it no matter how many times it has been registered. See <tt>AK::SoundEngine::RegisterGameObj</tt>.</summary>
|
||||
public const string registerGameObj = "ak.soundengine.registerGameObj";
|
||||
/// <summary>Set a the default active listeners for all subsequent game objects that are registered. See <tt>AK::SoundEngine::SetDefaultListeners</tt>.</summary>
|
||||
public const string setDefaultListeners = "ak.soundengine.setDefaultListeners";
|
||||
/// <summary>Set the position of a game object. See <tt>AK::SoundEngine::SetPosition</tt>.</summary>
|
||||
public const string setPosition = "ak.soundengine.setPosition";
|
||||
/// <summary>Display a message in the profiler's Capture Log view.</summary>
|
||||
public const string postMsgMonitor = "ak.soundengine.postMsgMonitor";
|
||||
/// <summary>Set the output bus volume (direct) to be used for the specified game object. See <tt>AK::SoundEngine::SetGameObjectOutputBusVolume</tt>.</summary>
|
||||
public const string setGameObjectOutputBusVolume = "ak.soundengine.setGameObjectOutputBusVolume";
|
||||
/// <summary>Set the State of a Switch Group. See <tt>AK::SoundEngine::SetSwitch</tt>.</summary>
|
||||
public const string setSwitch = "ak.soundengine.setSwitch";
|
||||
/// <summary>Stop playing the current content associated to the specified game object ID. If no game object is specified, all sounds will be stopped. See <tt>AK::SoundEngine::StopAll</tt>.</summary>
|
||||
public const string stopAll = "ak.soundengine.stopAll";
|
||||
/// <summary>Post the specified Trigger. See <tt>AK::SoundEngine::PostTrigger</tt>.</summary>
|
||||
public const string postTrigger = "ak.soundengine.postTrigger";
|
||||
|
||||
public class error
|
||||
{
|
||||
public const string invalid_playing_id = "ak.soundengine.invalid_playing_id";
|
||||
public const string wrong_volumeOffsets_length = "ak.soundengine.wrong_volumeOffsets_length";
|
||||
}
|
||||
}
|
||||
public class wwise
|
||||
{
|
||||
public class error
|
||||
{
|
||||
public const string invalid_arguments = "ak.wwise.invalid_arguments";
|
||||
public const string invalid_options = "ak.wwise.invalid_options";
|
||||
public const string invalid_json = "ak.wwise.invalid_json";
|
||||
public const string invalid_object = "ak.wwise.invalid_object";
|
||||
public const string invalid_property = "ak.wwise.invalid_property";
|
||||
public const string invalid_reference = "ak.wwise.invalid_reference";
|
||||
public const string invalid_query = "ak.wwise.query.invalid_query";
|
||||
public const string file_error = "ak.wwise.file_error";
|
||||
public const string unavailable = "ak.wwise.unavailable";
|
||||
public const string unexpected_error = "ak.wwise.unexpected_error";
|
||||
public const string locked = "ak.wwise.locked";
|
||||
public const string connection_failed = "ak.wwise.connection_failed";
|
||||
public const string already_connected = "ak.wwise.already_connected";
|
||||
public const string wwise_console = "ak.wwise.wwise_console";
|
||||
}
|
||||
public class debug
|
||||
{
|
||||
/// <summary>Private use only.</summary>
|
||||
public const string testAssert = "ak.wwise.debug.testAssert";
|
||||
/// <summary>Sent when an assert has failed. This is only available with Debug builds.</summary>
|
||||
public const string assertFailed = "ak.wwise.debug.assertFailed";
|
||||
/// <summary>Enable or disable the automation mode for Wwise. This reduces the potential interruptions caused by message boxes and dialogs. For instance, enabling the automation mode silently accepts: project migration, project load log, EULA acceptance, project licence display and generic message boxes.</summary>
|
||||
public const string enableAutomationMode = "ak.wwise.debug.enableAutomationMode";
|
||||
/// <summary>Enables debug assertions. Every call to enableAsserts with false increments the ref count. Calling with true will decrement the ref count. This is only available with Debug builds.</summary>
|
||||
public const string enableAsserts = "ak.wwise.debug.enableAsserts";
|
||||
}
|
||||
public class core
|
||||
{
|
||||
public class audioSourcePeaks
|
||||
{
|
||||
/// <summary>Get the min/max peak pairs, in a given region of an audio source, as a collection of binary strings (one per channel). The strings are base-64 encoded 16-bit signed int arrays, with min and max values being interleaved. If getCrossChannelPeaks is true, there will be only one binary string representing peaks across all channels globally.</summary>
|
||||
public const string getMinMaxPeaksInRegion = "ak.wwise.core.audioSourcePeaks.getMinMaxPeaksInRegion";
|
||||
/// <summary>Get the min/max peak pairs in the entire trimmed region of an audio source, for each channel, as an array of binary strings (one per channel). The strings are base-64 encoded 16-bit signed int arrays, with min and max values being interleaved. If getCrossChannelPeaks is true, there will be only one binary string representing peaks across all channels globally.</summary>
|
||||
public const string getMinMaxPeaksInTrimmedRegion = "ak.wwise.core.audioSourcePeaks.getMinMaxPeaksInTrimmedRegion";
|
||||
}
|
||||
public class remote
|
||||
{
|
||||
/// <summary>Retrieves the connection status.</summary>
|
||||
public const string getConnectionStatus = "ak.wwise.core.remote.getConnectionStatus";
|
||||
/// <summary>Retrieves all consoles available for connecting Wwise Authoring to a Sound Engine instance.</summary>
|
||||
public const string getAvailableConsoles = "ak.wwise.core.remote.getAvailableConsoles";
|
||||
/// <summary>Disconnects the Wwise Authoring application from a connected Wwise Sound Engine running executable.</summary>
|
||||
public const string disconnect = "ak.wwise.core.remote.disconnect";
|
||||
/// <summary>Connects the Wwise Authoring application to a Wwise Sound Engine running executable. The host must be running code with communication enabled.</summary>
|
||||
public const string connect = "ak.wwise.core.remote.connect";
|
||||
}
|
||||
public class log
|
||||
{
|
||||
/// <summary>Sent when an item is added to the log. This could be used to retrieve items added to the SoundBank generation log. To retrieve the complete log, refer to ak.wwise.core.log.get.</summary>
|
||||
public const string itemAdded = "ak.wwise.core.log.itemAdded";
|
||||
/// <summary>Retrieve the latest log for a specific channel. Refer to ak.wwise.core.log.itemadded to be notified when an item is added to the log.</summary>
|
||||
public const string get = "ak.wwise.core.log.get";
|
||||
}
|
||||
/// <summary>Retrieve global Wwise information.</summary>
|
||||
public const string getInfo = "ak.wwise.core.getInfo";
|
||||
public class @object
|
||||
{
|
||||
/// <summary>Sent when an object reference is changed.</summary>
|
||||
public const string referenceChanged = "ak.wwise.core.object.referenceChanged";
|
||||
/// <summary>Moves an object to the given parent. Returns the moved object.</summary>
|
||||
public const string move = "ak.wwise.core.object.move";
|
||||
/// <summary>Sent when an attenuation curve's link/unlink is changed.</summary>
|
||||
public const string attenuationCurveLinkChanged = "ak.wwise.core.object.attenuationCurveLinkChanged";
|
||||
/// <summary>Sent when an object is added as a child to another object.</summary>
|
||||
public const string childAdded = "ak.wwise.core.object.childAdded";
|
||||
/// <summary>Retrieves the list of all object types registered in Wwise's object model.</summary>
|
||||
public const string getTypes = "ak.wwise.core.object.getTypes";
|
||||
/// <summary>Sent when the watched property of an object changes.</summary>
|
||||
public const string propertyChanged = "ak.wwise.core.object.propertyChanged";
|
||||
/// <summary>Creates an object of type 'type', as a child of 'parent'. Refer to ak.wwise.core.audio.import to import audio files to Wwise.</summary>
|
||||
public const string create = "ak.wwise.core.object.create";
|
||||
/// <summary>Performs a query, returns specified data for each object in query result.</summary>
|
||||
public const string get = "ak.wwise.core.object.get";
|
||||
/// <summary>Sent prior to an object's deletion.</summary>
|
||||
public const string preDeleted = "ak.wwise.core.object.preDeleted";
|
||||
/// <summary>Sent when an object is renamed. Publishes the object which the name was changed.</summary>
|
||||
public const string nameChanged = "ak.wwise.core.object.nameChanged";
|
||||
/// <summary>Sent following an object's deletion.</summary>
|
||||
public const string postDeleted = "ak.wwise.core.object.postDeleted";
|
||||
/// <summary>Sent when the object's notes are changed.</summary>
|
||||
public const string notesChanged = "ak.wwise.core.object.notesChanged";
|
||||
/// <summary>Retrieves information about an object property.</summary>
|
||||
public const string getPropertyInfo = "ak.wwise.core.object.getPropertyInfo";
|
||||
/// <summary>Renames an object.</summary>
|
||||
public const string setName = "ak.wwise.core.object.setName";
|
||||
/// <summary>Sets the object's notes.</summary>
|
||||
public const string setNotes = "ak.wwise.core.object.setNotes";
|
||||
/// <summary>Sets the specified attenuation curve for a given attenuation object.</summary>
|
||||
public const string setAttenuationCurve = "ak.wwise.core.object.setAttenuationCurve";
|
||||
/// <summary>Sets a property value of an object for a specific platform. Refer to ak.wwise.core.object.setreference to set a reference to an object.</summary>
|
||||
public const string setProperty = "ak.wwise.core.object.setProperty";
|
||||
/// <summary>Copies an object to the given parent.</summary>
|
||||
public const string copy = "ak.wwise.core.object.copy";
|
||||
/// <summary>Return true if a property is enabled based on the values of the properties it depends on.</summary>
|
||||
public const string isPropertyEnabled = "ak.wwise.core.object.isPropertyEnabled";
|
||||
/// <summary>Sets the randomizer values of a property of an object for a specific platform.</summary>
|
||||
public const string setRandomizer = "ak.wwise.core.object.setRandomizer";
|
||||
/// <summary>Sets an object's reference value.</summary>
|
||||
public const string setReference = "ak.wwise.core.object.setReference";
|
||||
/// <summary>Sent when an attenuation curve is changed.</summary>
|
||||
public const string attenuationCurveChanged = "ak.wwise.core.object.attenuationCurveChanged";
|
||||
/// <summary>Sent when an object is created.</summary>
|
||||
public const string created = "ak.wwise.core.object.created";
|
||||
/// <summary>Sent when an object is removed from the children of another object.</summary>
|
||||
public const string childRemoved = "ak.wwise.core.object.childRemoved";
|
||||
/// <summary>Retrieves the list of property and reference names for an object.</summary>
|
||||
public const string getPropertyNames = "ak.wwise.core.object.getPropertyNames";
|
||||
/// <summary>Gets the specified attenuation curve for a given attenuation object.</summary>
|
||||
public const string getAttenuationCurve = "ak.wwise.core.object.getAttenuationCurve";
|
||||
/// <summary>Sent when one or many curves are changed.</summary>
|
||||
public const string curveChanged = "ak.wwise.core.object.curveChanged";
|
||||
/// <summary>Deletes the specified object.</summary>
|
||||
public const string delete = "ak.wwise.core.object.delete";
|
||||
/// <summary>Retrieves the list of property and reference names for an object.</summary>
|
||||
public const string getPropertyAndReferenceNames = "ak.wwise.core.object.getPropertyAndReferenceNames";
|
||||
/// <summary>Retrieves the list of operation made to objects.</summary>
|
||||
public const string structureChanged = "ak.wwise.core.object.structureChanged";
|
||||
/// <summary>Verify if WAAPI is currently available.</summary>
|
||||
public const string ping = "ak.wwise.core.ping";
|
||||
}
|
||||
public class undo
|
||||
{
|
||||
/// <summary>Ends the last undo group.</summary>
|
||||
public const string endGroup = "ak.wwise.core.undo.endGroup";
|
||||
/// <summary>Cancels the last undo group. Please note that this does not revert the operations made since the last ak.wwise.core.undo.begingroup call.</summary>
|
||||
public const string cancelGroup = "ak.wwise.core.undo.cancelGroup";
|
||||
/// <summary>Begins an undo group. Make sure to call ak.wwise.core.undo.endgroup exactly once for every ak.wwise.core.beginUndoGroup call you make. Calls to ak.wwise.core.undo.beginGroup can be nested.</summary>
|
||||
public const string beginGroup = "ak.wwise.core.undo.beginGroup";
|
||||
}
|
||||
public class profiler
|
||||
{
|
||||
/// <summary>Returns the current time of the specified profiler cursor in milliseconds.</summary>
|
||||
public const string getCursorTime = "ak.wwise.core.profiler.getCursorTime";
|
||||
/// <summary>Start the profiler capture and return the time at the beginning of the capture in milliseconds.</summary>
|
||||
public const string startCapture = "ak.wwise.core.profiler.startCapture";
|
||||
/// <summary>Retrieves all parameters affecting voice volume, highpass and lowpass for a voice path, resolved from pipeline IDs.</summary>
|
||||
public const string getVoiceContributions = "ak.wwise.core.profiler.getVoiceContributions";
|
||||
/// <summary>Retrieves the voices at a specific profiler capture time.</summary>
|
||||
public const string getVoices = "ak.wwise.core.profiler.getVoices";
|
||||
/// <summary>Retrieves the busses at a specific profiler capture time.</summary>
|
||||
public const string getBusses = "ak.wwise.core.profiler.getBusses";
|
||||
/// <summary>Stop the profiler capture and return the time at the end of the capture in milliseconds.</summary>
|
||||
public const string stopCapture = "ak.wwise.core.profiler.stopCapture";
|
||||
}
|
||||
public class project
|
||||
{
|
||||
/// <summary>Sent when the after the project is completely closed.</summary>
|
||||
public const string postClosed = "ak.wwise.core.project.postClosed";
|
||||
/// <summary>Sent when the project has been successfully loaded.</summary>
|
||||
public const string loaded = "ak.wwise.core.project.loaded";
|
||||
/// <summary>Sent when the project begins closing.</summary>
|
||||
public const string preClosed = "ak.wwise.core.project.preClosed";
|
||||
/// <summary>Saves the current project.</summary>
|
||||
public const string save = "ak.wwise.core.project.save";
|
||||
/// <summary>Sent when the project has been saved.</summary>
|
||||
public const string saved = "ak.wwise.core.project.saved";
|
||||
}
|
||||
public class transport
|
||||
{
|
||||
/// <summary>Gets the state of the given transport object.</summary>
|
||||
public const string getState = "ak.wwise.core.transport.getState";
|
||||
/// <summary>Sent when the transport's state has changed.</summary>
|
||||
public const string stateChanged = "ak.wwise.core.transport.stateChanged";
|
||||
/// <summary>Creates a transport object for the given Wwise object. The return transport object can be used to play, stop, pause and resume the Wwise object via the other transport functions.</summary>
|
||||
public const string create = "ak.wwise.core.transport.create";
|
||||
/// <summary>Returns the list of transport objects.</summary>
|
||||
public const string getList = "ak.wwise.core.transport.getList";
|
||||
/// <summary>Destroys the given transport object.</summary>
|
||||
public const string destroy = "ak.wwise.core.transport.destroy";
|
||||
/// <summary>Executes an action on the given transport object, or all transports if no transport is specified.</summary>
|
||||
public const string executeAction = "ak.wwise.core.transport.executeAction";
|
||||
}
|
||||
public class soundbank
|
||||
{
|
||||
/// <summary>Retrieves a SoundBank's inclusion list.</summary>
|
||||
public const string getInclusions = "ak.wwise.core.soundbank.getInclusions";
|
||||
/// <summary>Sent when a single SoundBank is generated. This could be sent multiple times during SoundBank generation, for every SoundBank generated and for every platform. To generate SoundBanks, refer to ak.wwise.ui.commands.execute with one of the SoundBank generation commands.</summary>
|
||||
public const string generated = "ak.wwise.core.soundbank.generated";
|
||||
/// <summary>Modifies a SoundBank's inclusion list. The 'operation' argument determines how the 'inclusions' argument modifies the SoundBank's inclusion list; 'inclusions' may be added to / removed from / replace the SoundBank's inclusion list.</summary>
|
||||
public const string setInclusions = "ak.wwise.core.soundbank.setInclusions";
|
||||
/// <summary>Generate the soundbanks.</summary>
|
||||
public const string generate = "ak.wwise.core.soundbank.generate";
|
||||
}
|
||||
public class audio
|
||||
{
|
||||
/// <summary>Create Wwise objects and import audio files. This function is using the same importation processor available through the Tab Delimited import in the Audio File Importer. The function returns an array of all objects created, replaced or re-used. Use the options to specify how the objects are returned.</summary>
|
||||
public const string import = "ak.wwise.core.audio.import";
|
||||
/// <summary>Scripted object creation and audio file import from a tab-delimited file.</summary>
|
||||
public const string importTabDelimited = "ak.wwise.core.audio.importTabDelimited";
|
||||
/// <summary>Sent at the end of an import operation.</summary>
|
||||
public const string imported = "ak.wwise.core.audio.imported";
|
||||
}
|
||||
public class switchContainer
|
||||
{
|
||||
/// <summary>Remove an assignment between a Switch Container's child and a State.</summary>
|
||||
public const string removeAssignment = "ak.wwise.core.switchContainer.removeAssignment";
|
||||
/// <summary>Returns the list of assignments between a Switch Container's children and states.</summary>
|
||||
public const string getAssignments = "ak.wwise.core.switchContainer.getAssignments";
|
||||
/// <summary>Sent when an assignment is removed from a Switch Container.</summary>
|
||||
public const string assignmentRemoved = "ak.wwise.core.switchContainer.assignmentRemoved";
|
||||
/// <summary>Assign a Switch Container's child to a Switch. This is the equivalent of doing a drag&drop of the child to a state in the Assigned Objects view. The child is always added at the end for each state.</summary>
|
||||
public const string addAssignment = "ak.wwise.core.switchContainer.addAssignment";
|
||||
/// <summary>Sent when an assignment is added to a Switch Container.</summary>
|
||||
public const string assignmentAdded = "ak.wwise.core.switchContainer.assignmentAdded";
|
||||
}
|
||||
public class plugin
|
||||
{
|
||||
/// <summary>Retrieves the list of all object types registered in Wwise's object model.</summary>
|
||||
public const string getList = "ak.wwise.core.plugin.getList";
|
||||
/// <summary>Retrieves information about an object property.</summary>
|
||||
public const string getProperty = "ak.wwise.core.plugin.getProperty";
|
||||
/// <summary>Retrieves the list of property and reference names for an object.</summary>
|
||||
public const string getProperties = "ak.wwise.core.plugin.getProperties";
|
||||
}
|
||||
}
|
||||
public class ui
|
||||
{
|
||||
public class project
|
||||
{
|
||||
/// <summary>Closes the current project.</summary>
|
||||
public const string close = "ak.wwise.ui.project.close";
|
||||
/// <summary>Opens a project, specified by path. Please refer to ak.wwise.core.project.loaded for further explanations on how to be notified when the operation has completed.</summary>
|
||||
public const string open = "ak.wwise.ui.project.open";
|
||||
}
|
||||
/// <summary>Bring Wwise main window to foreground. Refer to SetForegroundWindow and AllowSetForegroundWindow on MSDN for more information on the restrictions. Refer to ak.wwise.core.getInfo to obtain the Wwise process ID for AllowSetForegroundWindow.</summary>
|
||||
public const string bringToForeground = "ak.wwise.ui.bringToForeground";
|
||||
public class commands
|
||||
{
|
||||
/// <summary>Unregister an array of add-on UI commands.</summary>
|
||||
public const string unregister = "ak.wwise.ui.commands.unregister";
|
||||
/// <summary>Sent when a command is executed. The objects for which the command is executed are sent in the publication.</summary>
|
||||
public const string executed = "ak.wwise.ui.commands.executed";
|
||||
/// <summary>Executes a command. Some commands can take a list of objects as parameter.</summary>
|
||||
public const string execute = "ak.wwise.ui.commands.execute";
|
||||
/// <summary>Register an array of add-on commands. Registered commands remain until the Wwise process is terminated. Refer to to ak.wwise.ui.commands.executed.</summary>
|
||||
public const string register = "ak.wwise.ui.commands.register";
|
||||
/// <summary>Get the list of commands.</summary>
|
||||
public const string getCommands = "ak.wwise.ui.commands.getCommands";
|
||||
}
|
||||
/// <summary>Retrieves the list of objects currently selected by the user in the active view.</summary>
|
||||
public const string getSelectedObjects = "ak.wwise.ui.getSelectedObjects";
|
||||
/// <summary>Sent when the selection changes in the project.</summary>
|
||||
public const string selectionChanged = "ak.wwise.ui.selectionChanged";
|
||||
}
|
||||
public class waapi
|
||||
{
|
||||
/// <summary>Retrieve the list of topics to which a client can subscribe.</summary>
|
||||
public const string getTopics = "ak.wwise.waapi.getTopics";
|
||||
/// <summary>Retrieve the list of functions.</summary>
|
||||
public const string getFunctions = "ak.wwise.waapi.getFunctions";
|
||||
/// <summary>Retrieve the JSON schema of a Waapi URI.</summary>
|
||||
public const string getSchema = "ak.wwise.waapi.getSchema";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12890b20cf960be489806d648435d24c
|
||||
@@ -0,0 +1,592 @@
|
||||
/*******************************************************************************
|
||||
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) 2026 Audiokinetic Inc.
|
||||
*******************************************************************************/
|
||||
|
||||
using System.Linq;
|
||||
|
||||
/// <summary>
|
||||
/// WAMP protocol implementation using only strings and regular expressions. This implements only a subset of the WAMP feature set and is only compatible with Wwise.
|
||||
/// </summary>
|
||||
public class Wamp
|
||||
{
|
||||
/// <summary>Exception thrown during WAMP operations when the timeout is reached.</summary>
|
||||
public class TimeoutException : System.Exception
|
||||
{
|
||||
public TimeoutException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class WampNotConnectedException : System.Exception
|
||||
{
|
||||
public WampNotConnectedException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Exception thrown during WAMP operations.</summary>
|
||||
public class ErrorException : System.Exception
|
||||
{
|
||||
internal string Json { get; set; }
|
||||
internal Messages MessageId { get; set; }
|
||||
internal int RequestId { get; set; }
|
||||
internal string Uri { get; set; }
|
||||
|
||||
public ErrorException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public static ErrorException FromResponse(string response)
|
||||
{
|
||||
// [ERROR, CALL, CALL.Request|id, Details|dict, Error|uri, Arguments|list, ArgumentsKw|dict]
|
||||
string pattern = @"^\[\s*8,\s*(\d+)\s*,\s*(\d+)\s*,\s*\{\s*\}\s*,\s*""([^,\s]+)""\s*,\[\s*\]\s*,\s*(\{)";
|
||||
var match = System.Text.RegularExpressions.Regex.Match(response, pattern, System.Text.RegularExpressions.RegexOptions.Singleline);
|
||||
if (match.Groups.Count != 5)
|
||||
throw new ErrorException("Invalid ERROR message.");
|
||||
|
||||
Messages messageId = (Messages)int.Parse(match.Groups[1].Value);
|
||||
int requestId = int.Parse(match.Groups[2].Value);
|
||||
string uri = match.Groups[3].Value;
|
||||
string json = response.Substring(match.Groups[4].Index, response.Length - match.Groups[4].Index - 1);
|
||||
|
||||
return new ErrorException($"Error {uri} in {messageId.ToString()} operation.")
|
||||
{
|
||||
Json = json,
|
||||
MessageId = messageId,
|
||||
RequestId = requestId,
|
||||
Uri = uri
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Messages ids defined by the WAMP protocol</summary>
|
||||
internal enum Messages : int
|
||||
{
|
||||
HELLO = 1,
|
||||
WELCOME = 2,
|
||||
GOODBYE = 6,
|
||||
ERROR = 8,
|
||||
SUBSCRIBE = 32,
|
||||
SUBSCRIBED = 33,
|
||||
UNSUBSCRIBE = 34,
|
||||
UNSUBSCRIBED = 35,
|
||||
EVENT = 36,
|
||||
CALL = 48,
|
||||
RESULT = 50
|
||||
}
|
||||
|
||||
/// <summary>Encapsulate a response from the server.</summary>
|
||||
private class Response
|
||||
{
|
||||
public Messages MessageId { get; set; }
|
||||
public int RequestId { get; set; }
|
||||
public int ContextSpecificResultId { get; set; }
|
||||
public uint SubscriptionId { get; set; }
|
||||
public string Json { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>Publish events are delegates registered with Subscribe.</summary>
|
||||
public delegate void PublishHandler(string json);
|
||||
public delegate void DisconnectedHandler();
|
||||
|
||||
public event DisconnectedHandler Disconnected;
|
||||
|
||||
private System.Net.WebSockets.ClientWebSocket ws;
|
||||
private int sessionId = 0;
|
||||
private int currentRequestId = 0;
|
||||
private System.Threading.CancellationTokenSource stopServerTokenSource = new System.Threading.CancellationTokenSource();
|
||||
private System.Threading.Tasks.TaskCompletionSource<Response> taskCompletion = new System.Threading.Tasks.TaskCompletionSource<Response>();
|
||||
private System.Collections.Concurrent.ConcurrentDictionary<uint, PublishHandler> subscriptions = new System.Collections.Concurrent.ConcurrentDictionary<uint, PublishHandler>();
|
||||
|
||||
private async System.Threading.Tasks.Task Send(string msg, int timeout)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var cts = new System.Threading.CancellationTokenSource(timeout))
|
||||
{
|
||||
var segment = new System.ArraySegment<byte>(System.Text.Encoding.UTF8.GetBytes(msg));
|
||||
await ws.SendAsync(segment, System.Net.WebSockets.WebSocketMessageType.Text, true, cts.Token);
|
||||
}
|
||||
}
|
||||
catch (System.Threading.Tasks.TaskCanceledException)
|
||||
{
|
||||
throw new TimeoutException("Timeout when sending message.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Parse a WAMP message from the server.</summary>
|
||||
private Response Parse(string msg)
|
||||
{
|
||||
const string msgTypePattern = @"^\[\s*(\d+)";
|
||||
var match = System.Text.RegularExpressions.Regex.Match(msg, msgTypePattern, System.Text.RegularExpressions.RegexOptions.Singleline);
|
||||
|
||||
if (match.Groups.Count != 2)
|
||||
throw new ErrorException("Error while parsing response from server.");
|
||||
|
||||
Messages messageId = (Messages)int.Parse(match.Groups[1].Value);
|
||||
switch (messageId)
|
||||
{
|
||||
case Messages.WELCOME:
|
||||
return ParseWelcome(msg);
|
||||
case Messages.GOODBYE:
|
||||
return ParseGoodbye(msg);
|
||||
case Messages.SUBSCRIBED:
|
||||
return ParseSubscribed(msg);
|
||||
case Messages.UNSUBSCRIBED:
|
||||
return ParseUnsubscribed(msg);
|
||||
case Messages.EVENT:
|
||||
return ParseEvent(msg);
|
||||
case Messages.RESULT:
|
||||
return ParseResult(msg);
|
||||
case Messages.ERROR:
|
||||
throw ErrorException.FromResponse(msg);
|
||||
default:
|
||||
throw new ErrorException("Unexpected result from server.");
|
||||
}
|
||||
}
|
||||
|
||||
private static Response ParseResult(string msg)
|
||||
{
|
||||
// [RESULT, CALL.Request|id, Details|dict, YIELD.Arguments|list, YIELD.ArgumentsKw | dict]
|
||||
const string pattern = @"^\[\s*50,\s*(\d+)\s*,\s*\{\s*\}\s*,\s*\[\s*\]\s*,\s*(\{)";
|
||||
var match = System.Text.RegularExpressions.Regex.Match(msg, pattern, System.Text.RegularExpressions.RegexOptions.Singleline);
|
||||
if (!match.Success || match.Groups.Count != 3)
|
||||
throw new ErrorException("Invalid RESULT message.");
|
||||
|
||||
return new Response()
|
||||
{
|
||||
MessageId = Messages.RESULT,
|
||||
RequestId = (int.Parse(match.Groups[1].Value)),
|
||||
Json = msg.Substring(match.Groups[2].Index, msg.Length - match.Groups[2].Index - 1)
|
||||
};
|
||||
}
|
||||
|
||||
private static Response ParseSubscribed(string msg)
|
||||
{
|
||||
// [SUBSCRIBED, SUBSCRIBE.Request|id, Subscription|id]
|
||||
const string pattern = @"^\[\s*33,\s*(\d+)\s*,\s*(\d+)\s*]$";
|
||||
var match = System.Text.RegularExpressions.Regex.Match(msg, pattern, System.Text.RegularExpressions.RegexOptions.Singleline);
|
||||
if (!match.Success || match.Groups.Count != 3)
|
||||
throw new ErrorException("Invalid SUBSCRIBED message.");
|
||||
|
||||
return new Response()
|
||||
{
|
||||
MessageId = Messages.SUBSCRIBED,
|
||||
RequestId = (int.Parse(match.Groups[1].Value)),
|
||||
//ContextSpecificResultId = (int.Parse(match.Groups[2].Value))
|
||||
SubscriptionId = (uint.Parse(match.Groups[2].Value))
|
||||
};
|
||||
}
|
||||
|
||||
private static Response ParseUnsubscribed(string msg)
|
||||
{
|
||||
// [UNSUBSCRIBED, UNSUBSCRIBE.Request|id]
|
||||
const string pattern = @"^\[\s*35,\s*(\d+)\s*]$";
|
||||
var match = System.Text.RegularExpressions.Regex.Match(msg, pattern, System.Text.RegularExpressions.RegexOptions.Singleline);
|
||||
if (!match.Success || match.Groups.Count != 2)
|
||||
throw new ErrorException("Invalid UNSUBSCRIBED message.");
|
||||
|
||||
return new Response()
|
||||
{
|
||||
MessageId = Messages.UNSUBSCRIBED,
|
||||
RequestId = (int.Parse(match.Groups[1].Value))
|
||||
};
|
||||
}
|
||||
|
||||
private static Response ParseGoodbye(string msg)
|
||||
{
|
||||
// [GOODBYE, Details|dict, Reason|uri]
|
||||
const string pattern = @"^\[\s*6";
|
||||
var match = System.Text.RegularExpressions.Regex.Match(msg, pattern, System.Text.RegularExpressions.RegexOptions.Singleline);
|
||||
if (!match.Success || match.Groups.Count != 1)
|
||||
throw new ErrorException("Invalid GOODBYE message.");
|
||||
|
||||
return new Response()
|
||||
{
|
||||
MessageId = Messages.GOODBYE
|
||||
};
|
||||
}
|
||||
|
||||
private static Response ParseWelcome(string msg)
|
||||
{
|
||||
// [WELCOME, Session|id, Details|dict]
|
||||
const string pattern = @"^\[\s*2,\s*(\d+)";
|
||||
var match = System.Text.RegularExpressions.Regex.Match(msg, pattern, System.Text.RegularExpressions.RegexOptions.Singleline);
|
||||
if (!match.Success || match.Groups.Count != 2)
|
||||
throw new ErrorException("Invalid WELCOME message.");
|
||||
|
||||
return new Response()
|
||||
{
|
||||
MessageId = Messages.WELCOME,
|
||||
RequestId = 0,
|
||||
ContextSpecificResultId = (int.Parse(match.Groups[1].Value))
|
||||
};
|
||||
}
|
||||
|
||||
private static Response ParseEvent(string msg)
|
||||
{
|
||||
// [EVENT, SUBSCRIBED.Subscription|id, PUBLISHED.Publication|id, Details|dict, PUBLISH.Arguments|list, PUBLISH.ArgumentKw|dict]
|
||||
const string pattern = @"^\[\s*36,\s*(\d+)\s*,\s*(\d+)\s*,\s*\{\s*\}\s*,\s*\[\s*\]\s*,\s*(\{)";
|
||||
var match = System.Text.RegularExpressions.Regex.Match(msg, pattern, System.Text.RegularExpressions.RegexOptions.Singleline);
|
||||
if (match.Groups.Count != 4)
|
||||
throw new ErrorException("Invalid EVENT message.");
|
||||
|
||||
return new Response()
|
||||
{
|
||||
MessageId = Messages.EVENT,
|
||||
RequestId = (int.Parse(match.Groups[2].Value)),
|
||||
ContextSpecificResultId = (int.Parse(match.Groups[1].Value)),
|
||||
Json = msg.Substring(match.Groups[3].Index, msg.Length - match.Groups[3].Index - 1)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private async System.Threading.Tasks.Task<Response> ReceiveMessage()
|
||||
{
|
||||
// Receive one web socket message
|
||||
System.Collections.Generic.List<System.Collections.Generic.IEnumerable<byte>> segments = new System.Collections.Generic.List<System.Collections.Generic.IEnumerable<byte>>();
|
||||
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
byte[] buffer = new byte[4096];
|
||||
var segment = new System.ArraySegment<byte>(buffer, 0, buffer.Length);
|
||||
System.Net.WebSockets.WebSocketReceiveResult rcvResult = await ws.ReceiveAsync(segment, stopServerTokenSource.Token);
|
||||
|
||||
// Accumulate the byte arrays in a list, we will join them later
|
||||
segments.Add(segment.Skip(segment.Offset).Take(rcvResult.Count));
|
||||
|
||||
if (rcvResult.EndOfMessage)
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (System.Net.WebSockets.WebSocketException e)
|
||||
{
|
||||
throw e.InnerException;
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
throw new ErrorException("Error receiving response from server.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
byte[] bytes = segments.SelectMany(t => t).ToArray<byte>();
|
||||
string msg = System.Text.Encoding.UTF8.GetString(bytes);
|
||||
return Parse(msg);
|
||||
}
|
||||
catch (ErrorException e)
|
||||
{
|
||||
// Dispatch already built error
|
||||
throw e;
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
throw new ErrorException("Error while parsing response from server.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wait for the next response
|
||||
/// </summary>
|
||||
/// <returns>The response from the server.</returns>
|
||||
private async System.Threading.Tasks.Task<Response> Receive(int timeout)
|
||||
{
|
||||
System.Threading.Tasks.Task task = await System.Threading.Tasks.Task.WhenAny(
|
||||
taskCompletion.Task,
|
||||
System.Threading.Tasks.Task.Delay(timeout));
|
||||
|
||||
if (task != taskCompletion.Task)
|
||||
{
|
||||
taskCompletion = new System.Threading.Tasks.TaskCompletionSource<Response>();
|
||||
|
||||
// Timeout reached
|
||||
throw new TimeoutException("Timeout when receiving message.");
|
||||
}
|
||||
|
||||
if (task.Exception != null)
|
||||
{
|
||||
taskCompletion = new System.Threading.Tasks.TaskCompletionSource<Response>();
|
||||
|
||||
if (task.Exception.InnerException.InnerException != null)
|
||||
throw task.Exception.InnerException.InnerException;
|
||||
throw task.Exception;
|
||||
}
|
||||
|
||||
var result = taskCompletion.Task.Result;
|
||||
|
||||
// Since we can't re-use the task completion, create a new one for the next message
|
||||
taskCompletion = new System.Threading.Tasks.TaskCompletionSource<Response>();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wait for the next response and do some validation on the response
|
||||
/// </summary>
|
||||
/// <param name="message">What message to expect</param>
|
||||
/// <param name="requestId">What request id to expect</param>
|
||||
/// <param name="timeout">The maximum timeout in milliseconds for the function to execute. Will raise exception when timeout is reached.</param>
|
||||
/// <returns></returns>
|
||||
private async System.Threading.Tasks.Task<Response> ReceiveExpect(Messages message, int requestId, int timeout)
|
||||
{
|
||||
// Should receive the expected message or ERROR
|
||||
Response response = await Receive(timeout);
|
||||
|
||||
if (response.MessageId != message)
|
||||
throw new ErrorException($"{message.ToString()}: invalid response. Did not receive expected answer.");
|
||||
|
||||
if (response.RequestId != requestId)
|
||||
throw new ErrorException($"{message.ToString()}: invalid request id for result.");
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public System.Threading.CancellationTokenSource _connectionTokenSource;
|
||||
|
||||
/// <summary>
|
||||
/// Connect to the specified host, handshake and prepare the listening task.
|
||||
/// </summary>
|
||||
/// <param name="host">The URI of the host, usually something like ws://host:port</param>
|
||||
/// <param name="timeout">The maximum timeout in milliseconds for the function to execute. Will raise exception when timeout is reached.</param>
|
||||
/// <returns></returns>
|
||||
internal async System.Threading.Tasks.Task Connect(string host, int timeout)
|
||||
{
|
||||
try
|
||||
{
|
||||
System.Uri uri = new System.Uri(host);
|
||||
_connectionTokenSource = new System.Threading.CancellationTokenSource(timeout);
|
||||
// Connect
|
||||
if (ws == null)
|
||||
ws = new System.Net.WebSockets.ClientWebSocket();
|
||||
await ws.ConnectAsync(uri, _connectionTokenSource.Token);
|
||||
{
|
||||
// [HELLO, Realm|uri, Details|dict]
|
||||
await Send($"[{(int)Messages.HELLO},\"realm1\"]", timeout);
|
||||
}
|
||||
|
||||
StartListen();
|
||||
|
||||
{
|
||||
// Should receive the WELCOME
|
||||
Response response = await ReceiveExpect(Messages.WELCOME, 0, timeout);
|
||||
|
||||
sessionId = response.ContextSpecificResultId;
|
||||
}
|
||||
}
|
||||
catch (System.Net.WebSockets.WebSocketException e)
|
||||
{
|
||||
ws.Dispose();
|
||||
ws = new System.Net.WebSockets.ClientWebSocket();
|
||||
throw new ErrorException(e.ToString());
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
throw new ErrorException(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forcefully cancel the connection attempt to the host
|
||||
/// </summary>
|
||||
public void CancelCurrentConnection()
|
||||
{
|
||||
if (_connectionTokenSource != null)
|
||||
{
|
||||
_connectionTokenSource.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tell the connection state of the WebSocket client.
|
||||
/// </summary>
|
||||
/// <returns>Return true if the connection is open and ready.</returns>
|
||||
internal bool IsConnected()
|
||||
{
|
||||
if (ws == null)
|
||||
return false;
|
||||
|
||||
return ws.State == System.Net.WebSockets.WebSocketState.Open;
|
||||
}
|
||||
|
||||
internal System.Net.WebSockets.WebSocketState SocketState()
|
||||
{
|
||||
if (ws == null) return System.Net.WebSockets.WebSocketState.None;
|
||||
return ws.State;
|
||||
}
|
||||
|
||||
/// <summary>Close the connection.</summary>
|
||||
/// <param name="timeout">The maximum timeout in milliseconds for the function to execute. Will raise exception when timeout is reached.</param>
|
||||
internal async System.Threading.Tasks.Task Close(int timeout)
|
||||
{
|
||||
// [GOODBYE, Details|dict, Reason|uri]
|
||||
try
|
||||
{
|
||||
await Send($"[{(int)Messages.GOODBYE},{{}},\"bye_from_csharp_client\"]", timeout);
|
||||
Response response = await ReceiveExpect(Messages.GOODBYE, 0, timeout);
|
||||
|
||||
stopServerTokenSource.Cancel();
|
||||
|
||||
using (var cts = new System.Threading.CancellationTokenSource(timeout))
|
||||
{
|
||||
await ws.CloseOutputAsync(System.Net.WebSockets.WebSocketCloseStatus.NormalClosure, "wamp_close", cts.Token);
|
||||
}
|
||||
}
|
||||
catch (System.Net.WebSockets.WebSocketException)
|
||||
{
|
||||
ws.Dispose();
|
||||
stopServerTokenSource.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessEvent(Response message)
|
||||
{
|
||||
int subscriptionId = message.ContextSpecificResultId;
|
||||
|
||||
PublishHandler publishEvent = null;
|
||||
if (!subscriptions.TryGetValue((uint)subscriptionId, out publishEvent))
|
||||
throw new ErrorException("UNSUBSCRIBE: unknown subscription id.");
|
||||
|
||||
publishEvent(message.Json);
|
||||
}
|
||||
|
||||
private void StartListen()
|
||||
{
|
||||
// Start the receive task, that will remain running for the whole connection
|
||||
System.Threading.CancellationToken ct = stopServerTokenSource.Token;
|
||||
var task = System.Threading.Tasks.Task.Factory.StartNew(() =>
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
System.Threading.Tasks.Task<Response> receiveTask = ReceiveMessage();
|
||||
receiveTask.Wait();
|
||||
|
||||
if (receiveTask.Result.MessageId == Messages.EVENT)
|
||||
ProcessEvent(receiveTask.Result);
|
||||
else if (taskCompletion != null)
|
||||
taskCompletion.SetResult(receiveTask.Result);
|
||||
else
|
||||
throw new ErrorException("Received WAMP message that we did not expect.");
|
||||
|
||||
if (ct.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
if (e.InnerException.GetType() == typeof(System.Net.WebSockets.WebSocketException))
|
||||
{
|
||||
var exception = e.InnerException as System.Net.WebSockets.WebSocketException;
|
||||
if (exception.WebSocketErrorCode == System.Net.WebSockets.WebSocketError.ConnectionClosedPrematurely)
|
||||
{
|
||||
if (taskCompletion != null)
|
||||
taskCompletion.SetException(e);
|
||||
|
||||
OnDisconnect();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ws.State != System.Net.WebSockets.WebSocketState.Open)
|
||||
{
|
||||
OnDisconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Signal the exception to the other thread and continue to listen
|
||||
if (taskCompletion != null)
|
||||
taskCompletion.SetException(e);
|
||||
}
|
||||
}
|
||||
}, stopServerTokenSource.Token);
|
||||
}
|
||||
|
||||
private void OnDisconnect()
|
||||
{
|
||||
if (Disconnected != null)
|
||||
{
|
||||
Disconnected();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoke an RPC function from the uri
|
||||
/// </summary>
|
||||
/// <param name="uri">URI of the function</param>
|
||||
/// <param name="args">Arguments</param>
|
||||
/// <param name="options">Options</param>
|
||||
/// <param name="timeout">The maximum timeout in milliseconds for the function to execute. Will raise exception when Waapi.TimeoutException is reached.</param>
|
||||
/// <returns></returns>
|
||||
internal async System.Threading.Tasks.Task<string> Call(string uri, string args, string options, int timeout)
|
||||
{
|
||||
int requestId = ++currentRequestId;
|
||||
|
||||
// [CALL, Request|id, Options|dict, Procedure|uri, Arguments|list, ArgumentsKw|dict]
|
||||
await Send($"[{(int)Messages.CALL},{requestId},{options},\"{uri}\",[],{args}]", timeout);
|
||||
|
||||
// Should receive the RESULT or ERROR
|
||||
Response response = await ReceiveExpect(Messages.RESULT, requestId, timeout);
|
||||
return response.Json;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe to a WAMP topic.
|
||||
/// </summary>
|
||||
/// <param name="topic">The topic to which subscribe.</param>
|
||||
/// <param name="options">The options the subscription.</param>
|
||||
/// <param name="publishEvent">The delegate function to call when the topic is published.</param>
|
||||
/// <param name="timeout">The maximum timeout in milliseconds for the function to execute. Will raise Waapi.TimeoutException when timeout is reached.</param>
|
||||
/// <returns>Subscription id, that you can use to unsubscribe.</returns>
|
||||
internal async System.Threading.Tasks.Task<uint> Subscribe(string topic, string options, PublishHandler publishEvent, int timeout)
|
||||
{
|
||||
int requestId = ++currentRequestId;
|
||||
|
||||
// [SUBSCRIBE, Request|id, Options|dict, Topic|uri]
|
||||
await Send($"[{(int)Messages.SUBSCRIBE},{requestId},{options},\"{topic}\"]", timeout);
|
||||
|
||||
// Should receive the SUBSCRIBED or ERROR
|
||||
Response response = await ReceiveExpect(Messages.SUBSCRIBED, requestId, timeout);
|
||||
|
||||
subscriptions.TryAdd(response.SubscriptionId, publishEvent);
|
||||
return response.SubscriptionId;
|
||||
}
|
||||
|
||||
/// <summary>Unsubscribe from a subscription.</summary>
|
||||
/// <param name="subscriptionId">The subscription id received from the initial subscription.</param>
|
||||
/// <param name="timeout">The maximum timeout in milliseconds for the function to execute. Will raise Waapi.TimeoutException when timeout is reached.</param>
|
||||
internal async System.Threading.Tasks.Task Unsubscribe(uint subscriptionId, int timeout)
|
||||
{
|
||||
int requestId = ++currentRequestId;
|
||||
|
||||
// [UNSUBSCRIBE, Request|id, SUBSCRIBED.Subscription|id]
|
||||
await Send($"[{(int)Messages.UNSUBSCRIBE},{requestId},{subscriptionId}]", timeout);
|
||||
|
||||
Response response = await ReceiveExpect(Messages.UNSUBSCRIBED, requestId, timeout);
|
||||
PublishHandler oldEvent;
|
||||
subscriptions.TryRemove(subscriptionId, out oldEvent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a97d980ceabe2f48a3ad5246ddcc562
|
||||
Reference in New Issue
Block a user