diff --git a/Examples/ArrayParameterTests.uasset b/Examples/ArrayParameterTests.uasset new file mode 100644 index 0000000..a99689f Binary files /dev/null and b/Examples/ArrayParameterTests.uasset differ diff --git a/Examples/LocationReceiver_Actor.uasset b/Examples/LocationReceiver_Actor.uasset index 9d402ba..b680a00 100644 Binary files a/Examples/LocationReceiver_Actor.uasset and b/Examples/LocationReceiver_Actor.uasset differ diff --git a/Examples/LocationReceiver_Component.uasset b/Examples/LocationReceiver_Component.uasset index bfed85c..cb36424 100644 Binary files a/Examples/LocationReceiver_Component.uasset and b/Examples/LocationReceiver_Component.uasset differ diff --git a/Examples/LocationSender.uasset b/Examples/LocationSender.uasset index 20881ec..76490c7 100644 Binary files a/Examples/LocationSender.uasset and b/Examples/LocationSender.uasset differ diff --git a/Examples/PushPopParameterTests.uasset b/Examples/PushPopParameterTests.uasset index e01eb08..ad614d1 100644 Binary files a/Examples/PushPopParameterTests.uasset and b/Examples/PushPopParameterTests.uasset differ diff --git a/OSC/Source/OSC/Private/Common/OscDataStruct.h b/OSC/Source/OSC/Private/Common/OscDataStruct.h deleted file mode 100644 index 5ce5ec4..0000000 --- a/OSC/Source/OSC/Private/Common/OscDataStruct.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "OscDataElemStruct.h" -#include "OscDataStruct.generated.h" - - -USTRUCT() -struct FOscDataStruct -{ - GENERATED_USTRUCT_BODY() - - UPROPERTY() - int32 Index; - - UPROPERTY() - TArray Queue; - - FOscDataStruct() : Index(0) - { } - - FOscDataElemStruct Pop() - { - const auto idx = std::max(Index, 0); - if(idx < Queue.Num()) - { - ++Index; - return Queue[idx]; - } - return FOscDataElemStruct(); - } -}; diff --git a/OSC/Source/OSC/Private/Common/OscFunctionLibrary.cpp b/OSC/Source/OSC/Private/Common/OscFunctionLibrary.cpp index 87f5c20..99bd1da 100644 --- a/OSC/Source/OSC/Private/Common/OscFunctionLibrary.cpp +++ b/OSC/Source/OSC/Private/Common/OscFunctionLibrary.cpp @@ -10,58 +10,70 @@ UOscFunctionLibrary::UOscFunctionLibrary(const class FPostConstructInitializePro template static inline -void PopValueImpl(const FOscDataStruct & input, FOscDataStruct & output, T & Value) +void PopValueImpl(const TArray & input, TArray & output, T & Value) { - output = input; - Value = output.Pop().GetValue(); + if(input.Num() > 0) + { + output.Reserve(input.Num() - 1); + for(int32 i=1, n=input.Num(); i!=n; ++i) + { + output.Add(input[i]); + } + Value = input[0].GetValue(); + } + else + { + output.Empty(); + Value = FOscDataElemStruct().GetValue(); + } } -void UOscFunctionLibrary::PopBool(const FOscDataStruct & input, FOscDataStruct & output, bool & Value) +void UOscFunctionLibrary::PopBool(const TArray & input, TArray & output, bool & Value) { PopValueImpl(input, output, Value); } -void UOscFunctionLibrary::PopFloat(const FOscDataStruct & input, FOscDataStruct & output, float & Value) +void UOscFunctionLibrary::PopFloat(const TArray & input, TArray & output, float & Value) { PopValueImpl(input, output, Value); } -void UOscFunctionLibrary::PopInt(const FOscDataStruct & input, FOscDataStruct & output, int32 & Value) +void UOscFunctionLibrary::PopInt(const TArray & input, TArray & output, int32 & Value) { PopValueImpl(input, output, Value); } -void UOscFunctionLibrary::PopString(const FOscDataStruct & input, FOscDataStruct & output, FName & Value) +void UOscFunctionLibrary::PopString(const TArray & input, TArray & output, FName & Value) { PopValueImpl(input, output, Value); } -void UOscFunctionLibrary::PushBool(FOscDataStruct input, bool Value, FOscDataStruct & output) +void UOscFunctionLibrary::PushBool(const TArray & input, bool Value, TArray & output) { output = input; FOscDataElemStruct elem; elem.SetBool(Value); - output.Queue.Add(elem); + output.Add(elem); } -void UOscFunctionLibrary::PushFloat(FOscDataStruct input, float Value, FOscDataStruct & output) +void UOscFunctionLibrary::PushFloat(const TArray & input, float Value, TArray & output) { output = input; FOscDataElemStruct elem; elem.SetFloat(Value); - output.Queue.Add(elem); + output.Add(elem); } -void UOscFunctionLibrary::PushInt(FOscDataStruct input, int32 Value, FOscDataStruct & output) +void UOscFunctionLibrary::PushInt(const TArray & input, int32 Value, TArray & output) { output = input; FOscDataElemStruct elem; elem.SetInt(Value); - output.Queue.Add(elem); + output.Add(elem); } -void UOscFunctionLibrary::PushString(FOscDataStruct input, FName Value, FOscDataStruct & output) +void UOscFunctionLibrary::PushString(const TArray & input, FName Value, TArray & output) { if(Value.GetDisplayNameEntry()->IsWide()) { @@ -73,10 +85,61 @@ void UOscFunctionLibrary::PushString(FOscDataStruct input, FName Value, FOscData output = input; FOscDataElemStruct elem; elem.SetString(Value); - output.Queue.Add(elem); + output.Add(elem); } -void UOscFunctionLibrary::SendOsc(FName Address, const FOscDataStruct & Data, int32 TargetIndex) + +bool UOscFunctionLibrary::AsBool(const FOscDataElemStruct & input) +{ + return input.GetValue(); +} + +float UOscFunctionLibrary::AsFloat(const FOscDataElemStruct & input) +{ + return input.GetValue(); +} + +int32 UOscFunctionLibrary::AsInt(const FOscDataElemStruct & input) +{ + return input.GetValue(); +} + +FName UOscFunctionLibrary::AsString(const FOscDataElemStruct & input) +{ + return input.GetValue(); +} + + +FOscDataElemStruct UOscFunctionLibrary::FromBool(bool input) +{ + FOscDataElemStruct result; + result.SetBool(input); + return result; +} + +FOscDataElemStruct UOscFunctionLibrary::FromFloat(float input) +{ + FOscDataElemStruct result; + result.SetFloat(input); + return result; +} + +FOscDataElemStruct UOscFunctionLibrary::FromInt(int32 input) +{ + FOscDataElemStruct result; + result.SetInt(input); + return result; +} + +FOscDataElemStruct UOscFunctionLibrary::FromString(FName input) +{ + FOscDataElemStruct result; + result.SetString(input); + return result; +} + + +void UOscFunctionLibrary::SendOsc(FName Address, const TArray & Data, int32 TargetIndex) { if(Address.GetDisplayNameEntry()->IsWide()) { @@ -90,9 +153,8 @@ void UOscFunctionLibrary::SendOsc(FName Address, const FOscDataStruct & Data, in osc::OutboundPacketStream output((char *)buffer, sizeof(buffer)); output << osc::BeginMessage(Address.GetPlainANSIString()); - for(int32 i=Data.Index, n=Data.Queue.Num(); i & input, TArray & output, bool & Value); /// Get the next value from an OSC message as a floating point. UFUNCTION(BlueprintPure, Category=OSC) - static void PopFloat(const FOscDataStruct & input, FOscDataStruct & output, float & Value); + static void PopFloat(const TArray & input, TArray & output, float & Value); /// Get the next value from an OSC message as a integer. UFUNCTION(BlueprintPure, Category=OSC) - static void PopInt(const FOscDataStruct & input, FOscDataStruct & output, int32 & Value); + static void PopInt(const TArray & input, TArray & output, int32 & Value); /// Get the next value from an OSC message as a string. UFUNCTION(BlueprintPure, Category=OSC) - static void PopString(const FOscDataStruct & input, FOscDataStruct & output, FName & Value); + static void PopString(const TArray & input, TArray & output, FName & Value); /// Add a boolean value to an OSC message. - UFUNCTION(BlueprintPure, Category=OSC) - static void PushBool(FOscDataStruct input, bool Value, FOscDataStruct & output); + UFUNCTION(BlueprintPure, Category=OSC, meta=(AutoCreateRefTerm = "input")) + static void PushBool(const TArray & input, bool Value, TArray & output); /// Add a floating point value to an OSC message. - UFUNCTION(BlueprintPure, Category=OSC) - static void PushFloat(FOscDataStruct input, float Value, FOscDataStruct & output); + UFUNCTION(BlueprintPure, Category=OSC, meta=(AutoCreateRefTerm = "input")) + static void PushFloat(const TArray & input, float Value, TArray & output); /// Add a integer value to an OSC message. - UFUNCTION(BlueprintPure, Category=OSC) - static void PushInt(FOscDataStruct input, int32 Value, FOscDataStruct & output); + UFUNCTION(BlueprintPure, Category=OSC, meta=(AutoCreateRefTerm = "input")) + static void PushInt(const TArray & input, int32 Value, TArray & output); /// Add a string value to an OSC message. + UFUNCTION(BlueprintPure, Category=OSC, meta=(AutoCreateRefTerm = "input")) + static void PushString(const TArray & input, FName Value, TArray & output); + + + /// Interpret an OSC argument as a boolean UFUNCTION(BlueprintPure, Category=OSC) - static void PushString(FOscDataStruct input, FName Value, FOscDataStruct & output); + static bool AsBool(const FOscDataElemStruct & input); + + /// Interpret an OSC argument as a floating point. + UFUNCTION(BlueprintPure, Category=OSC) + static float AsFloat(const FOscDataElemStruct & input); + + /// Interpret an OSC argument as a integer. + UFUNCTION(BlueprintPure, Category=OSC) + static int32 AsInt(const FOscDataElemStruct & input); + + /// Interpret an OSC argument as a string. + UFUNCTION(BlueprintPure, Category=OSC) + static FName AsString(const FOscDataElemStruct & input); + + + /// Create an OSC argument from a boolean + UFUNCTION(BlueprintPure, Category=OSC) + static FOscDataElemStruct FromBool(bool input); + + /// Create an OSC argument from a floating point. + UFUNCTION(BlueprintPure, Category=OSC) + static FOscDataElemStruct FromFloat(float input); + + /// Create an OSC argument from a integer. + UFUNCTION(BlueprintPure, Category=OSC) + static FOscDataElemStruct FromInt(int32 input); + + /// Create an OSC argument from a string. + UFUNCTION(BlueprintPure, Category=OSC) + static FOscDataElemStruct FromString(FName input); /** @@ -49,6 +83,6 @@ class UOscFunctionLibrary : public UBlueprintFunctionLibrary * @param Data result of successive PushFloat/Int/String/etc. * @param Index index of the destination, -1 for all destinations. (SendTarget list of the plugin settings) */ - UFUNCTION(BlueprintCallable, Category=OSC) - static void SendOsc(FName Address, const FOscDataStruct & Data, int32 TargetIndex); + UFUNCTION(BlueprintCallable, Category=OSC, meta=(AutoCreateRefTerm = "Data")) + static void SendOsc(FName Address, const TArray & Data, int32 TargetIndex); }; diff --git a/OSC/Source/OSC/Private/Receive/OscDispatcher.cpp b/OSC/Source/OSC/Private/Receive/OscDispatcher.cpp index 0007f33..4b3f2dc 100644 --- a/OSC/Source/OSC/Private/Receive/OscDispatcher.cpp +++ b/OSC/Source/OSC/Private/Receive/OscDispatcher.cpp @@ -78,11 +78,11 @@ void UOscDispatcher::UnregisterReceiver(IOscReceiverInterface * receiver) _receivers.Remove(receiver); } -static void SendMessage(TCircularQueue> & _pendingMessages, const osc::ReceivedMessage & message) +static void SendMessage(TCircularQueue>> & _pendingMessages, const osc::ReceivedMessage & message) { const FName address(message.AddressPattern()); - FOscDataStruct data; + TArray data; const auto argBegin = message.ArgumentsBegin(); const auto argEnd = message.ArgumentsEnd(); @@ -113,14 +113,14 @@ static void SendMessage(TCircularQueue> & _pend { elem.SetString(FName(it->AsStringUnchecked())); } - data.Queue.Add(elem); + data.Add(elem); } // save it in pending messages _pendingMessages.Enqueue(std::make_pair(address, data)); } -static void SendBundle(TCircularQueue> & _pendingMessages, const osc::ReceivedBundle & bundle) +static void SendBundle(TCircularQueue>> & _pendingMessages, const osc::ReceivedBundle & bundle) { const auto begin = bundle.ElementsBegin(); const auto end = bundle.ElementsEnd(); @@ -166,7 +166,7 @@ void UOscDispatcher::Callback(const FArrayReaderPtr& data, const FIPv4Endpoint&) void UOscDispatcher::CallbackMainThread() { - std::pair message; + std::pair> message; while(_pendingMessages.Dequeue(message)) { for(auto receiver : _receivers) diff --git a/OSC/Source/OSC/Private/Receive/OscDispatcher.h b/OSC/Source/OSC/Private/Receive/OscDispatcher.h index 5641271..55e928d 100644 --- a/OSC/Source/OSC/Private/Receive/OscDispatcher.h +++ b/OSC/Source/OSC/Private/Receive/OscDispatcher.h @@ -1,6 +1,6 @@ #pragma once -#include "OscDataStruct.h" +#include "OscDataElemStruct.h" #include "OscDispatcher.generated.h" class IOscReceiverInterface; @@ -44,5 +44,5 @@ private: std::pair _listening; FSocket * _socket; FUdpSocketReceiver * _socketReceiver; - TCircularQueue> _pendingMessages; + TCircularQueue>> _pendingMessages; }; diff --git a/OSC/Source/OSC/Private/Receive/OscReceiverActor.h b/OSC/Source/OSC/Private/Receive/OscReceiverActor.h index 4981d1c..5bda466 100644 --- a/OSC/Source/OSC/Private/Receive/OscReceiverActor.h +++ b/OSC/Source/OSC/Private/Receive/OscReceiverActor.h @@ -2,7 +2,7 @@ #include "GameFramework/Actor.h" #include "OscReceiverInterface.h" -#include "OscDataStruct.h" +#include "OscDataElemStruct.h" #include "OscReceiverActor.generated.h" @@ -15,7 +15,7 @@ class AOscReceiverActor : public AActor, public IOscReceiverInterface FString AddressFilter; UFUNCTION(BlueprintImplementableEvent, Category=OSC) - void OnOscReceived(const FName & Address, const FOscDataStruct & Data); + void OnOscReceived(const FName & Address, const TArray & Data); protected: @@ -26,7 +26,7 @@ protected: return AddressFilter; } - virtual void SendEvent(const FName & Address, const FOscDataStruct & Data) override + virtual void SendEvent(const FName & Address, const TArray & Data) override { OnOscReceived(Address, Data); } diff --git a/OSC/Source/OSC/Private/Receive/OscReceiverComponent.h b/OSC/Source/OSC/Private/Receive/OscReceiverComponent.h index 365708f..27eea11 100644 --- a/OSC/Source/OSC/Private/Receive/OscReceiverComponent.h +++ b/OSC/Source/OSC/Private/Receive/OscReceiverComponent.h @@ -2,12 +2,12 @@ #include "Components/ActorComponent.h" #include "OscReceiverInterface.h" -#include "OscDataStruct.h" +#include "OscDataElemStruct.h" #include "OscReceiverComponent.generated.h" // declare the OnOscReceived event type -DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FComponentOscReceivedSignature, const FName &, Address, const FOscDataStruct &, Data); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FComponentOscReceivedSignature, const FName &, Address, const TArray &, Data); UCLASS(meta = (BlueprintSpawnableComponent)) @@ -31,7 +31,7 @@ protected: return AddressFilter; } - virtual void SendEvent(const FName & Address, const FOscDataStruct & Data) override + virtual void SendEvent(const FName & Address, const TArray & Data) override { OnOscReceived.Broadcast(Address, Data); } diff --git a/OSC/Source/OSC/Private/Receive/OscReceiverInterface.cpp b/OSC/Source/OSC/Private/Receive/OscReceiverInterface.cpp index 870124d..a16a564 100644 --- a/OSC/Source/OSC/Private/Receive/OscReceiverInterface.cpp +++ b/OSC/Source/OSC/Private/Receive/OscReceiverInterface.cpp @@ -14,5 +14,5 @@ const FString & IOscReceiverInterface::GetAddressFilter() return defaultValue; } -void IOscReceiverInterface::SendEvent(const FName & Address, const FOscDataStruct & Data) +void IOscReceiverInterface::SendEvent(const FName & Address, const TArray & Data) { } diff --git a/OSC/Source/OSC/Private/Receive/OscReceiverInterface.h b/OSC/Source/OSC/Private/Receive/OscReceiverInterface.h index d776015..0bcc6e2 100644 --- a/OSC/Source/OSC/Private/Receive/OscReceiverInterface.h +++ b/OSC/Source/OSC/Private/Receive/OscReceiverInterface.h @@ -1,6 +1,6 @@ #pragma once -#include "OscDataStruct.h" +#include "OscDataElemStruct.h" #include "OscReceiverInterface.generated.h" @@ -15,5 +15,5 @@ class IOscReceiverInterface GENERATED_IINTERFACE_BODY() virtual const FString & GetAddressFilter(); - virtual void SendEvent(const FName & Address, const FOscDataStruct & Data); + virtual void SendEvent(const FName & Address, const TArray & Data); }; diff --git a/README.md b/README.md index 7ea8d24..ba76089 100644 --- a/README.md +++ b/README.md @@ -23,14 +23,14 @@ Add a OscReceiverComponent to your Blueprint class and bind the OnOscReceived cu Subclass the OscReceiverActor and bind the OnOscReceived custom event. -Use the PopFloat/Int/Bool/String functions to retrieve the OSC message parameters. +Use the PopFloat/Int/Bool/String functions, or standard array functions, to retrieve the OSC message parameters. - Sender: Set the "send to" addresses in the plugin settings. -Use the PushFloat/Int/Bool/String functions to build the OSC message parameters. +Use the PushFloat/Int/Bool/String functions, or standard array functions, to build the OSC message parameters. Use the SendOsc function to send the OSC message diff --git a/VERSION b/VERSION index 8b3b9c2..7981786 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1,3 @@ +0.3: [breaking] parameters are stored as a standard array, allowing use of blueprint array functions, as well a Push/Pop functions 0.2: add receiver actor class 0.1: receiver component, send function, float integer boolean and string parameters