add support for OSC blob

This commit is contained in:
monsieurgustav
2016-12-20 16:37:49 +01:00
parent 8b946cb312
commit a6c68e2d6c
5 changed files with 160 additions and 38 deletions
@@ -8,24 +8,20 @@ struct FOscDataElemStruct
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
int32 Type;
UPROPERTY()
int64 Data;
FOscDataElemStruct() : Type(0), Data(0)
{ }
enum
{
FLOAT = 0,
INT = 1,
BOOL = 2,
FLOAT = 0,
INT = 1,
BOOL = 2,
STRING = 3,
BLOB = 4,
};
//-------------------------------------------------------------------------
public:
FOscDataElemStruct() : Type(0), Data(0)
{
}
void SetFloat(double value)
{
@@ -112,6 +108,27 @@ struct FOscDataElemStruct
//-------------------------------------------------------------------------
void SetBlob(TArray<uint8> value)
{
Data = 0;
Type = BLOB;
Blob = MakeShared<TArray<uint8>>(std::move(value));
}
const TArray<uint8> & AsBlobValue() const
{
check(IsBlob());
static const TArray<uint8> empty;
return Blob.IsValid() ? *Blob : empty;
}
bool IsBlob() const
{
return Type == BLOB;
}
//-------------------------------------------------------------------------
/// Cast the value to T.
template <class T>
T GetValue() const
@@ -150,6 +167,14 @@ struct FOscDataElemStruct
return Cast<T, isString>::eval(value);
}
}
else if(IsBlob())
{
const bool isBlob = std::is_same<T, TArray<uint8>>::value;
if(isBlob)
{
return Cast<T, isBlob>::eval(AsBlobValue());
}
}
return T();
}
@@ -163,6 +188,13 @@ private:
return T();
}
};
private:
int32 Type;
int64 Data;
TSharedPtr<TArray<uint8>> Blob;
};
@@ -44,6 +44,11 @@ void UOscFunctionLibrary::PopString(const TArray<FOscDataElemStruct> & input, TA
PopValueImpl(input, output, Value);
}
void UOscFunctionLibrary::PopBlob(const TArray<FOscDataElemStruct> & input, TArray<FOscDataElemStruct> & output, TArray<uint8> & Value)
{
PopValueImpl(input, output, Value);
}
void UOscFunctionLibrary::PushBool(const TArray<FOscDataElemStruct> & input, bool Value, TArray<FOscDataElemStruct> & output)
{
@@ -84,6 +89,14 @@ void UOscFunctionLibrary::PushString(const TArray<FOscDataElemStruct> & input, F
output.Add(elem);
}
void UOscFunctionLibrary::PushBlob(const TArray<FOscDataElemStruct> & input, const TArray<uint8> & Value, TArray<FOscDataElemStruct> & output)
{
output = input;
FOscDataElemStruct elem;
elem.SetBlob(Value);
output.Add(elem);
}
bool UOscFunctionLibrary::AsBool(const FOscDataElemStruct & input)
{
@@ -105,6 +118,11 @@ FName UOscFunctionLibrary::AsString(const FOscDataElemStruct & input)
return input.GetValue<FName>();
}
TArray<uint8> UOscFunctionLibrary::AsBlob(const FOscDataElemStruct & input)
{
return input.GetValue<TArray<uint8>>();
}
FOscDataElemStruct UOscFunctionLibrary::FromBool(bool input)
{
@@ -134,6 +152,13 @@ FOscDataElemStruct UOscFunctionLibrary::FromString(FName input)
return result;
}
FOscDataElemStruct UOscFunctionLibrary::FromBlob(const TArray<uint8> & input)
{
FOscDataElemStruct result;
result.SetBlob(input);
return result;
}
namespace
{
@@ -188,6 +213,11 @@ namespace
{
output << elem.AsStringValue().GetPlainANSIString();
}
else if(elem.IsBlob())
{
const TArray<uint8> & value = elem.AsBlobValue();
output << osc::Blob(value.GetData(), value.Num());
}
if(output.State() != osc::SUCCESS)
{
@@ -28,6 +28,10 @@ public:
UFUNCTION(BlueprintPure, Category=OSC)
static void PopString(const TArray<FOscDataElemStruct> & input, TArray<FOscDataElemStruct> & output, FName & Value);
/// Get the next value from an OSC message as a blob.
UFUNCTION(BlueprintPure, Category=OSC)
static void PopBlob(const TArray<FOscDataElemStruct> & input, TArray<FOscDataElemStruct> & output, TArray<uint8> & Value);
/// Add a boolean value to an OSC message.
UFUNCTION(BlueprintPure, Category=OSC, meta=(AutoCreateRefTerm = "input"))
@@ -45,6 +49,10 @@ public:
UFUNCTION(BlueprintPure, Category=OSC, meta=(AutoCreateRefTerm = "input"))
static void PushString(const TArray<FOscDataElemStruct> & input, FName Value, TArray<FOscDataElemStruct> & output);
/// Add a blob to an OSC message.
UFUNCTION(BlueprintPure, Category=OSC, meta=(AutoCreateRefTerm = "input"))
static void PushBlob(const TArray<FOscDataElemStruct> & input, const TArray<uint8> & Value, TArray<FOscDataElemStruct> & output);
/// Interpret an OSC argument as a boolean
UFUNCTION(BlueprintPure, Category=OSC)
@@ -62,6 +70,10 @@ public:
UFUNCTION(BlueprintPure, Category=OSC)
static FName AsString(const FOscDataElemStruct & input);
/// Interpret an OSC argument as a blob.
UFUNCTION(BlueprintPure, Category=OSC)
static TArray<uint8> AsBlob(const FOscDataElemStruct & input);
/// Create an OSC argument from a boolean
UFUNCTION(BlueprintPure, Category=OSC)
@@ -79,6 +91,10 @@ public:
UFUNCTION(BlueprintPure, Category=OSC)
static FOscDataElemStruct FromString(FName input);
/// Create an OSC argument from a blob.
UFUNCTION(BlueprintPure, Category=OSC)
static FOscDataElemStruct FromBlob(const TArray<uint8> & input);
/**
* @brief Send an OSC message.
@@ -131,6 +131,25 @@ static void SendMessage(TCircularQueue<std::tuple<FName, TArray<FOscDataElemStru
{
elem.SetString(FName(it->AsStringUnchecked()));
}
else if(it->IsBlob())
{
const void* buffer;
osc::osc_bundle_element_size_t size;
osc::Errors error = osc::SUCCESS;
it->AsBlobUnchecked(buffer, size, error);
TArray<uint8> blob;
if(size && !error)
{
blob.SetNumUninitialized(size);
FMemory::Memcpy(blob.GetData(), buffer, size);
}
else if(error)
{
UE_LOG(LogOSC, Warning, TEXT("OSC Received Message Error: %s"), osc::errorString(error));
}
elem.SetBlob(std::move(blob));
}
data.Add(elem);
}