RasterOverlay::activate.

This commit is contained in:
Kevin Ring 2025-09-15 09:10:39 +10:00
parent b5fc62f045
commit 97a7e9d2d1
15 changed files with 152 additions and 142 deletions

View File

@ -5,10 +5,24 @@
##### Breaking Changes :mega:
- `RasterOverlayTileProvider::loadTileImage` now receives a const `RasterOverlayTile`.
- Removed the following from `RasterOverlayTileProvider`:
- The constructor overloads that were used to create a placeholder tile provider.
- `isPlaceholder`
- `getTile`
- `getTileDataBytes`
- `getNumberOfTilesLoading`
- `removeTile`
- `loadTile`
- `loadTileThrottled`
##### Additions :tada:
- Added `RasterOverlayExternals` class. This is similar to `TilesetExternals` and is a more convenient way to pass around the various external interfaces that raster overlays use.
- Added `ActivatedRasterOverlay`, encapsulating most of the functionality that was previously found on `RasterOverlayTileProvider`.
##### Fixes :wrench:
- `LoadedTileEnumerator` now provides non-const access to enumerated `Tile` instances, even if the enumerator itself is const.
### v0.51.0 - 2025-09-02

View File

@ -127,13 +127,13 @@ public:
* @param pOverlay The pointer to the overlay. This may not be `nullptr`.
*/
void add(const CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlay>& pOverlay);
const CesiumRasterOverlays::RasterOverlay>& pOverlay);
/**
* @brief Remove the given {@link CesiumRasterOverlays::RasterOverlay} from this collection.
*/
void remove(const CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlay>& pOverlay) noexcept;
const CesiumRasterOverlays::RasterOverlay>& pOverlay) noexcept;
/**
* @brief Adds raster overlays to a new {@link Tile}.
@ -225,7 +225,8 @@ public:
* @brief A constant iterator for {@link CesiumRasterOverlays::RasterOverlay} instances.
*/
typedef std::vector<CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlay>>::const_iterator const_iterator;
const CesiumRasterOverlays::RasterOverlay>>::const_iterator
const_iterator;
/**
* @brief Returns an iterator at the beginning of this collection.

View File

@ -51,11 +51,10 @@ const std::vector<CesiumUtility::IntrusivePointer<RasterOverlayTileProvider>>
// RasterOverlayCollection has a LoadedTileEnumerator, which is owned
// externally and may become invalid before the async operations complete.
struct RasterOverlayCollection::OverlayList
: public CesiumUtility::ReferenceCountedNonThreadSafe<OverlayList> {
std::vector<CesiumUtility::IntrusivePointer<RasterOverlay>> overlays{};
: public ReferenceCountedNonThreadSafe<OverlayList> {
std::vector<IntrusivePointer<const RasterOverlay>> overlays{};
std::vector<CesiumUtility::IntrusivePointer<ActivatedRasterOverlay>>
activatedOverlays{};
std::vector<IntrusivePointer<ActivatedRasterOverlay>> activatedOverlays{};
};
RasterOverlayCollection::RasterOverlayCollection(
@ -87,11 +86,11 @@ void RasterOverlayCollection::setLoadedTileEnumerator(
}
void RasterOverlayCollection::add(
const CesiumUtility::IntrusivePointer<RasterOverlay>& pOverlay) {
const IntrusivePointer<const RasterOverlay>& pOverlay) {
IntrusivePointer<OverlayList> pList = this->_pOverlays;
pList->overlays.push_back(pOverlay);
pList->activatedOverlays.emplace_back(ActivatedRasterOverlay::create(
pList->activatedOverlays.emplace_back(pOverlay->activate(
RasterOverlayExternals{
.pAssetAccessor = this->_externals.pAssetAccessor,
.pPrepareRendererResources =
@ -99,7 +98,6 @@ void RasterOverlayCollection::add(
.asyncSystem = this->_externals.asyncSystem,
.pCreditSystem = this->_externals.pCreditSystem,
.pLogger = this->_externals.pLogger},
pOverlay,
this->_ellipsoid));
CesiumRasterOverlays::RasterOverlayTile* pPlaceholderTile =
@ -131,7 +129,7 @@ void RasterOverlayCollection::add(
}
void RasterOverlayCollection::remove(
const CesiumUtility::IntrusivePointer<RasterOverlay>& pOverlay) noexcept {
const IntrusivePointer<const RasterOverlay>& pOverlay) noexcept {
if (!this->_pOverlays)
return;

View File

@ -1,6 +1,7 @@
#pragma once
#include <CesiumAsync/Future.h>
#include <CesiumAsync/Promise.h>
#include <CesiumAsync/SharedFuture.h>
#include <CesiumGeometry/Rectangle.h>
#include <CesiumGeospatial/Ellipsoid.h>
@ -26,25 +27,25 @@ class CESIUMRASTEROVERLAYS_API ActivatedRasterOverlay
: public CesiumUtility::ReferenceCountedNonThreadSafe<
ActivatedRasterOverlay> {
public:
static CesiumUtility::IntrusivePointer<ActivatedRasterOverlay> create(
const CesiumRasterOverlays::RasterOverlayExternals& externals,
const CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlay>& pOverlay,
ActivatedRasterOverlay(
const RasterOverlayExternals& externals,
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOverlay,
const CesiumGeospatial::Ellipsoid& ellipsoid);
~ActivatedRasterOverlay();
CesiumAsync::SharedFuture<void>& getReadyEvent();
const CesiumRasterOverlays::RasterOverlay* getOverlay() const noexcept;
CesiumRasterOverlays::RasterOverlay* getOverlay() noexcept;
const CesiumRasterOverlays::RasterOverlayTileProvider*
getTileProvider() const noexcept;
CesiumRasterOverlays::RasterOverlayTileProvider* getTileProvider() noexcept;
void setTileProvider(
const CesiumUtility::IntrusivePointer<RasterOverlayTileProvider>&
pTileProvider);
const CesiumRasterOverlays::RasterOverlayTileProvider*
getPlaceholderTileProvider() const noexcept;
@ -144,12 +145,6 @@ public:
bool loadTileThrottled(RasterOverlayTile& tile);
private:
ActivatedRasterOverlay(
const CesiumRasterOverlays::RasterOverlayExternals& externals,
const CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlay>& pOverlay,
const CesiumGeospatial::Ellipsoid& ellipsoid);
CesiumAsync::Future<TileProviderAndTile>
doLoad(RasterOverlayTile& tile, bool isThrottledLoad);
@ -172,7 +167,7 @@ private:
*/
void finalizeTileLoad(bool isThrottledLoad) noexcept;
CesiumUtility::IntrusivePointer<CesiumRasterOverlays::RasterOverlay>
CesiumUtility::IntrusivePointer<const CesiumRasterOverlays::RasterOverlay>
_pOverlay;
CesiumUtility::IntrusivePointer<
CesiumRasterOverlays::RasterOverlayTileProvider>
@ -187,6 +182,7 @@ private:
int32_t _totalTilesCurrentlyLoading;
int32_t _throttledTilesCurrentlyLoading;
CesiumAsync::Promise<void> _readyPromise;
CesiumAsync::SharedFuture<void> _readyEvent;
};

