2020-09-08 14:13:51 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "MetasoundRouter.h"
2021-03-05 20:06:54 -04:00
2021-08-19 09:59:27 -04:00
# include "MetasoundFrontendDataTypeRegistry.h"
2021-03-05 20:06:54 -04:00
# include "MetasoundFrontendRegistries.h"
2020-09-08 14:13:51 -04:00
# include "MetasoundOperatorInterface.h"
# include "HAL/IConsoleManager.h"
2021-03-12 00:09:21 -04:00
2020-09-08 14:13:51 -04:00
// Convenience exec commands to push values to global params.
static FAutoConsoleCommand GPushFloatCommand (
2021-04-02 02:09:50 -04:00
TEXT ( " au.MetaSound.SetFloat " ) ,
TEXT ( " Use this with au.MetaSound.SetFloat [type] [address] [value]. Pushes a parameter value directly to a global address, which can then be received by Metasounds using a Receive node. " ) ,
2020-09-08 14:13:51 -04:00
FConsoleCommandWithArgsDelegate : : CreateStatic (
[ ] ( const TArray < FString > & Args )
{
2021-03-12 00:09:21 -04:00
if ( Args . Num ( ) < 3 )
2020-09-08 14:13:51 -04:00
{
2021-04-02 03:03:27 -04:00
UE_LOG ( LogMetaSound , Warning , TEXT ( " au.MetaSound.Set* should be called with three args- the data type of the channel, the address to send to and the value to send. " ) ) ;
2020-09-08 14:13:51 -04:00
return ;
}
2021-03-12 00:09:21 -04:00
FName DataType = FName ( * Args [ 0 ] ) ;
FName ChannelName = FName ( * Args [ 1 ] ) ;
float ValueToPush = TCString < TCHAR > : : Atof ( * Args [ 2 ] ) ;
2020-09-08 14:13:51 -04:00
2021-01-13 10:48:59 -04:00
Metasound : : FLiteral LiteralParam ( ValueToPush ) ;
2020-09-08 14:13:51 -04:00
2021-03-12 00:09:21 -04:00
Metasound : : FDataTransmissionCenter : : Get ( ) . PushLiteral ( DataType , ChannelName , LiteralParam ) ;
2020-09-08 14:13:51 -04:00
} )
) ;
static FAutoConsoleCommand GPushBoolCommand (
2021-04-02 02:09:50 -04:00
TEXT ( " au.MetaSound.SetBool " ) ,
TEXT ( " Use this with au.MetaSound.SetBool [address] [value]. Pushes a parameter value directly to a global address, which can then be received by Metasounds using a Receive node. " ) ,
2020-09-08 14:13:51 -04:00
FConsoleCommandWithArgsDelegate : : CreateStatic (
[ ] ( const TArray < FString > & Args )
{
if ( Args . Num ( ) < 2 )
{
2021-04-02 03:03:27 -04:00
UE_LOG ( LogMetaSound , Warning , TEXT ( " au.MetaSound.SetBool should be called with two args- the address to send to and the value to send. " ) ) ;
UE_LOG ( LogMetaSound , Warning , TEXT ( " au.MetaSound.Set* should be called with three args- the data type of the channel, the address to send to and the value to send. " ) ) ;
2020-09-08 14:13:51 -04:00
return ;
}
2021-03-12 00:09:21 -04:00
FName DataType = FName ( * Args [ 0 ] ) ;
FName ChannelName = FName ( * Args [ 1 ] ) ;
int32 ValueAsInt = TCString < TCHAR > : : Atoi ( * Args [ 2 ] ) ;
2020-09-08 14:13:51 -04:00
bool ValueToPush = ValueAsInt ! = 0 ;
2021-01-13 10:48:59 -04:00
Metasound : : FLiteral LiteralParam ( ValueToPush ) ;
2020-09-08 14:13:51 -04:00
2021-03-12 00:09:21 -04:00
Metasound : : FDataTransmissionCenter : : Get ( ) . PushLiteral ( DataType , ChannelName , LiteralParam ) ;
2020-09-08 14:13:51 -04:00
} )
) ;
static FAutoConsoleCommand GPushIntCommand (
2021-04-02 02:09:50 -04:00
TEXT ( " au.MetaSound.SetInt " ) ,
TEXT ( " Use this with au.MetaSound.SetInt [address] [value]. Pushes a parameter value directly to a global address, which can then be received by Metasounds using a Receive node. " ) ,
2020-09-08 14:13:51 -04:00
FConsoleCommandWithArgsDelegate : : CreateStatic (
[ ] ( const TArray < FString > & Args )
{
if ( Args . Num ( ) < 2 )
{
2021-04-02 03:03:27 -04:00
UE_LOG ( LogMetaSound , Warning , TEXT ( " au.MetaSound.Set* should be called with three args- the data type of the channel, the address to send to and the value to send. " ) ) ;
2020-09-08 14:13:51 -04:00
return ;
}
2021-03-12 00:09:21 -04:00
FName DataType = FName ( * Args [ 0 ] ) ;
FName ChannelName = FName ( * Args [ 1 ] ) ;
int32 ValueToPush = TCString < TCHAR > : : Atoi ( * Args [ 2 ] ) ;
2020-09-08 14:13:51 -04:00
2021-01-13 10:48:59 -04:00
Metasound : : FLiteral LiteralParam ( ValueToPush ) ;
2020-09-08 14:13:51 -04:00
2021-03-12 00:09:21 -04:00
Metasound : : FDataTransmissionCenter : : Get ( ) . PushLiteral ( DataType , ChannelName , LiteralParam ) ;
2020-09-08 14:13:51 -04:00
} )
) ;
static FAutoConsoleCommand GPushStringCommand (
2021-04-02 02:09:50 -04:00
TEXT ( " au.MetaSound.SetString " ) ,
TEXT ( " Use this with au.MetaSound.SetString [address] [value]. Pushes a parameter value directly to a global address, which can then be received by Metasounds using a Receive node. " ) ,
2020-09-08 14:13:51 -04:00
FConsoleCommandWithArgsDelegate : : CreateStatic (
[ ] ( const TArray < FString > & Args )
{
2021-03-12 00:09:21 -04:00
if ( Args . Num ( ) < 3 )
2020-09-08 14:13:51 -04:00
{
2021-04-02 03:03:27 -04:00
UE_LOG ( LogMetaSound , Warning , TEXT ( " au.MetaSound.SetBool should be called with three args- the data type of the channel, the address to send to and the value to send. " ) ) ;
UE_LOG ( LogMetaSound , Warning , TEXT ( " au.MetaSound.Set* should be called with three args- the data type of the channel, the address to send to and the value to send. " ) ) ;
2020-09-08 14:13:51 -04:00
return ;
}
2021-03-12 00:09:21 -04:00
FName DataType = FName ( * Args [ 0 ] ) ;
FName ChannelName = FName ( * Args [ 1 ] ) ;
2020-09-08 14:13:51 -04:00
2021-03-12 00:09:21 -04:00
Metasound : : FLiteral LiteralParam ( Args [ 2 ] ) ;
2020-09-08 14:13:51 -04:00
2021-03-12 00:09:21 -04:00
Metasound : : FDataTransmissionCenter : : Get ( ) . PushLiteral ( DataType , ChannelName , LiteralParam ) ;
2020-09-08 14:13:51 -04:00
} )
) ;
namespace Metasound
{
2021-10-12 21:21:22 -04:00
FSendAddress : : FSendAddress ( const FString & InChannelName )
: ChannelName ( * InChannelName )
, DataType ( )
, InstanceID ( INDEX_NONE )
{
}
FSendAddress : : FSendAddress ( const FName & InChannelName , const FName & InDataType , uint64 InInstanceID )
: ChannelName ( InChannelName )
, DataType ( InDataType )
, InstanceID ( InInstanceID )
{
}
2020-09-08 14:13:51 -04:00
IReceiver : : ~ IReceiver ( )
{
DataChannel - > OnReceiverDestroyed ( ) ;
}
ISender : : ~ ISender ( )
{
DataChannel - > OnSenderDestroyed ( ) ;
}
2021-03-05 20:06:54 -04:00
FDataTransmissionCenter & FDataTransmissionCenter : : Get ( )
2020-09-08 14:13:51 -04:00
{
static FDataTransmissionCenter Singleton ;
return Singleton ;
}
2021-10-12 21:21:22 -04:00
TUniquePtr < ISender > FDataTransmissionCenter : : RegisterNewSender ( const FSendAddress & InAddress , const FSenderInitParams & InitParams )
2020-09-08 14:13:51 -04:00
{
2021-10-12 21:21:22 -04:00
return GlobalRouter . RegisterNewSender ( InAddress , InitParams ) ;
2021-03-05 20:06:54 -04:00
}
2021-10-12 21:21:22 -04:00
TUniquePtr < IReceiver > FDataTransmissionCenter : : RegisterNewReceiver ( const FSendAddress & InAddress , const FReceiverInitParams & InitParams )
2021-03-05 20:06:54 -04:00
{
2021-10-12 21:21:22 -04:00
return GlobalRouter . RegisterNewReceiver ( InAddress , InitParams ) ;
2021-03-05 20:06:54 -04:00
}
2021-10-12 21:21:22 -04:00
bool FDataTransmissionCenter : : UnregisterDataChannel ( const FSendAddress & InAddress )
2021-04-06 01:41:29 -04:00
{
2021-10-12 21:21:22 -04:00
return GlobalRouter . UnregisterDataChannel ( InAddress ) ;
2021-04-07 22:12:28 -04:00
}
2021-10-12 21:21:22 -04:00
bool FDataTransmissionCenter : : UnregisterDataChannelIfUnconnected ( const FSendAddress & InAddress )
2021-04-07 22:12:28 -04:00
{
2021-10-12 21:21:22 -04:00
return GlobalRouter . UnregisterDataChannelIfUnconnected ( InAddress ) ;
2021-04-06 01:41:29 -04:00
}
2021-03-12 00:09:21 -04:00
bool FDataTransmissionCenter : : PushLiteral ( FName DataType , FName GlobalChannelName , const FLiteral & InParam )
2021-03-05 20:06:54 -04:00
{
2021-03-12 00:09:21 -04:00
return GlobalRouter . PushLiteral ( DataType , GlobalChannelName , InParam ) ;
2021-03-05 20:06:54 -04:00
}
2021-10-12 21:21:22 -04:00
TSharedPtr < IDataChannel , ESPMode : : ThreadSafe > FAddressRouter : : FindDataChannel ( const FSendAddress & InAddress )
2020-09-08 14:13:51 -04:00
{
2021-03-12 00:09:21 -04:00
TSharedPtr < IDataChannel , ESPMode : : ThreadSafe > Channel ;
2020-09-08 14:13:51 -04:00
2021-03-05 20:06:54 -04:00
{
FScopeLock ScopeLock ( & DataChannelMapMutationLock ) ;
2021-10-12 21:21:22 -04:00
if ( TSharedRef < IDataChannel , ESPMode : : ThreadSafe > * ExistingChannelPtr = DataChannelMap . Find ( InAddress ) )
2021-03-05 20:06:54 -04:00
{
2021-03-12 00:09:21 -04:00
Channel = * ExistingChannelPtr ;
2021-03-05 20:06:54 -04:00
}
2021-03-12 00:09:21 -04:00
}
2021-03-05 20:06:54 -04:00
2021-03-12 00:09:21 -04:00
return Channel ;
}
2021-10-12 21:21:22 -04:00
TSharedPtr < IDataChannel , ESPMode : : ThreadSafe > FAddressRouter : : GetDataChannel ( const FSendAddress & InAddress , const FOperatorSettings & InOperatorSettings )
2021-03-12 00:09:21 -04:00
{
2021-10-12 21:21:22 -04:00
TSharedPtr < IDataChannel , ESPMode : : ThreadSafe > DataChannel = FindDataChannel ( InAddress ) ;
2021-03-12 00:09:21 -04:00
if ( ! DataChannel . IsValid ( ) )
{
FScopeLock ScopeLock ( & DataChannelMapMutationLock ) ;
// This is the first time we're seeing this, add it to the map.
2021-10-12 21:21:22 -04:00
DataChannel = Metasound : : Frontend : : IDataTypeRegistry : : Get ( ) . CreateDataChannel ( InAddress . GetDataType ( ) , InOperatorSettings ) ;
2021-08-19 09:59:27 -04:00
if ( DataChannel . IsValid ( ) )
2021-03-12 00:09:21 -04:00
{
2021-10-12 21:21:22 -04:00
DataChannelMap . Add ( InAddress , DataChannel . ToSharedRef ( ) ) ;
2021-03-05 20:06:54 -04:00
}
}
return DataChannel ;
}
2021-10-12 21:21:22 -04:00
TUniquePtr < ISender > FAddressRouter : : RegisterNewSender ( const FSendAddress & InAddress , const FSenderInitParams & InitParams )
2021-03-05 20:06:54 -04:00
{
2021-10-12 21:21:22 -04:00
TSharedPtr < IDataChannel , ESPMode : : ThreadSafe > DataChannel = GetDataChannel ( InAddress , InitParams . OperatorSettings ) ;
2021-03-05 20:06:54 -04:00
if ( DataChannel . IsValid ( ) )
{
return DataChannel - > NewSender ( InitParams ) ;
}
else
{
return TUniquePtr < ISender > ( nullptr ) ;
}
}
2021-10-12 21:21:22 -04:00
bool FAddressRouter : : UnregisterDataChannel ( const FSendAddress & InAddress )
2021-04-06 01:41:29 -04:00
{
FScopeLock ScopeLock ( & DataChannelMapMutationLock ) ;
2021-10-12 21:21:22 -04:00
if ( TSharedRef < IDataChannel , ESPMode : : ThreadSafe > * Channel = DataChannelMap . Find ( InAddress ) )
2021-04-06 01:41:29 -04:00
{
if ( const int32 NumReceiversActive = Channel - > Get ( ) . GetNumActiveReceivers ( ) )
{
2021-10-12 21:21:22 -04:00
UE_LOG ( LogMetaSound , Verbose , TEXT ( " DataChannel '%s' shutting down with %d receivers active. " ) , * InAddress . ToString ( ) , NumReceiversActive ) ;
2021-04-06 01:41:29 -04:00
}
if ( const int32 NumSendersActive = Channel - > Get ( ) . GetNumActiveSenders ( ) )
{
2021-10-12 21:21:22 -04:00
UE_LOG ( LogMetaSound , Verbose , TEXT ( " DataChannel '%s' shutting down with %d senders active. " ) , * InAddress . ToString ( ) , NumSendersActive ) ;
2021-04-06 01:41:29 -04:00
}
}
2021-10-12 21:21:22 -04:00
return DataChannelMap . Remove ( InAddress ) > 0 ;
2021-04-06 01:41:29 -04:00
}
2021-10-12 21:21:22 -04:00
bool FAddressRouter : : UnregisterDataChannelIfUnconnected ( const FSendAddress & InAddress )
2021-04-07 22:12:28 -04:00
{
FScopeLock ScopeLock ( & DataChannelMapMutationLock ) ;
2021-10-12 21:21:22 -04:00
if ( TSharedRef < IDataChannel , ESPMode : : ThreadSafe > * Channel = DataChannelMap . Find ( InAddress ) )
2021-04-07 22:12:28 -04:00
{
if ( 0 = = Channel - > Get ( ) . GetNumActiveReceivers ( ) )
{
if ( 0 = = Channel - > Get ( ) . GetNumActiveSenders ( ) )
{
2021-10-12 21:21:22 -04:00
return DataChannelMap . Remove ( InAddress ) > 0 ;
2021-04-07 22:12:28 -04:00
}
}
}
return false ;
}
2021-10-12 21:21:22 -04:00
TUniquePtr < IReceiver > FAddressRouter : : RegisterNewReceiver ( const FSendAddress & InAddress , const FReceiverInitParams & InitParams )
2021-03-05 20:06:54 -04:00
{
2021-10-12 21:21:22 -04:00
TSharedPtr < IDataChannel , ESPMode : : ThreadSafe > DataChannel = GetDataChannel ( InAddress , InitParams . OperatorSettings ) ;
2021-03-05 20:06:54 -04:00
if ( DataChannel . IsValid ( ) )
{
return DataChannel - > NewReceiver ( InitParams ) ;
}
else
{
return TUniquePtr < IReceiver > ( nullptr ) ;
}
}
2020-09-08 14:13:51 -04:00
}