Compare commits

...

60 Commits

Author SHA1 Message Date
Janine Liu b8b1417c5b
Merge pull request #1273 from CesiumGS/credit-sources
cesium-native / Quick Checks (push) Waiting to run Details
cesium-native / Linting (push) Waiting to run Details
cesium-native / Documentation (push) Waiting to run Details
cesium-native / ${{matrix.platform}} / ${{matrix.build_type}} (Debug, windows-2022) (push) Waiting to run Details
cesium-native / ${{matrix.platform}} / ${{matrix.build_type}} (RelWithDebInfo, windows-2022) (push) Waiting to run Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (Debug, clang, macos-13) (push) Waiting to run Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (Debug, clang, ubuntu-22.04) (push) Waiting to run Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (Debug, gcc, ubuntu-24.04) (push) Waiting to run Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (RelWithDebInfo, clang, macos-13) (push) Waiting to run Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (RelWithDebInfo, clang, ubuntu-22.04) (push) Waiting to run Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (RelWithDebInfo, gcc, ubuntu-24.04) (push) Waiting to run Details
cesium-native / Emscripten v${{matrix.version}} ${{matrix.memory}}bit memory (32, 3.1.39) (push) Waiting to run Details
cesium-native / Emscripten v${{matrix.version}} ${{matrix.memory}}bit memory (32, 4.0.13) (push) Waiting to run Details
cesium-native / Emscripten v${{matrix.version}} ${{matrix.memory}}bit memory (64, 4.0.13) (push) Waiting to run Details
Add CreditSources to CreditSystem, refactor RasterOverlay::createTileProvider
2025-11-24 11:02:35 -05:00
Kevin Ring 612352eee9 Move TestCreditSystem to CesiumUtility.
cesium-native / Quick Checks (push) Has been cancelled Details
cesium-native / Linting (push) Has been cancelled Details
cesium-native / Documentation (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.build_type}} (Debug, windows-2022) (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.build_type}} (RelWithDebInfo, windows-2022) (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (Debug, clang, macos-13) (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (Debug, clang, ubuntu-22.04) (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (Debug, gcc, ubuntu-24.04) (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (RelWithDebInfo, clang, macos-13) (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (RelWithDebInfo, clang, ubuntu-22.04) (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (RelWithDebInfo, gcc, ubuntu-24.04) (push) Has been cancelled Details
cesium-native / Emscripten v${{matrix.version}} ${{matrix.memory}}bit memory (32, 3.1.39) (push) Has been cancelled Details
cesium-native / Emscripten v${{matrix.version}} ${{matrix.memory}}bit memory (32, 4.0.13) (push) Has been cancelled Details
cesium-native / Emscripten v${{matrix.version}} ${{matrix.memory}}bit memory (64, 4.0.13) (push) Has been cancelled Details
2025-11-24 13:41:31 +11:00
Kevin Ring f8c4fd7530 Improve misleading comment in test. 2025-11-24 13:36:12 +11:00
Kevin Ring 9aea35d9c3
Fix typo.
Co-authored-by: Janine Liu <32226860+j9liu@users.noreply.github.com>
2025-11-24 13:35:44 +11:00
Kevin Ring 473f3ccbd5 Clang warnings. 2025-11-24 13:30:40 +11:00
Kevin Ring 54b3b5764c Remove changelog entry that didn't actually happen. 2025-11-24 12:29:40 +11:00
Kevin Ring 8f2c1a9f54 Use copydoc to avoid doc duplication. 2025-11-24 12:29:02 +11:00
Kevin Ring 1b4700ecd2 Improve doc. 2025-11-24 12:29:02 +11:00
Kevin Ring a5d8e17300
Improve doc.
Co-authored-by: Janine Liu <32226860+j9liu@users.noreply.github.com>
2025-11-24 12:24:47 +11:00
Kevin Ring 3bff311dee Add tests. 2025-11-24 12:01:16 +11:00
Kevin Ring ed344cddb3 Only filter in favor of referenced credits. 2025-11-24 11:18:28 +11:00
Kevin Ring fbbaf4452a Add tests for credit filtering.
cesium-native / Quick Checks (push) Has been cancelled Details
cesium-native / Linting (push) Has been cancelled Details
cesium-native / Documentation (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.build_type}} (Debug, windows-2022) (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.build_type}} (RelWithDebInfo, windows-2022) (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (Debug, clang, macos-13) (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (Debug, clang, ubuntu-22.04) (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (Debug, gcc, ubuntu-24.04) (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (RelWithDebInfo, clang, macos-13) (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (RelWithDebInfo, clang, ubuntu-22.04) (push) Has been cancelled Details
cesium-native / ${{matrix.platform}} / ${{matrix.compiler}} / ${{matrix.build_type}} (RelWithDebInfo, gcc, ubuntu-24.04) (push) Has been cancelled Details
cesium-native / Emscripten v${{matrix.version}} ${{matrix.memory}}bit memory (32, 3.1.39) (push) Has been cancelled Details
cesium-native / Emscripten v${{matrix.version}} ${{matrix.memory}}bit memory (32, 4.0.13) (push) Has been cancelled Details
cesium-native / Emscripten v${{matrix.version}} ${{matrix.memory}}bit memory (64, 4.0.13) (push) Has been cancelled Details
2025-11-21 19:18:54 +11:00
Kevin Ring fd8aaef4be Fix Doxygen error. 2025-11-21 18:50:34 +11:00
Kevin Ring 32e509eb95 Simplify removed credit tracking.
There's no good reason this was so complicated before.
2025-11-21 18:01:52 +11:00
Kevin Ring 002d00e3f8 Add credit filtering option to getSnapshot. 2025-11-21 17:41:34 +11:00
Kevin Ring 77fff1077a Re-add useless property.
Removing it probably isn't the right thing, and anyway it doesn't belong
in this PR.
2025-11-20 22:12:40 +11:00
Kevin Ring a8df93e235 clang-tidy 2025-11-20 19:40:08 +11:00
Kevin Ring ced27961e4 Update CHANGES.md. 2025-11-20 19:38:48 +11:00
Kevin Ring 7213eed62f Fix silly logic error. 2025-11-20 19:37:34 +11:00
Kevin Ring 551c2bb67c Doc tweaks. 2025-11-20 19:32:59 +11:00
Kevin Ring 642bd2dbc5 Only override credit source if not specified. 2025-11-20 19:16:42 +11:00
Kevin Ring d6b2882148 Correct ownership and credit source for IonRasterOverlay. 2025-11-20 19:09:52 +11:00
Kevin Ring 8ede044fc4 Remove unused property. 2025-11-20 18:44:48 +11:00
Kevin Ring c1b5107758 Only add non-empty credit. 2025-11-20 18:39:32 +11:00
Kevin Ring 9db1f17a11 Fix doc. 2025-11-20 18:26:19 +11:00
Kevin Ring c3b7c131b3 Revert some unnecessary changes. 2025-11-20 18:24:17 +11:00
Kevin Ring b59305d4dd Fix use of removed function. 2025-11-20 18:18:26 +11:00
Kevin Ring 8c7ee9507a Remove declaration for undefined function, improve doc. 2025-11-20 17:27:08 +11:00
Kevin Ring 65dacbdb1b Options -> Parameters 2025-11-20 17:22:18 +11:00
Kevin Ring 436bb9be86 Factor out some common code. 2025-11-20 16:24:33 +11:00
Kevin Ring 2757937ea2 Improve doc. 2025-11-20 15:48:04 +11:00
Kevin Ring 11cf3812d2 Remove "referenced by raster" stuff from TilesetViewGroup.
We can use CreditSources instead, now.
2025-11-20 12:32:24 +11:00
Kevin Ring 47e8533e18 Use `@ref` instead of `\ref`. 2025-11-20 12:32:02 +11:00
Kevin Ring e4f46ba4e6 Remove unnecessary includes. 2025-11-20 12:29:46 +11:00
Kevin Ring a911d9f0ac clang-tidy 2025-11-20 11:34:52 +11:00
Kevin Ring c71daed34a Better fix for GCC warning. 2025-11-20 11:31:13 +11:00
Kevin Ring cce023d8ae Revert "Fix rather unnecessary GCC warnings."
This reverts commit 8d9fc928bb.
2025-11-20 11:28:49 +11:00
Kevin Ring 8d9fc928bb Fix rather unnecessary GCC warnings. 2025-11-20 11:27:23 +11:00
Kevin Ring e554a7d72c clang-tidy, remove unneeded getOwner function. 2025-11-20 10:24:15 +11:00
Kevin Ring 0b5616089e Default values for RasterOverlayExternals fields. 2025-11-20 10:04:52 +11:00
Kevin Ring 79a1c7bcdc Fixes for doc and 32-bit Emscripten. 2025-11-20 09:14:13 +11:00
Kevin Ring 4cabc9aaf9 Initialize pCreator in tile provider factory. 2025-11-20 09:09:26 +11:00
Kevin Ring d5920f6b5d Unsigned credit id and generation. 2025-11-20 07:58:45 +11:00
Kevin Ring 7a7f50877c Merge remote-tracking branch 'origin/main' into credit-sources 2025-11-20 07:34:16 +11:00
Kevin Ring 2cecdd9c2d createTileProvider refactoring. 2025-11-19 23:17:18 +11:00
Kevin Ring 81bcaf7755 CreditSource for GoogleMapTilesRasterOverlay. 2025-11-19 10:09:32 +11:00
Kevin Ring 541f55289c BingMapsRasterOverlay use CreditSource. 2025-11-19 10:07:45 +11:00
Kevin Ring 7a6f14ae86 Simpler lambda capture. 2025-11-19 09:28:35 +11:00
Kevin Ring 32ced86a1f Start adding CreditSource to raster overlays. 2025-11-18 22:26:28 +11:00
Kevin Ring a6a56c9ecf Tileset creates a CreditSource and associates its credits with it. 2025-11-18 21:27:17 +11:00
Kevin Ring 081906aeff Add some CreditReferencer generation tests. 2025-11-18 20:36:28 +11:00
Kevin Ring 684b9742d2 Generation-aware CreditReferencer. 2025-11-18 19:58:50 +11:00
Kevin Ring 5564afd7cb Initial implementation of credit sources. 2025-11-18 19:40:02 +11:00
Kevin Ring d3fb02136d Merge remote-tracking branch 'origin/main' into dev 2025-11-17 13:01:42 +11:00
Ludovic Cheval 864e328ed8 properly call release method instead of pointer reset 2025-11-13 08:39:09 -05:00
Ludovic Cheval 9fe157b4e2 Correct arg description in doc comment 2025-11-12 09:09:20 -05:00
Ludovic Cheval 2421678466 Correct test 2025-11-12 09:08:48 -05:00
Ludovic Cheval 8271d59a3b Apply formatting 2025-11-11 08:45:15 -05:00
Ludovic Cheval ca5104f3b7 #1260 - Update ViewGroup to check internal references; Introduce new referencer for raster overlay credits; 2025-11-10 11:37:17 -05:00
Ludovic Cheval cefcafd82a #1260 - Add a method in CreditReferencer to check if a credit is referenced or not 2025-11-10 11:36:07 -05:00
50 changed files with 1965 additions and 1429 deletions

View File

@ -1,5 +1,20 @@
# Change Log
### ? - ?
##### Breaking Changes :mega:
- `RasterOverlay::createTileProvider` now receives a reference to `CreateRasterOverlayTileProviderParameters` instead of a large number of individual parameters.
- The constructor parameters for `RasterOverlayTileProvider` and `QuadtreeRasterOverlayTileProvider` have changed.
- The `getCredit` method has been removed from `RasterOverlayCreditProvider`. Use `getCredits` instead.
##### Additions :tada:
- Added the concept of a `CreditSource`. Every `Credit` in a `CreditSystem` has a source, and these can be mapped back to `Tileset` and `RasterOverlayTileProvider` (via their `getCreditSource` methods) in order to determine which dataset created which credits.
- Added `TilesetViewGroup::isCreditReferenced`, which can be used to determine if a particular view group references a particular `Credit`.
- Added `CreditReferencer::isCreditReferenced`, which can be used to determine if the referencer is currently referencing a particular `Credit`.
- `CreditSystem::getSnapshot` now takes an optional parameter specifying if and how to filter `Credits` with identical HTML strings.
### v0.54.0 - 2025-11-17
##### Additions :tada:

View File

@ -141,6 +141,12 @@ public:
*/
void setShowCreditsOnScreen(bool showCreditsOnScreen) noexcept;
/**
* @brief Gets the @ref CesiumUtility::CreditSource that identifies this
* tileset's credits with the @ref CesiumUtility::CreditSystem.
*/
const CesiumUtility::CreditSource& getCreditSource() const noexcept;
/**
* @brief Gets the {@link TilesetExternals} that summarize the external
* interfaces used by this tileset.

View File

@ -164,8 +164,11 @@ public:
size_t getMainThreadLoadQueueLength() const;
/**
* @brief Starts a new frame, clearing the set of tiles to be loaded so that a
* new set can be selected.
* @brief Starts a new frame.
*
* This method clears the set of tiles to be loaded so that a new set can be
* selected. It also makes the current tile selection state the previous one
* and releases references to tiles in the old previous one.
*
* @param tileset The tileset that is starting the new frame.
* @param frameState The state of the new frame.
@ -174,11 +177,9 @@ public:
startNewFrame(const Tileset& tileset, const TilesetFrameState& frameState);
/**
* @brief Finishes the current frame by making the current tile selection
* state the previous one and releasing references to tiles in the old
* previous one.
* @brief Finishes the current frame.
*
* This method also updates the load progress percentage returned by
* This method updates the load progress percentage returned by
* {@link getPreviousLoadProgressPercentage} and makes sure credits used by
* this view group have been referenced on the
* {@link CesiumUtility::CreditSystem}.
@ -225,6 +226,24 @@ public:
/** @inheritdoc */
const Tile* getNextTileToLoadInMainThread() override;
/**
* @brief Checks if a given credit is referenced in the most recently
* completed frame.
*
* Note that this method checks the most recently _completed_ frame. So, after
* a call to @ref finishFrame (the common case), this method will check the
* frame that was just finished. If called in between calls to @ref
* startNewFrame and @ref finishFrame (i.e., during the course of a call to
* @ref Tileset::updateViewGroup), it will check the frame prior to the
* current, in-progress one, because the current one has not yet been
* completed.
*
* @param credit The credit to test.
* @return True if the credit was referenced in this view group's most
* recently completed frame.
*/
bool isCreditReferenced(CesiumUtility::Credit credit) const noexcept;
private:
double _weight = 1.0;
std::vector<TileLoadTask> _mainThreadLoadQueue;

View File

@ -170,6 +170,10 @@ void Tileset::setShowCreditsOnScreen(bool showCreditsOnScreen) noexcept {
}
}
const CesiumUtility::CreditSource& Tileset::getCreditSource() const noexcept {
return this->_pTilesetContentManager->getCreditSource();
}
const Tile* Tileset::getRootTile() const noexcept {
return this->_pTilesetContentManager->getRootTile();
}

View File

@ -48,6 +48,7 @@
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/RasterOverlayUtilities.h>
#include <CesiumUtility/Assert.h>
#include <CesiumUtility/CreditSystem.h>
#include <CesiumUtility/IntrusivePointer.h>
#include <CesiumUtility/Math.h>
#include <CesiumUtility/ReferenceCounted.h>
@ -713,6 +714,19 @@ postProcessContentInWorkerThread(
});
}
std::optional<Credit> createUserCredit(
const TilesetOptions& tilesetOptions,
const std::shared_ptr<CreditSystem>& pCreditSystem,
const CreditSource& creditSource) {
if (!tilesetOptions.credit || !pCreditSystem)
return std::nullopt;
return pCreditSystem->createCredit(
creditSource,
*tilesetOptions.credit,
tilesetOptions.showCreditsOnScreen);
}
} // namespace
TilesetContentManager::TilesetContentManager(
@ -724,12 +738,7 @@ TilesetContentManager::TilesetContentManager(
_requestHeaders{tilesetOptions.requestHeaders},
_pLoader{std::move(pLoader)},
_pRootTile{nullptr},
_userCredit(
(tilesetOptions.credit && externals.pCreditSystem)
? std::optional<Credit>(externals.pCreditSystem->createCredit(
tilesetOptions.credit.value(),
tilesetOptions.showCreditsOnScreen))
: std::nullopt),
_userCredit(),
_tilesetCredits{},
_overlayCollection(
LoadedTileEnumerator(pRootTile.get()),
@ -751,8 +760,14 @@ TilesetContentManager::TilesetContentManager(
_roundRobinValueWorker(0.0),
_roundRobinValueMain(0.0),
_requesterFractions(),
_requestersWithRequests() {
_requestersWithRequests(),
_creditSource(externals.pCreditSystem) {
CESIUM_ASSERT(this->_pLoader != nullptr);
this->_userCredit = createUserCredit(
tilesetOptions,
externals.pCreditSystem,
this->_creditSource);
this->_upsampler.setOwner(*this);
this->notifyTileStartLoading(nullptr);
@ -776,12 +791,7 @@ TilesetContentManager::TilesetContentManager(
_requestHeaders{tilesetOptions.requestHeaders},
_pLoader{},
_pRootTile{},
_userCredit(
(tilesetOptions.credit && externals.pCreditSystem)
? std::optional<Credit>(externals.pCreditSystem->createCredit(
tilesetOptions.credit.value(),
tilesetOptions.showCreditsOnScreen))
: std::nullopt),
_userCredit(),
_tilesetCredits{},
_overlayCollection(
LoadedTileEnumerator(nullptr),
@ -803,7 +813,13 @@ TilesetContentManager::TilesetContentManager(
_roundRobinValueWorker(0.0),
_roundRobinValueMain(0.0),
_requesterFractions(),
_requestersWithRequests() {
_requestersWithRequests(),
_creditSource(externals.pCreditSystem) {
this->_userCredit = createUserCredit(
tilesetOptions,
externals.pCreditSystem,
this->_creditSource);
this->_upsampler.setOwner(*this);
if (!url.empty()) {
@ -944,12 +960,7 @@ TilesetContentManager::TilesetContentManager(
_requestHeaders{tilesetOptions.requestHeaders},
_pLoader{},
_pRootTile{},
_userCredit(
(tilesetOptions.credit && externals.pCreditSystem)
? std::optional<Credit>(externals.pCreditSystem->createCredit(
tilesetOptions.credit.value(),
tilesetOptions.showCreditsOnScreen))
: std::nullopt),
_userCredit(),
_tilesetCredits{},
_overlayCollection(
LoadedTileEnumerator(nullptr),
@ -971,7 +982,13 @@ TilesetContentManager::TilesetContentManager(
_roundRobinValueWorker(0.0),
_roundRobinValueMain(0.0),
_requesterFractions(),
_requestersWithRequests() {
_requestersWithRequests(),
_creditSource(externals.pCreditSystem) {
this->_userCredit = createUserCredit(
tilesetOptions,
externals.pCreditSystem,
this->_creditSource);
this->_upsampler.setOwner(*this);
if (loaderFactory.isValid()) {
@ -1715,6 +1732,7 @@ void TilesetContentManager::finishLoading(
for (const std::string_view& creditString : creditStrings) {
credits.emplace_back(pCreditSystem->createCredit(
this->_creditSource,
std::string(creditString),
tilesetOptions.showCreditsOnScreen));
}
@ -2062,6 +2080,17 @@ void TilesetContentManager::releaseReference() const {
}
}
TilesetExternals& TilesetContentManager::getExternals() {
return this->_externals;
}
const TilesetExternals& TilesetContentManager::getExternals() const {
return this->_externals;
}
const CreditSource& TilesetContentManager::getCreditSource() const noexcept {
return this->_creditSource;
}
void TilesetContentManager::setTileContent(
Tile& tile,
TileLoadResult&& result,
@ -2306,9 +2335,11 @@ void TilesetContentManager::propagateTilesetContentLoaderResult(
this->_tilesetCredits.reserve(
this->_tilesetCredits.size() + result.credits.size());
for (const auto& creditResult : result.credits) {
this->_tilesetCredits.emplace_back(_externals.pCreditSystem->createCredit(
creditResult.creditText,
creditResult.showOnScreen));
this->_tilesetCredits.emplace_back(
this->_externals.pCreditSystem->createCredit(
this->_creditSource,
creditResult.creditText,
creditResult.showOnScreen));
}
this->_requestHeaders = std::move(result.requestHeaders);

View File

@ -180,8 +180,10 @@ public:
void markTilesetDestroyed() noexcept;
void releaseReference() const;
TilesetExternals& getExternals() { return this->_externals; }
const TilesetExternals& getExternals() const { return this->_externals; }
TilesetExternals& getExternals();
const TilesetExternals& getExternals() const;
const CesiumUtility::CreditSource& getCreditSource() const noexcept;
private:
static void setTileContent(
@ -252,5 +254,7 @@ private:
// These are scratch space, stored here to avoid heap allocations.
std::vector<double> _requesterFractions;
std::vector<TileLoadRequester*> _requestersWithRequests;
CesiumUtility::CreditSource _creditSource;
};
} // namespace Cesium3DTilesSelection

View File

@ -259,4 +259,9 @@ const Tile* TilesetViewGroup::getNextTileToLoadInMainThread() {
return pResult;
}
bool TilesetViewGroup::isCreditReferenced(
CesiumUtility::Credit credit) const noexcept {
return this->_previousFrameCredits.isCreditReferenced(credit);
}
} // namespace Cesium3DTilesSelection

View File

@ -1,200 +0,0 @@
#include <CesiumUtility/CreditSystem.h>
#include <doctest/doctest.h>
#include <string>
#include <vector>
using namespace CesiumUtility;
TEST_CASE("Test basic credit handling") {
CreditSystem creditSystem;
std::string html0 = "<html>Credit0</html>";
std::string html1 = "<html>Credit1</html>";
std::string html2 = "<html>Credit2</html>";
Credit credit0 = creditSystem.createCredit(html0);
Credit credit1 = creditSystem.createCredit(html1);
Credit credit2 = creditSystem.createCredit(html2);
REQUIRE(creditSystem.getHtml(credit1) == html1);
// Frame 0: Add 0 and 1
{
creditSystem.addCreditReference(credit0);
creditSystem.addCreditReference(credit1);
const CreditsSnapshot& snapshot0 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow0{credit0, credit1};
REQUIRE(snapshot0.currentCredits == expectedShow0);
std::vector<Credit> expectedHide0{};
REQUIRE(snapshot0.removedCredits == expectedHide0);
}
// Start frame 1: Add 2, remove 0
{
creditSystem.addCreditReference(credit2);
creditSystem.removeCreditReference(credit0);
const CreditsSnapshot& snapshot1 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow1{credit1, credit2};
REQUIRE(snapshot1.currentCredits == expectedShow1);
std::vector<Credit> expectedHide1{credit0};
REQUIRE(snapshot1.removedCredits == expectedHide1);
}
// Start frame 2: Add nothing, remove 1 and 2
{
creditSystem.removeCreditReference(credit1);
creditSystem.removeCreditReference(credit2);
const CreditsSnapshot& snapshot2 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow2{};
REQUIRE(snapshot2.currentCredits == expectedShow2);
std::vector<Credit> expectedHide2{credit1, credit2};
REQUIRE(snapshot2.removedCredits == expectedHide2);
}
// Start frame 3: Add nothing, remove nothing
{
const CreditsSnapshot& snapshot3 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow3{};
REQUIRE(snapshot3.currentCredits == expectedShow3);
std::vector<Credit> expectedHide3{};
REQUIRE(snapshot3.removedCredits == expectedHide3);
}
// Start frame 4: Add 2, remove nothing
{
creditSystem.addCreditReference(credit2);
const CreditsSnapshot& snapshot4 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow4{credit2};
REQUIRE(snapshot4.currentCredits == expectedShow4);
std::vector<Credit> expectedHide4{};
REQUIRE(snapshot4.removedCredits == expectedHide4);
}
// Start frame 5: Remove and then re-add 2
{
creditSystem.removeCreditReference(credit2);
creditSystem.addCreditReference(credit2);
const CreditsSnapshot& snapshot5 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow5{credit2};
REQUIRE(snapshot5.currentCredits == expectedShow5);
std::vector<Credit> expectedHide5{};
REQUIRE(snapshot5.removedCredits == expectedHide5);
}
// Start frame 6: Add and then remove 1
{
creditSystem.addCreditReference(credit1);
creditSystem.removeCreditReference(credit1);
const CreditsSnapshot& snapshot6 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow6{credit2};
REQUIRE(snapshot6.currentCredits == expectedShow6);
std::vector<Credit> expectedHide6{};
REQUIRE(snapshot6.removedCredits == expectedHide6);
}
}
TEST_CASE("Test wrong credit handling") {
CreditSystem creditSystemA;
CreditSystem creditSystemB;
std::string html0 = "<html>Credit0</html>";
std::string html1 = "<html>Credit1</html>";
Credit creditA0 = creditSystemA.createCredit(html0);
Credit creditA1 = creditSystemA.createCredit(html1);
/*Credit creditB0 = */ creditSystemB.createCredit(html0);
// NOTE: This is using a Credit from a different credit
// system, which coincidentally has a valid ID here.
// This is not (and can hardly be) checked right now,
// so this returns a valid HTML string:
REQUIRE(creditSystemB.getHtml(creditA0) == html0);
REQUIRE(creditSystemB.getHtml(creditA1) != html1);
}
TEST_CASE("Test sorting credits by frequency") {
CreditSystem creditSystem;
std::string html0 = "<html>Credit0</html>";
std::string html1 = "<html>Credit1</html>";
std::string html2 = "<html>Credit2</html>";
Credit credit0 = creditSystem.createCredit(html0);
Credit credit1 = creditSystem.createCredit(html1);
Credit credit2 = creditSystem.createCredit(html2);
REQUIRE(creditSystem.getHtml(credit1) == html1);
for (int i = 0; i < 3; i++) {
creditSystem.addCreditReference(credit0);
}
for (int i = 0; i < 2; i++) {
creditSystem.addCreditReference(credit1);
}
creditSystem.addCreditReference(credit2);
const CreditsSnapshot& snapshot0 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow0{credit0, credit1, credit2};
REQUIRE(snapshot0.currentCredits == expectedShow0);
for (int i = 0; i < 2; i++) {
creditSystem.addCreditReference(credit2);
}
for (int i = 0; i < 2; i++) {
creditSystem.removeCreditReference(credit0);
}
const CreditsSnapshot& snapshot1 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow1{credit2, credit1, credit0};
REQUIRE(snapshot1.currentCredits == expectedShow1);
}
TEST_CASE("Test setting showOnScreen on credits") {
CreditSystem creditSystem;
std::string html0 = "<html>Credit0</html>";
std::string html1 = "<html>Credit1</html>";
std::string html2 = "<html>Credit2</html>";
Credit credit0 = creditSystem.createCredit(html0, true);
Credit credit1 = creditSystem.createCredit(html1, false);
Credit credit2 = creditSystem.createCredit(html2, true);
REQUIRE(creditSystem.getHtml(credit1) == html1);
CHECK(creditSystem.shouldBeShownOnScreen(credit0) == true);
CHECK(creditSystem.shouldBeShownOnScreen(credit1) == false);
CHECK(creditSystem.shouldBeShownOnScreen(credit2) == true);
creditSystem.setShowOnScreen(credit0, false);
creditSystem.setShowOnScreen(credit1, true);
creditSystem.setShowOnScreen(credit2, true);
CHECK(creditSystem.shouldBeShownOnScreen(credit0) == false);
CHECK(creditSystem.shouldBeShownOnScreen(credit1) == true);
CHECK(creditSystem.shouldBeShownOnScreen(credit2) == true);
}

View File

@ -40,6 +40,7 @@
#include <CesiumNativeTests/SimpleAssetResponse.h>
#include <CesiumNativeTests/SimpleTaskProcessor.h>
#include <CesiumNativeTests/readFile.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/DebugColorizeTilesRasterOverlay.h>
#include <CesiumRasterOverlays/IPrepareRasterOverlayRendererResources.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
@ -1329,24 +1330,13 @@ TEST_CASE("Test the tileset content manager's post processing for gltf") {
class AlwaysMoreDetailProvider : public RasterOverlayTileProvider {
public:
AlwaysMoreDetailProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
std::optional<CesiumUtility::Credit> credit,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const CesiumGeospatial::Projection& projection,
const CesiumGeometry::Rectangle& coverageRectangle)
: RasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
credit,
pPrepareRendererResources,
pLogger,
pCreator,
parameters,
projection,
coverageRectangle) {}
@ -1375,29 +1365,18 @@ TEST_CASE("Test the tileset content manager's post processing for gltf") {
AlwaysMoreDetailRasterOverlay() : RasterOverlay("AlwaysMoreDetail") {}
CesiumAsync::Future<CreateTileProviderResult> createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<
CesiumUtility::CreditSystem>& /* pCreditSystem */,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner)
const CreateRasterOverlayTileProviderParameters& parameters)
const override {
return asyncSystem.createResolvedFuture(CreateTileProviderResult(
CesiumUtility::IntrusivePointer<RasterOverlayTileProvider>(
new AlwaysMoreDetailProvider(
pOwner ? pOwner : this,
asyncSystem,
pAssetAccessor,
nullptr,
std::nullopt,
pPrepareRendererResources,
pLogger,
CesiumGeospatial::GeographicProjection(),
projectRectangleSimple(
return parameters.externals.asyncSystem.createResolvedFuture(
CreateTileProviderResult(
CesiumUtility::IntrusivePointer<RasterOverlayTileProvider>(
new AlwaysMoreDetailProvider(
this,
parameters,
CesiumGeospatial::GeographicProjection(),
GlobeRectangle::MAXIMUM)))));
projectRectangleSimple(
CesiumGeospatial::GeographicProjection(),
GlobeRectangle::MAXIMUM)))));
}
};

View File

@ -209,13 +209,7 @@ public:
virtual ~AzureMapsRasterOverlay() override;
virtual CesiumAsync::Future<CreateTileProviderResult> createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner)
const CreateRasterOverlayTileProviderParameters& parameters)
const override;
private:

View File

@ -106,18 +106,10 @@ public:
virtual ~BingMapsRasterOverlay() override;
virtual CesiumAsync::Future<CreateTileProviderResult> createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner)
const CreateRasterOverlayTileProviderParameters& parameters)
const override;
private:
static const std::string BING_LOGO_HTML;
std::string _url;
std::string _key;
std::string _mapStyle;

View File

@ -0,0 +1,42 @@
#pragma once
#include <CesiumRasterOverlays/Library.h>
#include <CesiumRasterOverlays/RasterOverlayExternals.h>
#include <CesiumUtility/IntrusivePointer.h>
namespace CesiumUtility {
class CreditSource;
}
namespace CesiumRasterOverlays {
class RasterOverlay;
/**
* @brief Parameters passed to \ref RasterOverlay::createTileProvider.
*/
struct CESIUMRASTEROVERLAYS_API CreateRasterOverlayTileProviderParameters {
/**
* @brief The external interfaces for use by the raster overlay tile provider.
*/
RasterOverlayExternals externals;
/**
* @brief The overlay that owns the overlay that is creating the tile
* provider.
*
* If nullptr, this overlay is not aggregated, and the owner of the tile
* provider is the overlay that created it.
*/
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner{nullptr};
/**
* @brief The credit source that the new tile provider should use for its
* credits.
*
* If nullptr, a new credit source will be created for the tile provider.
*/
std::shared_ptr<CesiumUtility::CreditSource> pCreditSource{nullptr};
};
} // namespace CesiumRasterOverlays

View File

@ -24,13 +24,7 @@ public:
* @copydoc RasterOverlay::createTileProvider
*/
virtual CesiumAsync::Future<CreateTileProviderResult> createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner)
const CreateRasterOverlayTileProviderParameters& parameters)
const override;
};

View File

@ -86,13 +86,7 @@ public:
virtual ~GeoJsonDocumentRasterOverlay() override;
virtual CesiumAsync::Future<CreateTileProviderResult> createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner)
const CreateRasterOverlayTileProviderParameters& parameters)
const override;
private:

View File

@ -286,24 +286,12 @@ public:
/** @inheritdoc */
virtual CesiumAsync::Future<CreateTileProviderResult> createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner)
const CreateRasterOverlayTileProviderParameters& parameters)
const override;
private:
CesiumAsync::Future<CreateTileProviderResult> createNewSession(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner) const;
const CreateRasterOverlayTileProviderParameters& parameters) const;
std::optional<GoogleMapTilesNewSessionParameters> _newSessionParameters;
std::optional<GoogleMapTilesExistingSession> _existingSession;

View File

@ -62,13 +62,7 @@ public:
void setAssetOptions(const std::optional<std::string>& options) noexcept;
virtual CesiumAsync::Future<CreateTileProviderResult> createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner)
const CreateRasterOverlayTileProviderParameters& parameters)
const override;
protected:

View File

@ -30,39 +30,26 @@ namespace CesiumRasterOverlays {
*/
class CESIUMRASTEROVERLAYS_API QuadtreeRasterOverlayTileProvider
: public RasterOverlayTileProvider {
public:
/**
* @brief Creates a new instance.
*
* @param pOwner The raster overlay that created this tile provider.
* @param asyncSystem The async system used to do work in threads.
* @param pAssetAccessor The interface used to obtain assets (tiles, etc.) for
* this raster overlay.
* @param pCreditSystem The credit system that receives this tile provider's
* credits.
* @param credit The {@link CesiumUtility::Credit} for this tile provider, if it exists.
* @param pPrepareRendererResources The interface used to prepare raster
* images for rendering.
* @param pLogger The logger to which to send messages about the tile provider
* and tiles.
* @param pCreator The \ref RasterOverlay that directly created this instance.
* This will become the owner of this instance if another owner is not
* specified in \ref CreateRasterOverlayTileProviderParameters::pOwner.
* @param parameters The parameters for creating the tile provider.
* @param projection The {@link CesiumGeospatial::Projection}.
* @param tilingScheme The tiling scheme to be used by this {@link QuadtreeRasterOverlayTileProvider}.
* @param coverageRectangle The {@link CesiumGeometry::Rectangle}.
* @param coverageRectangle The rectangle that bounds all the area covered by
* this overlay, expressed in projected coordinates.
* @param minimumLevel The minimum quadtree tile level.
* @param maximumLevel The maximum quadtree tile level.
* @param imageWidth The image width.
* @param imageHeight The image height.
*/
QuadtreeRasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
std::optional<CesiumUtility::Credit> credit,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const CesiumGeospatial::Projection& projection,
const CesiumGeometry::QuadtreeTilingScheme& tilingScheme,
const CesiumGeometry::Rectangle& coverageRectangle,

View File

@ -28,8 +28,9 @@ namespace CesiumRasterOverlays {
class ActivatedRasterOverlay;
class IPrepareRasterOverlayRendererResources;
class RasterOverlayTileProvider;
class RasterOverlayExternals;
class RasterOverlayTileProvider;
struct CreateRasterOverlayTileProviderParameters;
/**
* @brief Options for loading raster overlays.
@ -219,28 +220,12 @@ public:
* @brief Begins asynchronous creation of a tile provider for this overlay
* and eventually returns it via a Future.
*
* @param asyncSystem The async system used to do work in threads.
* @param pAssetAccessor The interface used to download assets like overlay
* metadata and tiles.
* @param pCreditSystem The {@link CesiumUtility::CreditSystem} to use when creating a
* per-TileProvider {@link CesiumUtility::Credit}.
* @param pPrepareRendererResources The interface used to prepare raster
* images for rendering.
* @param pLogger The logger to which to send messages about the tile provider
* and tiles.
* @param pOwner The overlay that owns this overlay, or nullptr if this
* overlay is not aggregated.
* @param parameters The parameters for creating the tile provider.
* @return The future that resolves to the tile provider when it is ready, or
* to error details in the case of an error.
*/
virtual CesiumAsync::Future<CreateTileProviderResult> createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner) const = 0;
const CreateRasterOverlayTileProviderParameters& parameters) const = 0;
private:
struct DestructionCompleteDetails {

View File

@ -24,7 +24,7 @@ public:
* This may only be `nullptr` if the raster overlay does not attempt to
* download any resources.
*/
std::shared_ptr<CesiumAsync::IAssetAccessor> pAssetAccessor;
std::shared_ptr<CesiumAsync::IAssetAccessor> pAssetAccessor = nullptr;
/**
* @brief The @ref IPrepareRasterOverlayRendererResources that is used to
@ -34,7 +34,7 @@ public:
* for raster overlays.
*/
std::shared_ptr<IPrepareRasterOverlayRendererResources>
pPrepareRendererResources;
pPrepareRendererResources = nullptr;
/**
* @brief The async system to use to do work in threads.
@ -49,7 +49,7 @@ public:
* While not recommended, this may be `nullptr` if the client does not need to
* receive credits.
*/
std::shared_ptr<CesiumUtility::CreditSystem> pCreditSystem;
std::shared_ptr<CesiumUtility::CreditSystem> pCreditSystem = nullptr;
/**
* @brief A spdlog logger that will receive log messages.

View File

@ -25,6 +25,7 @@ namespace CesiumRasterOverlays {
class RasterOverlay;
class RasterOverlayTile;
class IPrepareRasterOverlayRendererResources;
struct CreateRasterOverlayTileProviderParameters;
/**
* @brief Summarizes the result of loading an image of a {@link RasterOverlay}.
@ -139,32 +140,17 @@ public:
/**
* @brief Creates a new instance.
*
* @param pOwner The raster overlay that created this tile provider.
* @param externals The external interfaces for use by the raster overlay.
* @param pCreator The \ref RasterOverlay that directly created this instance.
* This will become the owner of this instance if another owner is not
* specified in \ref CreateRasterOverlayTileProviderParameters::pOwner.
* @param parameters The parameters for creating the tile provider.
* @param projection The {@link CesiumGeospatial::Projection}.
* @param coverageRectangle The rectangle that bounds all the area covered by
* this overlay, expressed in projected coordinates.
*/
RasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
const RasterOverlayExternals& externals,
const CesiumGeospatial::Projection& projection,
const CesiumGeometry::Rectangle& coverageRectangle) noexcept;
/**
* @brief Creates a new instance.
* @deprecated Use the overload that takes a \ref RasterOverlayExternals
* instead.
*/
RasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
std::optional<CesiumUtility::Credit> credit,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const CesiumGeospatial::Projection& projection,
const CesiumGeometry::Rectangle& coverageRectangle) noexcept;
@ -233,12 +219,27 @@ public:
const CesiumGeometry::Rectangle& getCoverageRectangle() const noexcept;
/**
* @brief Get the per-TileProvider {@link CesiumUtility::Credit} if one exists.
* @deprecated Implement {@link addCredits} instead.
* @brief Gets the @ref CesiumUtility::CreditSource that identifies this
* raster overlay's credits with the @ref CesiumUtility::CreditSystem.
*/
[[deprecated(
"Use addCredits instead.")]] const std::optional<CesiumUtility::Credit>&
getCredit() const noexcept;
const CesiumUtility::CreditSource& getCreditSource() const noexcept;
/**
* @brief Gets the collection of credits that should be shown whenever this
* tile provider is shown.
*
* If called on a non-const instance, the returned collection may be modified
* to add or remove credits.
*
* The credits in this collection will be added to the @ref
* CesiumUtility::CreditReferencer in @ref addCredits.
*/
std::vector<CesiumUtility::Credit>& getCredits() noexcept;
/**
* @copydoc getCredits
*/
const std::vector<CesiumUtility::Credit>& getCredits() const noexcept;
/**
* @brief Loads the image for a tile.
@ -286,9 +287,10 @@ private:
CesiumUtility::IntrusivePointer<RasterOverlay> _pOwner;
RasterOverlayExternals _externals;
std::optional<CesiumUtility::Credit> _credit;
std::vector<CesiumUtility::Credit> _credits;
CesiumGeospatial::Projection _projection;
CesiumGeometry::Rectangle _coverageRectangle;
std::optional<DestructionCompleteDetails> _destructionCompleteDetails;
std::shared_ptr<CesiumUtility::CreditSource> _pCreditSource;
};
} // namespace CesiumRasterOverlays

View File

@ -50,13 +50,7 @@ public:
virtual ~RasterizedPolygonsOverlay() override;
virtual CesiumAsync::Future<CreateTileProviderResult> createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner)
const CreateRasterOverlayTileProviderParameters& parameters)
const override;
/**

View File

@ -106,13 +106,7 @@ public:
virtual ~TileMapServiceRasterOverlay() override;
virtual CesiumAsync::Future<CreateTileProviderResult> createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner)
const CreateRasterOverlayTileProviderParameters& parameters)
const override;
private:

View File

@ -119,13 +119,7 @@ public:
_options(urlTemplateOptions) {}
virtual CesiumAsync::Future<CreateTileProviderResult> createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner)
const CreateRasterOverlayTileProviderParameters& parameters)
const override;
private:

View File

@ -88,13 +88,7 @@ public:
virtual ~WebMapServiceRasterOverlay() override;
virtual CesiumAsync::Future<CreateTileProviderResult> createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner)
const CreateRasterOverlayTileProviderParameters& parameters)
const override;
private:

View File

@ -140,13 +140,7 @@ public:
virtual ~WebMapTileServiceRasterOverlay() override;
virtual CesiumAsync::Future<CreateTileProviderResult> createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner)
const CreateRasterOverlayTileProviderParameters& parameters)
const override;
private:

View File

@ -8,13 +8,12 @@
#include <CesiumJsonReader/JsonObjectJsonHandler.h>
#include <CesiumJsonReader/JsonReader.h>
#include <CesiumRasterOverlays/AzureMapsRasterOverlay.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/QuadtreeRasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayLoadFailureDetails.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumUtility/CreditReferencer.h>
#include <CesiumUtility/CreditSystem.h>
#include <CesiumUtility/ErrorList.h>
#include <CesiumUtility/IntrusivePointer.h>
#include <CesiumUtility/JsonHelpers.h>
@ -136,14 +135,9 @@ class AzureMapsRasterOverlayTileProvider final
: public QuadtreeRasterOverlayTileProvider {
public:
AzureMapsRasterOverlayTileProvider(
const IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
std::optional<CesiumUtility::Credit> credit,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const std::string& credit,
const std::string& baseUrl,
const std::string& apiVersion,
const std::string& tilesetId,
@ -166,9 +160,6 @@ public:
CesiumAsync::Future<void> loadCredits();
virtual void addCredits(
CesiumUtility::CreditReferencer& creditReferencer) noexcept override;
protected:
virtual CesiumAsync::Future<LoadedRasterOverlayImage> loadQuadtreeTileImage(
const CesiumGeometry::QuadtreeTileID& tileID) const override;
@ -179,9 +170,6 @@ private:
std::string _tilesetId;
std::string _key;
std::string _tileEndpoint;
std::optional<Credit> _azureCredit;
std::vector<Credit> _credits;
bool _showCreditsOnScreen;
};
AzureMapsRasterOverlay::AzureMapsRasterOverlay(
@ -199,13 +187,7 @@ AzureMapsRasterOverlay::~AzureMapsRasterOverlay() = default;
Future<RasterOverlay::CreateTileProviderResult>
AzureMapsRasterOverlay::createTileProvider(
const AsyncSystem& asyncSystem,
const std::shared_ptr<IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
IntrusivePointer<const RasterOverlay> pOwner) const {
const CreateRasterOverlayTileProviderParameters& parameters) const {
Uri tilesetUri(this->_sessionParameters.apiBaseUrl, "map/tileset");
UriQuery tilesetQuery(tilesetUri);
@ -218,16 +200,10 @@ AzureMapsRasterOverlay::createTileProvider(
std::string tilesetUrl = std::string(tilesetUri.toString());
pOwner = pOwner ? pOwner : this;
IntrusivePointer<const AzureMapsRasterOverlay> thiz = this;
auto handleResponse =
[pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
pPrepareRendererResources,
pLogger,
sessionParameters = this->_sessionParameters](
[parameters, thiz](
const std::shared_ptr<IAssetRequest>& pRequest,
const std::span<const std::byte>& data) -> CreateTileProviderResult {
JsonObjectJsonHandler handler{};
@ -334,32 +310,26 @@ AzureMapsRasterOverlay::createTileProvider(
"Azure Maps returned no valid endpoints for the given tilesetId."});
}
std::optional<Credit> topLevelCredit;
std::string topLevelCredit;
it = responseObject.find("attribution");
if (it != responseObject.end() && it->second.isString()) {
topLevelCredit = pCreditSystem->createCredit(
it->second.getString(),
pOwner->getOptions().showCreditsOnScreen);
topLevelCredit = it->second.getString();
}
auto* pProvider = new AzureMapsRasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
thiz,
parameters,
topLevelCredit,
pPrepareRendererResources,
pLogger,
sessionParameters.apiBaseUrl,
sessionParameters.apiVersion,
sessionParameters.tilesetId,
sessionParameters.key,
thiz->_sessionParameters.apiBaseUrl,
thiz->_sessionParameters.apiVersion,
thiz->_sessionParameters.tilesetId,
thiz->_sessionParameters.key,
tileEndpoint,
minimumLevel,
maximumLevel,
tileSize,
sessionParameters.showLogo);
thiz->_sessionParameters.showLogo);
// Start loading credits, but don't wait for the load to finish.
pProvider->loadCredits();
@ -369,11 +339,12 @@ AzureMapsRasterOverlay::createTileProvider(
auto cacheResultIt = sessionCache.find(tilesetUrl);
if (cacheResultIt != sessionCache.end()) {
return asyncSystem.createResolvedFuture(
return parameters.externals.asyncSystem.createResolvedFuture(
handleResponse(nullptr, std::span<std::byte>(cacheResultIt->second)));
}
return pAssetAccessor->get(asyncSystem, tilesetUrl)
return parameters.externals.pAssetAccessor
->get(parameters.externals.asyncSystem, tilesetUrl)
.thenInMainThread(
[tilesetUrl,
handleResponse](std::shared_ptr<IAssetRequest>&& pRequest)
@ -487,14 +458,9 @@ CesiumAsync::Future<rapidjson::Document> fetchAttributionData(
} // namespace
AzureMapsRasterOverlayTileProvider::AzureMapsRasterOverlayTileProvider(
const IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
std::optional<CesiumUtility::Credit> credit,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const std::string& credit,
const std::string& baseUrl,
const std::string& apiVersion,
const std::string& tilesetId,
@ -505,16 +471,11 @@ AzureMapsRasterOverlayTileProvider::AzureMapsRasterOverlayTileProvider(
uint32_t imageSize,
bool showLogo)
: QuadtreeRasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
credit,
pPrepareRendererResources,
pLogger,
WebMercatorProjection(pOwner->getOptions().ellipsoid),
createTilingScheme(pOwner),
createRectangle(pOwner),
pCreator,
parameters,
WebMercatorProjection(pCreator->getOptions().ellipsoid),
createTilingScheme(pCreator),
createRectangle(pCreator),
minimumLevel,
maximumLevel,
imageSize,
@ -523,13 +484,23 @@ AzureMapsRasterOverlayTileProvider::AzureMapsRasterOverlayTileProvider(
_apiVersion(apiVersion),
_tilesetId(tilesetId),
_key(key),
_tileEndpoint(tileEndpoint),
_azureCredit(),
_credits(),
_showCreditsOnScreen(pOwner->getOptions().showCreditsOnScreen) {
if (pCreditSystem && showLogo) {
this->_azureCredit =
pCreditSystem->createCredit(AZURE_MAPS_LOGO_HTML, true);
_tileEndpoint(tileEndpoint) {
if (parameters.externals.pCreditSystem) {
if (!credit.empty()) {
this->getCredits().emplace_back(
parameters.externals.pCreditSystem->createCredit(
this->getCreditSource(),
credit,
pCreator->getOptions().showCreditsOnScreen));
}
if (showLogo) {
this->getCredits().emplace_back(
parameters.externals.pCreditSystem->createCredit(
this->getCreditSource(),
AZURE_MAPS_LOGO_HTML,
true));
}
}
}
@ -596,37 +567,25 @@ Future<void> AzureMapsRasterOverlayTileProvider::loadCredits() {
return this->getAsyncSystem()
.all(std::move(creditFutures))
.thenInMainThread(
[thiz](std::vector<std::vector<std::string>>&& results) {
std::set<std::string> uniqueCredits;
for (size_t i = 0; i < results.size(); i++) {
const std::vector<std::string>& credits = results[i];
for (size_t j = 0; j < credits.size(); j++) {
if (!credits[j].empty()) {
uniqueCredits.insert(credits[j]);
}
}
.thenInMainThread([thiz](
std::vector<std::vector<std::string>>&& results) {
std::set<std::string> uniqueCredits;
for (size_t i = 0; i < results.size(); i++) {
const std::vector<std::string>& credits = results[i];
for (size_t j = 0; j < credits.size(); j++) {
if (!credits[j].empty()) {
uniqueCredits.insert(credits[j]);
}
}
}
for (const std::string& credit : uniqueCredits) {
thiz->_credits.emplace_back(thiz->getCreditSystem()->createCredit(
credit,
thiz->_showCreditsOnScreen));
}
});
}
void AzureMapsRasterOverlayTileProvider::addCredits(
CesiumUtility::CreditReferencer& creditReferencer) noexcept {
QuadtreeRasterOverlayTileProvider::addCredits(creditReferencer);
if (this->_azureCredit) {
creditReferencer.addCreditReference(*this->_azureCredit);
}
for (const Credit& credit : this->_credits) {
creditReferencer.addCreditReference(credit);
}
for (const std::string& credit : uniqueCredits) {
thiz->getCredits().emplace_back(thiz->getCreditSystem()->createCredit(
thiz->getCreditSource(),
credit,
thiz->getOwner().getOptions().showCreditsOnScreen));
}
});
}
} // namespace CesiumRasterOverlays

View File

@ -7,6 +7,7 @@
#include <CesiumGeospatial/Projection.h>
#include <CesiumGeospatial/WebMercatorProjection.h>
#include <CesiumRasterOverlays/BingMapsRasterOverlay.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/QuadtreeRasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayLoadFailureDetails.h>
@ -21,7 +22,6 @@
#include <nonstd/expected.hpp>
#include <rapidjson/document.h>
#include <rapidjson/pointer.h>
#include <spdlog/logger.h>
#include <cstddef>
#include <cstdint>
@ -45,6 +45,11 @@ struct CoverageArea {
uint32_t zoomMax;
};
struct CreditStringAndCoverageAreas {
std::string credit;
std::vector<CoverageArea> coverageAreas;
};
struct CreditAndCoverageAreas {
Credit credit;
std::vector<CoverageArea> coverageAreas;
@ -67,7 +72,9 @@ const std::string BingMapsStyle::CANVAS_GRAY = "CanvasGray";
const std::string BingMapsStyle::ORDNANCE_SURVEY = "OrdnanceSurvey";
const std::string BingMapsStyle::COLLINS_BART = "CollinsBart";
const std::string BingMapsRasterOverlay::BING_LOGO_HTML =
namespace {
const std::string BING_LOGO_HTML =
"<a href=\"http://www.bing.com\"><img "
"src=\"data:image/"
"png;base64,iVBORw0KGgoAAAANSUhEUgAAAFgAAAATCAMAAAAj1DqpAAAAq1BMVEUAAAD////"
@ -93,7 +100,6 @@ const std::string BingMapsRasterOverlay::BING_LOGO_HTML =
"OXfbBoeDOo8wHpy8lKpvoafRoG6YgXFYKP4GSj63gtwWfhHzl7Skq9JTshAAAAAElFTkSuQmCC"
"\" title=\"Bing Imagery\"/></a>";
namespace {
Rectangle createRectangle(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner) {
return WebMercatorProjection::computeMaximumProjectedRectangle(
@ -109,15 +115,9 @@ QuadtreeTilingScheme createTilingScheme(
class BingMapsTileProvider final : public QuadtreeRasterOverlayTileProvider {
public:
BingMapsTileProvider(
const IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
Credit bingCredit,
const std::vector<CreditAndCoverageAreas>& perTileCredits,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const std::vector<CreditStringAndCoverageAreas>& perTileCredits,
const std::string& baseUrl,
const std::string& urlTemplate,
const std::vector<std::string>& subdomains,
@ -127,25 +127,39 @@ public:
uint32_t maximumLevel,
const std::string& culture)
: QuadtreeRasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
bingCredit,
pPrepareRendererResources,
pLogger,
WebMercatorProjection(pOwner->getOptions().ellipsoid),
createTilingScheme(pOwner),
createRectangle(pOwner),
pCreator,
parameters,
WebMercatorProjection(pCreator->getOptions().ellipsoid),
createTilingScheme(pCreator),
createRectangle(pCreator),
minimumLevel,
maximumLevel,
width,
height),
_credits(perTileCredits),
_credits(),
_baseUrl(baseUrl),
_urlTemplate(urlTemplate),
_culture(culture),
_subdomains(subdomains) {}
_subdomains(subdomains) {
if (parameters.externals.pCreditSystem) {
this->getCredits().emplace_back(
parameters.externals.pCreditSystem->createCredit(
this->getCreditSource(),
BING_LOGO_HTML,
pCreator->getOptions().showCreditsOnScreen));
this->_credits.reserve(perTileCredits.size());
for (const CreditStringAndCoverageAreas& creditStringAndCoverageAreas :
perTileCredits) {
this->_credits.emplace_back(CreditAndCoverageAreas{
parameters.externals.pCreditSystem->createCredit(
this->getCreditSource(),
creditStringAndCoverageAreas.credit,
pCreator->getOptions().showCreditsOnScreen),
creditStringAndCoverageAreas.coverageAreas});
}
}
}
virtual ~BingMapsTileProvider() = default;
@ -287,19 +301,11 @@ namespace {
* \endcode
*
* @param pResource The JSON value for the resource
* @param pCreditSystem The `CreditSystem` that will create one credit for
* each attribution
* @return The `CreditAndCoverageAreas` objects that have been parsed, or an
* empty vector if pCreditSystem is nullptr.
* @return The `CreditStringAndCoverageAreas` objects that have been parsed.
*/
std::vector<CreditAndCoverageAreas> collectCredits(
const rapidjson::Value* pResource,
const std::shared_ptr<CreditSystem>& pCreditSystem,
bool showCreditsOnScreen) {
std::vector<CreditAndCoverageAreas> credits;
if (!pCreditSystem) {
return credits;
}
std::vector<CreditStringAndCoverageAreas>
collectCredits(const rapidjson::Value* pResource) {
std::vector<CreditStringAndCoverageAreas> credits;
const auto attributionsIt = pResource->FindMember("imageryProviders");
if (attributionsIt != pResource->MemberEnd() &&
@ -346,11 +352,9 @@ std::vector<CreditAndCoverageAreas> collectCredits(
const auto creditString = attribution.FindMember("attribution");
if (creditString != attribution.MemberEnd() &&
creditString->value.IsString()) {
credits.push_back(
{pCreditSystem->createCredit(
creditString->value.GetString(),
showCreditsOnScreen),
coverageAreas});
credits.emplace_back(CreditStringAndCoverageAreas{
creditString->value.GetString(),
coverageAreas});
}
}
}
@ -361,13 +365,7 @@ std::vector<CreditAndCoverageAreas> collectCredits(
Future<RasterOverlay::CreateTileProviderResult>
BingMapsRasterOverlay::createTileProvider(
const AsyncSystem& asyncSystem,
const std::shared_ptr<IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
IntrusivePointer<const RasterOverlay> pOwner) const {
const CreateRasterOverlayTileProviderParameters& parameters) const {
Uri metadataUri(
this->_url,
"REST/v1/Imagery/Metadata/" + this->_mapStyle,
@ -384,17 +382,10 @@ BingMapsRasterOverlay::createTileProvider(
std::string metadataUrl = std::string(metadataUri.toString());
pOwner = pOwner ? pOwner : this;
IntrusivePointer<const BingMapsRasterOverlay> thiz = this;
auto handleResponse =
[pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
pPrepareRendererResources,
pLogger,
baseUrl = this->_url,
culture = this->_culture](
[thiz, parameters](
const std::shared_ptr<IAssetRequest>& pRequest,
const std::span<const std::byte>& data) -> CreateTileProviderResult {
rapidjson::Document response;
@ -452,38 +443,31 @@ BingMapsRasterOverlay::createTileProvider(
"Bing Maps tile imageUrl is missing or empty."});
}
bool showCredits = pOwner->getOptions().showCreditsOnScreen;
std::vector<CreditAndCoverageAreas> credits =
collectCredits(pResource, pCreditSystem, showCredits);
Credit bingCredit =
pCreditSystem->createCredit(BING_LOGO_HTML, showCredits);
std::vector<CreditStringAndCoverageAreas> credits =
collectCredits(pResource);
return new BingMapsTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
bingCredit,
thiz,
parameters,
credits,
pPrepareRendererResources,
pLogger,
baseUrl,
thiz->_url,
urlTemplate,
subdomains,
width,
height,
0,
maximumLevel,
culture);
thiz->_culture);
};
auto cacheResultIt = sessionCache.find(metadataUrl);
if (cacheResultIt != sessionCache.end()) {
return asyncSystem.createResolvedFuture(
return parameters.externals.asyncSystem.createResolvedFuture(
handleResponse(nullptr, std::span<std::byte>(cacheResultIt->second)));
}
return pAssetAccessor->get(asyncSystem, metadataUrl)
return parameters.externals.pAssetAccessor
->get(parameters.externals.asyncSystem, metadataUrl)
.thenInMainThread(
[metadataUrl,
handleResponse](std::shared_ptr<IAssetRequest>&& pRequest)

View File

@ -1,23 +1,18 @@
#include <CesiumAsync/AsyncSystem.h>
#include <CesiumAsync/Future.h>
#include <CesiumAsync/IAssetAccessor.h>
#include <CesiumGeospatial/Ellipsoid.h>
#include <CesiumGeospatial/GeographicProjection.h>
#include <CesiumGltf/ImageAsset.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/DebugColorizeTilesRasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumUtility/CreditSystem.h>
#include <CesiumUtility/IntrusivePointer.h>
#include <CesiumUtility/SpanHelper.h>
#include <spdlog/logger.h>
#include <cstdint>
#include <cstdlib>
#include <memory>
#include <optional>
#include <span>
#include <string>
#include <utility>
@ -32,24 +27,14 @@ namespace {
class DebugTileProvider : public RasterOverlayTileProvider {
public:
DebugTileProvider(
const IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const Ellipsoid& ellipsoid)
const IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters)
: RasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
nullptr,
std::nullopt,
pPrepareRendererResources,
pLogger,
GeographicProjection(ellipsoid),
GeographicProjection::computeMaximumProjectedRectangle(ellipsoid)) {
}
pCreator,
parameters,
GeographicProjection(pCreator->getOptions().ellipsoid),
GeographicProjection::computeMaximumProjectedRectangle(
pCreator->getOptions().ellipsoid)) {}
virtual CesiumAsync::Future<LoadedRasterOverlayImage>
loadTileImage(const RasterOverlayTile& overlayTile) override {
@ -91,21 +76,9 @@ DebugColorizeTilesRasterOverlay::DebugColorizeTilesRasterOverlay(
CesiumAsync::Future<RasterOverlay::CreateTileProviderResult>
DebugColorizeTilesRasterOverlay::createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& /* pCreditSystem */,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner) const {
pOwner = pOwner ? pOwner : this;
return asyncSystem.createResolvedFuture<CreateTileProviderResult>(
IntrusivePointer<RasterOverlayTileProvider>(new DebugTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pPrepareRendererResources,
pLogger,
this->getOptions().ellipsoid)));
const CreateRasterOverlayTileProviderParameters& parameters) const {
return parameters.externals.asyncSystem
.createResolvedFuture<CreateTileProviderResult>(
IntrusivePointer<RasterOverlayTileProvider>(
new DebugTileProvider(this, parameters)));
}

View File

@ -5,21 +5,14 @@
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumUtility/IntrusivePointer.h>
#include <optional>
namespace CesiumRasterOverlays {
EmptyRasterOverlayTileProvider::EmptyRasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem) noexcept
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters) noexcept
: RasterOverlayTileProvider(
pOwner,
asyncSystem,
nullptr,
nullptr,
std::nullopt,
nullptr,
nullptr,
pCreator,
parameters,
CesiumGeospatial::GeographicProjection(),
CesiumGeometry::Rectangle()) {}

View File

@ -9,8 +9,8 @@ class EmptyRasterOverlayTileProvider
public:
EmptyRasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<
const CesiumRasterOverlays::RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem) noexcept;
const CesiumRasterOverlays::RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters) noexcept;
protected:
virtual CesiumAsync::Future<CesiumRasterOverlays::LoadedRasterOverlayImage>

View File

@ -1,10 +1,9 @@
#include "CesiumGeometry/Rectangle.h"
#include <CesiumAsync/AsyncSystem.h>
#include <CesiumAsync/Future.h>
#include <CesiumAsync/IAssetAccessor.h>
#include <CesiumGeometry/QuadtreeTileID.h>
#include <CesiumGeometry/QuadtreeTilingScheme.h>
#include <CesiumGeometry/Rectangle.h>
#include <CesiumGeospatial/BoundingRegionBuilder.h>
#include <CesiumGeospatial/Cartographic.h>
#include <CesiumGeospatial/Ellipsoid.h>
@ -12,6 +11,7 @@
#include <CesiumGeospatial/GlobeRectangle.h>
#include <CesiumGeospatial/Projection.h>
#include <CesiumGltf/ImageAsset.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/GeoJsonDocumentRasterOverlay.h>
#include <CesiumRasterOverlays/Library.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
@ -19,7 +19,6 @@
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumUtility/Assert.h>
#include <CesiumUtility/CreditSystem.h>
#include <CesiumUtility/IntrusivePointer.h>
#include <CesiumVectorData/GeoJsonDocument.h>
#include <CesiumVectorData/GeoJsonObject.h>
@ -30,7 +29,6 @@
#include <glm/common.hpp>
#include <glm/ext/vector_int2.hpp>
#include <nonstd/expected.hpp>
#include <spdlog/logger.h>
#include <algorithm>
#include <cstddef>
@ -514,32 +512,22 @@ private:
public:
GeoJsonDocumentRasterOverlayTileProvider(
const IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const GeoJsonDocumentRasterOverlayOptions& options,
const IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const GeoJsonDocumentRasterOverlayOptions& geoJsonOptions,
std::shared_ptr<CesiumVectorData::GeoJsonDocument>&& pDocument)
: RasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
std::nullopt,
pPrepareRendererResources,
pLogger,
GeographicProjection(options.ellipsoid),
pCreator,
parameters,
GeographicProjection(geoJsonOptions.ellipsoid),
projectRectangleSimple(
GeographicProjection(options.ellipsoid),
GeographicProjection(geoJsonOptions.ellipsoid),
GlobeRectangle::MAXIMUM)),
_pDocument(std::move(pDocument)),
_defaultStyle(options.defaultStyle),
_defaultStyle(geoJsonOptions.defaultStyle),
_tree(),
_ellipsoid(options.ellipsoid),
_mipLevels(options.mipLevels) {
_ellipsoid(geoJsonOptions.ellipsoid),
_mipLevels(geoJsonOptions.mipLevels) {
CESIUM_ASSERT(this->_pDocument);
this->_tree = buildQuadtree(this->_pDocument, this->_defaultStyle);
}
@ -643,27 +631,14 @@ GeoJsonDocumentRasterOverlay::~GeoJsonDocumentRasterOverlay() = default;
CesiumAsync::Future<RasterOverlay::CreateTileProviderResult>
GeoJsonDocumentRasterOverlay::createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner) const {
const CreateRasterOverlayTileProviderParameters& parameters) const {
pOwner = pOwner ? pOwner : this;
IntrusivePointer<const GeoJsonDocumentRasterOverlay> thiz = this;
return std::move(
const_cast<GeoJsonDocumentRasterOverlay*>(this)->_documentFuture)
.thenInMainThread(
[pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
pPrepareRendererResources,
pLogger,
options =
this->_options](std::shared_ptr<GeoJsonDocument>&& pDocument)
[thiz, parameters](std::shared_ptr<GeoJsonDocument>&& pDocument)
-> CreateTileProviderResult {
if (!pDocument) {
return nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
@ -674,13 +649,9 @@ GeoJsonDocumentRasterOverlay::createTileProvider(
return IntrusivePointer<RasterOverlayTileProvider>(
new GeoJsonDocumentRasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
pPrepareRendererResources,
pLogger,
options,
thiz,
parameters,
thiz->_options,
std::move(pDocument)));
});
}

View File

@ -13,14 +13,13 @@
#include <CesiumJsonReader/JsonReader.h>
#include <CesiumJsonWriter/JsonObjectWriter.h>
#include <CesiumJsonWriter/PrettyJsonWriter.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/GoogleMapTilesRasterOverlay.h>
#include <CesiumRasterOverlays/IPrepareRasterOverlayRendererResources.h>
#include <CesiumRasterOverlays/QuadtreeRasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayLoadFailureDetails.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumUtility/Assert.h>
#include <CesiumUtility/CreditReferencer.h>
#include <CesiumUtility/ErrorList.h>
#include <CesiumUtility/IntrusivePointer.h>
#include <CesiumUtility/JsonHelpers.h>
@ -140,13 +139,8 @@ class GoogleMapTilesRasterOverlayTileProvider
: public QuadtreeRasterOverlayTileProvider {
public:
GoogleMapTilesRasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const std::string& apiBaseUrl,
const std::string& session,
const std::string& key,
@ -160,9 +154,6 @@ public:
CesiumAsync::Future<void> loadCredits();
virtual void addCredits(
CesiumUtility::CreditReferencer& creditReferencer) noexcept override;
protected:
virtual CesiumAsync::Future<LoadedRasterOverlayImage> loadQuadtreeTileImage(
const CesiumGeometry::QuadtreeTileID& tileID) const override;
@ -174,9 +165,6 @@ private:
std::string _apiBaseUrl;
std::string _session;
std::string _key;
std::optional<Credit> _googleCredit;
std::optional<Credit> _credits;
bool _showCreditsOnScreen;
mutable QuadtreeRectangleAvailability _availableTiles;
mutable QuadtreeRectangleAvailability _availableAvailability;
@ -212,34 +200,16 @@ GoogleMapTilesRasterOverlay::GoogleMapTilesRasterOverlay(
Future<RasterOverlay::CreateTileProviderResult>
GoogleMapTilesRasterOverlay::createTileProvider(
const AsyncSystem& asyncSystem,
const std::shared_ptr<IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
IntrusivePointer<const RasterOverlay> pOwner) const {
pOwner = pOwner ? pOwner : this;
const CreateRasterOverlayTileProviderParameters& parameters) const {
if (this->_newSessionParameters) {
return this->createNewSession(
asyncSystem,
pAssetAccessor,
pCreditSystem,
pPrepareRendererResources,
pLogger,
pOwner);
return this->createNewSession(parameters);
} else if (this->_existingSession) {
const GoogleMapTilesExistingSession& session = *this->_existingSession;
IntrusivePointer pTileProvider =
new GoogleMapTilesRasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
pPrepareRendererResources,
pLogger,
this,
parameters,
session.apiBaseUrl,
session.session,
session.key,
@ -259,25 +229,20 @@ GoogleMapTilesRasterOverlay::createTileProvider(
return CreateTileProviderResult(pTileProvider);
});
} else {
return asyncSystem.createResolvedFuture<CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
.type = RasterOverlayLoadType::TileProvider,
.pRequest = nullptr,
.message =
"GoogleMapTilesRasterOverlay is not configured with either "
"new session parameters or an existing session."}));
return parameters.externals.asyncSystem
.createResolvedFuture<CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
.type = RasterOverlayLoadType::TileProvider,
.pRequest = nullptr,
.message =
"GoogleMapTilesRasterOverlay is not configured with either "
"new session parameters or an existing session."}));
}
}
Future<RasterOverlay::CreateTileProviderResult>
GoogleMapTilesRasterOverlay::createNewSession(
const AsyncSystem& asyncSystem,
const std::shared_ptr<IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const IntrusivePointer<const RasterOverlay>& pOwner) const {
const CreateRasterOverlayTileProviderParameters& parameters) const {
CESIUM_ASSERT(this->_newSessionParameters);
Uri createSessionUri(
@ -329,37 +294,34 @@ GoogleMapTilesRasterOverlay::createNewSession(
writeJsonValue(requestPayload, writer);
std::vector<std::byte> requestPayloadBytes = writer.toBytes();
return pAssetAccessor
IntrusivePointer<const GoogleMapTilesRasterOverlay> thiz = this;
return parameters.externals.pAssetAccessor
->request(
asyncSystem,
parameters.externals.asyncSystem,
"POST",
std::string(createSessionUri.toString()),
{{"Content-Type", "application/json"}},
requestPayloadBytes)
.thenInMainThread(
[asyncSystem,
pAssetAccessor,
pCreditSystem,
pPrepareRendererResources,
pLogger,
pOwner,
newSessionParameters = this->_newSessionParameters](
std::shared_ptr<IAssetRequest>&& pRequest)
[thiz, parameters](std::shared_ptr<IAssetRequest>&& pRequest)
-> Future<CreateTileProviderResult> {
const IAssetResponse* pResponse = pRequest->response();
if (!pResponse) {
return asyncSystem.createResolvedFuture<CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
.type = RasterOverlayLoadType::TileProvider,
.pRequest = pRequest,
.message =
"No response received from Google Map Tiles API "
"createSession service."}));
return parameters.externals.asyncSystem
.createResolvedFuture<CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
.type = RasterOverlayLoadType::TileProvider,
.pRequest = pRequest,
.message =
"No response received from Google Map Tiles API "
"createSession service."}));
}
if (pResponse->statusCode() < 200 ||
pResponse->statusCode() >= 300) {
return asyncSystem.createResolvedFuture<CreateTileProviderResult>(
return parameters.externals.asyncSystem.createResolvedFuture<
CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
.type = RasterOverlayLoadType::TileProvider,
.pRequest = pRequest,
@ -378,7 +340,8 @@ GoogleMapTilesRasterOverlay::createNewSession(
errorList.errors = std::move(response.errors);
errorList.warnings = std::move(response.warnings);
return asyncSystem.createResolvedFuture<CreateTileProviderResult>(
return parameters.externals.asyncSystem.createResolvedFuture<
CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
.type = RasterOverlayLoadType::TileProvider,
.pRequest = pRequest,
@ -388,13 +351,14 @@ GoogleMapTilesRasterOverlay::createNewSession(
}
if (!response.value->isObject()) {
return asyncSystem.createResolvedFuture<CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
.type = RasterOverlayLoadType::TileProvider,
.pRequest = pRequest,
.message =
"Response from Google Map Tiles API "
"createSession service was not a JSON object."}));
return parameters.externals.asyncSystem
.createResolvedFuture<CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
.type = RasterOverlayLoadType::TileProvider,
.pRequest = pRequest,
.message =
"Response from Google Map Tiles API "
"createSession service was not a JSON object."}));
}
const JsonValue::Object& responseObject =
@ -402,42 +366,45 @@ GoogleMapTilesRasterOverlay::createNewSession(
auto it = responseObject.find("session");
if (it == responseObject.end() || !it->second.isString()) {
return asyncSystem.createResolvedFuture<CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
.type = RasterOverlayLoadType::TileProvider,
.pRequest = pRequest,
.message =
"Response from Google Map Tiles API "
"createSession service did not contain a valid "
"'session' property."}));
return parameters.externals.asyncSystem
.createResolvedFuture<CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
.type = RasterOverlayLoadType::TileProvider,
.pRequest = pRequest,
.message =
"Response from Google Map Tiles API "
"createSession service did not contain a valid "
"'session' property."}));
}
std::string session = it->second.getString();
it = responseObject.find("tileWidth");
if (it == responseObject.end() || !it->second.isNumber()) {
return asyncSystem.createResolvedFuture<CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
.type = RasterOverlayLoadType::TileProvider,
.pRequest = pRequest,
.message =
"Response from Google Map Tiles API "
"createSession service did not contain a valid "
"'tileWidth' property."}));
return parameters.externals.asyncSystem
.createResolvedFuture<CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
.type = RasterOverlayLoadType::TileProvider,
.pRequest = pRequest,
.message =
"Response from Google Map Tiles API "
"createSession service did not contain a valid "
"'tileWidth' property."}));
}
int32_t tileWidth = it->second.getSafeNumberOrDefault<int32_t>(256);
it = responseObject.find("tileHeight");
if (it == responseObject.end() || !it->second.isNumber()) {
return asyncSystem.createResolvedFuture<CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
.type = RasterOverlayLoadType::TileProvider,
.pRequest = pRequest,
.message =
"Response from Google Map Tiles API "
"createSession service did not contain a valid "
"'tileHeight' property."}));
return parameters.externals.asyncSystem
.createResolvedFuture<CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
.type = RasterOverlayLoadType::TileProvider,
.pRequest = pRequest,
.message =
"Response from Google Map Tiles API "
"createSession service did not contain a valid "
"'tileHeight' property."}));
}
int32_t tileHeight =
@ -445,15 +412,11 @@ GoogleMapTilesRasterOverlay::createNewSession(
IntrusivePointer pTileProvider =
new GoogleMapTilesRasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
pPrepareRendererResources,
pLogger,
newSessionParameters->apiBaseUrl,
thiz,
parameters,
thiz->_newSessionParameters->apiBaseUrl,
session,
newSessionParameters->key,
thiz->_newSessionParameters->key,
maximumZoomLevel,
static_cast<uint32_t>(tileWidth),
static_cast<uint32_t>(tileHeight),
@ -489,13 +452,8 @@ QuadtreeTilingScheme createTilingScheme(
GoogleMapTilesRasterOverlayTileProvider::
GoogleMapTilesRasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const std::string& apiBaseUrl,
const std::string& session,
const std::string& key,
@ -504,16 +462,11 @@ GoogleMapTilesRasterOverlayTileProvider::
uint32_t imageHeight,
bool showLogo)
: QuadtreeRasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
std::nullopt,
pPrepareRendererResources,
pLogger,
WebMercatorProjection(pOwner->getOptions().ellipsoid),
createTilingScheme(pOwner),
createRectangle(pOwner),
pCreator,
parameters,
WebMercatorProjection(pCreator->getOptions().ellipsoid),
createTilingScheme(pCreator),
createRectangle(pCreator),
0,
maximumLevel,
imageWidth,
@ -521,27 +474,14 @@ GoogleMapTilesRasterOverlayTileProvider::
_apiBaseUrl(apiBaseUrl),
_session(session),
_key(key),
_googleCredit(),
_credits(),
_showCreditsOnScreen(pOwner->getOptions().showCreditsOnScreen),
_availableTiles(createTilingScheme(pOwner), maximumLevel),
_availableAvailability(createTilingScheme(pOwner), maximumLevel) {
if (pCreditSystem && showLogo) {
this->_googleCredit =
pCreditSystem->createCredit(GOOGLE_MAPS_LOGO_HTML, true);
}
}
void GoogleMapTilesRasterOverlayTileProvider::addCredits(
CesiumUtility::CreditReferencer& creditReferencer) noexcept {
QuadtreeRasterOverlayTileProvider::addCredits(creditReferencer);
if (this->_googleCredit) {
creditReferencer.addCreditReference(*this->_googleCredit);
}
if (this->_credits) {
creditReferencer.addCreditReference(*this->_credits);
_availableTiles(createTilingScheme(pCreator), maximumLevel),
_availableAvailability(createTilingScheme(pCreator), maximumLevel) {
if (parameters.externals.pCreditSystem && showLogo) {
this->getCredits().emplace_back(
parameters.externals.pCreditSystem->createCredit(
this->getCreditSource(),
GOOGLE_MAPS_LOGO_HTML,
true));
}
}
@ -972,9 +912,10 @@ Future<void> GoogleMapTilesRasterOverlayTileProvider::loadCredits() {
}
// Create a single credit from this giant string.
thiz->_credits = thiz->getCreditSystem()->createCredit(
thiz->getCredits().emplace_back(thiz->getCreditSystem()->createCredit(
thiz->getCreditSource(),
joined,
thiz->_showCreditsOnScreen);
thiz->getOwner().getOptions().showCreditsOnScreen));
});
}