View File

@ -26,6 +26,7 @@ class CreditSystem;
namespace CesiumRasterOverlays {
class ActivatedRasterOverlay;
class IPrepareRasterOverlayRendererResources;
class RasterOverlayTileProvider;
class RasterOverlayExternals;
@ -187,6 +188,22 @@ public:
return this->_credits;
}
/**
* @brief Activates this overlay.
*
* This method is called by a {@link RasterOverlayCollection} when an overlay
* is added to it. The returned {@link ActivatedRasterOverlay} is used by the
* collection to manage the overlay.
*
* @param externals The external interfaces for use by the raster overlay.
* @param ellipsoid The {@link CesiumGeospatial::Ellipsoid}.
* @return The activated overlay.
*/
CesiumUtility::IntrusivePointer<ActivatedRasterOverlay> activate(
const RasterOverlayExternals& externals,
const CesiumGeospatial::Ellipsoid& ellipsoid
CESIUM_DEFAULT_ELLIPSOID) const;
/**
* @brief Create a placeholder tile provider can be used in place of the real
* one while {@link createTileProvider} completes asynchronously.

View File

@ -144,11 +144,6 @@ public:
*/
const RasterOverlayTileProvider& getTileProvider() const noexcept;
/**
* @brief Returns the {@link RasterOverlay} that created this instance.
*/
RasterOverlay& getOverlay() noexcept;
/**
* @brief Returns the {@link RasterOverlay} that created this instance.
*/

