From 27dd87723bdced80fff1c96587a670bb616a49d8 Mon Sep 17 00:00:00 2001 From: Giser <65968233+newpeople123@users.noreply.github.com> Date: Wed, 30 Apr 2025 11:22:06 +0800 Subject: [PATCH] fix:Solution to https://community.cesium.com/t/it-took-more-than-ten-seconds-to-exit/23354 problem --- .../CesiumRuntime/Private/Cesium3DTileset.cpp | 22 ++++++++++ .../Private/CesiumBingMapsRasterOverlay.cpp | 5 +++ .../CesiumRuntime/Private/CesiumIonServer.cpp | 5 +++ .../Private/CesiumRasterOverlay.cpp | 40 ++++++++++++++++++- .../CesiumTileMapServiceRasterOverlay.cpp | 5 +++ .../CesiumUrlTemplateRasterOverlay.cpp | 5 +++ .../CesiumWebMapServiceRasterOverlay.cpp | 5 +++ .../CesiumWebMapTileServiceRasterOverlay.cpp | 5 +++ .../Private/UnrealAssetAccessor.cpp | 38 ++++++++++++++++++ .../Public/CesiumBingMapsRasterOverlay.h | 1 + .../Public/CesiumIonRasterOverlay.h | 1 + .../Public/CesiumRasterOverlay.h | 2 + .../CesiumTileMapServiceRasterOverlay.h | 1 + .../Public/CesiumUrlTemplateRasterOverlay.h | 1 + .../Public/CesiumWebMapServiceRasterOverlay.h | 1 + .../CesiumWebMapTileServiceRasterOverlay.h | 1 + .../Public/UnrealAssetAccessor.h | 3 ++ 17 files changed, 139 insertions(+), 2 deletions(-) diff --git a/Source/CesiumRuntime/Private/Cesium3DTileset.cpp b/Source/CesiumRuntime/Private/Cesium3DTileset.cpp index 40c835f26..62f1e4f7a 100644 --- a/Source/CesiumRuntime/Private/Cesium3DTileset.cpp +++ b/Source/CesiumRuntime/Private/Cesium3DTileset.cpp @@ -48,6 +48,7 @@ #include "StereoRendering.h" #include "UnrealPrepareRendererResources.h" #include "VecMath.h" +#include "UnrealAssetAccessor.h" #include #include #include @@ -2293,6 +2294,27 @@ void ACesium3DTileset::BeginDestroy() { bool ACesium3DTileset::IsReadyForFinishDestroy() { bool ready = AActor::IsReadyForFinishDestroy(); + + //If the request has not ended yet, actively cancel the request + { + FScopeLock lock(&UnrealAssetAccessor::_pendingRequestsLock); + for (const TSharedRef& pRequest : UnrealAssetAccessor::_pendingRequests) { + EHttpRequestStatus::Type status = pRequest->GetStatus(); + if (status == EHttpRequestStatus::NotStarted || status == EHttpRequestStatus::Processing) { + const FString& requestUrl = pRequest->GetURL(); + UE_LOG(LogTemp, Log, TEXT("3DTiles URL = %s, Request URL = %s"), *this->Url, *requestUrl); + if (this->TilesetSource == ETilesetSource::FromCesiumIon && requestUrl.Contains("CesiumWorldTerrain")) + pRequest->CancelRequest(); + else if (this->TilesetSource == ETilesetSource::FromUrl) { + FString originUrl = this->Url; + originUrl.RemoveFromEnd(TEXT("tileset.json")); + if (requestUrl.Contains(UCesiumRasterOverlay::ExtractCleanBaseUrl(originUrl))) + pRequest->CancelRequest(); + } + } + } + } + ready &= this->_tilesetsBeingDestroyed == 0; if (!ready) { diff --git a/Source/CesiumRuntime/Private/CesiumBingMapsRasterOverlay.cpp b/Source/CesiumRuntime/Private/CesiumBingMapsRasterOverlay.cpp index bcc7c0046..9e5981409 100644 --- a/Source/CesiumRuntime/Private/CesiumBingMapsRasterOverlay.cpp +++ b/Source/CesiumRuntime/Private/CesiumBingMapsRasterOverlay.cpp @@ -45,3 +45,8 @@ UCesiumBingMapsRasterOverlay::CreateOverlay( "", options); } + +bool UCesiumBingMapsRasterOverlay::IsReadyForFinishDestroy() { + this->SetUrl(TEXT("https://dev.virtualearth.net")); + return Super::IsReadyForFinishDestroy(); +} \ No newline at end of file diff --git a/Source/CesiumRuntime/Private/CesiumIonServer.cpp b/Source/CesiumRuntime/Private/CesiumIonServer.cpp index d7d803ed5..9ff5e2323 100644 --- a/Source/CesiumRuntime/Private/CesiumIonServer.cpp +++ b/Source/CesiumRuntime/Private/CesiumIonServer.cpp @@ -194,3 +194,8 @@ CesiumAsync::Future UCesiumIonServer::ResolveApiUrl() { }); } #endif + +bool UCesiumIonRasterOverlay::IsReadyForFinishDestroy() { + this->SetUrl(this->CesiumIonServer->ApiUrl); + return Super::IsReadyForFinishDestroy(); +} \ No newline at end of file diff --git a/Source/CesiumRuntime/Private/CesiumRasterOverlay.cpp b/Source/CesiumRuntime/Private/CesiumRasterOverlay.cpp index 1df30d070..9aa7110e3 100644 --- a/Source/CesiumRuntime/Private/CesiumRasterOverlay.cpp +++ b/Source/CesiumRuntime/Private/CesiumRasterOverlay.cpp @@ -7,6 +7,7 @@ #include "CesiumAsync/IAssetResponse.h" #include "CesiumRasterOverlays/RasterOverlayLoadFailureDetails.h" #include "CesiumRuntime.h" +#include "UnrealAssetAccessor.h" FCesiumRasterOverlayLoadFailure OnCesiumRasterOverlayLoadFailure{}; @@ -56,8 +57,9 @@ void UCesiumRasterOverlay::AddToTileset() { options.showCreditsOnScreen = this->ShowCreditsOnScreen; options.rendererOptions = &this->rendererOptions; options.loadErrorCallback = - [this](const CesiumRasterOverlays::RasterOverlayLoadFailureDetails& - details) { + [this]( + const CesiumRasterOverlays::RasterOverlayLoadFailureDetails& + details) { static_assert( uint8_t(ECesiumRasterOverlayLoadType::CesiumIon) == uint8_t(CesiumRasterOverlays::RasterOverlayLoadType::CesiumIon)); @@ -195,6 +197,40 @@ void UCesiumRasterOverlay::OnComponentDestroyed(bool bDestroyingHierarchy) { bool UCesiumRasterOverlay::IsReadyForFinishDestroy() { bool ready = Super::IsReadyForFinishDestroy(); + + // If the request has not ended yet, actively cancel the request + { + FScopeLock lock(&UnrealAssetAccessor::_pendingRequestsLock); + const FString originBaseUrl = ExtractCleanBaseUrl(_url); + for (const TSharedRef& pRequest : + UnrealAssetAccessor::_pendingRequests) { + EHttpRequestStatus::Type status = pRequest->GetStatus(); + if (status == EHttpRequestStatus::NotStarted || + status == EHttpRequestStatus::Processing) { + const FString& requestUrl = pRequest->GetURL(); + const FString requestBaseUrl = ExtractCleanBaseUrl(requestUrl); + + UE_LOG( + LogTemp, + Log, + TEXT("WMTS URL = %s, Request URL = %s"), + *_url, + *requestUrl); + if (_url == TEXT("https://dev.virtualearth.net") || + _url == TEXT("https://api.cesium.com")) { + // bing map + if (requestUrl.Contains(TEXT("tiles.virtualearth.net/tiles"))) { + pRequest->CancelRequest(); + } + } else if (originBaseUrl == requestBaseUrl) { + // other map(china Tianditu map\mapbox sate1lite map\arcgis online + // world map\and other map(with kvp or restful)) + pRequest->CancelRequest(); + } + } + } + } + ready &= this->_overlaysBeingDestroyed == 0; if (!ready) { diff --git a/Source/CesiumRuntime/Private/CesiumTileMapServiceRasterOverlay.cpp b/Source/CesiumRuntime/Private/CesiumTileMapServiceRasterOverlay.cpp index 769f182a5..271ea4fa6 100644 --- a/Source/CesiumRuntime/Private/CesiumTileMapServiceRasterOverlay.cpp +++ b/Source/CesiumRuntime/Private/CesiumTileMapServiceRasterOverlay.cpp @@ -33,3 +33,8 @@ UCesiumTileMapServiceRasterOverlay::CreateOverlay( tmsOptions, options); } + +bool UCesiumTileMapServiceRasterOverlay::IsReadyForFinishDestroy() { + this->SetUrl(this->Url); + return Super::IsReadyForFinishDestroy(); +} \ No newline at end of file diff --git a/Source/CesiumRuntime/Private/CesiumUrlTemplateRasterOverlay.cpp b/Source/CesiumRuntime/Private/CesiumUrlTemplateRasterOverlay.cpp index 2bebfa044..951e6b349 100644 --- a/Source/CesiumRuntime/Private/CesiumUrlTemplateRasterOverlay.cpp +++ b/Source/CesiumRuntime/Private/CesiumUrlTemplateRasterOverlay.cpp @@ -70,3 +70,8 @@ UCesiumUrlTemplateRasterOverlay::CreateOverlay( urlTemplateOptions, options); } + +bool UCesiumUrlTemplateRasterOverlay::IsReadyForFinishDestroy() { + this->SetUrl(this->TemplateUrl); + return Super::IsReadyForFinishDestroy(); +} \ No newline at end of file diff --git a/Source/CesiumRuntime/Private/CesiumWebMapServiceRasterOverlay.cpp b/Source/CesiumRuntime/Private/CesiumWebMapServiceRasterOverlay.cpp index 2e5c53642..9549dd027 100644 --- a/Source/CesiumRuntime/Private/CesiumWebMapServiceRasterOverlay.cpp +++ b/Source/CesiumRuntime/Private/CesiumWebMapServiceRasterOverlay.cpp @@ -37,3 +37,8 @@ UCesiumWebMapServiceRasterOverlay::CreateOverlay( wmsOptions, options); } + +bool UCesiumWebMapServiceRasterOverlay::IsReadyForFinishDestroy() { + this->SetUrl(this->BaseUrl); + return Super::IsReadyForFinishDestroy(); +} \ No newline at end of file diff --git a/Source/CesiumRuntime/Private/CesiumWebMapTileServiceRasterOverlay.cpp b/Source/CesiumRuntime/Private/CesiumWebMapTileServiceRasterOverlay.cpp index 1126246c3..26302fe9b 100644 --- a/Source/CesiumRuntime/Private/CesiumWebMapTileServiceRasterOverlay.cpp +++ b/Source/CesiumRuntime/Private/CesiumWebMapTileServiceRasterOverlay.cpp @@ -119,3 +119,8 @@ UCesiumWebMapTileServiceRasterOverlay::CreateOverlay( wmtsOptions, options); } + +bool UCesiumWebMapTileServiceRasterOverlay::IsReadyForFinishDestroy() { + this->SetUrl(this->BaseUrl); + return Super::IsReadyForFinishDestroy(); +} \ No newline at end of file diff --git a/Source/CesiumRuntime/Private/UnrealAssetAccessor.cpp b/Source/CesiumRuntime/Private/UnrealAssetAccessor.cpp index 663ff7a8f..5f7053e1e 100644 --- a/Source/CesiumRuntime/Private/UnrealAssetAccessor.cpp +++ b/Source/CesiumRuntime/Private/UnrealAssetAccessor.cpp @@ -176,6 +176,9 @@ void rejectPromiseOnUnsuccessfulConnection( } // namespace +TSet> UnrealAssetAccessor::_pendingRequests; +FCriticalSection UnrealAssetAccessor::_pendingRequestsLock; + CesiumAsync::Future> UnrealAssetAccessor::get( const CesiumAsync::AsyncSystem& asyncSystem, @@ -211,6 +214,12 @@ UnrealAssetAccessor::get( pRequest->AppendToHeader(TEXT("User-Agent"), userAgent); + // Add to the pending list when initiating a request + { + FScopeLock lock(&UnrealAssetAccessor::_pendingRequestsLock); + UnrealAssetAccessor::_pendingRequests.Add(pRequest); + } + pRequest->OnProcessRequestComplete().BindLambda( [promise, CESIUM_TRACE_LAMBDA_CAPTURE_TRACK()]( FHttpRequestPtr pRequest, @@ -219,6 +228,17 @@ UnrealAssetAccessor::get( CESIUM_TRACE_USE_CAPTURED_TRACK(); CESIUM_TRACE_END_IN_TRACK("requestAsset"); + // Request to end removal + { + FScopeLock lock(&UnrealAssetAccessor::_pendingRequestsLock); + for (auto It = UnrealAssetAccessor::_pendingRequests.CreateIterator(); It; ++It) { + if (&(It->Get()) == pRequest.Get()) { + It.RemoveCurrent(); + break; + } + } + } + if (connectedSuccessfully) { promise.resolve( std::make_unique(pRequest, pResponse)); @@ -268,6 +288,12 @@ UnrealAssetAccessor::request( pRequest->AppendToHeader(TEXT("User-Agent"), userAgent); + // Add to the pending list when initiating a request + { + FScopeLock lock(&UnrealAssetAccessor::_pendingRequestsLock); + UnrealAssetAccessor::_pendingRequests.Add(pRequest); + } + pRequest->SetContent(TArray( reinterpret_cast(contentPayload.data()), contentPayload.size())); @@ -277,6 +303,18 @@ UnrealAssetAccessor::request( FHttpRequestPtr pRequest, FHttpResponsePtr pResponse, bool connectedSuccessfully) { + + // Request to end removal + { + FScopeLock lock(&UnrealAssetAccessor::_pendingRequestsLock); + for (auto It = UnrealAssetAccessor::_pendingRequests.CreateIterator(); It; ++It) { + if (&(It->Get()) == pRequest.Get()) { + It.RemoveCurrent(); + break; + } + } + } + if (connectedSuccessfully) { promise.resolve( std::make_unique(pRequest, pResponse)); diff --git a/Source/CesiumRuntime/Public/CesiumBingMapsRasterOverlay.h b/Source/CesiumRuntime/Public/CesiumBingMapsRasterOverlay.h index 92f04f45b..160655f55 100644 --- a/Source/CesiumRuntime/Public/CesiumBingMapsRasterOverlay.h +++ b/Source/CesiumRuntime/Public/CesiumBingMapsRasterOverlay.h @@ -40,6 +40,7 @@ class CESIUMRUNTIME_API UCesiumBingMapsRasterOverlay UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium") EBingMapsStyle MapStyle = EBingMapsStyle::Aerial; + virtual bool IsReadyForFinishDestroy() override; protected: virtual std::unique_ptr CreateOverlay( const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override; diff --git a/Source/CesiumRuntime/Public/CesiumIonRasterOverlay.h b/Source/CesiumRuntime/Public/CesiumIonRasterOverlay.h index eac335338..479d41b61 100644 --- a/Source/CesiumRuntime/Public/CesiumIonRasterOverlay.h +++ b/Source/CesiumRuntime/Public/CesiumIonRasterOverlay.h @@ -64,6 +64,7 @@ class CESIUMRUNTIME_API UCesiumIonRasterOverlay : public UCesiumRasterOverlay { // UActorComponent overrides virtual void PostLoad() override; + virtual bool IsReadyForFinishDestroy() override; protected: virtual std::unique_ptr CreateOverlay( const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override; diff --git a/Source/CesiumRuntime/Public/CesiumRasterOverlay.h b/Source/CesiumRuntime/Public/CesiumRasterOverlay.h index 41d1fdd0e..8b3812b76 100644 --- a/Source/CesiumRuntime/Public/CesiumRasterOverlay.h +++ b/Source/CesiumRuntime/Public/CesiumRasterOverlay.h @@ -166,6 +166,7 @@ class CESIUMRUNTIME_API UCesiumRasterOverlay : public UActorComponent { virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override; virtual bool IsReadyForFinishDestroy() override; + static FString ExtractCleanBaseUrl(const FString& InUrl); protected: /** * The maximum number of pixels of error when rendering this overlay. @@ -257,4 +258,5 @@ class CESIUMRUNTIME_API UCesiumRasterOverlay : public UActorComponent { private: CesiumRasterOverlays::RasterOverlay* _pOverlay; int32 _overlaysBeingDestroyed; + FString _url; }; diff --git a/Source/CesiumRuntime/Public/CesiumTileMapServiceRasterOverlay.h b/Source/CesiumRuntime/Public/CesiumTileMapServiceRasterOverlay.h index dca53363a..b4241e568 100644 --- a/Source/CesiumRuntime/Public/CesiumTileMapServiceRasterOverlay.h +++ b/Source/CesiumRuntime/Public/CesiumTileMapServiceRasterOverlay.h @@ -58,6 +58,7 @@ class CESIUMRUNTIME_API UCesiumTileMapServiceRasterOverlay UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium") TMap RequestHeaders; + virtual bool IsReadyForFinishDestroy() override; protected: virtual std::unique_ptr CreateOverlay( const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override; diff --git a/Source/CesiumRuntime/Public/CesiumUrlTemplateRasterOverlay.h b/Source/CesiumRuntime/Public/CesiumUrlTemplateRasterOverlay.h index 5fb429a90..dd4e93de9 100644 --- a/Source/CesiumRuntime/Public/CesiumUrlTemplateRasterOverlay.h +++ b/Source/CesiumRuntime/Public/CesiumUrlTemplateRasterOverlay.h @@ -226,6 +226,7 @@ class CESIUMRUNTIME_API UCesiumUrlTemplateRasterOverlay UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium") TMap RequestHeaders; + virtual bool IsReadyForFinishDestroy() override; protected: virtual std::unique_ptr CreateOverlay( const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override; diff --git a/Source/CesiumRuntime/Public/CesiumWebMapServiceRasterOverlay.h b/Source/CesiumRuntime/Public/CesiumWebMapServiceRasterOverlay.h index 2d2658228..a1d94502c 100644 --- a/Source/CesiumRuntime/Public/CesiumWebMapServiceRasterOverlay.h +++ b/Source/CesiumRuntime/Public/CesiumWebMapServiceRasterOverlay.h @@ -81,6 +81,7 @@ class CESIUMRUNTIME_API UCesiumWebMapServiceRasterOverlay UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium") TMap RequestHeaders; + virtual bool IsReadyForFinishDestroy() override; protected: virtual std::unique_ptr CreateOverlay( const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override; diff --git a/Source/CesiumRuntime/Public/CesiumWebMapTileServiceRasterOverlay.h b/Source/CesiumRuntime/Public/CesiumWebMapTileServiceRasterOverlay.h index c0de5947f..20289d660 100644 --- a/Source/CesiumRuntime/Public/CesiumWebMapTileServiceRasterOverlay.h +++ b/Source/CesiumRuntime/Public/CesiumWebMapTileServiceRasterOverlay.h @@ -275,6 +275,7 @@ class CESIUMRUNTIME_API UCesiumWebMapTileServiceRasterOverlay virtual void Serialize(FArchive& Ar) override; + virtual bool IsReadyForFinishDestroy() override; protected: virtual std::unique_ptr CreateOverlay( const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override; diff --git a/Source/CesiumRuntime/Public/UnrealAssetAccessor.h b/Source/CesiumRuntime/Public/UnrealAssetAccessor.h index 01095bcf9..eac4b1e6a 100644 --- a/Source/CesiumRuntime/Public/UnrealAssetAccessor.h +++ b/Source/CesiumRuntime/Public/UnrealAssetAccessor.h @@ -9,6 +9,7 @@ #include "HAL/Platform.h" #include +class IHttpRequest; class CESIUMRUNTIME_API UnrealAssetAccessor : public CesiumAsync::IAssetAccessor { public: @@ -30,6 +31,8 @@ class CESIUMRUNTIME_API UnrealAssetAccessor virtual void tick() noexcept override; + static TSet> _pendingRequests; + static FCriticalSection _pendingRequestsLock; private: CesiumAsync::Future> getFromFile( const CesiumAsync::AsyncSystem& asyncSystem,