void FWorkerConnection::WaitForConnectionFuture( std::uint32_t TimeoutMillis, SpatialOSFuture<SpatialOSConnection> ConnectionFuture, FOnConnectedDelegate OnConnectedCallback) { if (ConnectionFuture.Wait(TimeoutMillis)) { auto WorkerConnection = TSharedPtr<SpatialOSConnection>(new SpatialOSConnection{ConnectionFuture.Get()}); if (WorkerConnection->IsConnected()) { AsyncTask(ENamedThreads::GameThread, [OnConnectedCallback, WorkerConnection, this]() { Connection = WorkerConnection; OnConnectedCallback.Execute(true); }); UE_LOG(LogSpatialOS, Log, TEXT("Connected.")); } else { AsyncTask(ENamedThreads::GameThread, [OnConnectedCallback]() { OnConnectedCallback.Execute(false); }); UE_LOG(LogSpatialOS, Error, TEXT("Connection failed.")); } } else { AsyncTask(ENamedThreads::GameThread, [OnConnectedCallback]() { OnConnectedCallback.Execute(false); }); UE_LOG(LogSpatialOS, Error, TEXT("Connection timed out.")); } bIsConnecting = false; }
void UCarlaSettingsDelegate::SetAllActorsDrawDistance(UWorld* world, const float max_draw_distance) const { ///@TODO: use semantics to grab all actors by type (vehicles,ground,people,props) and set different distances configured in the global properties if(!world||!IsValid(world)||world->IsPendingKill()) return; AsyncTask(ENamedThreads::GameThread, [=](){ if(!world||!IsValid(world)||world->IsPendingKill()) return; TArray<AActor*> actors; #define _MAX_SCALE_SIZE 50.0f //set the lower quality - max draw distance UGameplayStatics::GetAllActorsOfClass(world, AActor::StaticClass(),actors); for(int32 i=0; i<actors.Num(); i++) { AActor* actor = actors[i]; if(!IsValid(actor) || actor->IsPendingKill() || actor->IsA<AInstancedFoliageActor>() || //foliage culling is controlled per instance actor->IsA<ALandscape>() || //dont touch landscapes nor roads actor->ActorHasTag(UCarlaSettings::CARLA_ROAD_TAG) || actor->ActorHasTag(UCarlaSettings::CARLA_SKY_TAG) ){ continue; } SetActorComponentsDrawDistance(actor, max_draw_distance); } }); }
void FWorkerConnection::GetDeploymentListAsync( const FString& ProjectName, const FString& LocatorHost, const FString& LoginToken, FOnDeploymentsFoundDelegate OnDeploymentsFoundCallback, std::uint32_t TimeoutMillis) { AsyncTask(ENamedThreads::GameThread, [ProjectName, LocatorHost, LoginToken, TimeoutMillis, OnDeploymentsFoundCallback, this]() { WaitForDeploymentFuture( TimeoutMillis, CreateLocator(ProjectName, LocatorHost, LoginToken).GetDeploymentListAsync(), OnDeploymentsFoundCallback); }); }
void FWorkerConnection::WaitForDeploymentFuture( std::uint32_t TimeoutMillis, SpatialOSFuture<worker::DeploymentList> DeploymentListFuture, FOnDeploymentsFoundDelegate OnDeploymentsFoundCallback) { if (DeploymentListFuture.Wait(TimeoutMillis)) { auto DeploymentList = DeploymentListFuture.Get(); AsyncTask(ENamedThreads::GameThread, [DeploymentList, OnDeploymentsFoundCallback]() { OnDeploymentsFoundCallback.Execute(DeploymentList); }); } else { AsyncTask(ENamedThreads::GameThread, [OnDeploymentsFoundCallback]() { OnDeploymentsFoundCallback.Execute( worker::DeploymentList{worker::List<worker::Deployment>{}, std::string{"Timed out waiting for deployment list."}}); }); } }
void FWorkerConnection::ConnectToLocatorAsync( const FString& ProjectName, const FString& LocatorHost, const FString& DeploymentId, const FString& LoginToken, const worker::ConnectionParameters& Params, FQueueStatusDelegate QueueStatusCallback, FOnConnectedDelegate OnConnectedCallback, std::uint32_t TimeoutMillis) { if (!CanCreateNewConnection()) { UE_LOG( LogSpatialOS, Error, TEXT("Can not connect to SpatialOS; a connection already exists. Call Disconnect first.")); return; } auto QueueStatusWrapper = [QueueStatusCallback](const worker::QueueStatus& status) { TPromise<bool> QueueStatusCallbackReturnValue; auto QueueStatusReturnValueFuture = QueueStatusCallbackReturnValue.GetFuture(); AsyncTask(ENamedThreads::GameThread, [QueueStatusCallback, status, &QueueStatusCallbackReturnValue]() { QueueStatusCallbackReturnValue.SetValue(QueueStatusCallback.Execute(status)); }); return QueueStatusReturnValueFuture.Get(); }; bIsConnecting = true; AsyncTask(ENamedThreads::AnyBackgroundThreadNormalTask, [ProjectName, LocatorHost, LoginToken, TimeoutMillis, DeploymentId, Params, QueueStatusWrapper, OnConnectedCallback, this]() { WaitForConnectionFuture(TimeoutMillis, CreateLocator(ProjectName, LocatorHost, LoginToken) .ConnectAsync(improbable::unreal::Components{}, TCHAR_TO_UTF8(*DeploymentId), Params, QueueStatusWrapper), OnConnectedCallback); }); }
void UCarlaSettingsDelegate::SetAllRoads(UWorld* world, const float max_draw_distance, const TArray<FStaticMaterial> &road_pieces_materials) const { if(!world||!IsValid(world)||world->IsPendingKill()) return; AsyncTask(ENamedThreads::GameThread, [=](){ if(!world||!IsValid(world)||world->IsPendingKill()) return; TArray<AActor*> actors; UGameplayStatics::GetAllActorsWithTag(world, UCarlaSettings::CARLA_ROAD_TAG,actors); for(int32 i=0; i<actors.Num(); i++) { AActor* actor = actors[i]; if(!IsValid(actor) || actor->IsPendingKill()) continue; TArray<UActorComponent*> components = actor->GetComponentsByClass(UStaticMeshComponent::StaticClass()); for(int32 j=0; j<components.Num(); j++) { UStaticMeshComponent* staticmeshcomponent = Cast<UStaticMeshComponent>(components[j]); if(staticmeshcomponent) { staticmeshcomponent->bAllowCullDistanceVolume = (max_draw_distance>0); staticmeshcomponent->bUseAsOccluder = false; staticmeshcomponent->LDMaxDrawDistance = max_draw_distance; staticmeshcomponent->CastShadow = (max_draw_distance==0); if(road_pieces_materials.Num()>0) { TArray<FName> meshslotsnames = staticmeshcomponent->GetMaterialSlotNames(); for(int32 k=0; k<meshslotsnames.Num(); k++) { const FName &slotname = meshslotsnames[k]; road_pieces_materials.ContainsByPredicate( [staticmeshcomponent,slotname](const FStaticMaterial& material) { if(material.MaterialSlotName.IsEqual(slotname)) { staticmeshcomponent->SetMaterial( staticmeshcomponent->GetMaterialIndex(slotname), material.MaterialInterface ); return true; } else return false; }); } } } } } }); //,DELAY_TIME_TO_SET_ALL_ROADS, false); }
TFunction<void()> AARCharacter::SpatialComplete() { //DrawBox() auto func = [&]() { auto func2 = [&]() { for (const FVector& Pos : Result.Get().Data) { DrawDebugPoint(GetWorld(), Pos, 20, FColor::Red, true, 10); } }; AsyncTask(ENamedThreads::GameThread, func2); }; return func; }
void FWorkerConnection::ConnectToReceptionistAsync(const FString& Hostname, std::uint16_t Port, const FString& WorkerId, const worker::ConnectionParameters& Params, FOnConnectedDelegate OnConnectedCallback, std::uint32_t TimeoutMillis) { if (!CanCreateNewConnection()) { return; } UE_LOG(LogSpatialOS, Log, TEXT("Connecting to %s:%i..."), *Hostname, Port); bIsConnecting = true; AsyncTask(ENamedThreads::AnyBackgroundThreadNormalTask, [TimeoutMillis, Hostname, Port, WorkerId, Params, OnConnectedCallback, this]() { WaitForConnectionFuture(TimeoutMillis, SpatialOSConnection::ConnectAsync( improbable::unreal::Components{}, std::string{TCHAR_TO_UTF8(*Hostname)}, Port, std::string{TCHAR_TO_UTF8(*WorkerId)}, Params), OnConnectedCallback); }); }
void UCarlaSettingsDelegate::SetAllLights(UWorld* world, const float max_distance_fade, const bool cast_shadows, const bool hide_non_directional) const { if(!world||!IsValid(world)||world->IsPendingKill()) return; AsyncTask(ENamedThreads::GameThread, [=](){ if(!world||!IsValid(world)||world->IsPendingKill()) return; TArray<AActor*> actors; UGameplayStatics::GetAllActorsOfClass(world, ALight::StaticClass(), actors); for(int32 i=0;i<actors.Num();i++) { if(!IsValid(actors[i]) || actors[i]->IsPendingKill()) continue; //tweak directional lights ADirectionalLight* directionallight = Cast<ADirectionalLight>(actors[i]); if(directionallight) { directionallight->SetCastShadows(cast_shadows); directionallight->SetLightFunctionFadeDistance(max_distance_fade); continue; } //disable any other type of light actors[i]->SetActorHiddenInGame(hide_non_directional); } }); }
void FluidApplication::StartFluidEvolveTask() { auto evolve = std::bind(&Fluid::Evolve, &_fluid, 0.25f); AsyncTask(UWM_EVOLVE_FLUID_TASK, GetHwnd()).Run(evolve); }