TileGrid::~TileGrid() { #ifdef DEBUG_COUNT ClassTracker::instance()->decrement("TileGrid"); #endif removeTiles(); }
// remove lower line in game field // return true if there are still tiles that can be dropped down // in contest const bool GameField::removeLowerLine(const bool contest) { #ifdef DEBUG std::cout << "GameField::removeLowerLine(" << contest << ")" << std::endl; #endif bool ok = false; // create array with lower line ScoredTileArray tArray; ScoredTile sTile( FieldPos(0, 0), 10, ScoredTile::FIELDDIRECTION_RIGHT, m_field[0][0], 0 ); tArray.push_back(sTile); // remove tiles removeTiles(tArray); // let all existing tiles fall to the ground ok = fallTilesToGround(contest); // and fill with new ones fillEmptyTiles(); // clear array again tArray.clear(); return ok; }
// search for equal entries and removes them on the set // return true if something has been removed void GameField::removeTiles(const ScoredTileArray& tArray) { // delete the positions stored in the array for ( std::vector<ScoredTile>::const_iterator it = tArray.begin(); it < tArray.end(); it++ ) { // std::cout << "GameField::removeTiles() " // << (*it).getPos().x() << " " << (*it).getPos().y() << std::endl; removeTiles(*it); } }
void TileGrid::removeAllSecondaryTiles() { Vector<TileIndex> tilesToRemove; for (auto& entry : m_tiles) { const TileInfo& tileInfo = entry.value; if (tileInfo.cohort == VisibleTileCohort) continue; tilesToRemove.append(entry.key); } removeTiles(tilesToRemove); }
void TileGrid::removeTilesInCohort(TileCohort cohort) { ASSERT(cohort != VisibleTileCohort); Vector<TileIndex> tilesToRemove; for (auto& entry : m_tiles) { const TileInfo& tileInfo = entry.value; if (tileInfo.cohort != cohort) continue; tilesToRemove.append(entry.key); } removeTiles(tilesToRemove); }
void TileGrid::dropTilesInRect(const IntRect& rect) { if (m_tiles.isEmpty()) return; FloatRect scaledRect(rect); scaledRect.scale(m_scale); IntRect dropRectInTileCoords(enclosingIntRect(scaledRect)); Vector<TileIndex> tilesToRemove; for (auto& index : m_tiles.keys()) { if (rectForTileIndex(index).intersects(dropRectInTileCoords)) tilesToRemove.append(index); } removeTiles(tilesToRemove); }
// remove tiles and fill the game fields until only maximum // two same tiles are next to each other void GameField::cascade(void) { // print(); ScoredTileArray tArray; while ( findSameTiles(tArray) ) { // remove tiles removeTiles(tArray); // first let all existing tiles fall to the ground fallTilesToGround(false); // and fill with new ones fillEmptyTiles(); // clear array again tArray.clear(); } }
void MapView::zoom(int dZoom) { int newZoom = currentZoom + dZoom; if (newZoom > MapSource.maxzoom || newZoom < MapSource.minzoom || dZoom == 0) {getTilesInView(); return;} scale(pow(2,dZoom),pow(2,dZoom)); currentZoom += dZoom; emit zoomChanged(currentZoom); //remove tiles that are not in the current zoomlevel or up to maxLayers-1 above int maxLayers = 4; for(int i = 0; i<=MapSource.maxzoom; ++i) { if (i < currentZoom - (maxLayers - 1)|| i > currentZoom) removeTiles(i); } updateOutlines(); removeDistantTiles(); getTilesInView(); }
void MapView::setMapSource(sourceName source) { //get new map source struct osmMapSource newSource = mapSource(source); //check if map source changed, if it did not, abort if (newSource.id == MapSource.id) return; emit mapSourceChanged(newSource.minzoom, newSource.maxzoom); //remove all tiles, resize tilemanager if (MapSource.id != None) { for (int z = MapSource.minzoom; z <= MapSource.maxzoom; ++z) removeTiles(z); delete[] tiles; } if (newSource.id != None) tiles = new QList<OSMTile*>[newSource.maxzoom+1]; MapSource = newSource; if (currentZoom > MapSource.maxzoom) zoomTo(MapSource.maxzoom); else if (currentZoom < MapSource.minzoom) zoomTo(MapSource.minzoom); else getTilesInView(); }
void TileGrid::revalidateTiles(TileValidationPolicy validationPolicy) { FloatRect coverageRect = m_controller.coverageRect(); IntRect bounds = m_controller.bounds(); if (coverageRect.isEmpty() || bounds.isEmpty()) return; FloatRect scaledRect(coverageRect); scaledRect.scale(m_scale); IntRect coverageRectInTileCoords(enclosingIntRect(scaledRect)); TileCohort currCohort = nextTileCohort(); unsigned tilesInCohort = 0; double minimumRevalidationTimerDuration = std::numeric_limits<double>::max(); bool needsTileRevalidation = false; // Move tiles newly outside the coverage rect into the cohort map. for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) { TileInfo& tileInfo = it->value; TileIndex tileIndex = it->key; PlatformCALayer* tileLayer = tileInfo.layer.get(); IntRect tileRect = rectForTileIndex(tileIndex); if (tileRect.intersects(coverageRectInTileCoords)) { tileInfo.cohort = VisibleTileCohort; if (tileInfo.hasStaleContent) { // FIXME: store a dirty region per layer? tileLayer->setNeedsDisplay(); tileInfo.hasStaleContent = false; } } else { // Add to the currentCohort if not already in one. if (tileInfo.cohort == VisibleTileCohort) { tileInfo.cohort = currCohort; ++tilesInCohort; if (m_controller.unparentsOffscreenTiles()) tileLayer->removeFromSuperlayer(); } else if (m_controller.unparentsOffscreenTiles() && m_controller.shouldAggressivelyRetainTiles() && tileLayer->superlayer()) { // Aggressive tile retention means we'll never remove cohorts, but we need to make sure they're unparented. // We can't immediately unparent cohorts comprised of secondary tiles that never touch the primary coverage rect, // because that would defeat the usefulness of prepopulateRect(); instead, age prepopulated tiles out as if they were being removed. for (auto& cohort : m_cohortList) { if (cohort.cohort != tileInfo.cohort) continue; double timeUntilCohortExpires = cohort.timeUntilExpiration(); if (timeUntilCohortExpires > 0) { minimumRevalidationTimerDuration = std::min(minimumRevalidationTimerDuration, timeUntilCohortExpires); needsTileRevalidation = true; } else tileLayer->removeFromSuperlayer(); break; } } } } if (needsTileRevalidation) m_controller.scheduleTileRevalidation(minimumRevalidationTimerDuration); if (tilesInCohort) startedNewCohort(currCohort); if (!m_controller.shouldAggressivelyRetainTiles()) { if (m_controller.shouldTemporarilyRetainTileCohorts()) scheduleCohortRemoval(); else if (tilesInCohort) removeTilesInCohort(currCohort); } // Ensure primary tile coverage tiles. m_primaryTileCoverageRect = ensureTilesForRect(coverageRect, CoverageType::PrimaryTiles); if (validationPolicy & PruneSecondaryTiles) { removeAllSecondaryTiles(); m_cohortList.clear(); } else { for (auto& secondaryCoverageRect : m_secondaryTileCoverageRects) { FloatRect secondaryRectInLayerCoordinates(secondaryCoverageRect); secondaryRectInLayerCoordinates.scale(1 / m_scale); ensureTilesForRect(secondaryRectInLayerCoordinates, CoverageType::SecondaryTiles); } m_secondaryTileCoverageRects.clear(); } if (m_controller.unparentsOffscreenTiles() && (validationPolicy & UnparentAllTiles)) { for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) it->value.layer->removeFromSuperlayer(); } auto boundsAtLastRevalidate = m_controller.boundsAtLastRevalidate(); if (boundsAtLastRevalidate != bounds) { // If there are margin tiles and the bounds have grown taller or wider, then the tiles that used to // be bottom or right margin tiles need to be invalidated. if (m_controller.hasMargins()) { if (bounds.width() > boundsAtLastRevalidate.width() || bounds.height() > boundsAtLastRevalidate.height()) { IntRect boundsWithoutMargin = m_controller.boundsWithoutMargin(); IntRect oldBoundsWithoutMargin = m_controller.boundsAtLastRevalidateWithoutMargin(); if (bounds.height() > boundsAtLastRevalidate.height()) { IntRect formerBottomMarginRect = IntRect(oldBoundsWithoutMargin.x(), oldBoundsWithoutMargin.height(), oldBoundsWithoutMargin.width(), boundsWithoutMargin.height() - oldBoundsWithoutMargin.height()); setNeedsDisplayInRect(formerBottomMarginRect); } if (bounds.width() > boundsAtLastRevalidate.width()) { IntRect formerRightMarginRect = IntRect(oldBoundsWithoutMargin.width(), oldBoundsWithoutMargin.y(), boundsWithoutMargin.width() - oldBoundsWithoutMargin.width(), oldBoundsWithoutMargin.height()); setNeedsDisplayInRect(formerRightMarginRect); } } } FloatRect scaledBounds(bounds); scaledBounds.scale(m_scale); IntRect boundsInTileCoords(enclosingIntRect(scaledBounds)); TileIndex topLeftForBounds; TileIndex bottomRightForBounds; getTileIndexRangeForRect(boundsInTileCoords, topLeftForBounds, bottomRightForBounds); Vector<TileIndex> tilesToRemove; for (auto& index : m_tiles.keys()) { if (index.y() < topLeftForBounds.y() || index.y() > bottomRightForBounds.y() || index.x() < topLeftForBounds.x() || index.x() > bottomRightForBounds.x()) tilesToRemove.append(index); } removeTiles(tilesToRemove); } m_controller.didRevalidateTiles(); }