| 334 | } |
| 335 | |
| 336 | uint32_t CreditSystem::filterCreditForSnapshot( |
| 337 | CreditFilteringMode filteringMode, |
| 338 | const CreditRecord& record) noexcept { |
| 339 | if (filteringMode == CreditFilteringMode::None) { |
| 340 | return CreditSystem::INVALID_CREDIT_INDEX; |
| 341 | } else if (filteringMode == CreditFilteringMode::UniqueHtmlAndShowOnScreen) { |
| 342 | uint32_t currentCreditIndex = record.previousCreditWithSameHtml; |
| 343 | |
| 344 | while (currentCreditIndex != INVALID_CREDIT_INDEX) { |
| 345 | const CreditRecord& otherRecord = |
| 346 | this->_credits[size_t(currentCreditIndex)]; |
| 347 | |
| 348 | // If the other credit is referenced and has the same showOnScreen value, |
| 349 | // filter this one out in favor of it. |
| 350 | if (otherRecord.referenceCount > 0 && |
| 351 | otherRecord.showOnScreen == record.showOnScreen) { |
| 352 | return currentCreditIndex; |
| 353 | } |
| 354 | |
| 355 | currentCreditIndex = otherRecord.previousCreditWithSameHtml; |
| 356 | } |
| 357 | |
| 358 | return CreditSystem::INVALID_CREDIT_INDEX; |
| 359 | } else { |
| 360 | CESIUM_ASSERT(filteringMode == CreditFilteringMode::UniqueHtml); |
| 361 | |
| 362 | // In this filtering mode, we need to find the first referenced credit in |
| 363 | // the linked list with showOnScreen=true. Or if they're all |
| 364 | // showOnScreen=false, return the first one. Unlike |
| 365 | // `UniqueHtmlAndShowOnScreen`, the Credit we want may occur after the |
| 366 | // current one. |
| 367 | |
| 368 | // Walk backwards to find the first referenced credit in the linked list. |
| 369 | uint32_t previousCreditIndex = uint32_t(&record - this->_credits.data()); |
| 370 | uint32_t firstReferencedCreditIndex = INVALID_CREDIT_INDEX; |
| 371 | do { |
| 372 | const CreditRecord& otherRecord = |
| 373 | this->_credits[size_t(previousCreditIndex)]; |
| 374 | if (otherRecord.referenceCount > 0) { |
| 375 | firstReferencedCreditIndex = previousCreditIndex; |
| 376 | } |
| 377 | previousCreditIndex = otherRecord.previousCreditWithSameHtml; |
| 378 | } while (previousCreditIndex != INVALID_CREDIT_INDEX); |
| 379 | |
| 380 | // Walk forward from the first referenced credit to find one with |
| 381 | // showOnScreen=true (if any). |
| 382 | uint32_t currentCreditIndex = firstReferencedCreditIndex; |
| 383 | while (currentCreditIndex != INVALID_CREDIT_INDEX) { |
| 384 | const CreditRecord& otherRecord = |
| 385 | this->_credits[size_t(currentCreditIndex)]; |
| 386 | |
| 387 | if (otherRecord.showOnScreen && otherRecord.referenceCount > 0) { |
| 388 | // Found the first referenced credit with showOnScreen=true. Filter this |
| 389 | // credit out in favor of it. Unless the currentCreditIndex points to |
| 390 | // the same credit we started with! |
| 391 | return currentCreditIndex == uint32_t(&record - this->_credits.data()) |
| 392 | ? CreditSystem::INVALID_CREDIT_INDEX |
| 393 | : currentCreditIndex; |