Compare commits
2 Commits
main
...
sending-support
| Author | SHA1 | Date | |
|---|---|---|---|
| a8a32faa4c | |||
| 0f09aaf285 |
Binary file not shown.
@@ -1,22 +1,33 @@
|
||||
#include "API/Operations/SendOperation.h"
|
||||
|
||||
#include "Mixpanel.h"
|
||||
#include "Transports/Transport.h"
|
||||
|
||||
|
||||
// USendOperation* USendOperation::SendOperation(UObject* WorldContextObject, UBase* Base, TScriptArray<TScriptInterface<ITransport>> Transports)
|
||||
// {
|
||||
// USendOperation* Node = NewObject<USendOperation>();
|
||||
// Node->Base = Base;
|
||||
// Node->Transports = Transports;
|
||||
//
|
||||
// Node->RegisterWithGameInstance(WorldContextObject);
|
||||
// return Node;
|
||||
// }
|
||||
//
|
||||
// void USendOperation::Activate()
|
||||
// {
|
||||
// check(Transports.Num() > 0);
|
||||
//
|
||||
// //TODO implement
|
||||
// unimplemented();
|
||||
//
|
||||
// }
|
||||
USendOperation* USendOperation::SendOperation(UObject* WorldContextObject, UBase* Base, TArray<TScriptInterface<ITransport>> Transports)
|
||||
{
|
||||
|
||||
USendOperation* Node = NewObject<USendOperation>();
|
||||
Node->Base = Base;
|
||||
Node->Transports = Transports;
|
||||
|
||||
Node->RegisterWithGameInstance(WorldContextObject);
|
||||
return Node;
|
||||
}
|
||||
|
||||
void USendOperation::Activate()
|
||||
{
|
||||
FAnalytics::TrackEvent("unknown", "unknown", "NodeRun", TMap<FString, FString> { {"name", StaticClass()->GetName() }});
|
||||
Send();
|
||||
}
|
||||
|
||||
void USendOperation::Send()
|
||||
{
|
||||
check(Transports.Num() > 0);
|
||||
|
||||
for (const auto t : Transports)
|
||||
{
|
||||
//TODO
|
||||
//ITransport::
|
||||
}
|
||||
}
|
||||
@@ -64,3 +64,18 @@ UBase* USpeckleSerializer::DeserializeBaseById(const FString& ObjectId,
|
||||
auto Obj = ReadTransport->GetSpeckleObject(ObjectId);
|
||||
return DeserializeBase(Obj, ReadTransport);
|
||||
}
|
||||
|
||||
|
||||
UBase* TrySetProperties(const TSubclassOf<UBase> BaseType, const FString& SerialisedObject, TScriptInterface<ITransport> Transport)
|
||||
{
|
||||
UBase* Base = NewObject<UBase>(GetTransientPackage(), BaseType);
|
||||
|
||||
|
||||
TSharedRef<FJsonStringReader> Reader = FJsonStringReader::Create(SerialisedObject);
|
||||
for(auto foo : Reader.)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return Base;
|
||||
}
|
||||
|
||||
@@ -34,11 +34,10 @@ void UAggregateConverter::PostEditChangeProperty(FPropertyChangedEvent& Property
|
||||
}
|
||||
#endif
|
||||
|
||||
UBase* UAggregateConverter::ConvertToSpeckle_Implementation(const UObject* Object)
|
||||
void UAggregateConverter::ConvertToSpeckle_Implementation(const UObject* Object, UBase* SpeckleObject)
|
||||
{
|
||||
//TODO implement ToSpeckle
|
||||
unimplemented();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +79,7 @@ bool UAggregateConverter::CanConvertToNative_Implementation(TSubclassOf<UBase> B
|
||||
return GetConverter(BaseType).GetInterface() != nullptr;
|
||||
}
|
||||
|
||||
|
||||
TScriptInterface<ISpeckleConverter> UAggregateConverter::GetConverter(const TSubclassOf<UBase> BaseType)
|
||||
{
|
||||
// Check if this SpeckleType has a known converter.
|
||||
|
||||
@@ -366,7 +366,7 @@ void UStaticMeshConverter::GenerateMeshParams(UStaticMesh::FBuildMeshDescription
|
||||
}
|
||||
|
||||
|
||||
UBase* UStaticMeshConverter::ConvertToSpeckle_Implementation(const UObject* Object)
|
||||
void UStaticMeshConverter::ConvertToSpeckle_Implementation(const UObject* Object, UBase* SpeckleObject)
|
||||
{
|
||||
const UStaticMeshComponent* M = Cast<UStaticMeshComponent>(Object);
|
||||
|
||||
@@ -378,15 +378,68 @@ UBase* UStaticMeshConverter::ConvertToSpeckle_Implementation(const UObject* Obje
|
||||
M = A->FindComponentByClass<UStaticMeshComponent>();
|
||||
}
|
||||
}
|
||||
if(M == nullptr) return nullptr;
|
||||
if(M == nullptr) return;
|
||||
|
||||
//SpeckleObject->DynamicProperties.Add(TEXT("@displayValue"), MeshToSpeckle(M));
|
||||
|
||||
return MeshToSpeckle(M);
|
||||
}
|
||||
|
||||
|
||||
UBase* UStaticMeshConverter::MeshToSpeckle(const UStaticMeshComponent* Object)
|
||||
TArray<UMesh*> UStaticMeshConverter::MeshToSpeckle(const UStaticMeshComponent* MeshComponent)
|
||||
{
|
||||
return nullptr; //TODO implement ToSpeckle function
|
||||
|
||||
UStaticMeshDescription* StaticMeshDescription = NewObject<UStaticMeshDescription>(GetTransientPackage(), NAME_None, RF_Transient);
|
||||
const FMeshDescription* MeshDescription = MeshComponent->GetStaticMesh()->GetMeshDescription(0);;
|
||||
StaticMeshDescription->SetMeshDescription(*MeshDescription);
|
||||
StaticMeshDescription->RegisterAttributes();
|
||||
|
||||
const FVertexArray& nVertices = StaticMeshDescription->Vertices();
|
||||
TArray<FVector> sVertices;
|
||||
sVertices.Reserve(nVertices.Num()); // * 3));
|
||||
|
||||
TMap<FVertexID, int32> VertexIdToIndex;
|
||||
VertexIdToIndex.Reserve(nVertices.Num() * 3);
|
||||
|
||||
int32 i = 0;
|
||||
for (const FVertexID& VertexId : nVertices.GetElementIDs())
|
||||
{
|
||||
const FVector Vert = StaticMeshDescription->GetVertexPosition(VertexId);
|
||||
sVertices.Add(Vert);
|
||||
|
||||
VertexIdToIndex.Add(VertexId, i);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
FTriangleArray& nTriangles = StaticMeshDescription->Triangles();
|
||||
TArray<int32> sFaces;
|
||||
sFaces.Reserve(nTriangles.Num());
|
||||
|
||||
for (const FTriangleID& TriangleId : nTriangles.GetElementIDs())
|
||||
{
|
||||
TArray<FVertexID> Tri;
|
||||
StaticMeshDescription->GetTriangleVertices(TriangleId, Tri);
|
||||
|
||||
sFaces.Add(3);
|
||||
sFaces.Add(VertexIdToIndex[Tri[0]]);
|
||||
sFaces.Add(VertexIdToIndex[Tri[1]]);
|
||||
sFaces.Add(VertexIdToIndex[Tri[2]]);
|
||||
}
|
||||
|
||||
//TODO colors
|
||||
|
||||
//TODO tex-coords
|
||||
|
||||
//TODO split mesh by material
|
||||
UMesh* Mesh = NewObject<UMesh>(GetTransientPackage(), NAME_None, RF_Transient);
|
||||
|
||||
Mesh->Vertices = sVertices;
|
||||
Mesh->Faces = sFaces;
|
||||
//Mesh->Colors = sColors;
|
||||
//Mesh->TextureCoordinates = sTexCoords;
|
||||
Mesh->Units = "cm";
|
||||
|
||||
return TArray<UMesh*>{Mesh};
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -176,4 +176,4 @@ void USpeckleConverterComponent::FinishConversion()
|
||||
SpeckleConverter->FinishConversion_Internal();
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,60 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Conversion/SpeckleConverter.h"
|
||||
#include "Conversion/SpeckleConverterComponent.h"
|
||||
#include "Conversion/Converters/AggregateConverter.h"
|
||||
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FSpeckleUnrealModule"
|
||||
|
||||
|
||||
UBase* USpeckleConverterComponent::RecursivelyConvertToSpeckle(const TArray<AActor*>& RootActors, FActorPredicate& Predicate)
|
||||
{
|
||||
TArray<UBase*> ConvertedRootActors;
|
||||
for(const AActor* RootActor : RootActors)
|
||||
{
|
||||
RecurseTreeToSpeckle(RootActor, Predicate, ConvertedRootActors);
|
||||
}
|
||||
|
||||
UBase* Wrapper = NewObject<UBase>(GetTransientPackage(), NAME_None, RF_Transient);
|
||||
|
||||
//Converted->DynamicProperties["objects"] = ConvertedRootActors; //TODO set children
|
||||
|
||||
return Wrapper;
|
||||
}
|
||||
|
||||
void USpeckleConverterComponent::RecurseTreeToSpeckle(const AActor* RootActor, FActorPredicate& Predicate, TArray<UBase*>& OutConverted)
|
||||
{
|
||||
// Convert children first
|
||||
TArray<UBase*> ConvertedChildren;
|
||||
ConvertedChildren.Reserve(RootActor->Children.Num());
|
||||
for (const AActor* Child : RootActor->Children)
|
||||
{
|
||||
RecurseTreeToSpeckle(Child, Predicate, ConvertedChildren);
|
||||
}
|
||||
|
||||
bool ShouldConvert;
|
||||
Predicate.Execute(RootActor, ShouldConvert);
|
||||
if(ISpeckleConverter::Execute_CanConvertToSpeckle(SpeckleConverter, RootActor) && ShouldConvert)
|
||||
{
|
||||
// Convert and output
|
||||
UBase* Converted = NewObject<UBase>(GetTransientPackage(), NAME_None, RF_Transient);
|
||||
//Converted->DynamicProperties["name"] = RootActor->GetName(),
|
||||
//["transform"] = TransformToSpeckle(go.Transform), //TODO set common props
|
||||
//Converted->DynamicProperties["tag"] = go.tag,
|
||||
//Converted->DynamicProperties["layer"] = go.layer,
|
||||
//Converted->DynamicProperties["isStatic"] = go.isStatic,
|
||||
|
||||
ISpeckleConverter::Execute_ConvertToSpeckle(SpeckleConverter, RootActor, Converted);
|
||||
//Converted->DynamicProperties["objects"] = ConvertedChildren; //TODO set children
|
||||
OutConverted.Add(Converted);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip this object, and output any children
|
||||
OutConverted.Append(ConvertedChildren);
|
||||
}
|
||||
|
||||
}
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright AEC Systems Ltd
|
||||
|
||||
#include "Objects/DynamicBase.h"
|
||||
#include "Misc/Variant.h"
|
||||
|
||||
template <typename T>
|
||||
bool UDynamicBase::TryGetDynamicProperty(const FString& Key, T& OutValue) const
|
||||
{
|
||||
const auto Wrapper = DynamicProperties.FindRef(Key);
|
||||
if(Wrapper.IsValid()) return false;
|
||||
|
||||
if(Wrapper->GetType() != TVariantTraits<T>::GetType()) return false;
|
||||
|
||||
OutValue = Wrapper->GetValue<T>();
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void UDynamicBase::SetDynamicProperty(const FString& Key, T Value)
|
||||
{
|
||||
DynamicProperties.Add(Key, MakeShareable(new FVariant(Value)));
|
||||
}
|
||||
|
||||
int32 UDynamicBase::RemoveDynamicProperty(const FString& Key)
|
||||
{
|
||||
return DynamicProperties.Remove(Key);
|
||||
}
|
||||
|
||||
//-------------------
|
||||
|
||||
bool UDynamicBase::TryGetDynamicStringProperty(const FString& Key, FString& OutValue) const
|
||||
{
|
||||
return TryGetDynamicProperty(Key, OutValue);
|
||||
}
|
||||
|
||||
bool UDynamicBase::TryGetDynamicIntProperty(const FString& Key, int32& OutValue) const
|
||||
{
|
||||
return TryGetDynamicProperty(Key, OutValue);
|
||||
}
|
||||
|
||||
bool UDynamicBase::TryGetDynamicFloatProperty(const FString& Key, float& OutValue) const
|
||||
{
|
||||
return TryGetDynamicProperty(Key, OutValue);
|
||||
}
|
||||
|
||||
bool UDynamicBase::TryGetDynamicBoolProperty(const FString& Key, bool& OutValue) const
|
||||
{
|
||||
return TryGetDynamicProperty(Key, OutValue);
|
||||
}
|
||||
|
||||
bool UDynamicBase::TryGetDynamicBaseProperty(const FString& Key, UBase*& OutValue) const
|
||||
{
|
||||
return TryGetDynamicProperty(Key, OutValue);
|
||||
}
|
||||
|
||||
void UDynamicBase::SetDynamicStringProperty(const FString& Key, FString& OutValue)
|
||||
{
|
||||
SetDynamicProperty(Key, OutValue);
|
||||
}
|
||||
|
||||
void UDynamicBase::SetDynamicIntProperty(const FString& Key, int32& OutValue)
|
||||
{
|
||||
SetDynamicProperty(Key, OutValue);
|
||||
}
|
||||
|
||||
void UDynamicBase::SetDynamicFloatProperty(const FString& Key, float& OutValue)
|
||||
{
|
||||
SetDynamicProperty(Key, OutValue);
|
||||
}
|
||||
|
||||
void UDynamicBase::SetDynamicBoolProperty(const FString& Key, bool& OutValue)
|
||||
{
|
||||
SetDynamicProperty(Key, OutValue);
|
||||
}
|
||||
|
||||
void UDynamicBase::SetDynamicBaseProperty(const FString& Key, UBase*& OutValue)
|
||||
{
|
||||
SetDynamicProperty(Key, OutValue);
|
||||
}
|
||||
|
||||
@@ -105,6 +105,64 @@ bool UMesh::Parse(const TSharedPtr<FJsonObject> Obj, const TScriptInterface<ITra
|
||||
return Vertices.Num() > 0 && Faces.Num() > 0;
|
||||
}
|
||||
|
||||
void UMesh::ToJson(TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>> Writer)
|
||||
{
|
||||
Super::ToJson(Writer);
|
||||
|
||||
// Serialize Transform
|
||||
// TODO todo transform
|
||||
|
||||
// Serialize Vertices
|
||||
{
|
||||
TArray<double> FlattenedVertices;
|
||||
FlattenedVertices.Reserve(Vertices.Num() * 3);
|
||||
for(size_t i = 0, j = 0; i < Vertices.Num(); i++)
|
||||
{
|
||||
const FVector& v = Vertices[i];
|
||||
FlattenedVertices[j++] = v.X;
|
||||
FlattenedVertices[j++] = -v.Y;
|
||||
FlattenedVertices[j++] = v.Z;
|
||||
}
|
||||
Writer.WriteValue(TEXT("vertices"), FlattenedVertices);
|
||||
}
|
||||
|
||||
// Serialize Faces
|
||||
Writer.WriteValue(TEXT("faces"), Faces);
|
||||
|
||||
|
||||
//Parse TextureCoords
|
||||
{
|
||||
TArray<double> FlattenedTexCoords;
|
||||
FlattenedTexCoords.Reserve(TextureCoordinates.Num() * 2);
|
||||
for(size_t i = 0, j = 0; i < TextureCoordinates.Num(); i++)
|
||||
{
|
||||
const FVector2D& c = TextureCoordinates[i];
|
||||
FlattenedTexCoords[j++] = c.X;
|
||||
FlattenedTexCoords[j++] = -c.Y;
|
||||
}
|
||||
Writer.WriteValue(TEXT("textureCoordinates"), FlattenedTexCoords);
|
||||
}
|
||||
|
||||
//Parse VertexColors
|
||||
{
|
||||
TArray<int32> ArgbColors;
|
||||
ArgbColors.Reserve(VertexColors.Num());
|
||||
for(size_t i = 0; i < VertexColors.Num(); i++)
|
||||
{
|
||||
ArgbColors[i] = VertexColors[i].ToPackedARGB();
|
||||
}
|
||||
Writer.WriteValue(TEXT("colors"), ArgbColors);
|
||||
}
|
||||
|
||||
|
||||
// Parse Optional RenderMaterial
|
||||
//if (RenderMaterial != nullptr)
|
||||
{
|
||||
//TODO renderMaterial
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If not already so, this method will align vertices
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "FBatchSender.h"
|
||||
|
||||
FBatchSender::FBatchSender(FString& ServerUrl, FString& StreamId, FString& AuthToken, int32 MaxBatchSizeMb,
|
||||
int32 MaxBufferLength, int32 ThreadCount)
|
||||
: ServerUrl(ServerUrl)
|
||||
, StreamId(StreamId)
|
||||
, AuthToken(AuthToken)
|
||||
, MaxBatchSizeMb(MaxBatchSizeMb)
|
||||
, MaxBufferLength(MaxBufferLength)
|
||||
, ThreadCount(ThreadCount)
|
||||
{
|
||||
SendingThread = FRunnableThread::Create(this, TEXT("Speckle Transport Send Thread"), 0);
|
||||
ensure(SendingThread != nullptr);
|
||||
}
|
||||
|
||||
FBatchSender::~FBatchSender()
|
||||
{
|
||||
if (SendingThread)
|
||||
{
|
||||
SendingThread->Kill();
|
||||
delete SendingThread;
|
||||
SendingThread = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32 FBatchSender::Run()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
if(!ShouldSendThreadRun) return 0;
|
||||
|
||||
TArray<TTuple<FString, FString>> Buffer;
|
||||
FScopeLock Lock(&Lock_SendBuffer);
|
||||
if(SendBuffer.Num() > 0)
|
||||
{
|
||||
Buffer.Append(SendBuffer);
|
||||
SendBuffer.Empty();
|
||||
}
|
||||
else
|
||||
{
|
||||
IsWriteComplete = true;
|
||||
}
|
||||
|
||||
if(Buffer.Num() <= 0)
|
||||
{
|
||||
FPlatformProcess::Sleep(0.1);
|
||||
continue;
|
||||
}
|
||||
|
||||
TArray<FString> ObjectIds;
|
||||
ObjectIds.Reserve(Buffer.Num());
|
||||
for(const auto& Item: Buffer)
|
||||
{
|
||||
ObjectIds.Add(Item.Key);
|
||||
}
|
||||
|
||||
//TODO only send objects that aren't already on the server.
|
||||
//TMap<FString, bool> HasObjects = API.HasObjects(StreamId, ObjectIds);
|
||||
|
||||
//TODO api upload
|
||||
//API.UploadObjects(StreamId, Buffer);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void FBatchSender::Stop()
|
||||
{
|
||||
ShouldSendThreadRun = false;
|
||||
}
|
||||
|
||||
void FBatchSender::EnqueueSend(const FString& Id, const FString& Object)
|
||||
{
|
||||
FScopeLock Lock(&Lock_SendBuffer);
|
||||
SendBuffer.Emplace(Id, Object);
|
||||
IsWriteComplete = false;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class SPECKLEUNREAL_API FBatchSender : public FRunnable
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
FString ServerUrl;
|
||||
FString StreamId;
|
||||
FString AuthToken;
|
||||
int32 MaxBatchSizeMb;
|
||||
int32 MaxBufferLength;
|
||||
int32 ThreadCount;
|
||||
|
||||
bool ShouldSendThreadRun = false;
|
||||
bool IsWriteComplete = false;
|
||||
FRunnableThread* SendingThread;
|
||||
FCriticalSection Lock_SendBuffer;
|
||||
TArray<TTuple<const FString, const FString>> SendBuffer;
|
||||
|
||||
public:
|
||||
|
||||
FBatchSender(FString& ServerUrl, FString& StreamId, FString& AuthToken, int32 MaxBatchSizeMb=1, int32 MaxBufferLength = 10, int32 ThreadCount = 4);
|
||||
|
||||
virtual ~FBatchSender() override;
|
||||
|
||||
virtual uint32 Run() override;
|
||||
virtual void Stop() override;
|
||||
|
||||
|
||||
virtual void EnqueueSend(const FString& Id, const FString& Object);
|
||||
virtual void Flush();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void SendingThreadMain();
|
||||
};
|
||||
@@ -8,7 +8,6 @@ bool UMemoryTransport::HasObject(const FString& ObjectId) const
|
||||
return SpeckleObjects.Contains(ObjectId);
|
||||
}
|
||||
|
||||
|
||||
TSharedPtr<FJsonObject> UMemoryTransport::GetSpeckleObject(const FString& ObjectId) const
|
||||
{
|
||||
return SpeckleObjects.FindRef(ObjectId);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "Transports/ServerTransport.h"
|
||||
|
||||
#include "FBatchSender.h"
|
||||
#include "LogSpeckle.h"
|
||||
#include "HttpModule.h"
|
||||
#include "JsonObjectConverter.h"
|
||||
@@ -12,20 +13,39 @@
|
||||
#include "Policies/CondensedJsonPrintPolicy.h"
|
||||
|
||||
|
||||
|
||||
|
||||
TSharedPtr<FJsonObject> UServerTransport::GetSpeckleObject(const FString& ObjectId) const
|
||||
{
|
||||
unimplemented();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void UServerTransport::SaveObject(const FString& ObjectId, const TSharedPtr<FJsonObject> SerializedObject)
|
||||
void UServerTransport::SaveObject(const FString& ObjectId, const TSharedPtr<FJsonObject> Object)
|
||||
{
|
||||
unimplemented(); //TODO implement
|
||||
FString SerializedObject;
|
||||
{
|
||||
auto Writer = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>::Create(&SerializedObject);
|
||||
FJsonSerializerWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>> SerializerWriter(Writer);
|
||||
FJsonSerializer::Serialize(Object.ToSharedRef(), Writer);
|
||||
}
|
||||
|
||||
BatchSender.EnqueueSend(ObjectId, SerializedObject);
|
||||
}
|
||||
|
||||
void UServerTransport::BeginWrite()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UServerTransport::EndWrite()
|
||||
{
|
||||
BatchSender.Flush();
|
||||
}
|
||||
|
||||
bool UServerTransport::HasObject(const FString& ObjectId) const
|
||||
{
|
||||
unimplemented(); //TODO implement
|
||||
unimplemented();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,47 +1,48 @@
|
||||
// // Copyright 2022 AEC Systems, Licensed under the Apache License, Version 2.0
|
||||
//
|
||||
// #pragma once
|
||||
//
|
||||
// #include "CoreMinimal.h"
|
||||
// #include "Kismet/BlueprintAsyncActionBase.h"
|
||||
//
|
||||
// #include "SendOperation.generated.h"
|
||||
//
|
||||
//
|
||||
// class ITransport;
|
||||
// class UBase;
|
||||
//
|
||||
// DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FSendOperationHandler, const FString&, Id, const FString&, ErrorMessage);
|
||||
//
|
||||
// /**
|
||||
// *
|
||||
// */
|
||||
// UCLASS()
|
||||
// class SPECKLEUNREAL_API USendOperation : public UBlueprintAsyncActionBase
|
||||
// {
|
||||
// GENERATED_BODY()
|
||||
//
|
||||
// public:
|
||||
//
|
||||
// UPROPERTY(BlueprintAssignable)
|
||||
// FSendOperationHandler OnSendSuccessfully;
|
||||
//
|
||||
//
|
||||
// UPROPERTY(BlueprintAssignable)
|
||||
// FSendOperationHandler OnErrorAction;
|
||||
//
|
||||
//
|
||||
// UFUNCTION(BlueprintCallable, Category = "Speckle|Operations", meta = (WorldContext = "WorldContextObject"))
|
||||
// static USendOperation* SendOperation(UObject* WorldContextObject, UBase* Base, TArray<TScriptInterface<ITransport>> Transports);
|
||||
//
|
||||
// virtual void Activate() override;
|
||||
//
|
||||
// protected:
|
||||
//
|
||||
//
|
||||
// TWeakObjectPtr<UBase> Base;
|
||||
//
|
||||
// TScriptArray<TScriptInterface<ITransport>> Transports;
|
||||
//
|
||||
//
|
||||
// };
|
||||
// Copyright 2022 AEC Systems, Licensed under the Apache License, Version 2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintAsyncActionBase.h"
|
||||
|
||||
#include "SendOperation.generated.h"
|
||||
|
||||
|
||||
class ITransport;
|
||||
class UBase;
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FSendOperationHandler, const FString&, Id, const FString&, ErrorMessage);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class SPECKLEUNREAL_API USendOperation : public UBlueprintAsyncActionBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FSendOperationHandler OnSendSuccessfully;
|
||||
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FSendOperationHandler OnErrorAction;
|
||||
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Speckle|Operations", meta = (WorldContext = "WorldContextObject"))
|
||||
static USendOperation* SendOperation(UObject* WorldContextObject, UBase* Base, TArray<TScriptInterface<ITransport>> Transports);
|
||||
|
||||
virtual void Activate() override;
|
||||
void Send();
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
TWeakObjectPtr<UBase> Base;
|
||||
|
||||
TArray<TScriptInterface<ITransport>> Transports;
|
||||
|
||||
|
||||
};
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
virtual bool CanConvertToNative_Implementation(TSubclassOf<UBase> BaseType) override;
|
||||
|
||||
|
||||
virtual UBase* ConvertToSpeckle_Implementation(const UObject* Object) override;
|
||||
virtual void ConvertToSpeckle_Implementation(const UObject* Object, UBase* SpeckleObject) override;
|
||||
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Conversion")
|
||||
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
UStaticMeshConverter();
|
||||
|
||||
virtual UObject* ConvertToNative_Implementation(const UBase* SpeckleBase, UWorld* World, TScriptInterface<ISpeckleConverter>& AvailableConverters) override;
|
||||
virtual UBase* ConvertToSpeckle_Implementation(const UObject* Object) override;
|
||||
virtual void ConvertToSpeckle_Implementation(const UObject* Object, UBase* SpeckleObject) override;
|
||||
virtual void FinishConversion_Implementation() override;
|
||||
|
||||
// Converts a multiple Speckle Meshes to a native actor of type MeshActorType
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
FActorSpawnParameters());
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="ToSpeckle")
|
||||
virtual UBase* MeshToSpeckle(const UStaticMeshComponent* Object);
|
||||
virtual TArray<UMesh*> MeshToSpeckle(const UStaticMeshComponent* Object);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
@@ -34,13 +34,22 @@ public:
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="ToNative")
|
||||
UObject* ConvertToNative(const UBase* SpeckleBase, UWorld* World, UPARAM(ref) TScriptInterface<ISpeckleConverter>& AvailableConverters);
|
||||
|
||||
/// Tries to convert a given Actor or Component into a Speckle Base
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="ToSpeckle")
|
||||
UBase* ConvertToSpeckle(const UObject* Object);
|
||||
|
||||
/// Clean up any cached assets that now may be unused
|
||||
/// Clean up cached resources, and finish any pending build tasks to complete ToNative conversion.
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="ToNative")
|
||||
void FinishConversion();
|
||||
|
||||
|
||||
/// Will return true if this converter can convert a given
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="ToSpeckle")
|
||||
void CanConvertToSpeckle(const AActor* Actor);
|
||||
|
||||
/// Tries to convert a given Actor or Component into a Speckle Base
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="ToSpeckle")
|
||||
void ConvertToSpeckle(const UObject* Object, UBase* SpeckleObject);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "SpeckleConverterComponent.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_DELEGATE_TwoParams(FActorPredicate, const AActor*, Actor, bool&, OutShouldConvert);
|
||||
|
||||
class ITransport;
|
||||
class ISpeckleConverter;
|
||||
@@ -32,16 +33,25 @@ public:
|
||||
USpeckleConverterComponent();
|
||||
|
||||
// Converts the given Base and all children into native actors.
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Conversion")
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Conversion|ToNative")
|
||||
UPARAM(DisplayName = "RootActor") AActor* RecursivelyConvertToNative(AActor* AOwner, const UBase* Base, const TScriptInterface<ITransport>& LocalTransport, bool DisplayProgressBar, TArray<AActor*>& OutActors);
|
||||
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Conversion")
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Conversion|ToNative")
|
||||
virtual void FinishConversion();
|
||||
|
||||
// Converts the given Base and all children into native actors.
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Conversion|ToSpeckle")
|
||||
virtual UBase* RecursivelyConvertToSpeckle(const TArray<AActor*>& RootActors, FActorPredicate& Predicate);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Conversion|ToSpeckle")
|
||||
virtual void RecurseTreeToSpeckle(const AActor* RootActor, FActorPredicate& Predicate, TArray<UBase*>& OutConverted);
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual AActor* RecursivelyConvertToNative_Internal(AActor* AOwner, const UBase* Base, const TScriptInterface<ITransport>& LocalTransport, FSlowTask* Task, TArray<AActor*>& OutActors);
|
||||
|
||||
|
||||
virtual void ConvertChild(const TSharedPtr<FJsonValue> Object, AActor* AOwner, const TScriptInterface<ITransport>& LocalTransport, FSlowTask* Task, TArray<AActor*>& OutActors);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "DynamicBase.h"
|
||||
#include "Dom/JsonObject.h"
|
||||
|
||||
#include "Base.generated.h"
|
||||
@@ -14,7 +15,7 @@ class ASpeckleUnrealManager;
|
||||
* Base type that all Object Models inherit from
|
||||
*/
|
||||
UCLASS(BlueprintType, meta=(ScriptName="Base (Speckle.Objects)"))
|
||||
class SPECKLEUNREAL_API UBase : public UObject
|
||||
class SPECKLEUNREAL_API UBase : public UDynamicBase
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -33,8 +34,6 @@ public:
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category="Speckle|Objects")
|
||||
FString Id;
|
||||
|
||||
TMap<FString, TSharedPtr<FJsonValue>> DynamicProperties; //TODO this won't be serialised!
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category="Speckle|Objects")
|
||||
FString Units;
|
||||
|
||||
@@ -44,7 +43,12 @@ public:
|
||||
virtual bool Parse(const TSharedPtr<FJsonObject> Obj, const TScriptInterface<ITransport> ReadTransport)
|
||||
{
|
||||
bool IsValid = false;
|
||||
DynamicProperties = Obj->Values;
|
||||
DynamicProperties.Reserve(Obj->Values.Num());
|
||||
for(const auto kvp : Obj->Values)
|
||||
{
|
||||
SetDynamicProperty(kvp.Key, kvp.Value->Type);
|
||||
}
|
||||
|
||||
if(Obj->TryGetStringField("id", Id))
|
||||
{
|
||||
IsValid = true;
|
||||
@@ -57,37 +61,18 @@ public:
|
||||
return IsValid;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Objects")
|
||||
int32 RemoveDynamicProperty(UPARAM(ref) const FString& Key)
|
||||
virtual void ToJson(TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>> Writer)
|
||||
{
|
||||
return DynamicProperties.Remove(Key);
|
||||
}
|
||||
Writer.WriteValue(TEXT("units"), Units);
|
||||
Writer.WriteValue(TEXT("speckle_type"), SpeckleType);
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Objects")
|
||||
bool TryGetDynamicString(UPARAM(ref) const FString& Key, FString& OutString) const
|
||||
{
|
||||
const TSharedPtr<FJsonValue> Value = DynamicProperties.FindRef(Key);
|
||||
if(Value == nullptr) return false;
|
||||
return Value->TryGetString(OutString);
|
||||
for(const auto& p : DynamicProperties)
|
||||
{
|
||||
//Writer.WriteValue(p.Key, p.Value.mmmmmm));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Objects")
|
||||
bool TryGetDynamicNumber(UPARAM(ref) const FString& Key, float& OutNumber) const
|
||||
{
|
||||
const TSharedPtr<FJsonValue> Value = DynamicProperties.FindRef(Key);
|
||||
if(Value == nullptr) return false;
|
||||
return Value->TryGetNumber(OutNumber);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Objects")
|
||||
bool TryGetDynamicBool(UPARAM(ref) const FString& Key, bool& OutBool) const
|
||||
{
|
||||
const TSharedPtr<FJsonValue> Value = DynamicProperties.FindRef(Key);
|
||||
if(Value == nullptr) return false;
|
||||
return Value->TryGetBool(OutBool);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright AEC Systems Ltd
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "DynamicBase.generated.h"
|
||||
|
||||
|
||||
|
||||
class UBase;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS(Abstract)
|
||||
class SPECKLEUNREAL_API UDynamicBase : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
protected:
|
||||
|
||||
TMap<FString, TSharedPtr<FVariant>> DynamicProperties;
|
||||
|
||||
public:
|
||||
|
||||
template <typename T>
|
||||
bool TryGetDynamicProperty(const FString& Key, T& OutValue) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Objects")
|
||||
bool TryGetDynamicStringProperty(UPARAM(ref) const FString& Key, FString& OutValue) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Objects")
|
||||
bool TryGetDynamicIntProperty(UPARAM(ref) const FString& Key, int32& OutValue) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Objects")
|
||||
bool TryGetDynamicFloatProperty(UPARAM(ref) const FString& Key, float& OutValue) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Objects")
|
||||
bool TryGetDynamicBoolProperty(UPARAM(ref) const FString& Key, bool& OutValue) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Objects")
|
||||
bool TryGetDynamicBaseProperty(UPARAM(ref) const FString& Key, UBase*& OutValue) const;
|
||||
|
||||
|
||||
template <typename T>
|
||||
void SetDynamicProperty(const FString& Key, T Value);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Objects")
|
||||
void SetDynamicStringProperty(UPARAM(ref) const FString& Key, FString& OutValue);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Objects")
|
||||
void SetDynamicIntProperty(UPARAM(ref) const FString& Key, int32& OutValue);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Objects")
|
||||
void SetDynamicFloatProperty(UPARAM(ref) const FString& Key, float& OutValue);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Objects")
|
||||
void SetDynamicBoolProperty(UPARAM(ref) const FString& Key, bool& OutValue);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Objects")
|
||||
void SetDynamicBaseProperty(UPARAM(ref) const FString& Key, UBase*& OutValue);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Objects")
|
||||
int32 RemoveDynamicProperty(UPARAM(ref) const FString& Key);
|
||||
|
||||
};
|
||||
@@ -41,6 +41,8 @@ public:
|
||||
|
||||
virtual bool Parse(const TSharedPtr<FJsonObject> Obj, const TScriptInterface<ITransport> ReadTransport) override;
|
||||
|
||||
virtual void ToJson(TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>> Writer) override;
|
||||
|
||||
protected:
|
||||
virtual void AlignVerticesWithTexCoordsByIndex();
|
||||
};
|
||||
|
||||
@@ -44,6 +44,6 @@ public:
|
||||
UFUNCTION(BlueprintPure, Category="Speckle/ObjectUtils")
|
||||
static FTransform CreateTransform(UPARAM(ref) const FMatrix& TransformMatrix);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle/ObjectUtils")
|
||||
UFUNCTION(BlueprintCallable, meta = (DeterminesOutputType = "Class"), Category="Speckle/ObjectUtils")
|
||||
static AActor* SpawnActorInWorld(const TSubclassOf<AActor> Class, UWorld* World, UPARAM(ref) const FTransform& Transform);
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ class SPECKLEUNREAL_API UMemoryTransport : public UObject, public ITransport
|
||||
public:
|
||||
|
||||
virtual TSharedPtr<FJsonObject> GetSpeckleObject(const FString& ObjectId) const override;
|
||||
virtual void SaveObject(const FString& ObjectId, const TSharedPtr<FJsonObject> SerializedObject) override;
|
||||
virtual void SaveObject(const FString& ObjectId, const FString& SerializedObject) override;
|
||||
|
||||
virtual bool HasObject(const FString& ObjectId) const override;
|
||||
virtual void CopyObjectAndChildren(const FString& ObjectId, TScriptInterface<ITransport> TargetTransport, const FTransportCopyObjectCompleteDelegate& OnCompleteAction, const FTransportErrorDelegate& OnErrorAction) override { unimplemented(); }
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "ServerTransport.generated.h"
|
||||
|
||||
|
||||
class FBatchSender;
|
||||
class FHttpModule;
|
||||
|
||||
// Data for graphQL request for object ids.
|
||||
@@ -47,6 +47,8 @@ protected:
|
||||
public:
|
||||
|
||||
|
||||
virtual ~UServerTransport() override;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Speckle|Transports")
|
||||
static UServerTransport* CreateServerTransport(UPARAM(ref) FString& _ServerUrl, UPARAM(ref) FString& _StreamId, UPARAM(ref) FString& _AuthToken)
|
||||
{
|
||||
@@ -58,7 +60,10 @@ public:
|
||||
}
|
||||
|
||||
virtual TSharedPtr<FJsonObject> GetSpeckleObject(const FString& ObjectId) const override;
|
||||
|
||||
virtual void SaveObject(const FString& ObjectId, const TSharedPtr<FJsonObject> SerializedObject) override;
|
||||
virtual void BeginWrite() override;
|
||||
virtual void EndWrite() override;
|
||||
|
||||
virtual bool HasObject(const FString& ObjectId) const override;
|
||||
|
||||
@@ -88,6 +93,11 @@ protected:
|
||||
static bool LoadJson(const FString& ObjectJson, TSharedPtr<FJsonObject>& OutJsonObject);
|
||||
static int32 SplitLines(const FString& Content, TArray<FString>& OutLines);
|
||||
|
||||
FBatchSender BatchSender;
|
||||
|
||||
// FCriticalSection Lock_SendBuffer;
|
||||
// TArray<TTuple<const FString, const FString>> SendBuffer;
|
||||
// FRunnableThread* SendingThread;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -28,13 +28,16 @@ class SPECKLEUNREAL_API ITransport
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
virtual void SaveObject(const FString& ObjectId, const TSharedPtr<FJsonObject> SerializedObject) = 0;
|
||||
//TODO consider changing SerializedObject to FString&
|
||||
virtual void SaveObject(const FString& ObjectId, const TSharedPtr<FJsonObject> SerializedObject) = 0;
|
||||
|
||||
//virtual void SaveObjectFromTransport(FString& ObjectID, TScriptInterface<ITransport> SourceTransport) = 0;
|
||||
|
||||
virtual TSharedPtr<FJsonObject> GetSpeckleObject(const FString& ObjectId) const = 0;
|
||||
virtual bool HasObject(const FString& ObjectId) const;
|
||||
|
||||
virtual bool HasObject(const FString& ObjectId) const = 0;
|
||||
virtual void BeginWrite();
|
||||
virtual void EndWrite();
|
||||
|
||||
virtual void CopyObjectAndChildren(const FString& ObjectId,
|
||||
TScriptInterface<ITransport> TargetTransport,
|
||||
|
||||
Reference in New Issue
Block a user