// Fill out your copyright notice in the Description page of Project Settings. #include "API/Operations/ReceiveOperation.h" #include "Dom/JsonObject.h" #include "Transports/Transport.h" #include "API/SpeckleSerializer.h" #include "LogSpeckle.h" #include "Objects/Base.h" #include "Mixpanel.h" // ReceiveOperation UReceiveOperation* UReceiveOperation::ReceiveOperation(UObject* WorldContextObject, const FString& ObjectId, TScriptInterface RemoteTransport, TScriptInterface LocalTransport) { UReceiveOperation* Node = NewObject(); Node->ObjectId = ObjectId; Node->RemoteTransport = RemoteTransport; Node->LocalTransport = LocalTransport; Node->RegisterWithGameInstance(WorldContextObject); return Node; } // Activate void UReceiveOperation::Activate() { FAnalytics::TrackEvent("unknown", "unknown", "NodeRun", TMap { {"name", StaticClass()->GetName() }}); //Async(EAsyncExecution::Thread, [this]{Receive();}); Receive(); } void UReceiveOperation::Receive() { check(LocalTransport != nullptr); // 1. Try and get object from local transport auto Obj = LocalTransport->GetSpeckleObject(ObjectId); if (Obj != nullptr ) { HandleReceive(Obj); return; } // 2. Try and get object from remote transport if(RemoteTransport == nullptr) { FString ErrorMessage = TEXT( "Could not find specified object using the local transport, and you didn't provide a fallback remote from which to pull it."); HandleError(ErrorMessage); return; } FTransportCopyObjectCompleteDelegate CompleteDelegate; CompleteDelegate.BindUObject(this, &UReceiveOperation::HandleReceive); FTransportErrorDelegate ErrorDelegate; ErrorDelegate.BindUObject(this, &UReceiveOperation::HandleError); RemoteTransport->CopyObjectAndChildren(ObjectId, LocalTransport, CompleteDelegate, ErrorDelegate); } void UReceiveOperation::HandleReceive(TSharedPtr Object) { check(IsInGameThread()) // FString OutputString; // TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&OutputString); // FJsonSerializer::Serialize(Object.ToSharedRef(), Writer); //UE_LOG(LogSpeckle, Log, TEXT("JSoN: %s"), *OutputString); FEditorScriptExecutionGuard ScriptGuard; if(Object == nullptr) { OnError.Broadcast(nullptr, FString::Printf(TEXT("Failed to get object %s from transport"), *ObjectId), TArray(), TArray() ); } else { UBase* Res = USpeckleSerializer::DeserializeBase(Object, LocalTransport); TMap> jsonMap = Object->Values; TArray Ids = TArray(); TArray LayerNames = TArray(); //UE_LOG(LogSpeckle, Log, TEXT("JSoN: %s"), *OutputString); for (auto &currJsonValue: jsonMap) { // Get the json key name FString Key = currJsonValue.Key; // Get the json value TSharedPtr Value = currJsonValue.Value; UE_LOG(LogTemp, Warning, TEXT("KEY NAME: %s "), *Key); if (Key.Contains("::")) { const TArray>* SubArrayPtr; if (Value->TryGetArray(SubArrayPtr)) { for (const TSharedPtr& ArrayElement : *SubArrayPtr) { const TSharedPtr* ArraySubObjPtr; if (ArrayElement->TryGetObject(ArraySubObjPtr)) { // TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&id_mesh); // FJsonSerializer::Serialize((*ArraySubObjPtr).ToSharedRef(), Writer); FString MeshId = (*ArraySubObjPtr)->GetStringField("referencedId"); Ids.Add(*MeshId); LayerNames.Add(*Key); //UE_LOG(LogTemp, Warning, TEXT("KEY VAL 2: %s - %s"), *id_mesh, *id_Layer ); } } } } } if(IsValid(Res)) { OnReceiveSuccessfully.Broadcast(Res, "", Ids, LayerNames); } else { OnError.Broadcast(nullptr, FString::Printf(TEXT("Root Speckle Object %s failed to deserialize"),*ObjectId), TArray(), TArray() ); } } SetReadyToDestroy(); } void UReceiveOperation::HandleError(FString& Message) { FEditorScriptExecutionGuard ScriptGuard; OnError.Broadcast(nullptr, Message, TArray(), TArray()); SetReadyToDestroy(); }