View File

@ -18,70 +18,9 @@ using namespace CesiumUtility;
namespace CesiumRasterOverlays {
IntrusivePointer<ActivatedRasterOverlay> ActivatedRasterOverlay::create(
const RasterOverlayExternals& externals,
const IntrusivePointer<RasterOverlay>& pOverlay,
const Ellipsoid& ellipsoid) {
IntrusivePointer<ActivatedRasterOverlay> pResult =
new ActivatedRasterOverlay(externals, pOverlay, ellipsoid);
CesiumAsync::Future<RasterOverlay::CreateTileProviderResult> future =
pOverlay->createTileProvider(
externals.asyncSystem,
externals.pAssetAccessor,
externals.pCreditSystem,
externals.pPrepareRendererResources,
externals.pLogger,
nullptr);
// This continuation, by capturing pResult, keeps the instance from being
// destroyed. But it does not keep the RasterOverlayCollection itself alive.
pResult->_readyEvent =
std::move(future)
.catchInMainThread(
[](const std::exception& e)
-> RasterOverlay::CreateTileProviderResult {
return nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
RasterOverlayLoadType::Unknown,
nullptr,
fmt::format(
"Error while creating tile provider: {0}",
e.what())});
})
.thenInMainThread(
[pOverlay, pResult, externals](
RasterOverlay::CreateTileProviderResult&& result) {
IntrusivePointer<RasterOverlayTileProvider> pProvider = nullptr;
if (result) {
pProvider = *result;
} else {
// Report error creating the tile provider.
const RasterOverlayLoadFailureDetails& failureDetails =
result.error();
SPDLOG_LOGGER_ERROR(
externals.pLogger,
failureDetails.message);
if (pOverlay->getOptions().loadErrorCallback) {
pOverlay->getOptions().loadErrorCallback(failureDetails);
}
// Create a tile provider that does not provide any tiles at
// all.
pProvider = new EmptyRasterOverlayTileProvider(
pOverlay,
externals.asyncSystem);
}
pResult->_pTileProvider = pProvider;
})
.share();
return pResult;
}
ActivatedRasterOverlay::ActivatedRasterOverlay(
const RasterOverlayExternals& externals,
const IntrusivePointer<RasterOverlay>& pOverlay,
const IntrusivePointer<const RasterOverlay>& pOverlay,
const Ellipsoid& ellipsoid)
: _pOverlay(pOverlay),
_pPlaceholderTileProvider(
@ -91,7 +30,8 @@ ActivatedRasterOverlay::ActivatedRasterOverlay(
_tileDataBytes(0),
_totalTilesCurrentlyLoading(0),
_throttledTilesCurrentlyLoading(0),
_readyEvent(externals.asyncSystem.createResolvedFuture().share()) {
_readyPromise(externals.asyncSystem.createPromise<void>()),
_readyEvent(this->_readyPromise.getFuture().share()) {
this->_pPlaceholderTile =
new RasterOverlayTile(*this, glm::dvec2(0.0), Rectangle());
}
@ -113,10 +53,6 @@ const RasterOverlay* ActivatedRasterOverlay::getOverlay() const noexcept {
return this->_pOverlay;
}
RasterOverlay* ActivatedRasterOverlay::getOverlay() noexcept {
return this->_pOverlay;
}
const CesiumRasterOverlays::RasterOverlayTileProvider*
ActivatedRasterOverlay::getTileProvider() const noexcept {
return this->_pTileProvider;
@ -127,6 +63,17 @@ ActivatedRasterOverlay::getTileProvider() noexcept {
return this->_pTileProvider;
}
void ActivatedRasterOverlay::setTileProvider(
const IntrusivePointer<RasterOverlayTileProvider>& pTileProvider) {
CESIUM_ASSERT(pTileProvider != nullptr);
bool hadValue = this->_pTileProvider != nullptr;
this->_pTileProvider = pTileProvider;
if (!hadValue && this->_pTileProvider != nullptr) {
this->_readyPromise.resolve();
}
}
const CesiumRasterOverlays::RasterOverlayTileProvider*
ActivatedRasterOverlay::getPlaceholderTileProvider() const noexcept {
return this->_pPlaceholderTileProvider;

View File

@ -18,4 +18,4 @@ protected:
const CesiumRasterOverlays::RasterOverlayTile& overlayTile) override;
};
} // namespace Cesium3DTilesSelection
} // namespace CesiumRasterOverlays

View File

@ -1,8 +1,6 @@
#include <CesiumAsync/AsyncSystem.h>
#include <CesiumAsync/Future.h>
#include <CesiumAsync/IAssetAccessor.h>
#include <CesiumAsync/SharedFuture.h>
#include <CesiumGeospatial/Ellipsoid.h>
#include "EmptyRasterOverlayTileProvider.h"
#include <CesiumRasterOverlays/ActivatedRasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayExternals.h>
#include <CesiumRasterOverlays/RasterOverlayLoadFailureDetails.h>
@ -77,6 +75,62 @@ RasterOverlay::getAsyncDestructionCompleteEvent(
return this->_destructionCompleteDetails->future;
}
CesiumUtility::IntrusivePointer<ActivatedRasterOverlay> RasterOverlay::activate(
const RasterOverlayExternals& externals,
const CesiumGeospatial::Ellipsoid& ellipsoid) const {
IntrusivePointer<ActivatedRasterOverlay> pResult =
new ActivatedRasterOverlay(externals, this, ellipsoid);
CesiumAsync::Future<RasterOverlay::CreateTileProviderResult> future =
this->createTileProvider(
externals.asyncSystem,
externals.pAssetAccessor,
externals.pCreditSystem,
externals.pPrepareRendererResources,
externals.pLogger,
this);
// This continuation, by capturing pResult, keeps the instance from being
// destroyed. But it does not keep the RasterOverlayCollection itself alive.
std::move(future)
.catchInMainThread(
[](const std::exception& e)
-> RasterOverlay::CreateTileProviderResult {
return nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
RasterOverlayLoadType::Unknown,
nullptr,
fmt::format(
"Error while creating tile provider: {0}",
e.what())});
})
.thenInMainThread([pResult, externals](
RasterOverlay::CreateTileProviderResult&& result) {
IntrusivePointer<RasterOverlayTileProvider> pProvider = nullptr;
if (result) {
pProvider = *result;
} else {
// Report error creating the tile provider.
const RasterOverlayLoadFailureDetails& failureDetails =
result.error();
SPDLOG_LOGGER_ERROR(externals.pLogger, failureDetails.message);
if (pResult->getOverlay()->getOptions().loadErrorCallback) {
pResult->getOverlay()->getOptions().loadErrorCallback(
failureDetails);
}
// Create a tile provider that does not provide any tiles at
// all.
pProvider = new EmptyRasterOverlayTileProvider(
pResult->getOverlay(),
externals.asyncSystem);
}
pResult->setTileProvider(pProvider);
});
return pResult;
}
CesiumUtility::IntrusivePointer<RasterOverlayTileProvider>
RasterOverlay::createPlaceholder(
const RasterOverlayExternals& externals,
@ -87,4 +141,4 @@ RasterOverlay::createPlaceholder(
externals.pAssetAccessor,
nullptr,
ellipsoid);
}
}