View File

@ -5,6 +5,7 @@
#include <CesiumAsync/SharedAssetDepot.h>
#include <CesiumRasterOverlays/AzureMapsRasterOverlay.h>
#include <CesiumRasterOverlays/BingMapsRasterOverlay.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/GoogleMapTilesRasterOverlay.h>
#include <CesiumRasterOverlays/IonRasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
@ -24,7 +25,6 @@
#include <fmt/format.h>
#include <nonstd/expected.hpp>
#include <rapidjson/document.h>
#include <spdlog/logger.h>
#include <spdlog/spdlog.h>
#include <chrono>
@ -64,8 +64,8 @@ public:
expected<AggregatedTileProviderSuccess, RasterOverlayLoadFailureDetails>;
struct CreateTileProvider {
IntrusivePointer<const RasterOverlay> pOwner;
RasterOverlayExternals externals;
IntrusivePointer<const IonRasterOverlay> pCreator;
CreateRasterOverlayTileProviderParameters parameters;
SharedFuture<AggregatedTileProviderResult>
operator()(const IntrusivePointer<ExternalAssetEndpoint>& pEndpoint);
@ -75,12 +75,14 @@ public:
DerivedValue<IntrusivePointer<ExternalAssetEndpoint>, CreateTileProvider>;
TileProvider(
const IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const IntrusivePointer<RasterOverlayTileProvider>& pInitialProvider,
const NetworkAssetDescriptor& descriptor,
TileProviderFactoryType&& tileProviderFactory)
: RasterOverlayTileProvider(
&pInitialProvider->getOwner(),
pInitialProvider->getExternals(),
pCreator,
parameters,
pInitialProvider->getProjection(),
pInitialProvider->getCoverageRectangle()),
_descriptor(descriptor),
@ -88,20 +90,26 @@ public:
_credits() {}
static CesiumAsync::Future<RasterOverlay::CreateTileProviderResult> create(
const RasterOverlayExternals& externals,
const NetworkAssetDescriptor& descriptor,
const IntrusivePointer<const RasterOverlay>& pOwner) {
const IntrusivePointer<const IonRasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const NetworkAssetDescriptor& descriptor) {
auto pFactory = std::make_unique<TileProvider::TileProviderFactoryType>(
TileProvider::TileProviderFactoryType(TileProvider::CreateTileProvider{
.pOwner = pOwner,
.externals = externals}));
return TileProvider::getTileProvider(externals, descriptor, *pFactory)
.pCreator = pCreator,
.parameters = parameters}));
return TileProvider::getTileProvider(
parameters.externals,
descriptor,
*pFactory)
.thenInMainThread(
[descriptor, pFactory = std::move(pFactory)](
[descriptor, pFactory = std::move(pFactory), pCreator, parameters](
AggregatedTileProviderResult&& result) mutable
-> CreateTileProviderResult {
if (result) {
IntrusivePointer p = new TileProvider(
pCreator,
parameters,
result.value().pAggregated,
descriptor,
std::move(*pFactory));
@ -279,15 +287,7 @@ void IonRasterOverlay::setAssetOptions(
Future<RasterOverlay::CreateTileProviderResult>
IonRasterOverlay::createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner) const {
pOwner = pOwner ? pOwner : this;
const CreateRasterOverlayTileProviderParameters& parameters) const {
NetworkAssetDescriptor descriptor;
descriptor.url = this->_overlayUrl;
@ -305,15 +305,19 @@ IonRasterOverlay::createTileProvider(
descriptor.url = uri.toString();
}
RasterOverlayExternals externals{
.pAssetAccessor = pAssetAccessor,
.pPrepareRendererResources = pPrepareRendererResources,
.asyncSystem = asyncSystem,
.pCreditSystem = pCreditSystem,
.pLogger = pLogger,
};
// The aggregated tile provider should be owned by this overlay and use a
// common credit source. But the conditions account for the possibility that
// the IonRasterOverlay itself is aggregated by some other overlay.
CreateRasterOverlayTileProviderParameters parametersCopy = parameters;
if (parametersCopy.pOwner == nullptr) {
parametersCopy.pOwner = this;
}
if (parametersCopy.pCreditSource == nullptr) {
parametersCopy.pCreditSource =
std::make_shared<CreditSource>(parameters.externals.pCreditSystem);
}
return TileProvider::create(externals, descriptor, pOwner);
return TileProvider::create(this, parametersCopy, descriptor);
}
void IonRasterOverlay::ExternalAssetEndpoint::parseAzure2DOptions(
@ -573,7 +577,7 @@ IonRasterOverlay::TileProvider::CreateTileProvider::operator()(
const IntrusivePointer<ExternalAssetEndpoint>& pEndpoint) {
if (pEndpoint == nullptr ||
std::holds_alternative<std::monostate>(pEndpoint->options)) {
return this->externals.asyncSystem
return this->parameters.externals.asyncSystem
.createResolvedFuture<AggregatedTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
RasterOverlayLoadType::CesiumIon,
@ -589,21 +593,21 @@ IonRasterOverlay::TileProvider::CreateTileProvider::operator()(
ExternalAssetEndpoint::Azure2D& azure2D =
std::get<ExternalAssetEndpoint::Azure2D>(pEndpoint->options);
pOverlay = new AzureMapsRasterOverlay(
this->pOwner->getName(),
this->pCreator->getName(),
AzureMapsSessionParameters{
.key = azure2D.key,
.tilesetId = azure2D.tilesetId,
.showLogo = false,
.apiBaseUrl = azure2D.url,
},
this->pOwner->getOptions());
this->pCreator->getOptions());
} else if (pEndpoint->externalType == "GOOGLE_2D_MAPS") {
CESIUM_ASSERT(std::holds_alternative<ExternalAssetEndpoint::Google2D>(
pEndpoint->options));
ExternalAssetEndpoint::Google2D& google2D =
std::get<ExternalAssetEndpoint::Google2D>(pEndpoint->options);
pOverlay = new GoogleMapTilesRasterOverlay(
this->pOwner->getName(),
this->pCreator->getName(),
GoogleMapTilesExistingSession{
.key = google2D.key,
.session = google2D.session,
@ -614,55 +618,49 @@ IonRasterOverlay::TileProvider::CreateTileProvider::operator()(
.showLogo = false,
.apiBaseUrl = google2D.url,
},
this->pOwner->getOptions());
this->pCreator->getOptions());
} else if (pEndpoint->externalType == "BING") {
CESIUM_ASSERT(std::holds_alternative<ExternalAssetEndpoint::Bing>(
pEndpoint->options));
ExternalAssetEndpoint::Bing& bing =
std::get<ExternalAssetEndpoint::Bing>(pEndpoint->options);
pOverlay = new BingMapsRasterOverlay(
this->pOwner->getName(),
this->pCreator->getName(),
bing.url,
bing.key,
bing.mapStyle,
bing.culture,
this->pOwner->getOptions());
this->pCreator->getOptions());
} else {
CESIUM_ASSERT(std::holds_alternative<ExternalAssetEndpoint::TileMapService>(
pEndpoint->options));
ExternalAssetEndpoint::TileMapService& tileMapService =
std::get<ExternalAssetEndpoint::TileMapService>(pEndpoint->options);
pOverlay = new TileMapServiceRasterOverlay(
this->pOwner->getName(),
this->pCreator->getName(),
tileMapService.url,
std::vector<CesiumAsync::IAssetAccessor::THeader>{std::make_pair(
"Authorization",
"Bearer " + tileMapService.accessToken)},
TileMapServiceRasterOverlayOptions(),
this->pOwner->getOptions());
this->pCreator->getOptions());
}
std::vector<Credit> credits;
if (this->externals.pCreditSystem) {
if (this->parameters.externals.pCreditSystem) {
credits.reserve(pEndpoint->attributions.size());
for (const AssetEndpointAttribution& attribution :
pEndpoint->attributions) {
credits.emplace_back(this->externals.pCreditSystem->createCredit(
attribution.html,
!attribution.collapsible ||
this->pOwner->getOptions().showCreditsOnScreen));
credits.emplace_back(
this->parameters.externals.pCreditSystem->createCredit(
attribution.html,
!attribution.collapsible ||
this->pCreator->getOptions().showCreditsOnScreen));
}
}
return pOverlay
->createTileProvider(
this->externals.asyncSystem,
this->externals.pAssetAccessor,
this->externals.pCreditSystem,
this->externals.pPrepareRendererResources,
this->externals.pLogger,
this->pOwner)
return pOverlay->createTileProvider(parameters)
.thenImmediately([credits = std::move(credits)](
CreateTileProviderResult&& result) mutable {
if (result) {

View File

@ -20,7 +20,6 @@
#include <glm/common.hpp>
#include <glm/exponential.hpp>
#include <glm/ext/vector_double2.hpp>
#include <spdlog/logger.h>
#include <algorithm>
#include <cstddef>
@ -52,14 +51,8 @@ constexpr double pixelTolerance = 0.01;
namespace CesiumRasterOverlays {
QuadtreeRasterOverlayTileProvider::QuadtreeRasterOverlayTileProvider(
const IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
std::optional<Credit> credit,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const CesiumGeospatial::Projection& projection,
const CesiumGeometry::QuadtreeTilingScheme& tilingScheme,
const CesiumGeometry::Rectangle& coverageRectangle,
@ -68,13 +61,8 @@ QuadtreeRasterOverlayTileProvider::QuadtreeRasterOverlayTileProvider(
uint32_t imageWidth,
uint32_t imageHeight) noexcept
: RasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
credit,
pPrepareRendererResources,
pLogger,
pCreator,
parameters,
projection,
coverageRectangle),
_minimumLevel(minimumLevel),

View File

@ -7,6 +7,7 @@
#include <CesiumGeospatial/Ellipsoid.h>
#include <CesiumGeospatial/GeographicProjection.h>
#include <CesiumRasterOverlays/ActivatedRasterOverlay.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayExternals.h>
#include <CesiumRasterOverlays/RasterOverlayLoadFailureDetails.h>
@ -19,7 +20,6 @@
#include <spdlog/spdlog.h>
#include <exception>
#include <memory>
#include <optional>
#include <string>
#include <utility>
@ -32,19 +32,12 @@ namespace {
class PlaceholderTileProvider : public RasterOverlayTileProvider {
public:
PlaceholderTileProvider(
const IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
const IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const CesiumGeospatial::Ellipsoid& ellipsoid) noexcept
: RasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
std::nullopt,
nullptr,
spdlog::default_logger(),
pCreator,
parameters,
CesiumGeospatial::GeographicProjection(ellipsoid),
CesiumGeometry::Rectangle()) {}
@ -93,14 +86,13 @@ CesiumUtility::IntrusivePointer<ActivatedRasterOverlay> RasterOverlay::activate(
IntrusivePointer<ActivatedRasterOverlay> pResult =
new ActivatedRasterOverlay(externals, this, ellipsoid);
CreateRasterOverlayTileProviderParameters parameters{
.externals = externals,
.pOwner = nullptr,
.pCreditSource = nullptr};
CesiumAsync::Future<RasterOverlay::CreateTileProviderResult> future =
this->createTileProvider(
externals.asyncSystem,
externals.pAssetAccessor,
externals.pCreditSystem,
externals.pPrepareRendererResources,
externals.pLogger,
this);
this->createTileProvider(parameters);
// This continuation, by capturing pResult, keeps the instance from being
// destroyed. But it does not keep the RasterOverlayCollection itself alive.
@ -115,7 +107,7 @@ CesiumUtility::IntrusivePointer<ActivatedRasterOverlay> RasterOverlay::activate(
"Error while creating tile provider: {0}",
e.what())});
})
.thenInMainThread([pResult, externals](
.thenInMainThread([pResult, parameters](
RasterOverlay::CreateTileProviderResult&& result) {
IntrusivePointer<RasterOverlayTileProvider> pProvider = nullptr;
if (result) {
@ -124,7 +116,9 @@ CesiumUtility::IntrusivePointer<ActivatedRasterOverlay> RasterOverlay::activate(
// Report error creating the tile provider.
const RasterOverlayLoadFailureDetails& failureDetails =
result.error();
SPDLOG_LOGGER_ERROR(externals.pLogger, failureDetails.message);
SPDLOG_LOGGER_ERROR(
parameters.externals.pLogger,
failureDetails.message);
if (pResult->getOverlay().getOptions().loadErrorCallback) {
pResult->getOverlay().getOptions().loadErrorCallback(
failureDetails);
@ -134,7 +128,7 @@ CesiumUtility::IntrusivePointer<ActivatedRasterOverlay> RasterOverlay::activate(
// all.
pProvider = new EmptyRasterOverlayTileProvider(
&pResult->getOverlay(),
externals.asyncSystem);
parameters);
}
pResult->setTileProvider(pProvider);
@ -149,8 +143,9 @@ RasterOverlay::createPlaceholder(
const CesiumGeospatial::Ellipsoid& ellipsoid) const {
return new PlaceholderTileProvider(
this,
externals.asyncSystem,
externals.pAssetAccessor,
nullptr,
CreateRasterOverlayTileProviderParameters{
.externals = externals,
.pOwner = nullptr,
.pCreditSource = nullptr},
ellipsoid);
}

View File

@ -6,11 +6,13 @@
#include <CesiumGeometry/Rectangle.h>
#include <CesiumGeospatial/Projection.h>
#include <CesiumGltfReader/ImageDecoder.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/IPrepareRasterOverlayRendererResources.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayExternals.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumUtility/Assert.h>
#include <CesiumUtility/CreditReferencer.h>
#include <CesiumUtility/ErrorList.h>
#include <CesiumUtility/IntrusivePointer.h>
@ -37,39 +39,24 @@ using namespace CesiumUtility;
namespace CesiumRasterOverlays {
RasterOverlayTileProvider::RasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
const RasterOverlayExternals& externals,
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const CesiumGeospatial::Projection& projection,
const CesiumGeometry::Rectangle& coverageRectangle) noexcept
: _pOwner(const_intrusive_cast<RasterOverlay>(pOwner)),
_externals(externals),
_credit(),
: _pOwner(const_intrusive_cast<RasterOverlay>(
parameters.pOwner ? parameters.pOwner : pCreator)),
_externals(parameters.externals),
_credits(),
_projection(projection),
_coverageRectangle(coverageRectangle),
_destructionCompleteDetails() {}
RasterOverlayTileProvider::RasterOverlayTileProvider(
const CesiumUtility::IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
std::optional<Credit> credit,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const CesiumGeospatial::Projection& projection,
const Rectangle& coverageRectangle) noexcept
: RasterOverlayTileProvider(
pOwner,
RasterOverlayExternals{
.pAssetAccessor = pAssetAccessor,
.pPrepareRendererResources = pPrepareRendererResources,
.asyncSystem = asyncSystem,
.pCreditSystem = pCreditSystem,
.pLogger = pLogger},
projection,
coverageRectangle) {
this->_credit = credit;
_destructionCompleteDetails(),
_pCreditSource(
parameters.pCreditSource ? parameters.pCreditSource
: std::make_shared<CreditSource>(
parameters.externals.pCreditSystem)) {
CESIUM_ASSERT(
this->_pCreditSource->getCreditSystem() ==
parameters.externals.pCreditSystem.get());
}
RasterOverlayTileProvider::~RasterOverlayTileProvider() noexcept {
@ -139,15 +126,31 @@ RasterOverlayTileProvider::getCoverageRectangle() const noexcept {
return this->_coverageRectangle;
}
const std::optional<CesiumUtility::Credit>&
RasterOverlayTileProvider::getCredit() const noexcept {
return _credit;
const CesiumUtility::CreditSource&
RasterOverlayTileProvider::getCreditSource() const noexcept {
return *this->_pCreditSource;
}
std::vector<CesiumUtility::Credit>&
RasterOverlayTileProvider::getCredits() noexcept {
return this->_credits;
}
const std::vector<CesiumUtility::Credit>&
RasterOverlayTileProvider::getCredits() const noexcept {
return this->_credits;
}
void RasterOverlayTileProvider::addCredits(
CreditReferencer& creditReferencer) noexcept {
if (this->_credit) {
creditReferencer.addCreditReference(*this->_credit);
CESIUM_ASSERT(
creditReferencer.getCreditSystem().get() ==
this->_pCreditSource->getCreditSystem());
for (const CesiumUtility::Credit& credit : this->_credits) {
CESIUM_ASSERT(
this->getCreditSystem()->getCreditSource(credit) ==
this->_pCreditSource.get());
creditReferencer.addCreditReference(credit);
}
}

View File

@ -5,22 +5,20 @@
#include <CesiumGeospatial/GlobeRectangle.h>
#include <CesiumGeospatial/Projection.h>
#include <CesiumGltf/ImageAsset.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/Library.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/RasterizedPolygonsOverlay.h>
#include <CesiumUtility/CreditSystem.h>
#include <CesiumUtility/IntrusivePointer.h>
#include <glm/common.hpp>
#include <glm/ext/vector_double2.hpp>
#include <glm/geometric.hpp>
#include <spdlog/fwd.h>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <vector>
@ -177,23 +175,14 @@ private:
public:
RasterizedPolygonsTileProvider(
const IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const CesiumGeospatial::Projection& projection,
const std::vector<CartographicPolygon>& polygons,
bool invertSelection)
: RasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
nullptr,
std::nullopt,
pPrepareRendererResources,
pLogger,
pCreator,
parameters,
projection,
// computeCoverageRectangle(projection, polygons)),
projectRectangleSimple(
@ -252,27 +241,17 @@ RasterizedPolygonsOverlay::~RasterizedPolygonsOverlay() = default;
CesiumAsync::Future<RasterOverlay::CreateTileProviderResult>
RasterizedPolygonsOverlay::createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& /*pCreditSystem*/,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner) const {
const CreateRasterOverlayTileProviderParameters& parameters) const {
pOwner = pOwner ? pOwner : this;
return asyncSystem.createResolvedFuture<CreateTileProviderResult>(
IntrusivePointer<RasterOverlayTileProvider>(
new RasterizedPolygonsTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pPrepareRendererResources,
pLogger,
this->_projection,
this->_polygons,
this->_invertSelection)));
return parameters.externals.asyncSystem
.createResolvedFuture<CreateTileProviderResult>(
IntrusivePointer<RasterOverlayTileProvider>(
new RasterizedPolygonsTileProvider(
this,
parameters,
this->_projection,
this->_polygons,
this->_invertSelection)));
}
} // namespace CesiumRasterOverlays

View File

@ -9,21 +9,19 @@
#include <CesiumGeospatial/GlobeRectangle.h>
#include <CesiumGeospatial/Projection.h>
#include <CesiumGeospatial/WebMercatorProjection.h>
#include <CesiumRasterOverlays/IPrepareRasterOverlayRendererResources.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/QuadtreeRasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayLoadFailureDetails.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/TileMapServiceRasterOverlay.h>
#include <CesiumUtility/CreditSystem.h>
#include <CesiumUtility/ErrorList.h>
#include <CesiumUtility/IntrusivePointer.h>
#include <CesiumUtility/Uri.h>
#include <glm/common.hpp>
#include <nonstd/expected.hpp>
#include <spdlog/logger.h>
#include <tinyxml2.h>
#include <cstddef>
@ -87,14 +85,9 @@ class TileMapServiceTileProvider final
: public QuadtreeRasterOverlayTileProvider {
public:
TileMapServiceTileProvider(
const IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
std::optional<Credit> credit,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
std::optional<std::string> credit,
const CesiumGeospatial::Projection& projection,
const CesiumGeometry::QuadtreeTilingScheme& tilingScheme,
const CesiumGeometry::Rectangle& coverageRectangle,
@ -107,13 +100,8 @@ public:
uint32_t maximumLevel,
const std::vector<TileMapServiceTileset>& tileSets)
: QuadtreeRasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
credit,
pPrepareRendererResources,
pLogger,
pCreator,
parameters,
projection,
tilingScheme,
coverageRectangle,
@ -124,7 +112,15 @@ public:
_url(url),
_headers(headers),
_fileExtension(fileExtension),
_tileSets(tileSets) {}
_tileSets(tileSets) {
if (parameters.externals.pCreditSystem && credit) {
this->getCredits().emplace_back(
parameters.externals.pCreditSystem->createCredit(
this->getCreditSource(),
*credit,
pCreator->getOptions().showCreditsOnScreen));
}
}
virtual ~TileMapServiceTileProvider() = default;
@ -300,37 +296,19 @@ Future<GetXmlDocumentResult> getXmlDocument(
Future<RasterOverlay::CreateTileProviderResult>
TileMapServiceRasterOverlay::createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner) const {
const CreateRasterOverlayTileProviderParameters& parameters) const {
std::string xmlUrl = this->_url;
pOwner = pOwner ? pOwner : this;
IntrusivePointer<const TileMapServiceRasterOverlay> thiz = this;
std::optional<Credit> credit = std::nullopt;
if (pCreditSystem && this->_options.credit) {
credit = pCreditSystem->createCredit(
*this->_options.credit,
pOwner->getOptions().showCreditsOnScreen);
}
return getXmlDocument(asyncSystem, pAssetAccessor, xmlUrl, this->_headers)
return getXmlDocument(
parameters.externals.asyncSystem,
parameters.externals.pAssetAccessor,
xmlUrl,
this->_headers)
.thenInMainThread(
[pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
credit,
pPrepareRendererResources,
pLogger,
options = this->_options,
url = this->_url,
headers = this->_headers](
GetXmlDocumentResult&& xml) -> CreateTileProviderResult {
[thiz,
parameters](GetXmlDocumentResult&& xml) -> CreateTileProviderResult {
if (!xml) {
return nonstd::make_unexpected(std::move(xml).error());
}
@ -340,11 +318,11 @@ TileMapServiceRasterOverlay::createTileProvider(
tinyxml2::XMLElement* pTileFormat =
pRoot->FirstChildElement("TileFormat");
std::string fileExtension = options.fileExtension.value_or(
std::string fileExtension = thiz->_options.fileExtension.value_or(
getAttributeString(pTileFormat, "extension").value_or("png"));
uint32_t tileWidth = options.tileWidth.value_or(
uint32_t tileWidth = thiz->_options.tileWidth.value_or(
getAttributeUint32(pTileFormat, "width").value_or(256));
uint32_t tileHeight = options.tileHeight.value_or(
uint32_t tileHeight = thiz->_options.tileHeight.value_or(
getAttributeUint32(pTileFormat, "height").value_or(256));
uint32_t minimumLevel = std::numeric_limits<uint32_t>::max();
@ -376,7 +354,7 @@ TileMapServiceRasterOverlay::createTileProvider(
}
const CesiumGeospatial::Ellipsoid& ellipsoid =
pOwner->getOptions().ellipsoid;
thiz->getOptions().ellipsoid;
CesiumGeospatial::GlobeRectangle tilingSchemeRectangle =
CesiumGeospatial::GeographicProjection::MAXIMUM_GLOBE_RECTANGLE;
@ -385,8 +363,8 @@ TileMapServiceRasterOverlay::createTileProvider(
uint32_t rootTilesX = 1;
bool isRectangleInDegrees = false;
if (options.projection) {
projection = options.projection.value();
if (thiz->_options.projection) {
projection = thiz->_options.projection.value();
} else {
std::string projectionName =
getAttributeString(pTilesets, "profile").value_or("mercator");
@ -440,14 +418,14 @@ TileMapServiceRasterOverlay::createTileProvider(
minimumLevel = glm::min(minimumLevel, maximumLevel);
minimumLevel = options.minimumLevel.value_or(minimumLevel);
maximumLevel = options.maximumLevel.value_or(maximumLevel);
minimumLevel = thiz->_options.minimumLevel.value_or(minimumLevel);
maximumLevel = thiz->_options.maximumLevel.value_or(maximumLevel);
CesiumGeometry::Rectangle coverageRectangle =
projectRectangleSimple(projection, tilingSchemeRectangle);
if (options.coverageRectangle) {
coverageRectangle = options.coverageRectangle.value();
if (thiz->_options.coverageRectangle) {
coverageRectangle = thiz->_options.coverageRectangle.value();
} else {
tinyxml2::XMLElement* pBoundingBox =
pRoot->FirstChildElement("BoundingBox");
@ -485,31 +463,27 @@ TileMapServiceRasterOverlay::createTileProvider(
rootTilesX,
1);
std::string updatedUrl = url;
std::string updatedUrl = thiz->_url;
std::string urlPath = Uri::getPath(url);
std::string urlPath = Uri::getPath(thiz->_url);
if (!(urlPath.size() < 4)) {
if (urlPath.substr(urlPath.size() - 4, 4) != ".xml") {
if (urlPath[urlPath.size() - 1] != '/') {
urlPath += "/";
updatedUrl = Uri::setPath(url, urlPath);
updatedUrl = Uri::setPath(thiz->_url, urlPath);
}
}
}
return new TileMapServiceTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
credit,
pPrepareRendererResources,
pLogger,
thiz,
parameters,
thiz->_options.credit,
projection,
tilingScheme,
coverageRectangle,
updatedUrl,
headers,
thiz->_headers,
!fileExtension.empty() ? "." + fileExtension : fileExtension,
tileWidth,
tileHeight,

View File

@ -8,20 +8,16 @@
#include <CesiumGeospatial/GlobeRectangle.h>
#include <CesiumGeospatial/Projection.h>
#include <CesiumGeospatial/WebMercatorProjection.h>
#include <CesiumRasterOverlays/IPrepareRasterOverlayRendererResources.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/QuadtreeRasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/UrlTemplateRasterOverlay.h>
#include <CesiumUtility/CreditSystem.h>
#include <CesiumUtility/IntrusivePointer.h>
#include <CesiumUtility/Math.h>
#include <CesiumUtility/Uri.h>
#include <spdlog/logger.h>
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <utility>
@ -39,14 +35,9 @@ class UrlTemplateRasterOverlayTileProvider final
: public QuadtreeRasterOverlayTileProvider {
public:
UrlTemplateRasterOverlayTileProvider(
const IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
std::optional<Credit> credit,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
std::optional<std::string> credit,
const CesiumGeospatial::Projection& projection,
const CesiumGeometry::QuadtreeTilingScheme& tilingScheme,
const CesiumGeometry::Rectangle& coverageRectangle,
@ -57,13 +48,8 @@ public:
uint32_t minimumLevel,
uint32_t maximumLevel)
: QuadtreeRasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
credit,
pPrepareRendererResources,
pLogger,
pCreator,
parameters,
projection,
tilingScheme,
coverageRectangle,
@ -72,7 +58,15 @@ public:
width,
height),
_url(url),
_headers(headers) {}
_headers(headers) {
if (parameters.externals.pCreditSystem && credit) {
this->getCredits().emplace_back(
parameters.externals.pCreditSystem->createCredit(
this->getCreditSource(),
*credit,
pCreator->getOptions().showCreditsOnScreen));
}
}
virtual ~UrlTemplateRasterOverlayTileProvider() = default;
@ -137,24 +131,9 @@ private:
CesiumAsync::Future<RasterOverlay::CreateTileProviderResult>
UrlTemplateRasterOverlay::createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner) const {
pOwner = pOwner ? pOwner : this;
std::optional<Credit> credit = std::nullopt;
if (pCreditSystem && this->_options.credit) {
credit = pCreditSystem->createCredit(
*this->_options.credit,
pOwner->getOptions().showCreditsOnScreen);
}
CesiumGeospatial::Projection projection = _options.projection.value_or(
CesiumGeospatial::WebMercatorProjection(pOwner->getOptions().ellipsoid));
const CreateRasterOverlayTileProviderParameters& parameters) const {
CesiumGeospatial::Projection projection = this->_options.projection.value_or(
CesiumGeospatial::WebMercatorProjection(this->getOptions().ellipsoid));
CesiumGeospatial::GlobeRectangle tilingSchemeRectangle =
CesiumGeospatial::WebMercatorProjection::MAXIMUM_GLOBE_RECTANGLE;
@ -165,34 +144,30 @@ UrlTemplateRasterOverlay::createTileProvider(
rootTilesX = 2;
}
CesiumGeometry::Rectangle coverageRectangle =
_options.coverageRectangle.value_or(
this->_options.coverageRectangle.value_or(
projectRectangleSimple(projection, tilingSchemeRectangle));
CesiumGeometry::QuadtreeTilingScheme tilingScheme =
_options.tilingScheme.value_or(CesiumGeometry::QuadtreeTilingScheme(
this->_options.tilingScheme.value_or(CesiumGeometry::QuadtreeTilingScheme(
coverageRectangle,
rootTilesX,
1));
return asyncSystem
return parameters.externals.asyncSystem
.createResolvedFuture<RasterOverlay::CreateTileProviderResult>(
new UrlTemplateRasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
credit,
pPrepareRendererResources,
pLogger,
this,
parameters,
this->_options.credit,
projection,
tilingScheme,
coverageRectangle,
_url,
_headers,
_options.tileWidth,
_options.tileHeight,
_options.minimumLevel,
_options.maximumLevel));
this->_url,
this->_headers,
this->_options.tileWidth,
this->_options.tileHeight,
this->_options.minimumLevel,
this->_options.maximumLevel));
}
} // namespace CesiumRasterOverlays

View File

@ -8,21 +8,19 @@
#include <CesiumGeospatial/GeographicProjection.h>
#include <CesiumGeospatial/GlobeRectangle.h>
#include <CesiumGeospatial/Projection.h>
#include <CesiumRasterOverlays/IPrepareRasterOverlayRendererResources.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/QuadtreeRasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayLoadFailureDetails.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/WebMapServiceRasterOverlay.h>
#include <CesiumUtility/CreditSystem.h>
#include <CesiumUtility/IntrusivePointer.h>
#include <CesiumUtility/Math.h>
#include <CesiumUtility/Uri.h>
#include <fmt/format.h>
#include <nonstd/expected.hpp>
#include <spdlog/logger.h>
#include <tinyxml2.h>
#include <cstddef>
@ -149,14 +147,9 @@ class WebMapServiceTileProvider final
: public QuadtreeRasterOverlayTileProvider {
public:
WebMapServiceTileProvider(
const IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
std::optional<Credit> credit,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
std::optional<std::string> credit,
const CesiumGeospatial::Projection& projection,
const CesiumGeometry::QuadtreeTilingScheme& tilingScheme,
const CesiumGeometry::Rectangle& coverageRectangle,
@ -170,13 +163,8 @@ public:
uint32_t minimumLevel,
uint32_t maximumLevel)
: QuadtreeRasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
credit,
pPrepareRendererResources,
pLogger,
pCreator,
parameters,
projection,
tilingScheme,
coverageRectangle,
@ -188,7 +176,15 @@ public:
_headers(headers),
_version(version),
_layers(layers),
_format(format) {}
_format(format) {
if (parameters.externals.pCreditSystem && credit) {
this->getCredits().emplace_back(
parameters.externals.pCreditSystem->createCredit(
this->getCreditSource(),
*credit,
pCreator->getOptions().showCreditsOnScreen));
}
}
virtual ~WebMapServiceTileProvider() = default;
@ -268,13 +264,7 @@ WebMapServiceRasterOverlay::~WebMapServiceRasterOverlay() = default;
Future<RasterOverlay::CreateTileProviderResult>
WebMapServiceRasterOverlay::createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner) const {
const CreateRasterOverlayTileProviderParameters& parameters) const {
std::string xmlUrlGetcapabilities =
CesiumUtility::Uri::substituteTemplateParameters(
@ -295,27 +285,15 @@ WebMapServiceRasterOverlay::createTileProvider(
return "{" + placeholder + "}";
});
pOwner = pOwner ? pOwner : this;
IntrusivePointer<const WebMapServiceRasterOverlay> thiz = this;
std::optional<Credit> credit = std::nullopt;
if (pCreditSystem && this->_options.credit) {
credit = pCreditSystem->createCredit(
*this->_options.credit,
pOwner->getOptions().showCreditsOnScreen);
}
return pAssetAccessor->get(asyncSystem, xmlUrlGetcapabilities, this->_headers)
return parameters.externals.pAssetAccessor
->get(
parameters.externals.asyncSystem,
xmlUrlGetcapabilities,
this->_headers)
.thenInMainThread(
[pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
credit,
pPrepareRendererResources,
pLogger,
options = this->_options,
url = this->_baseUrl,
headers = this->_headers](std::shared_ptr<IAssetRequest>&& pRequest)
[thiz, parameters](std::shared_ptr<IAssetRequest>&& pRequest)
-> CreateTileProviderResult {
const IAssetResponse* pResponse = pRequest->response();
if (!pResponse) {
@ -347,15 +325,18 @@ WebMapServiceRasterOverlay::createTileProvider(
"element."});
}
const WebMapServiceRasterOverlayOptions& wmsOptions =
thiz->_options;
std::string validationError;
if (!validateCapabilities(pRoot, options, validationError)) {
if (!validateCapabilities(pRoot, wmsOptions, validationError)) {
return nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
RasterOverlayLoadType::TileProvider,
std::move(pRequest),
validationError});
}
const Ellipsoid& ellipsoid = pOwner->getOptions().ellipsoid;
const Ellipsoid& ellipsoid = thiz->getOptions().ellipsoid;
const auto projection =
CesiumGeospatial::GeographicProjection(ellipsoid);
@ -374,25 +355,24 @@ WebMapServiceRasterOverlay::createTileProvider(
rootTilesY);
return new WebMapServiceTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
credit,
pPrepareRendererResources,
pLogger,
thiz,
parameters,
wmsOptions.credit,
projection,
tilingScheme,
coverageRectangle,
url,
headers,
options.version,
options.layers,
options.format,
options.tileWidth < 1 ? 1 : uint32_t(options.tileWidth),
options.tileHeight < 1 ? 1 : uint32_t(options.tileHeight),
options.minimumLevel < 0 ? 0 : uint32_t(options.minimumLevel),
options.maximumLevel < 0 ? 0 : uint32_t(options.maximumLevel));
thiz->_baseUrl,
thiz->_headers,
wmsOptions.version,
wmsOptions.layers,
wmsOptions.format,
wmsOptions.tileWidth < 1 ? 1 : uint32_t(wmsOptions.tileWidth),
wmsOptions.tileHeight < 1 ? 1 : uint32_t(wmsOptions.tileHeight),
wmsOptions.minimumLevel < 0 ? 0
: uint32_t(wmsOptions.minimumLevel),
wmsOptions.maximumLevel < 0
? 0
: uint32_t(wmsOptions.maximumLevel));
});
}

View File

@ -7,24 +7,21 @@
#include <CesiumGeospatial/GlobeRectangle.h>
#include <CesiumGeospatial/Projection.h>
#include <CesiumGeospatial/WebMercatorProjection.h>
#include <CesiumRasterOverlays/IPrepareRasterOverlayRendererResources.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/QuadtreeRasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayLoadFailureDetails.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/WebMapTileServiceRasterOverlay.h>
#include <CesiumUtility/CreditSystem.h>
#include <CesiumUtility/IntrusivePointer.h>
#include <CesiumUtility/Uri.h>
#include <nonstd/expected.hpp>
#include <spdlog/logger.h>
#include <algorithm>
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <utility>
@ -40,14 +37,9 @@ class WebMapTileServiceTileProvider final
: public QuadtreeRasterOverlayTileProvider {
public:
WebMapTileServiceTileProvider(
const IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& pCreditSystem,
std::optional<Credit> credit,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
std::optional<std::string> credit,
const CesiumGeospatial::Projection& projection,
const CesiumGeometry::QuadtreeTilingScheme& tilingScheme,
const CesiumGeometry::Rectangle& coverageRectangle,
@ -66,13 +58,8 @@ public:
const std::optional<std::map<std::string, std::string>>& dimensions,
const std::vector<std::string>& subdomains)
: QuadtreeRasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
credit,
pPrepareRendererResources,
pLogger,
pCreator,
parameters,
projection,
tilingScheme,
coverageRectangle,
@ -89,7 +76,15 @@ public:
_tileMatrixSetID(std::move(_tileMatrixSetID)),
_labels(tileMatrixLabels),
_staticDimensions(dimensions),
_subdomains(subdomains) {}
_subdomains(subdomains) {
if (parameters.externals.pCreditSystem && credit) {
this->getCredits().emplace_back(
parameters.externals.pCreditSystem->createCredit(
this->getCreditSource(),
*credit,
pCreator->getOptions().showCreditsOnScreen));
}
}
virtual ~WebMapTileServiceTileProvider() = default;
@ -204,22 +199,7 @@ WebMapTileServiceRasterOverlay::~WebMapTileServiceRasterOverlay() = default;
Future<RasterOverlay::CreateTileProviderResult>
WebMapTileServiceRasterOverlay::createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner) const {
pOwner = pOwner ? pOwner : this;
std::optional<Credit> credit = std::nullopt;
if (pCreditSystem && this->_options.credit) {
credit = pCreditSystem->createCredit(
*this->_options.credit,
pOwner->getOptions().showCreditsOnScreen);
}
const CreateRasterOverlayTileProviderParameters& parameters) const {
bool hasError = false;
std::string errorMessage;
@ -245,7 +225,7 @@ WebMapTileServiceRasterOverlay::createTileProvider(
}
CesiumGeospatial::Projection projection = _options.projection.value_or(
CesiumGeospatial::WebMercatorProjection(pOwner->getOptions().ellipsoid));
CesiumGeospatial::WebMercatorProjection(this->getOptions().ellipsoid));
CesiumGeospatial::GlobeRectangle tilingSchemeRectangle =
CesiumGeospatial::WebMercatorProjection::MAXIMUM_GLOBE_RECTANGLE;
uint32_t rootTilesX = 1;
@ -265,40 +245,36 @@ WebMapTileServiceRasterOverlay::createTileProvider(
1));
if (hasError) {
return asyncSystem
return parameters.externals.asyncSystem
.createResolvedFuture<RasterOverlay::CreateTileProviderResult>(
nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
RasterOverlayLoadType::TileProvider,
nullptr,
errorMessage}));
}
return asyncSystem
return parameters.externals.asyncSystem
.createResolvedFuture<RasterOverlay::CreateTileProviderResult>(
new WebMapTileServiceTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
credit,
pPrepareRendererResources,
pLogger,
this,
parameters,
this->_options.credit,
projection,
tilingScheme,
coverageRectangle,
_url,
_headers,
this->_url,
this->_headers,
useKVP,
format,
tileWidth,
tileHeight,
minimumLevel,
maximumLevel,
_options.layer,
_options.style,
_options.tileMatrixSetID,
_options.tileMatrixLabels,
_options.dimensions,
_options.subdomains));
this->_options.layer,
this->_options.style,
this->_options.tileMatrixSetID,
this->_options.tileMatrixLabels,
this->_options.dimensions,
this->_options.subdomains));
}
} // namespace CesiumRasterOverlays

View File

@ -1,3 +1,4 @@
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/UrlTemplateRasterOverlay.h>
@ -12,31 +13,19 @@ public:
MyRasterOverlay() : RasterOverlay("name", {}) {}
virtual CesiumAsync::Future<CreateTileProviderResult> createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner)
const CreateRasterOverlayTileProviderParameters& parameters)
const override;
};
//! [use-url-template]
CesiumAsync::Future<RasterOverlay::CreateTileProviderResult>
MyRasterOverlay::createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner) const {
const CreateRasterOverlayTileProviderParameters& parameters) const {
// Create a new raster overlay with a URL template.
CesiumGeometry::Rectangle coverageRectangle = CesiumGeospatial::
WebMercatorProjection::computeMaximumProjectedRectangle();
UrlTemplateRasterOverlayOptions options{
UrlTemplateRasterOverlayOptions urlTemplateOptions{
.credit = "Copyright (c) Some Amazing Source",
.projection = CesiumGeospatial::WebMercatorProjection(),
.tilingScheme =
@ -53,16 +42,15 @@ MyRasterOverlay::createTileProvider(
this->getName(),
"https://example.com/level-{z}/column-{x}/row-{y}.png",
{},
options);
urlTemplateOptions);
CreateRasterOverlayTileProviderParameters parametersCopy = parameters;
if (!parametersCopy.pOwner) {
parametersCopy.pOwner = this;
}
// Get that raster overlay's tile provider.
return pUrlTemplate->createTileProvider(
asyncSystem,
pAssetAccessor,
pCreditSystem,
pPrepareRendererResources,
pLogger,
pOwner != nullptr ? pOwner : this);
return pUrlTemplate->createTileProvider(parametersCopy);
}
//! [use-url-template]

View File

@ -12,6 +12,7 @@
#include <CesiumNativeTests/SimpleAssetAccessor.h>
#include <CesiumNativeTests/SimpleAssetRequest.h>
#include <CesiumRasterOverlays/ActivatedRasterOverlay.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/QuadtreeRasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/RasterOverlay.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
@ -47,14 +48,8 @@ namespace {
class TestTileProvider : public QuadtreeRasterOverlayTileProvider {
public:
TestTileProvider(
const IntrusivePointer<const RasterOverlay>& pOwner,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CesiumUtility::CreditSystem>& pCreditSystem,
std::optional<Credit> credit,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
const IntrusivePointer<const RasterOverlay>& pCreator,
const CreateRasterOverlayTileProviderParameters& parameters,
const CesiumGeospatial::Projection& projection,
const CesiumGeometry::QuadtreeTilingScheme& tilingScheme,
const CesiumGeometry::Rectangle& coverageRectangle,
@ -63,13 +58,8 @@ public:
uint32_t imageWidth,
uint32_t imageHeight) noexcept
: QuadtreeRasterOverlayTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
pCreditSystem,
credit,
pPrepareRendererResources,
pLogger,
pCreator,
parameters,
projection,
tilingScheme,
coverageRectangle,
@ -114,27 +104,12 @@ public:
: RasterOverlay(name, options) {}
virtual CesiumAsync::Future<CreateTileProviderResult> createTileProvider(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<CreditSystem>& /* pCreditSystem */,
const std::shared_ptr<IPrepareRasterOverlayRendererResources>&
pPrepareRendererResources,
const std::shared_ptr<spdlog::logger>& pLogger,
CesiumUtility::IntrusivePointer<const RasterOverlay> pOwner)
const CreateRasterOverlayTileProviderParameters& parameters)
const override {
if (!pOwner) {
pOwner = this;
}
return asyncSystem.createResolvedFuture<CreateTileProviderResult>(
new TestTileProvider(
pOwner,
asyncSystem,
pAssetAccessor,
nullptr,
std::nullopt,
pPrepareRendererResources,
pLogger,
return parameters.externals.asyncSystem
.createResolvedFuture<CreateTileProviderResult>(new TestTileProvider(
this,
parameters,
WebMercatorProjection(Ellipsoid::WGS84),
QuadtreeTilingScheme(
WebMercatorProjection::computeMaximumProjectedRectangle(

View File

@ -7,6 +7,7 @@
#include <CesiumNativeTests/readFile.h>
#include <CesiumNativeTests/waitForFuture.h>
#include <CesiumRasterOverlays/ActivatedRasterOverlay.h>
#include <CesiumRasterOverlays/CreateRasterOverlayTileProviderParameters.h>
#include <CesiumRasterOverlays/RasterOverlayTile.h>
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
#include <CesiumRasterOverlays/TileMapServiceRasterOverlay.h>
@ -125,12 +126,12 @@ TEST_CASE("TileMapServiceRasterOverlay") {
RasterOverlay::CreateTileProviderResult result = waitForFuture(
asyncSystem,
pRasterOverlay->createTileProvider(
asyncSystem,
pMockAssetAccessor,
nullptr,
nullptr,
spdlog::default_logger(),
nullptr));
CreateRasterOverlayTileProviderParameters{
.externals =
{.pAssetAccessor = pMockAssetAccessor,
.asyncSystem = asyncSystem,
.pLogger = spdlog::default_logger()},
}));
REQUIRE(result);
}
@ -160,12 +161,12 @@ TEST_CASE("TileMapServiceRasterOverlay") {
RasterOverlay::CreateTileProviderResult result = waitForFuture(
asyncSystem,
pRasterOverlay->createTileProvider(
asyncSystem,
pMockAssetAccessor,
nullptr,
nullptr,
spdlog::default_logger(),
nullptr));
CreateRasterOverlayTileProviderParameters{
.externals =
{.pAssetAccessor = pMockAssetAccessor,
.asyncSystem = asyncSystem,
.pLogger = spdlog::default_logger()},
}));
REQUIRE(result);
}
@ -215,12 +216,12 @@ TEST_CASE("TileMapServiceRasterOverlay") {
RasterOverlay::CreateTileProviderResult result = waitForFuture(
asyncSystem,
pRasterOverlay->createTileProvider(
asyncSystem,
pMockAssetAccessor,
nullptr,
nullptr,
spdlog::default_logger(),
nullptr));
CreateRasterOverlayTileProviderParameters{
.externals =
{.pAssetAccessor = pMockAssetAccessor,
.asyncSystem = asyncSystem,
.pLogger = spdlog::default_logger()},
}));
REQUIRE(result);
}
@ -237,12 +238,13 @@ TEST_CASE("TileMapServiceRasterOverlay") {
RasterOverlay::CreateTileProviderResult result = waitForFuture(
asyncSystem,
pRasterOverlayWithCredit->createTileProvider(
asyncSystem,
pMockAssetAccessor,
pCreditSystem,
nullptr,
spdlog::default_logger(),
nullptr));
CreateRasterOverlayTileProviderParameters{
.externals =
{.pAssetAccessor = pMockAssetAccessor,
.asyncSystem = asyncSystem,
.pCreditSystem = pCreditSystem,
.pLogger = spdlog::default_logger()},
}));
REQUIRE(result);
@ -266,12 +268,12 @@ TEST_CASE("TileMapServiceRasterOverlay") {
RasterOverlay::CreateTileProviderResult result = waitForFuture(
asyncSystem,
pRasterOverlayWithCredit->createTileProvider(
asyncSystem,
pMockAssetAccessor,
nullptr,
nullptr,
spdlog::default_logger(),
nullptr));
CreateRasterOverlayTileProviderParameters{
.externals =
{.pAssetAccessor = pMockAssetAccessor,
.asyncSystem = asyncSystem,
.pLogger = spdlog::default_logger()},
}));
REQUIRE(result);

View File

@ -106,9 +106,17 @@ public:
*/
void releaseAllReferences() noexcept;
/**
* @brief Tests if a credit is referenced by this referencer.
*
* @param credit The credit to test if it is referenced.
*/
bool isCreditReferenced(Credit credit) const noexcept;
private:
std::shared_ptr<CreditSystem> _pCreditSystem;
std::vector<int32_t> _references;
std::vector<uint32_t> _generations;
};
} // namespace CesiumUtility

View File

@ -3,6 +3,8 @@
#include <CesiumUtility/Library.h>
#include <cstdint>
#include <limits>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
@ -10,6 +12,45 @@
namespace CesiumUtility {
class CreditSystem;
/**
* @brief Specifies how credit system snapshots should handle multiple
* credits with the same HTML string.
*/
enum class CreditFilteringMode : uint8_t {
/**
* @brief No filtering is performed. Each unique @ref Credit is reported.
*/
None = 0,
/**
* @brief Credits are filtered so that each reported credit has a combination
* of HTML string and @ref CreditSystem::shouldBeShownOnScreen value that is
* unique from all the other reported credits.
*
* If multiple credits have the same HTML string but different
* @ref CreditSystem::shouldBeShownOnScreen values, they will be reported as
* separate credits.
*
* It is unspecified which of the multiple credits with the same properties
* will be reported.
*/
UniqueHtmlAndShowOnScreen = 1,
/**
* @brief Credits with identical HTML strings are reported as one Credit even
* if they have a different @ref CreditSource or @ref
* CreditSystem::shouldBeShownOnScreen value.
*
* It is unspecified which of the multiple credits with the same source will
* be reported. However, it is guaranteed that if any of the multiple credits
* has @ref CreditSystem::shouldBeShownOnScreen set to `true`, the reported
* credit will also have it set to `true`.
*/
UniqueHtml = 2
};
/**
* @brief Represents an HTML string that should be shown on screen to attribute
* third parties for used data, imagery, etc. Acts as a handle into a
@ -21,18 +62,75 @@ public:
* @brief Returns `true` if two credit objects have the same ID.
*/
bool operator==(const Credit& rhs) const noexcept {
return this->id == rhs.id;
return this->_id == rhs._id && this->_generation == rhs._generation;
}
private:
size_t id;
uint32_t _id;
uint32_t _generation;
Credit(size_t id_) noexcept : id(id_) {}
Credit(uint32_t id, uint32_t generation) noexcept
: _id(id), _generation(generation) {}
friend class CreditSystem;
friend class CreditReferencer;
};
/**
* @brief Represents a source of credits, such as a tileset or raster overlay,
* provided to a @ref CreditSystem.
*
* While the @ref CreditSystem does not directly map credit source instances to
* tilesets or raster overlays (or vice-versa), a tileset or raster overlay can
* be queried for its credit source instance and that instance can be compared
* against one known to the credit system.
*
* When the last reference to a credit source is released, all credits
* associated with that source are invalidated as well.
*/
class CESIUMUTILITY_API CreditSource {
public:
/**
* @brief Constructs a new credit source associated with a given credit
* system.
*
* @param creditSystem The credit system to associate with this source.
*/
CreditSource(CreditSystem& creditSystem) noexcept;
/**
* @brief Constructs a new credit source associated with a given credit
* system.
*
* @param pCreditSystem The credit system to associate with this source. This
* is allowed to be nullptr in order to enable simpler client code when
* working with an optional credit system.
*/
CreditSource(const std::shared_ptr<CreditSystem>& pCreditSystem) noexcept;
~CreditSource() noexcept;
/**
* @brief Gets the @ref CreditSystem associated with this source.
*
* This may be nullptr if this source was never associated with a credit
* system, or if the credit system has been destroyed.
*/
CreditSystem* getCreditSystem() noexcept;
/**
* @copydoc getCreditSystem
*/
const CreditSystem* getCreditSystem() const noexcept;
private:
void notifyCreditSystemDestroyed() noexcept;
CreditSystem* _pCreditSystem;
friend class CreditSystem;
};
/**
* @brief A snapshot of the credits currently active in a {@link CreditSystem}.
*/
@ -57,18 +155,56 @@ struct CreditsSnapshot {
class CESIUMUTILITY_API CreditSystem final {
public:
/**
* @brief Inserts a credit string
* @brief Constructs a new instance.
*/
CreditSystem() noexcept = default;
~CreditSystem() noexcept;
CreditSystem(const CreditSystem&) = delete;
CreditSystem& operator=(const CreditSystem&) = delete;
/**
* @brief Inserts a credit string.
*
* @param source The source of the credit. This should be an instance created
* and owned by a tileset, raster overlay, or other data source.
* @param html The HTML string for the credit.
* @param showOnScreen Whether or not the credit should be shown on screen.
* Credits not shown on the screen should be shown in a separate popup window.
* @return If this string already exists from the same source, returns a
* Credit handle to the existing entry. Otherwise returns a Credit handle to a
* new entry.
*/
Credit createCredit(
const CreditSource& source,
std::string&& html,
bool showOnScreen = false);
/** @copydoc createCredit */
Credit createCredit(
const CreditSource& source,
const std::string& html,
bool showOnScreen = false);
/**
* @brief Inserts a credit string associated with the @ref
* getDefaultCreditSource.
*
* @return If this string already exists, returns a Credit handle to the
* existing entry. Otherwise returns a Credit handle to a new entry.
*
* @deprecated Use the overload that takes a @ref CreditSource.
*/
Credit createCredit(std::string&& html, bool showOnScreen = false);
/**
* @brief Inserts a credit string
* @brief Inserts a credit string associated with the @ref
* getDefaultCreditSource.
*
* @return If this string already exists, returns a Credit handle to the
* existing entry. Otherwise returns a Credit handle to a new entry.
*
* @deprecated Use the overload that takes a @ref CreditSource.
*/
Credit createCredit(const std::string& html, bool showOnScreen = false);
@ -83,26 +219,40 @@ public:
void setShowOnScreen(Credit credit, bool showOnScreen) noexcept;
/**
* @brief Get the HTML string for this credit
* @brief Get the HTML string for this credit.
*/
const std::string& getHtml(Credit credit) const noexcept;
/**
* @brief Gets the source of this credit.
*
* @return The source of this credit, or nullptr if the credit is invalid or
* was created by a \ref CreditSource that has been destroyed.
*/
const CreditSource* getCreditSource(Credit credit) const noexcept;
/**
* @brief Adds a reference to a credit, incrementing its reference count. The
* referenced credit will be shown until its reference count goes back down to
* zero.
*
* @param credit The credit to reference.
* @returns `true` if the credit was valid and the reference was added.
* `false` if the credit was created by a @ref CreditSource that has been
* destroyed and so the reference could not be added.
*/
void addCreditReference(Credit credit);
bool addCreditReference(Credit credit);
/**
* @brief Removes a reference from a credit, decrementing its reference count.
* When the reference count goes to zero, this credit will no longer be shown.
*
* @param credit The credit from which to remove a reference.
* @returns `true` if the credit was valid and the reference was removed.
* `false` if the credit was created by a @ref CreditSource that has been
* destroyed and so the reference could not be removed.
*/
void removeCreditReference(Credit credit);
bool removeCreditReference(Credit credit);
/**
* @brief Gets a snapshot of the credits. The returned instance is only valid
@ -111,27 +261,67 @@ public:
* The snapshot will include a sorted list of credits that are currently
* active, as well as a list of credits that have been removed since the last
* snapshot.
*
* @param filteringMode Specifies how multiple credits with the same HTML
* string should be reported in the snapshot.
*/
const CreditsSnapshot& getSnapshot() noexcept;
const CreditsSnapshot& getSnapshot(
CreditFilteringMode filteringMode =
CreditFilteringMode::UniqueHtml) noexcept;
/**
* @brief Gets the default credit source used when no other source is
* specified.
*
* @deprecated Instead of using the default, create a CreditSource instance
* for each tileset, raster overlay, or other data source.
*/
const CreditSource& getDefaultCreditSource() const noexcept;
private:
void addBulkReferences(const std::vector<int32_t>& references) noexcept;
void releaseBulkReferences(const std::vector<int32_t>& references) noexcept;
struct CreditRecord {
std::string html{};
bool showOnScreen{false};
int32_t referenceCount{0};
bool shownLastSnapshot{0};
uint32_t generation{0};
const CreditSource* pSource{nullptr};
uint32_t previousCreditWithSameHtml{INVALID_CREDIT_INDEX};
uint32_t nextCreditWithSameHtml{INVALID_CREDIT_INDEX};
};
void addBulkReferences(
const std::vector<int32_t>& references,
const std::vector<uint32_t>& generations) noexcept;
void releaseBulkReferences(
const std::vector<int32_t>& references,
const std::vector<uint32_t>& generations) noexcept;
void createCreditSource(CreditSource& creditSource) noexcept;
void destroyCreditSource(CreditSource& creditSource) noexcept;
uint32_t filterCreditForSnapshot(
CreditFilteringMode filteringMode,
const CreditRecord& record) noexcept;
const std::string INVALID_CREDIT_MESSAGE =
"Error: Invalid Credit, cannot get HTML string.";
struct CreditRecord {
std::string html;
bool showOnScreen;
int32_t referenceCount;
bool shownLastSnapshot;
};
static const uint32_t INVALID_CREDIT_INDEX{
std::numeric_limits<uint32_t>::max()};
std::vector<CreditSource*> _creditSources;
std::vector<CreditRecord> _credits;
std::vector<Credit> _creditsToNoLongerShowThisSnapshot;
CreditsSnapshot _snapshot;
std::vector<int32_t> _referenceCountScratch;
// Each entry in this vector is an index into _credits that is unused and can
// be reused for a new credit.
std::vector<size_t> _unusedCreditRecords;
CreditSource _defaultCreditSource{*this};
friend class CreditReferencer;
friend class CreditSource;
};
} // namespace CesiumUtility

View File

@ -10,12 +10,16 @@ CreditReferencer::CreditReferencer() noexcept : CreditReferencer(nullptr) {}
CreditReferencer::CreditReferencer(
const std::shared_ptr<CreditSystem>& pCreditSystem) noexcept
: _pCreditSystem(pCreditSystem) {}
: _pCreditSystem(pCreditSystem), _references(), _generations() {}
CreditReferencer::CreditReferencer(const CreditReferencer& rhs) noexcept
: _pCreditSystem(rhs._pCreditSystem), _references(rhs._references) {
: _pCreditSystem(rhs._pCreditSystem),
_references(rhs._references),
_generations(rhs._generations) {
if (this->_pCreditSystem) {
this->_pCreditSystem->addBulkReferences(this->_references);
this->_pCreditSystem->addBulkReferences(
this->_references,
this->_generations);
}
}
@ -23,12 +27,15 @@ CreditReferencer&
CreditReferencer::operator=(const CreditReferencer& rhs) noexcept {
if (this != &rhs) {
if (this->_pCreditSystem) {
this->_pCreditSystem->addBulkReferences(rhs._references);
this->_pCreditSystem->addBulkReferences(
rhs._references,
rhs._generations);
}
this->releaseAllReferences();
this->_pCreditSystem = rhs._pCreditSystem;
this->_references = rhs._references;
this->_generations = rhs._generations;
}
return *this;
@ -43,6 +50,7 @@ CreditReferencer& CreditReferencer::operator=(CreditReferencer&& rhs) noexcept {
this->releaseAllReferences();
this->_pCreditSystem = std::move(rhs._pCreditSystem);
this->_references = std::move(rhs._references);
this->_generations = std::move(rhs._generations);
}
return *this;
@ -65,21 +73,50 @@ void CreditReferencer::addCreditReference(Credit credit) noexcept {
if (!this->_pCreditSystem)
return;
if (this->_references.size() <= credit.id) {
this->_references.resize(credit.id + 1);
if (!this->_pCreditSystem->addCreditReference(credit)) {
// This credit was created by a CreditSource that has been destroyed. Ignore
// it.
return;
}
++this->_references[credit.id];
this->_pCreditSystem->addCreditReference(credit);
if (this->_references.size() <= credit._id) {
this->_references.resize(credit._id + 1);
this->_generations.resize(credit._id + 1);
}
if (this->_generations[credit._id] != credit._generation) {
// The existing references (if any) refer to an older generation of this
// credit (i.e., from a previous CreditSource that has been destroyed). So
// reset the reference count to zero.
this->_references[credit._id] = 0;
this->_generations[credit._id] = credit._generation;
}
++this->_references[credit._id];
}
void CreditReferencer::releaseAllReferences() noexcept {
if (!this->_pCreditSystem)
return;
this->_pCreditSystem->releaseBulkReferences(this->_references);
this->_pCreditSystem->releaseBulkReferences(
this->_references,
this->_generations);
this->_references.clear();
this->_generations.clear();
}
bool CreditReferencer::isCreditReferenced(Credit credit) const noexcept {
if (!this->_pCreditSystem)
return false;
if (this->_references.size() <= credit._id ||
this->_generations[credit._id] != credit._generation) {
return false;
}
return this->_references[credit._id] > 0;
}
} // namespace CesiumUtility

View File

@ -4,105 +4,239 @@
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>
namespace CesiumUtility {
Credit CreditSystem::createCredit(const std::string& html, bool showOnScreen) {
return this->createCredit(std::string(html), showOnScreen);
CreditSource::CreditSource(CreditSystem& creditSystem) noexcept
: _pCreditSystem(&creditSystem) {
this->_pCreditSystem->createCreditSource(*this);
}
Credit CreditSystem::createCredit(std::string&& html, bool showOnScreen) {
// if this credit already exists, return a Credit handle to it
CreditSource::CreditSource(
const std::shared_ptr<CreditSystem>& pCreditSystem) noexcept
: _pCreditSystem(pCreditSystem.get()) {
if (this->_pCreditSystem) {
this->_pCreditSystem->createCreditSource(*this);
}
}
CreditSource::~CreditSource() noexcept {
if (this->_pCreditSystem) {
this->_pCreditSystem->destroyCreditSource(*this);
}
}
CreditSystem* CreditSource::getCreditSystem() noexcept {
return this->_pCreditSystem;
}
const CreditSystem* CreditSource::getCreditSystem() const noexcept {
return this->_pCreditSystem;
}
void CreditSource::notifyCreditSystemDestroyed() noexcept {
this->_pCreditSystem = nullptr;
}
CreditSystem::~CreditSystem() noexcept {
this->_defaultCreditSource.notifyCreditSystemDestroyed();
for (CreditSource* pSource : this->_creditSources) {
pSource->notifyCreditSystemDestroyed();
}
}
Credit CreditSystem::createCredit(
const CreditSource& source,
const std::string& html,
bool showOnScreen) {
return this->createCredit(source, std::string(html), showOnScreen);
}
Credit CreditSystem::createCredit(
const CreditSource& source,
std::string&& html,
bool showOnScreen) {
// If this credit already exists, return a Credit handle to it
uint32_t lastCreditWithSameHtml = INVALID_CREDIT_INDEX;
for (size_t id = 0; id < this->_credits.size(); ++id) {
if (this->_credits[id].html == html) {
// Override the existing credit's showOnScreen value.
this->_credits[id].showOnScreen = showOnScreen;
return Credit(id);
CreditRecord& record = this->_credits[id];
if (record.html == html) {
if (record.pSource == &source) {
// Override the existing credit's showOnScreen value.
record.showOnScreen = showOnScreen;
return Credit(uint32_t(id), record.generation);
} else if (record.pSource != nullptr) {
// Same HTML, but different source.
lastCreditWithSameHtml = uint32_t(id);
}
}
}
this->_credits.push_back({std::move(html), showOnScreen, 0, false});
// Otherwise, create a new credit record by reusing an existing entry.
size_t creditIndex;
if (!this->_unusedCreditRecords.empty()) {
creditIndex = this->_unusedCreditRecords.back();
this->_unusedCreditRecords.pop_back();
} else {
creditIndex = this->_credits.size();
this->_credits.emplace_back();
}
return Credit(this->_credits.size() - 1);
CreditRecord& record = this->_credits[creditIndex];
record.html = std::move(html);
record.showOnScreen = showOnScreen;
record.referenceCount = 0;
record.shownLastSnapshot = false;
// Do not modify `generation` here; it is either initialized to zero for a new
// Credit slot, or incremented when the previous CreditSource that used this
// slot was destroyed.
record.pSource = &source;
if (lastCreditWithSameHtml != INVALID_CREDIT_INDEX) {
// Even though `lastCreditWithSameHtml` is the credit with the same HTML
// that has the largest index, it is not necessarily last in the linked
// list.
CreditRecord& lastRecord = this->_credits[size_t(lastCreditWithSameHtml)];
record.previousCreditWithSameHtml = lastCreditWithSameHtml;
record.nextCreditWithSameHtml = lastRecord.nextCreditWithSameHtml;
lastRecord.nextCreditWithSameHtml = uint32_t(creditIndex);
if (record.nextCreditWithSameHtml != INVALID_CREDIT_INDEX) {
CreditRecord& nextRecord =
this->_credits[size_t(record.nextCreditWithSameHtml)];
nextRecord.previousCreditWithSameHtml = uint32_t(creditIndex);
}
}
return Credit(uint32_t(creditIndex), record.generation);
}
Credit CreditSystem::createCredit(std::string&& html, bool showOnScreen) {
return this->createCredit(
this->getDefaultCreditSource(),
std::move(html),
showOnScreen);
}
Credit CreditSystem::createCredit(const std::string& html, bool showOnScreen) {
return this->createCredit(this->getDefaultCreditSource(), html, showOnScreen);
}
bool CreditSystem::shouldBeShownOnScreen(Credit credit) const noexcept {
if (credit.id < this->_credits.size()) {
return this->_credits[credit.id].showOnScreen;
if (credit._id < this->_credits.size() &&
credit._generation == this->_credits[credit._id].generation) {
return this->_credits[credit._id].showOnScreen;
}
return false;
}
void CreditSystem::setShowOnScreen(Credit credit, bool showOnScreen) noexcept {
if (credit.id < this->_credits.size()) {
this->_credits[credit.id].showOnScreen = showOnScreen;
if (credit._id < this->_credits.size() &&
credit._generation == this->_credits[credit._id].generation) {
this->_credits[credit._id].showOnScreen = showOnScreen;
}
}
const std::string& CreditSystem::getHtml(Credit credit) const noexcept {
if (credit.id < this->_credits.size()) {
return this->_credits[credit.id].html;
if (credit._id < this->_credits.size() &&
credit._generation == this->_credits[credit._id].generation) {
return this->_credits[credit._id].html;
}
return INVALID_CREDIT_MESSAGE;
}
void CreditSystem::addCreditReference(Credit credit) {
CreditRecord& record = this->_credits[credit.id];
++record.referenceCount;
// If this is the first reference to this credit, and it was shown last frame,
// make sure this credit doesn't exist in _creditsToNoLongerShowThisSnapshot.
if (record.shownLastSnapshot && record.referenceCount == 1) {
this->_creditsToNoLongerShowThisSnapshot.erase(
std::remove(
this->_creditsToNoLongerShowThisSnapshot.begin(),
this->_creditsToNoLongerShowThisSnapshot.end(),
credit),
this->_creditsToNoLongerShowThisSnapshot.end());
const CreditSource*
CreditSystem::getCreditSource(Credit credit) const noexcept {
if (credit._id < this->_credits.size() &&
credit._generation == this->_credits[credit._id].generation) {
return this->_credits[credit._id].pSource;
}
return nullptr;
}
void CreditSystem::removeCreditReference(Credit credit) {
CreditRecord& record = this->_credits[credit.id];
bool CreditSystem::addCreditReference(Credit credit) {
CreditRecord& record = this->_credits[credit._id];
// If the Credit is from a previous generation (a deleted credit source),
// ignore it.
if (credit._generation != record.generation) {
return false;
}
++record.referenceCount;
return true;
}
bool CreditSystem::removeCreditReference(Credit credit) {
CreditRecord& record = this->_credits[credit._id];
// If the Credit is from a previous generation (a deleted credit source),
// ignore it.
if (credit._generation != record.generation) {
return false;
}
CESIUM_ASSERT(record.referenceCount > 0);
--record.referenceCount;
// If this was the last reference to this credit, and it was shown last frame,
// add this credit to _creditsToNoLongerShowThisSnapshot.
if (record.shownLastSnapshot && record.referenceCount == 0) {
this->_creditsToNoLongerShowThisSnapshot.emplace_back(credit);
}
return true;
}
const CreditsSnapshot& CreditSystem::getSnapshot() noexcept {
const CreditsSnapshot&
CreditSystem::getSnapshot(CreditFilteringMode filteringMode) noexcept {
std::vector<Credit>& currentCredits = this->_snapshot.currentCredits;
std::vector<Credit>& removedCredits = this->_snapshot.removedCredits;
currentCredits.clear();
removedCredits.clear();
std::vector<int32_t>& effectiveReferenceCounts = this->_referenceCountScratch;
effectiveReferenceCounts.assign(this->_credits.size(), 0);
for (size_t i = 0; i < this->_credits.size(); ++i) {
CreditRecord& record = this->_credits[i];
// A credit whose source has been destroyed will always have a reference
// count of zero.
if (record.referenceCount > 0) {
currentCredits.emplace_back(Credit(i));
record.shownLastSnapshot = true;
} else {
CESIUM_ASSERT(record.pSource != nullptr);
// This credit is active, but it may be filtered out in favor of another
// credit with the same HTML.
uint32_t filteredInFavorOf =
this->filterCreditForSnapshot(filteringMode, record);
if (filteredInFavorOf != INVALID_CREDIT_INDEX) {
// Credit filtered out in favor of another credit.
// That other credit inherits this credit's reference count.
effectiveReferenceCounts[filteredInFavorOf] += record.referenceCount;
if (record.shownLastSnapshot) {
removedCredits.emplace_back(Credit(uint32_t(i), record.generation));
record.shownLastSnapshot = false;
}
} else {
// This credit is not filtered.
currentCredits.emplace_back(Credit(uint32_t(i), record.generation));
effectiveReferenceCounts[i] += record.referenceCount;
record.shownLastSnapshot = true;
}
} else if (record.shownLastSnapshot) {
removedCredits.emplace_back(Credit(uint32_t(i), record.generation));
record.shownLastSnapshot = false;
}
}
this->_creditsToNoLongerShowThisSnapshot.swap(this->_snapshot.removedCredits);
this->_creditsToNoLongerShowThisSnapshot.clear();
// sort credits based on the number of occurrences
std::sort(
currentCredits.begin(),
currentCredits.end(),
[this](const Credit& a, const Credit& b) {
int32_t aCounts = this->_credits[a.id].referenceCount;
int32_t bCounts = this->_credits[b.id].referenceCount;
[&](const Credit& a, const Credit& b) {
int32_t aCounts = effectiveReferenceCounts[a._id];
int32_t bCounts = effectiveReferenceCounts[b._id];
if (aCounts == bCounts)
return a.id < b.id;
return a._id < b._id;
else
return aCounts > bCounts;
});
@ -110,43 +244,157 @@ const CreditsSnapshot& CreditSystem::getSnapshot() noexcept {
return this->_snapshot;
}
const CreditSource& CreditSystem::getDefaultCreditSource() const noexcept {
return this->_defaultCreditSource;
}
void CreditSystem::addBulkReferences(
const std::vector<int32_t>& references) noexcept {
const std::vector<int32_t>& references,
const std::vector<uint32_t>& generations) noexcept {
for (size_t i = 0; i < references.size(); ++i) {
CreditRecord& record = this->_credits[i];
if (record.generation != generations[i]) {
// The generations do not match, so these references are to a credit
// created by a CreditSource that has since been destroyed. Ignore them.
continue;
}
int32_t referencesToAdd = references[i];
record.referenceCount += referencesToAdd;
// If this is the first reference to this credit, and it was shown last
// frame, make sure this credit doesn't exist in
// _creditsToNoLongerShowThisSnapshot.
if (record.shownLastSnapshot && record.referenceCount == referencesToAdd) {
this->_creditsToNoLongerShowThisSnapshot.erase(
std::remove(
this->_creditsToNoLongerShowThisSnapshot.begin(),
this->_creditsToNoLongerShowThisSnapshot.end(),
Credit(i)),
this->_creditsToNoLongerShowThisSnapshot.end());
}
}
}
void CreditSystem::releaseBulkReferences(
const std::vector<int32_t>& references) noexcept {
const std::vector<int32_t>& references,
const std::vector<uint32_t>& generations) noexcept {
for (size_t i = 0; i < references.size(); ++i) {
CreditRecord& record = this->_credits[i];
if (record.generation != generations[i]) {
// The generations do not match, so these references are to a credit
// created by a CreditSource that has since been destroyed. Ignore them.
continue;
}
int32_t referencesToRemove = references[i];
CESIUM_ASSERT(record.referenceCount >= referencesToRemove);
record.referenceCount -= referencesToRemove;
}
}
// If this was the last reference to this credit, and it was shown last
// frame, add this credit to _creditsToNoLongerShowThisSnapshot.
if (record.shownLastSnapshot && record.referenceCount == 0) {
this->_creditsToNoLongerShowThisSnapshot.emplace_back(Credit(i));
void CreditSystem::createCreditSource(CreditSource& creditSource) noexcept {
this->_creditSources.emplace_back(&creditSource);
}
void CreditSystem::destroyCreditSource(CreditSource& creditSource) noexcept {
for (CreditRecord& record : this->_credits) {
if (record.pSource == &creditSource) {
record.pSource = nullptr;
++record.generation;
this->_unusedCreditRecords.emplace_back(&record - this->_credits.data());
// Delete this record from the linked list of credits with the same HTML.
if (record.nextCreditWithSameHtml != INVALID_CREDIT_INDEX) {
CreditRecord& nextRecord =
this->_credits[record.nextCreditWithSameHtml];
nextRecord.previousCreditWithSameHtml =
record.previousCreditWithSameHtml;
}
if (record.previousCreditWithSameHtml != INVALID_CREDIT_INDEX) {
CreditRecord& previousRecord =
this->_credits[record.previousCreditWithSameHtml];
previousRecord.nextCreditWithSameHtml = record.nextCreditWithSameHtml;
}
record.referenceCount = 0;
record.shownLastSnapshot = false;
record.nextCreditWithSameHtml = INVALID_CREDIT_INDEX;
record.previousCreditWithSameHtml = INVALID_CREDIT_INDEX;
}
}
this->_creditSources.erase(
std::remove(
this->_creditSources.begin(),
this->_creditSources.end(),
&creditSource),
this->_creditSources.end());
}
uint32_t CreditSystem::filterCreditForSnapshot(
CreditFilteringMode filteringMode,
const CreditRecord& record) noexcept {
if (filteringMode == CreditFilteringMode::None) {
return CreditSystem::INVALID_CREDIT_INDEX;
} else if (filteringMode == CreditFilteringMode::UniqueHtmlAndShowOnScreen) {
uint32_t currentCreditIndex = record.previousCreditWithSameHtml;
while (currentCreditIndex != INVALID_CREDIT_INDEX) {
const CreditRecord& otherRecord =
this->_credits[size_t(currentCreditIndex)];
// If the other credit is referenced and has the same showOnScreen value,
// filter this one out in favor of it.
if (otherRecord.referenceCount > 0 &&
otherRecord.showOnScreen == record.showOnScreen) {
return currentCreditIndex;
}
currentCreditIndex = otherRecord.previousCreditWithSameHtml;
}
return CreditSystem::INVALID_CREDIT_INDEX;
} else {
CESIUM_ASSERT(filteringMode == CreditFilteringMode::UniqueHtml);
// In this filtering mode, we need to find the first referenced credit in
// the linked list with showOnScreen=true. Or if they're all
// showOnScreen=false, return the first one. Unlike
// `UniqueHtmlAndShowOnScreen`, the Credit we want may occur after the
// current one.
// Walk backwards to find the first referenced credit in the linked list.
uint32_t previousCreditIndex = uint32_t(&record - this->_credits.data());
uint32_t firstReferencedCreditIndex = INVALID_CREDIT_INDEX;
do {
const CreditRecord& otherRecord =
this->_credits[size_t(previousCreditIndex)];
if (otherRecord.referenceCount > 0) {
firstReferencedCreditIndex = previousCreditIndex;
}
previousCreditIndex = otherRecord.previousCreditWithSameHtml;
} while (previousCreditIndex != INVALID_CREDIT_INDEX);
// Walk forward from the first referenced credit to find one with
// showOnScreen=true (if any).
uint32_t currentCreditIndex = firstReferencedCreditIndex;
while (currentCreditIndex != INVALID_CREDIT_INDEX) {
const CreditRecord& otherRecord =
this->_credits[size_t(currentCreditIndex)];
if (otherRecord.showOnScreen && otherRecord.referenceCount > 0) {
// Found the first referenced credit with showOnScreen=true. Filter this
// credit out in favor of it. Unless the currentCreditIndex points to
// the same credit we started with!
return currentCreditIndex == uint32_t(&record - this->_credits.data())
? CreditSystem::INVALID_CREDIT_INDEX
: currentCreditIndex;
}
currentCreditIndex = otherRecord.nextCreditWithSameHtml;
}
// Reached the end of the linked list without finding any credit with
// showOnScreen=true. So return the first referenced credit in the list.
// Unless the firstReferencedCreditIndex points to the same credit we
// started with!
return firstReferencedCreditIndex ==
uint32_t(&record - this->_credits.data())
? CreditSystem::INVALID_CREDIT_INDEX
: firstReferencedCreditIndex;
}
}
} // namespace CesiumUtility

View File

@ -19,6 +19,7 @@ TEST_CASE("CreditReferencer") {
referencer.addCreditReference(credit1);
referencer.releaseAllReferences();
REQUIRE(referencer.isCreditReferenced(credit1) == false);
}
SUBCASE("adds references to the underlying credit system") {
@ -115,5 +116,76 @@ TEST_CASE("CreditReferencer") {
const CreditsSnapshot& snapshot2 = pCreditSystem->getSnapshot();
REQUIRE(snapshot2.currentCredits.size() == 0);
}
SUBCASE("and checks credit references") {
REQUIRE(pReferencer->isCreditReferenced(credit1) == true);
REQUIRE(pReferencer->isCreditReferenced(credit2) == true);
REQUIRE(pReferencer->isCreditReferenced(credit3) == false);
}
SUBCASE("and checks credit references after releasing them") {
pReferencer->releaseAllReferences();
REQUIRE(pReferencer->isCreditReferenced(credit1) == false);
REQUIRE(pReferencer->isCreditReferenced(credit2) == false);
REQUIRE(pReferencer->isCreditReferenced(credit3) == false);
}
SUBCASE("and checks credit references after duplicating via the copy "
"constructor") {
CreditReferencer referencerCopy(*pReferencer);
REQUIRE(referencerCopy.isCreditReferenced(credit1) == true);
REQUIRE(referencerCopy.isCreditReferenced(credit2) == true);
REQUIRE(referencerCopy.isCreditReferenced(credit3) == false);
pReferencer->releaseAllReferences();
REQUIRE(pReferencer->isCreditReferenced(credit1) == false);
REQUIRE(pReferencer->isCreditReferenced(credit2) == false);
REQUIRE(pReferencer->isCreditReferenced(credit3) == false);
REQUIRE(referencerCopy.isCreditReferenced(credit1) == true);
REQUIRE(referencerCopy.isCreditReferenced(credit2) == true);
REQUIRE(referencerCopy.isCreditReferenced(credit3) == false);
}
SUBCASE("and checks credit references after duplicating via the move "
"constructor") {
CreditReferencer referencerMove(std::move(*pReferencer));
REQUIRE(referencerMove.isCreditReferenced(credit1) == true);
REQUIRE(referencerMove.isCreditReferenced(credit2) == true);
REQUIRE(referencerMove.isCreditReferenced(credit3) == false);
pReferencer->releaseAllReferences();
REQUIRE(pReferencer->isCreditReferenced(credit1) == false);
REQUIRE(pReferencer->isCreditReferenced(credit2) == false);
REQUIRE(pReferencer->isCreditReferenced(credit3) == false);
REQUIRE(referencerMove.isCreditReferenced(credit1) == true);
REQUIRE(referencerMove.isCreditReferenced(credit2) == true);
REQUIRE(referencerMove.isCreditReferenced(credit3) == false);
}
SUBCASE("unless the CreditSource has been destroyed") {
std::unique_ptr<CreditSource> pSource =
std::make_unique<CreditSource>(*pCreditSystem);
Credit credit = pCreditSystem->createCredit(*pSource, "source credit");
pReferencer->addCreditReference(credit);
CHECK(pCreditSystem->getSnapshot().currentCredits.size() == 3);
pSource.reset();
// The credit from the destroyed source should be gone.
CHECK(pCreditSystem->getSnapshot().currentCredits.size() == 2);
SUBCASE("and attempting to re-add it should have no effect") {
pReferencer->addCreditReference(credit);
CHECK(pCreditSystem->getSnapshot().currentCredits.size() == 2);
}
SUBCASE("and releasing all references should not cause problems even "
"though some references are stale") {
pReferencer->releaseAllReferences();
CHECK(pCreditSystem->getSnapshot().currentCredits.size() == 0);
}
}
}
}

View File

@ -0,0 +1,522 @@
#include <CesiumUtility/CreditSystem.h>
#include <doctest/doctest.h>
#include <optional>
#include <string>
#include <vector>
using namespace CesiumUtility;
TEST_CASE("Test basic credit handling") {
CreditSystem creditSystem;
std::string html0 = "<html>Credit0</html>";
std::string html1 = "<html>Credit1</html>";
std::string html2 = "<html>Credit2</html>";
Credit credit0 = creditSystem.createCredit(html0);
Credit credit1 = creditSystem.createCredit(html1);
Credit credit2 = creditSystem.createCredit(html2);
REQUIRE(creditSystem.getHtml(credit1) == html1);
// Frame 0: Add 0 and 1
{
creditSystem.addCreditReference(credit0);
creditSystem.addCreditReference(credit1);
const CreditsSnapshot& snapshot0 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow0{credit0, credit1};
REQUIRE(snapshot0.currentCredits == expectedShow0);
std::vector<Credit> expectedHide0{};
REQUIRE(snapshot0.removedCredits == expectedHide0);
}
// Start frame 1: Add 2, remove 0
{
creditSystem.addCreditReference(credit2);
creditSystem.removeCreditReference(credit0);
const CreditsSnapshot& snapshot1 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow1{credit1, credit2};
REQUIRE(snapshot1.currentCredits == expectedShow1);
std::vector<Credit> expectedHide1{credit0};
REQUIRE(snapshot1.removedCredits == expectedHide1);
}
// Start frame 2: Add nothing, remove 1 and 2
{
creditSystem.removeCreditReference(credit1);
creditSystem.removeCreditReference(credit2);
const CreditsSnapshot& snapshot2 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow2{};
REQUIRE(snapshot2.currentCredits == expectedShow2);
std::vector<Credit> expectedHide2{credit1, credit2};
REQUIRE(snapshot2.removedCredits == expectedHide2);
}
// Start frame 3: Add nothing, remove nothing
{
const CreditsSnapshot& snapshot3 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow3{};
REQUIRE(snapshot3.currentCredits == expectedShow3);
std::vector<Credit> expectedHide3{};
REQUIRE(snapshot3.removedCredits == expectedHide3);
}
// Start frame 4: Add 2, remove nothing
{
creditSystem.addCreditReference(credit2);
const CreditsSnapshot& snapshot4 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow4{credit2};
REQUIRE(snapshot4.currentCredits == expectedShow4);
std::vector<Credit> expectedHide4{};
REQUIRE(snapshot4.removedCredits == expectedHide4);
}
// Start frame 5: Remove and then re-add 2
{
creditSystem.removeCreditReference(credit2);
creditSystem.addCreditReference(credit2);
const CreditsSnapshot& snapshot5 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow5{credit2};
REQUIRE(snapshot5.currentCredits == expectedShow5);
std::vector<Credit> expectedHide5{};
REQUIRE(snapshot5.removedCredits == expectedHide5);
}
// Start frame 6: Add and then remove 1
{
creditSystem.addCreditReference(credit1);
creditSystem.removeCreditReference(credit1);
const CreditsSnapshot& snapshot6 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow6{credit2};
REQUIRE(snapshot6.currentCredits == expectedShow6);
std::vector<Credit> expectedHide6{};
REQUIRE(snapshot6.removedCredits == expectedHide6);
}
}
TEST_CASE("Test wrong credit handling") {
CreditSystem creditSystemA;
CreditSystem creditSystemB;
std::string html0 = "<html>Credit0</html>";
std::string html1 = "<html>Credit1</html>";
Credit creditA0 = creditSystemA.createCredit(html0);
Credit creditA1 = creditSystemA.createCredit(html1);
/*Credit creditB0 = */ creditSystemB.createCredit(html0);
// NOTE: This is using a Credit from a different credit
// system, which coincidentally has a valid ID here.
// This is not (and can hardly be) checked right now,
// so this returns a valid HTML string:
REQUIRE(creditSystemB.getHtml(creditA0) == html0);
REQUIRE(creditSystemB.getHtml(creditA1) != html1);
}
TEST_CASE("Test sorting credits by frequency") {
CreditSystem creditSystem;
std::string html0 = "<html>Credit0</html>";
std::string html1 = "<html>Credit1</html>";
std::string html2 = "<html>Credit2</html>";
Credit credit0 = creditSystem.createCredit(html0);
Credit credit1 = creditSystem.createCredit(html1);
Credit credit2 = creditSystem.createCredit(html2);
REQUIRE(creditSystem.getHtml(credit1) == html1);
for (int i = 0; i < 3; i++) {
creditSystem.addCreditReference(credit0);
}
for (int i = 0; i < 2; i++) {
creditSystem.addCreditReference(credit1);
}
creditSystem.addCreditReference(credit2);
const CreditsSnapshot& snapshot0 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow0{credit0, credit1, credit2};
REQUIRE(snapshot0.currentCredits == expectedShow0);
for (int i = 0; i < 2; i++) {
creditSystem.addCreditReference(credit2);
}
for (int i = 0; i < 2; i++) {
creditSystem.removeCreditReference(credit0);
}
const CreditsSnapshot& snapshot1 = creditSystem.getSnapshot();
std::vector<Credit> expectedShow1{credit2, credit1, credit0};
REQUIRE(snapshot1.currentCredits == expectedShow1);
}
TEST_CASE("Test setting showOnScreen on credits") {
CreditSystem creditSystem;
std::string html0 = "<html>Credit0</html>";
std::string html1 = "<html>Credit1</html>";
std::string html2 = "<html>Credit2</html>";
Credit credit0 = creditSystem.createCredit(html0, true);
Credit credit1 = creditSystem.createCredit(html1, false);
Credit credit2 = creditSystem.createCredit(html2, true);
REQUIRE(creditSystem.getHtml(credit1) == html1);
CHECK(creditSystem.shouldBeShownOnScreen(credit0) == true);
CHECK(creditSystem.shouldBeShownOnScreen(credit1) == false);
CHECK(creditSystem.shouldBeShownOnScreen(credit2) == true);
creditSystem.setShowOnScreen(credit0, false);
creditSystem.setShowOnScreen(credit1, true);
creditSystem.setShowOnScreen(credit2, true);
CHECK(creditSystem.shouldBeShownOnScreen(credit0) == false);
CHECK(creditSystem.shouldBeShownOnScreen(credit1) == true);
CHECK(creditSystem.shouldBeShownOnScreen(credit2) == true);
}
TEST_CASE("Test CreditSystem with CreditSources") {
CreditSystem creditSystem;
CreditSource sourceA(creditSystem);
CreditSource sourceB(creditSystem);
std::string html0 = "<html>Credit0</html>";
std::string html1 = "<html>Credit1</html>";
std::string html2 = "<html>Credit2</html>";
SUBCASE("can create credits from multiple sources") {
Credit credit0 = creditSystem.createCredit(sourceA, html0);
Credit credit1 = creditSystem.createCredit(sourceB, html1);
CHECK(creditSystem.getCreditSource(credit0) == &sourceA);
CHECK(creditSystem.getHtml(credit0) == html0);
CHECK(creditSystem.getCreditSource(credit1) == &sourceB);
CHECK(creditSystem.getHtml(credit1) == html1);
}
SUBCASE("credits become invalid when their source is destroyed") {
std::optional<Credit> credit;
{
CreditSource tempSourceA(creditSystem);
credit = creditSystem.createCredit(tempSourceA, html0);
CHECK(creditSystem.getCreditSource(*credit) == &tempSourceA);
}
// tempSourceA is destroyed here.
// The credit should no longer have a source.
CHECK(creditSystem.getCreditSource(*credit) == nullptr);
// Getting HTML from a credit with no source should not crash and it provide
// a non-empty (error) message.
CHECK(!creditSystem.getHtml(*credit).empty());
// Creating a new credit from a different source should still work.
CreditSource tempSourceB(creditSystem);
Credit credit1 = creditSystem.createCredit(tempSourceB, html1);
CHECK(creditSystem.getCreditSource(credit1) == &tempSourceB);
CHECK(creditSystem.getHtml(credit1) == html1);
}
SUBCASE("when the source of a credit last frame is destroyed, that credit is "
"not reported") {
std::unique_ptr<CreditSource> pTempSourceA =
std::make_unique<CreditSource>(creditSystem);
Credit credit0 = creditSystem.createCredit(*pTempSourceA, html0);
creditSystem.addCreditReference(credit0);
const CreditsSnapshot& snapshot0 = creditSystem.getSnapshot();
CHECK(snapshot0.currentCredits.size() == 1);
CHECK(snapshot0.currentCredits[0] == credit0);
// Remove the credit reference. If we were to ask for a snapshot after this,
// this credit would show up in the `removedCredits`.
creditSystem.removeCreditReference(credit0);
// Destroy the source. Now, the removed credit should no longer be reported
// in the next snapshot.
pTempSourceA.reset();
const CreditsSnapshot& snapshot1 = creditSystem.getSnapshot();
CHECK(snapshot1.currentCredits.empty());
CHECK(snapshot1.removedCredits.empty());
}
SUBCASE("CreditSystem may be destroyed before CreditSource") {
std::unique_ptr<CreditSystem> pCreditSystem =
std::make_unique<CreditSystem>();
std::unique_ptr<CreditSource> pSource =
std::make_unique<CreditSource>(*pCreditSystem);
// Destroy the system, then the source. This should not crash.
pCreditSystem.reset();
pSource.reset();
}
SUBCASE("two strings from different sources produce different credits") {
Credit credit0 = creditSystem.createCredit(sourceA, html0);
Credit credit1 = creditSystem.createCredit(sourceB, html0);
CHECK(credit0 != credit1);
}
SUBCASE("two strings from the same source produce the same credit") {
Credit credit0 = creditSystem.createCredit(sourceA, html0);
Credit credit1 = creditSystem.createCredit(sourceA, html0);
CHECK(credit0 == credit1);
}
SUBCASE("destroying a source resets the reference counts of its credits") {
std::unique_ptr<CreditSource> pSourceTemp =
std::make_unique<CreditSource>(creditSystem);
Credit credit0 = creditSystem.createCredit(*pSourceTemp, html0);
creditSystem.addCreditReference(credit0);
pSourceTemp.reset();
creditSystem.createCredit(sourceA, html0);
const CreditsSnapshot& snapshot = creditSystem.getSnapshot();
CHECK(snapshot.currentCredits.empty());
CHECK(snapshot.removedCredits.empty());
}
SUBCASE(
"releasing a reference to a credit from a destroyed source is a no-op") {
std::unique_ptr<CreditSource> pSourceTemp =
std::make_unique<CreditSource>(creditSystem);
Credit credit0 = creditSystem.createCredit(*pSourceTemp, html0);
creditSystem.addCreditReference(credit0);
pSourceTemp.reset();
// Create another credit in a new source, which will reuse the same credit
// record.
Credit credit1 = creditSystem.createCredit(sourceA, html0);
creditSystem.addCreditReference(credit1);
// This should be a no-op and not crash.
creditSystem.removeCreditReference(credit0);
const CreditsSnapshot& snapshot = creditSystem.getSnapshot();
REQUIRE(snapshot.currentCredits.size() == 1);
CHECK(snapshot.currentCredits[0] == credit1);
CHECK(snapshot.removedCredits.empty());
}
SUBCASE("getSnapshot") {
SUBCASE("None filtering mode") {
SUBCASE("includes all Credits from all sources") {
CreditSource sourceC(creditSystem);
Credit credit0 = creditSystem.createCredit(sourceA, html0);
Credit credit1 = creditSystem.createCredit(sourceB, html0);
Credit credit2 = creditSystem.createCredit(sourceC, html0);
creditSystem.addCreditReference(credit0);
creditSystem.addCreditReference(credit1);
creditSystem.addCreditReference(credit2);
const CreditsSnapshot& snapshot =
creditSystem.getSnapshot(CreditFilteringMode::None);
REQUIRE(snapshot.currentCredits.size() == 3);
CHECK(snapshot.currentCredits[0] == credit0);
CHECK(snapshot.currentCredits[1] == credit1);
CHECK(snapshot.currentCredits[2] == credit2);
CHECK(snapshot.removedCredits.empty());
}
}
SUBCASE("UniqueHtmlAndShowOnScreen filtering mode") {
SUBCASE(
"filters out credits with identical HTML and showOnScreen values") {
CreditSource sourceC(creditSystem);
Credit credit0 = creditSystem.createCredit(sourceA, html0, true);
Credit credit1 = creditSystem.createCredit(sourceB, html0, true);
Credit credit2 = creditSystem.createCredit(sourceC, html0, false);
creditSystem.addCreditReference(credit0);
creditSystem.addCreditReference(credit1);
creditSystem.addCreditReference(credit2);
const CreditsSnapshot& snapshot = creditSystem.getSnapshot(
CreditFilteringMode::UniqueHtmlAndShowOnScreen);
REQUIRE(snapshot.currentCredits.size() == 2);
CHECK(snapshot.currentCredits[0] == credit0);
CHECK(snapshot.currentCredits[1] == credit2);
CHECK(snapshot.removedCredits.empty());
}
SUBCASE("does not filter in favor of unreferenced credits") {
CreditSource sourceC(creditSystem);
[[maybe_unused]] Credit credit0 =
creditSystem.createCredit(sourceA, html0, true);
Credit credit1 = creditSystem.createCredit(sourceB, html0, true);
Credit credit2 = creditSystem.createCredit(sourceC, html0, false);
creditSystem.addCreditReference(credit1);
creditSystem.addCreditReference(credit2);
// Note: credit0 is not referenced.
const CreditsSnapshot& snapshot = creditSystem.getSnapshot(
CreditFilteringMode::UniqueHtmlAndShowOnScreen);
REQUIRE(snapshot.currentCredits.size() == 2);
CHECK(snapshot.currentCredits[0] == credit1);
CHECK(snapshot.currentCredits[1] == credit2);
CHECK(snapshot.removedCredits.empty());
}
SUBCASE("reference count is the sum of collapsed credits") {
CreditSource sourceC(creditSystem);
Credit credit0 = creditSystem.createCredit(sourceA, html0, false);
Credit credit1 = creditSystem.createCredit(sourceB, html0, true);
Credit credit2 = creditSystem.createCredit(sourceC, html0, true);
creditSystem.addCreditReference(credit0);
creditSystem.addCreditReference(credit0);
creditSystem.addCreditReference(credit1);
creditSystem.addCreditReference(credit2);
creditSystem.addCreditReference(credit2);
const CreditsSnapshot& snapshot = creditSystem.getSnapshot(
CreditFilteringMode::UniqueHtmlAndShowOnScreen);
// credit0 has a reference count of 2. credit1 and credit2 are collapsed
// into one credit with a reference count of 3 and represented by
// credit1. So credit1 should be shown before credit0.
REQUIRE(snapshot.currentCredits.size() == 2);
CHECK(snapshot.currentCredits[0] == credit1);
CHECK(snapshot.currentCredits[1] == credit0);
CHECK(snapshot.removedCredits.empty());
}
}
SUBCASE("UniqueHtml filtering mode") {
SUBCASE(
"filters out credits with identical HTML from different sources") {
CreditSource sourceC(creditSystem);
Credit credit0 = creditSystem.createCredit(sourceA, html0);
Credit credit1 = creditSystem.createCredit(sourceB, html0);
Credit credit2 = creditSystem.createCredit(sourceC, html0);
creditSystem.addCreditReference(credit0);
creditSystem.addCreditReference(credit1);
creditSystem.addCreditReference(credit2);
const CreditsSnapshot& snapshot =
creditSystem.getSnapshot(CreditFilteringMode::UniqueHtml);
REQUIRE(snapshot.currentCredits.size() == 1);
CHECK(snapshot.currentCredits[0] == credit0);
CHECK(snapshot.removedCredits.empty());
}
SUBCASE("includes the Credit with showOnScreen=true if one exists.") {
CreditSource sourceC(creditSystem);
Credit credit0 = creditSystem.createCredit(sourceA, html0, false);
Credit credit1 = creditSystem.createCredit(sourceB, html0, true);
Credit credit2 = creditSystem.createCredit(sourceC, html0, false);
creditSystem.addCreditReference(credit0);
creditSystem.addCreditReference(credit1);
creditSystem.addCreditReference(credit2);
const CreditsSnapshot& snapshot =
creditSystem.getSnapshot(CreditFilteringMode::UniqueHtml);
REQUIRE(snapshot.currentCredits.size() == 1);
CHECK(snapshot.currentCredits[0] == credit1);
CHECK(snapshot.removedCredits.empty());
}
SUBCASE("includes the first of multiple Credits with showOnScreen=true") {
CreditSource sourceC(creditSystem);
Credit credit0 = creditSystem.createCredit(sourceA, html0, true);
Credit credit1 = creditSystem.createCredit(sourceB, html0, true);
Credit credit2 = creditSystem.createCredit(sourceC, html0, false);
creditSystem.addCreditReference(credit0);
creditSystem.addCreditReference(credit1);
creditSystem.addCreditReference(credit2);
const CreditsSnapshot& snapshot =
creditSystem.getSnapshot(CreditFilteringMode::UniqueHtml);
REQUIRE(snapshot.currentCredits.size() == 1);
CHECK(snapshot.currentCredits[0] == credit0);
CHECK(snapshot.removedCredits.empty());
}
SUBCASE("does not filter in favor of unreferenced credits") {
CreditSource sourceC(creditSystem);
Credit credit0 = creditSystem.createCredit(sourceA, html0, false);
Credit credit1 = creditSystem.createCredit(sourceB, html0, false);
[[maybe_unused]] Credit credit2 =
creditSystem.createCredit(sourceC, html0, true);
creditSystem.addCreditReference(credit0);
creditSystem.addCreditReference(credit1);
// Note: credit2 is not referenced.
const CreditsSnapshot& snapshot =
creditSystem.getSnapshot(CreditFilteringMode::UniqueHtml);
REQUIRE(snapshot.currentCredits.size() == 1);
CHECK(snapshot.currentCredits[0] == credit0);
CHECK(snapshot.removedCredits.empty());
}
SUBCASE("reference count is the sum of collapsed credits") {
CreditSource sourceC(creditSystem);
Credit credit0 = creditSystem.createCredit(sourceA, html0);
Credit credit1 = creditSystem.createCredit(sourceB, html1);
Credit credit2 = creditSystem.createCredit(sourceC, html1);
creditSystem.addCreditReference(credit0);
creditSystem.addCreditReference(credit0);
creditSystem.addCreditReference(credit1);
creditSystem.addCreditReference(credit2);
creditSystem.addCreditReference(credit2);
const CreditsSnapshot& snapshot =
creditSystem.getSnapshot(CreditFilteringMode::UniqueHtml);
// credit0 has a reference count of 2. credit1 and credit2 are collapsed
// into one credit with a reference count of 3 and represented by
// credit1. So credit1 should be shown before credit0.
REQUIRE(snapshot.currentCredits.size() == 2);
CHECK(snapshot.currentCredits[0] == credit1);
CHECK(snapshot.currentCredits[1] == credit0);
CHECK(snapshot.removedCredits.empty());
}
}
}
// Reference count for sorting is the sum of collapsed credit reference
// counts.
}