From dda5c9f13a0a3d9d89faa90a5447f75248f98438 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Thu, 13 Mar 2025 19:42:57 +0000 Subject: [PATCH] Map objects now use shared_ptr (editor) --- mapeditor/mainwindow.cpp | 6 +-- mapeditor/mapcontroller.cpp | 42 ++++++++++----------- mapeditor/mapcontroller.h | 2 +- mapeditor/maphandler.cpp | 4 +- mapeditor/mapsettings/abstractsettings.cpp | 6 +-- mapeditor/mapsettings/abstractsettings.h | 4 +- mapeditor/mapsettings/loseconditions.cpp | 2 +- mapeditor/mapsettings/timedevent.cpp | 2 +- mapeditor/mapsettings/victoryconditions.cpp | 2 +- mapeditor/mapview.cpp | 10 ++--- mapeditor/playerparams.cpp | 4 +- mapeditor/scenelayer.cpp | 5 +-- mapeditor/scenelayer.h | 2 +- mapeditor/validator.cpp | 8 +--- 14 files changed, 45 insertions(+), 54 deletions(-) diff --git a/mapeditor/mainwindow.cpp b/mapeditor/mainwindow.cpp index 4989673e0..8dba41a85 100644 --- a/mapeditor/mainwindow.cpp +++ b/mapeditor/mainwindow.cpp @@ -698,7 +698,7 @@ void MainWindow::addGroupIntoCatalog(const QString & groupName, bool useCustomNa } //create object to extract name - std::unique_ptr temporaryObj(factory->create(nullptr, templ)); + auto temporaryObj(factory->create(nullptr, templ)); QString translated = useCustomName ? QString::fromStdString(temporaryObj->getObjectName().c_str()) : subGroupName; itemType->setText(translated); @@ -1401,8 +1401,8 @@ void MainWindow::on_actionLock_triggered() { for(auto obj : controller.map()->objects) { - controller.scene(mapLevel)->selectionObjectsView.setLockObject(obj, true); - controller.scene(mapLevel)->objectsView.setLockObject(obj, true); + controller.scene(mapLevel)->selectionObjectsView.setLockObject(obj.get(), true); + controller.scene(mapLevel)->objectsView.setLockObject(obj.get(), true); } } else diff --git a/mapeditor/mapcontroller.cpp b/mapeditor/mapcontroller.cpp index cd30a7713..286378e0c 100644 --- a/mapeditor/mapcontroller.cpp +++ b/mapeditor/mapcontroller.cpp @@ -110,19 +110,16 @@ void MapController::repairMap(CMap * map) //fix owners for objects auto allImpactedObjects(map->objects); - allImpactedObjects.insert(allImpactedObjects.end(), map->predefinedHeroes.begin(), map->predefinedHeroes.end()); + + for (const auto & hero : map->predefinedHeroes) + allImpactedObjects.push_back(hero); + for(auto obj : allImpactedObjects) { //fix flags if(obj->getOwner() == PlayerColor::UNFLAGGABLE) { - if(dynamic_cast(obj.get()) || - dynamic_cast(obj.get()) || - dynamic_cast(obj.get()) || - dynamic_cast(obj.get()) || - dynamic_cast(obj.get()) || - dynamic_cast(obj.get()) || - dynamic_cast(obj.get())) + if(obj->asOwnable()) obj->tempOwner = PlayerColor::NEUTRAL; } //fix hero instance @@ -364,9 +361,9 @@ void MapController::pasteFromClipboard(int level) QStringList errors; for(auto & objUniquePtr : _clipboard) { - auto * obj = CMemorySerializer::deepCopy(*objUniquePtr).release(); + auto obj = CMemorySerializer::deepCopyShared(*objUniquePtr); QString errorMsg; - if (!canPlaceObject(level, obj, errorMsg)) + if (!canPlaceObject(level, obj.get(), errorMsg)) { errors.push_back(std::move(errorMsg)); continue; @@ -376,10 +373,10 @@ void MapController::pasteFromClipboard(int level) obj->pos = newPos; obj->pos.z = level; - Initializer init(*this, obj, defaultPlayer); + Initializer init(*this, obj.get(), defaultPlayer); _map->getEditManager()->insertObject(obj); - _scenes[level]->selectionObjectsView.selectObject(obj); - _mapHandler->invalidate(obj); + _scenes[level]->selectionObjectsView.selectObject(obj.get()); + _mapHandler->invalidate(obj.get()); } if(!errors.isEmpty()) QMessageBox::warning(main, QObject::tr("Can't place object"), errors.join('\n')); @@ -397,8 +394,7 @@ bool MapController::discardObject(int level) const _scenes[level]->selectionObjectsView.clear(); if(_scenes[level]->selectionObjectsView.newObject) { - delete _scenes[level]->selectionObjectsView.newObject; - _scenes[level]->selectionObjectsView.newObject = nullptr; + _scenes[level]->selectionObjectsView.newObject.reset(); _scenes[level]->selectionObjectsView.shift = QPoint(0, 0); _scenes[level]->selectionObjectsView.selectionMode = SelectionObjectsLayer::NOTHING; _scenes[level]->selectionObjectsView.draw(); @@ -407,7 +403,7 @@ bool MapController::discardObject(int level) const return false; } -void MapController::createObject(int level, CGObjectInstance * obj) const +void MapController::createObject(int level, std::shared_ptr obj) const { _scenes[level]->selectionObjectsView.newObject = obj; _scenes[level]->selectionObjectsView.selectionMode = SelectionObjectsLayer::MOVEMENT; @@ -438,10 +434,10 @@ void MapController::commitObstacleFill(int level) for(auto & sel : _obstaclePainters) { - for(auto * o : sel.second->placeObstacles(CRandomGenerator::getDefault())) + for(auto o : sel.second->placeObstacles(CRandomGenerator::getDefault())) { - _mapHandler->invalidate(o); - _scenes[level]->objectsView.setDirty(o); + _mapHandler->invalidate(o.get()); + _scenes[level]->objectsView.setDirty(o.get()); } } @@ -509,7 +505,7 @@ void MapController::commitObjectShift(int level) void MapController::commitObjectCreate(int level) { - auto * newObj = _scenes[level]->selectionObjectsView.newObject; + auto newObj = _scenes[level]->selectionObjectsView.newObject; if(!newObj) return; @@ -521,11 +517,11 @@ void MapController::commitObjectCreate(int level) newObj->pos = pos; - Initializer init(*this, newObj, defaultPlayer); + Initializer init(*this, newObj.get(), defaultPlayer); _map->getEditManager()->insertObject(newObj); - _mapHandler->invalidate(newObj); - _scenes[level]->objectsView.setDirty(newObj); + _mapHandler->invalidate(newObj.get()); + _scenes[level]->objectsView.setDirty(newObj.get()); _scenes[level]->selectionObjectsView.newObject = nullptr; _scenes[level]->selectionObjectsView.shift = QPoint(0, 0); diff --git a/mapeditor/mapcontroller.h b/mapeditor/mapcontroller.h index 89c6ec337..067942e03 100644 --- a/mapeditor/mapcontroller.h +++ b/mapeditor/mapcontroller.h @@ -59,7 +59,7 @@ public: void pasteFromClipboard(int level); bool discardObject(int level) const; - void createObject(int level, CGObjectInstance * obj) const; + void createObject(int level, std::shared_ptr obj) const; bool canPlaceObject(int level, CGObjectInstance * obj, QString & error) const; static ModCompatibilityInfo modAssessmentAll(); diff --git a/mapeditor/maphandler.cpp b/mapeditor/maphandler.cpp index 9c4d92ec0..e77c1e1f3 100644 --- a/mapeditor/maphandler.cpp +++ b/mapeditor/maphandler.cpp @@ -259,9 +259,9 @@ void MapHandler::initObjectRects() tileObjects.resize(map->width * map->height * (map->twoLevel ? 2 : 1)); //initializing objects / rects - for(const CGObjectInstance * elem : map->objects) + for(const auto & elem : map->objects) { - addObject(elem); + addObject(elem.get()); } for(auto & tt : tileObjects) diff --git a/mapeditor/mapsettings/abstractsettings.cpp b/mapeditor/mapsettings/abstractsettings.cpp index a21d2f24b..5480b734a 100644 --- a/mapeditor/mapsettings/abstractsettings.cpp +++ b/mapeditor/mapsettings/abstractsettings.cpp @@ -89,7 +89,7 @@ void AbstractSettings::initialize(MapController & c) std::string AbstractSettings::getTownName(const CMap & map, int objectIdx) { std::string name; - if(auto town = dynamic_cast(map.objects[objectIdx].get())) + if(auto town = dynamic_cast(map.objects.at(objectIdx).get())) { name = town->getNameTranslated(); @@ -102,7 +102,7 @@ std::string AbstractSettings::getTownName(const CMap & map, int objectIdx) std::string AbstractSettings::getHeroName(const CMap & map, int objectIdx) { std::string name; - if(auto hero = dynamic_cast(map.objects[objectIdx].get())) + if(auto hero = dynamic_cast(map.objects.at(objectIdx).get())) { name = hero->getNameTranslated(); } @@ -112,7 +112,7 @@ std::string AbstractSettings::getHeroName(const CMap & map, int objectIdx) std::string AbstractSettings::getMonsterName(const CMap & map, int objectIdx) { std::string name; - if(auto monster = dynamic_cast(map.objects[objectIdx].get())) + if(auto monster = dynamic_cast(map.objects.at(objectIdx).get())) { name = boost::str(boost::format("%1% at %2%") % monster->getObjectName() % monster->anchorPos().toString()); } diff --git a/mapeditor/mapsettings/abstractsettings.h b/mapeditor/mapsettings/abstractsettings.h index bf729be06..72f2ce77b 100644 --- a/mapeditor/mapsettings/abstractsettings.h +++ b/mapeditor/mapsettings/abstractsettings.h @@ -46,7 +46,7 @@ public: std::vector result; for(int i = 0; i < map.objects.size(); ++i) { - if(auto obj = dynamic_cast(map.objects[i].get())) + if(auto obj = dynamic_cast(map.objects.at(i).get())) result.push_back(i); } return result; @@ -57,7 +57,7 @@ public: { for(int i = 0; i < map.objects.size(); ++i) { - if(auto obj = dynamic_cast(map.objects[i].get())) + if(auto obj = dynamic_cast(map.objects.at(i).get())) { if(obj->pos == pos) return i; diff --git a/mapeditor/mapsettings/loseconditions.cpp b/mapeditor/mapsettings/loseconditions.cpp index 3a6555323..84e26a881 100644 --- a/mapeditor/mapsettings/loseconditions.cpp +++ b/mapeditor/mapsettings/loseconditions.cpp @@ -331,7 +331,7 @@ void LoseConditions::onObjectPicked(const CGObjectInstance * obj) for(int i = 0; i < loseTypeWidget->count(); ++i) { auto data = controller->map()->objects.at(loseTypeWidget->itemData(i).toInt()); - if(data == obj) + if(data.get() == obj) { loseTypeWidget->setCurrentIndex(i); break; diff --git a/mapeditor/mapsettings/timedevent.cpp b/mapeditor/mapsettings/timedevent.cpp index d3484ae4f..5cbb25ca8 100644 --- a/mapeditor/mapsettings/timedevent.cpp +++ b/mapeditor/mapsettings/timedevent.cpp @@ -63,7 +63,7 @@ TimedEvent::TimedEvent(MapController & c, QListWidgetItem * t, QWidget *parent) auto id = ObjectInstanceID(idAsVariant.toInt()); auto obj = controller.map()->objects[id]; if(obj) - insertObjectToDelete(obj); + insertObjectToDelete(obj.get()); } show(); } diff --git a/mapeditor/mapsettings/victoryconditions.cpp b/mapeditor/mapsettings/victoryconditions.cpp index ccab73386..e2dae21bf 100644 --- a/mapeditor/mapsettings/victoryconditions.cpp +++ b/mapeditor/mapsettings/victoryconditions.cpp @@ -559,7 +559,7 @@ void VictoryConditions::onObjectPicked(const CGObjectInstance * obj) continue; auto data = controller->map()->objects.at(w->itemData(i).toInt()); - if(data == obj) + if(data.get() == obj) { w->setCurrentIndex(i); break; diff --git a/mapeditor/mapview.cpp b/mapeditor/mapview.cpp index 283c544f1..caad98717 100644 --- a/mapeditor/mapview.cpp +++ b/mapeditor/mapview.cpp @@ -386,7 +386,7 @@ void MapView::mousePressEvent(QMouseEvent *event) sc->selectionTerrainView.clear(); sc->selectionTerrainView.draw(); - if(sc->selectionObjectsView.newObject && sc->selectionObjectsView.isSelected(sc->selectionObjectsView.newObject)) + if(sc->selectionObjectsView.newObject && sc->selectionObjectsView.isSelected(sc->selectionObjectsView.newObject.get())) { if(event->button() == Qt::RightButton) controller->discardObject(sc->level); @@ -614,11 +614,11 @@ void MapView::dropEvent(QDropEvent * event) if(sc->selectionObjectsView.newObject) { QString errorMsg; - if(controller->canPlaceObject(sc->level, sc->selectionObjectsView.newObject, errorMsg)) + if(controller->canPlaceObject(sc->level, sc->selectionObjectsView.newObject.get(), errorMsg)) { - auto * obj = sc->selectionObjectsView.newObject; + auto obj = sc->selectionObjectsView.newObject; controller->commitObjectCreate(sc->level); - openObjectProperties(obj, false); + openObjectProperties(obj.get(), false); } else { @@ -643,7 +643,7 @@ void MapView::dragMoveEvent(QDragMoveEvent * event) if(sc->selectionObjectsView.newObject) { sc->selectionObjectsView.shift = QPoint(tile.x, tile.y); - sc->selectionObjectsView.selectObject(sc->selectionObjectsView.newObject); + sc->selectionObjectsView.selectObject(sc->selectionObjectsView.newObject.get()); sc->selectionObjectsView.selectionMode = SelectionObjectsLayer::MOVEMENT; sc->selectionObjectsView.draw(); } diff --git a/mapeditor/playerparams.cpp b/mapeditor/playerparams.cpp index 98c513cc7..9f5f82987 100644 --- a/mapeditor/playerparams.cpp +++ b/mapeditor/playerparams.cpp @@ -77,7 +77,7 @@ PlayerParams::PlayerParams(MapController & ctrl, int playerId, QWidget *parent) int foundMainTown = -1; for(int i = 0, townIndex = 0; i < controller.map()->objects.size(); ++i) { - if(auto town = dynamic_cast(controller.map()->objects[i].get())) + if(auto town = dynamic_cast(controller.map()->objects.at(i).get())) { auto * ctown = town->getTown(); @@ -223,7 +223,7 @@ void PlayerParams::onTownPicked(const CGObjectInstance * obj) for(int i = 0; i < ui->mainTown->count(); ++i) { auto town = controller.map()->objects.at(ui->mainTown->itemData(i).toInt()); - if(town == obj) + if(town.get() == obj) { ui->mainTown->setCurrentIndex(i); break; diff --git a/mapeditor/scenelayer.cpp b/mapeditor/scenelayer.cpp index 207ca66a7..cf699160f 100644 --- a/mapeditor/scenelayer.cpp +++ b/mapeditor/scenelayer.cpp @@ -455,8 +455,7 @@ void SelectionObjectsLayer::update() selectedObjects.clear(); onSelection(); shift = QPoint(); - delete newObject; - newObject = nullptr; + newObject.reset(); pixmap.reset(new QPixmap(map->width * 32, map->height * 32)); //pixmap->fill(QColor(0, 0, 0, 0)); @@ -477,7 +476,7 @@ void SelectionObjectsLayer::draw() for(auto * obj : selectedObjects) { - if(obj != newObject) + if(obj != newObject.get()) { QRect bbox(obj->anchorPos().x, obj->anchorPos().y, 1, 1); for(auto & t : obj->getBlockedPos()) diff --git a/mapeditor/scenelayer.h b/mapeditor/scenelayer.h index 468f29697..cccc130a4 100644 --- a/mapeditor/scenelayer.h +++ b/mapeditor/scenelayer.h @@ -191,7 +191,7 @@ public: void unlockAll(); QPoint shift; - CGObjectInstance * newObject; + std::shared_ptr newObject; //FIXME: magic number SelectionMode selectionMode = SelectionMode::NOTHING; diff --git a/mapeditor/validator.cpp b/mapeditor/validator.cpp index 79525b7f1..5c281ca94 100644 --- a/mapeditor/validator.cpp +++ b/mapeditor/validator.cpp @@ -90,13 +90,9 @@ std::set Validator::validate(const CMap * map) //owners for objects if(o->getOwner() == PlayerColor::UNFLAGGABLE) { - if(dynamic_cast(o.get()) || - dynamic_cast(o.get()) || - dynamic_cast(o.get()) || - dynamic_cast(o.get()) || - dynamic_cast(o.get())) + if(o->asOwnable()) { - issues.insert({ tr("Armored instance %1 is UNFLAGGABLE but must have NEUTRAL or player owner").arg(o->instanceName.c_str()), true }); + issues.insert({ tr("Ownable object %1 is UNFLAGGABLE but must have NEUTRAL or player owner").arg(o->instanceName.c_str()), true }); } } if(o->getOwner() != PlayerColor::NEUTRAL && o->getOwner().getNum() < map->players.size())