Compare commits
4 Commits
77fff1077a
...
fbbaf4452a
| Author | SHA1 | Date |
|---|---|---|
|
|
fbbaf4452a | |
|
|
fd8aaef4be | |
|
|
32e509eb95 | |
|
|
002d00e3f8 |
|
|
@ -8,13 +8,13 @@
|
|||
- The constructor parameters for `RasterOverlayTileProvider` and `QuadtreeRasterOverlayTileProvider` have changed.
|
||||
- The `getCredit` method has been removed from `RasterOverlayCreditProvider`. Use `getCredits` instead.
|
||||
- Removed unused property `RasterOverlayOptions::subTileCacheBytes`.
|
||||
- The `CreditSystem` would previously treat credits with identical text as the same credit, even if they came from different sources. Now, credits from different `CreditSource` instances are treated as different credits.
|
||||
|
||||
##### 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
|
||||
|
||||
|
|
|
|||
|
|
@ -326,4 +326,158 @@ TEST_CASE("Test CreditSystem with CreditSources") {
|
|||
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("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("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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Refeference count for sorting is the sum of collapsed credit reference
|
||||
// counts.
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#include <CesiumUtility/Library.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
|
@ -13,6 +14,43 @@ 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
|
||||
|
|
@ -116,8 +154,15 @@ struct CreditsSnapshot {
|
|||
*/
|
||||
class CESIUMUTILITY_API CreditSystem final {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a new instance.
|
||||
*/
|
||||
CreditSystem() noexcept = default;
|
||||
~CreditSystem() noexcept;
|
||||
|
||||
CreditSystem(const CreditSystem&) = delete;
|
||||
CreditSystem& operator=(const CreditSystem&) = delete;
|
||||
|
||||
/**
|
||||
* @brief Inserts a credit string.
|
||||
*
|
||||
|
|
@ -227,8 +272,13 @@ 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
|
||||
|
|
@ -240,6 +290,17 @@ public:
|
|||
const CreditSource& getDefaultCreditSource() const noexcept;
|
||||
|
||||
private:
|
||||
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;
|
||||
|
|
@ -250,22 +311,20 @@ private:
|
|||
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{false};
|
||||
int32_t referenceCount{0};
|
||||
bool shownLastSnapshot{0};
|
||||
uint32_t generation{0};
|
||||
const CreditSource* pSource{nullptr};
|
||||
};
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -61,12 +61,18 @@ Credit CreditSystem::createCredit(
|
|||
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) {
|
||||
CreditRecord& record = this->_credits[id];
|
||||
if (record.pSource == &source && record.html == html) {
|
||||
// Override the existing credit's showOnScreen value.
|
||||
record.showOnScreen = showOnScreen;
|
||||
return Credit(uint32_t(id), record.generation);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -90,6 +96,14 @@ Credit CreditSystem::createCredit(
|
|||
// slot was destroyed.
|
||||
record.pSource = &source;
|
||||
|
||||
if (lastCreditWithSameHtml != INVALID_CREDIT_INDEX) {
|
||||
record.previousCreditWithSameHtml = lastCreditWithSameHtml;
|
||||
record.nextCreditWithSameHtml = INVALID_CREDIT_INDEX;
|
||||
CreditRecord& lastRecord = this->_credits[size_t(lastCreditWithSameHtml)];
|
||||
CESIUM_ASSERT(lastRecord.nextCreditWithSameHtml == INVALID_CREDIT_INDEX);
|
||||
lastRecord.nextCreditWithSameHtml = uint32_t(creditIndex);
|
||||
}
|
||||
|
||||
return Credit(uint32_t(creditIndex), record.generation);
|
||||
}
|
||||
|
||||
|
|
@ -147,19 +161,6 @@ bool CreditSystem::addCreditReference(Credit credit) {
|
|||
|
||||
++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_if(
|
||||
this->_creditsToNoLongerShowThisSnapshot.begin(),
|
||||
this->_creditsToNoLongerShowThisSnapshot.end(),
|
||||
[id = credit._id](const Credit& candidate) {
|
||||
return candidate._id == id;
|
||||
}),
|
||||
this->_creditsToNoLongerShowThisSnapshot.end());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -174,18 +175,18 @@ bool CreditSystem::removeCreditReference(Credit credit) {
|
|||
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];
|
||||
|
|
@ -194,23 +195,38 @@ const CreditsSnapshot& CreditSystem::getSnapshot() noexcept {
|
|||
// count of zero.
|
||||
if (record.referenceCount > 0) {
|
||||
CESIUM_ASSERT(record.pSource != nullptr);
|
||||
currentCredits.emplace_back(Credit(uint32_t(i), record.generation));
|
||||
record.shownLastSnapshot = true;
|
||||
} else {
|
||||
|
||||
// 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;
|
||||
else
|
||||
|
|
@ -238,20 +254,6 @@ void CreditSystem::addBulkReferences(
|
|||
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_if(
|
||||
this->_creditsToNoLongerShowThisSnapshot.begin(),
|
||||
this->_creditsToNoLongerShowThisSnapshot.end(),
|
||||
[i = uint32_t(i)](const Credit& candidate) {
|
||||
return candidate._id == i;
|
||||
}),
|
||||
this->_creditsToNoLongerShowThisSnapshot.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -270,13 +272,6 @@ void CreditSystem::releaseBulkReferences(
|
|||
|
||||
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(uint32_t(i), record.generation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -291,17 +286,24 @@ void CreditSystem::destroyCreditSource(CreditSource& creditSource) noexcept {
|
|||
++record.generation;
|
||||
this->_unusedCreditRecords.emplace_back(&record - this->_credits.data());
|
||||
|
||||
if (record.referenceCount > 0) {
|
||||
record.referenceCount = 0;
|
||||
} else {
|
||||
this->_creditsToNoLongerShowThisSnapshot.erase(
|
||||
std::remove_if(
|
||||
this->_creditsToNoLongerShowThisSnapshot.begin(),
|
||||
this->_creditsToNoLongerShowThisSnapshot.end(),
|
||||
[id = uint32_t(&record - this->_credits.data())](
|
||||
const Credit& candidate) { return candidate._id == id; }),
|
||||
this->_creditsToNoLongerShowThisSnapshot.end());
|
||||
// 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;
|
||||
record.nextCreditWithSameHtml = INVALID_CREDIT_INDEX;
|
||||
}
|
||||
|
||||
if (record.previousCreditWithSameHtml != INVALID_CREDIT_INDEX) {
|
||||
CreditRecord& previousRecord =
|
||||
this->_credits[record.previousCreditWithSameHtml];
|
||||
previousRecord.nextCreditWithSameHtml = record.nextCreditWithSameHtml;
|
||||
record.previousCreditWithSameHtml = INVALID_CREDIT_INDEX;
|
||||
}
|
||||
|
||||
record.referenceCount = 0;
|
||||
record.shownLastSnapshot = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -313,4 +315,72 @@ void CreditSystem::destroyCreditSource(CreditSource& creditSource) noexcept {
|
|||
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 has the same showOnScreen value, filter this one
|
||||
// out in favor of it.
|
||||
if (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 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 credit in the linked list.
|
||||
uint32_t previousCreditIndex = uint32_t(&record - this->_credits.data());
|
||||
uint32_t firstCreditIndex;
|
||||
do {
|
||||
firstCreditIndex = previousCreditIndex;
|
||||
const CreditRecord& otherRecord =
|
||||
this->_credits[size_t(firstCreditIndex)];
|
||||
previousCreditIndex = otherRecord.previousCreditWithSameHtml;
|
||||
} while (previousCreditIndex != INVALID_CREDIT_INDEX);
|
||||
|
||||
// Walk forward from the first credit to find one with showOnScreen=true (if
|
||||
// any).
|
||||
uint32_t currentCreditIndex = firstCreditIndex;
|
||||
while (currentCreditIndex != INVALID_CREDIT_INDEX) {
|
||||
const CreditRecord& otherRecord =
|
||||
this->_credits[size_t(currentCreditIndex)];
|
||||
|
||||
if (otherRecord.showOnScreen) {
|
||||
// Found the first 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 credit in the list. Unless the
|
||||
// firstCreditIndex points to the same credit we started with!
|
||||
return firstCreditIndex == uint32_t(&record - this->_credits.data())
|
||||
? CreditSystem::INVALID_CREDIT_INDEX
|
||||
: firstCreditIndex;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace CesiumUtility
|
||||
|
|
|
|||
Loading…
Reference in New Issue