View File

@ -78,10 +78,6 @@ RasterOverlayTile::getTileProvider() const noexcept {
return *this->_pActivatedOverlay->getTileProvider();
}
RasterOverlay& RasterOverlayTile::getOverlay() noexcept {
return *this->_pActivatedOverlay->getOverlay();
}
const RasterOverlay& RasterOverlayTile::getOverlay() const noexcept {
return *this->_pActivatedOverlay->getOverlay();
}

View File

@ -132,14 +132,13 @@ TEST_CASE("Add raster overlay to glTF") {
new TileMapServiceRasterOverlay("test", tmr);
IntrusivePointer<ActivatedRasterOverlay> pActivated =
ActivatedRasterOverlay::create(
pRasterOverlay->activate(
RasterOverlayExternals{
.pAssetAccessor = pMockAssetAccessor,
.pPrepareRendererResources = nullptr,
.asyncSystem = asyncSystem,
.pCreditSystem = nullptr,
.pLogger = spdlog::default_logger()},
pRasterOverlay,
Ellipsoid::WGS84);
auto future =

View File

@ -73,16 +73,14 @@ TEST_CASE(
std::string,
std::shared_ptr<CesiumNativeTests::SimpleAssetRequest>>());
IntrusivePointer<ActivatedRasterOverlay> pActivated =
ActivatedRasterOverlay::create(
RasterOverlayExternals{
.pAssetAccessor = pAssetAccessor,
.pPrepareRendererResources = nullptr,
.asyncSystem = asyncSystem,
.pCreditSystem = nullptr,
.pLogger = spdlog::default_logger()},
pOverlay,
Ellipsoid::WGS84);
IntrusivePointer<ActivatedRasterOverlay> pActivated = pOverlay->activate(
RasterOverlayExternals{
.pAssetAccessor = pAssetAccessor,
.pPrepareRendererResources = nullptr,
.asyncSystem = asyncSystem,
.pCreditSystem = nullptr,
.pLogger = spdlog::default_logger()},
Ellipsoid::WGS84);
pActivated->getReadyEvent().waitInMainThread();

View File

@ -165,16 +165,14 @@ TEST_CASE("QuadtreeRasterOverlayTileProvider getTile") {
AsyncSystem asyncSystem(pTaskProcessor);
IntrusivePointer<TestRasterOverlay> pOverlay = new TestRasterOverlay("Test");
IntrusivePointer<ActivatedRasterOverlay> pActivated =
ActivatedRasterOverlay::create(
RasterOverlayExternals{
pAssetAccessor,
nullptr,
asyncSystem,
nullptr,
spdlog::default_logger()},
pOverlay,
Ellipsoid::WGS84);
IntrusivePointer<ActivatedRasterOverlay> pActivated = pOverlay->activate(
RasterOverlayExternals{
pAssetAccessor,
nullptr,
asyncSystem,
nullptr,
spdlog::default_logger()},
Ellipsoid::WGS84);
asyncSystem.dispatchMainThreadTasks();

View File

@ -73,14 +73,13 @@ TEST_CASE("TileMapServiceRasterOverlay") {
SUBCASE("can load images") {
IntrusivePointer<ActivatedRasterOverlay> pActivated =
ActivatedRasterOverlay::create(
pRasterOverlay->activate(
RasterOverlayExternals{
pMockAssetAccessor,
nullptr,
asyncSystem,
nullptr,
spdlog::default_logger()},
pRasterOverlay,
CesiumGeospatial::Ellipsoid::WGS84);
waitForFuture(

View File

@ -43,16 +43,14 @@ TEST_CASE("UrlTemplateRasterOverlay getTile") {
"Test",
"http://example.com/{x}/{y}/{z}.png");
IntrusivePointer<ActivatedRasterOverlay> pActivated =
ActivatedRasterOverlay::create(
RasterOverlayExternals{
pAssetAccessor,
nullptr,
asyncSystem,
nullptr,
spdlog::default_logger()},
pOverlay,
Ellipsoid::WGS84);
IntrusivePointer<ActivatedRasterOverlay> pActivated = pOverlay->activate(
RasterOverlayExternals{
pAssetAccessor,
nullptr,
asyncSystem,
nullptr,
spdlog::default_logger()},
Ellipsoid::WGS84);
asyncSystem.dispatchMainThreadTasks();