fix model storage actions

This commit is contained in:
T1ti
2024-07-23 09:29:34 +02:00
parent 21a0e69e05
commit 4853c8aa37
14 changed files with 166 additions and 157 deletions

View File

@@ -240,10 +240,10 @@ unsigned Noggit::Action::handleObjectAdded(unsigned uid, bool redo)
unsigned old_uid = pair.first;
SceneObject* obj;
if (pair.second.type == ActionObjectTypes::WMO)
obj = _map_view->getWorld()->addWMOAndGetInstance(pair.second.file_key, pair.second.pos, pair.second.dir);
obj = _map_view->getWorld()->addWMOAndGetInstance(pair.second.file_key, pair.second.pos, pair.second.dir, false);
else
obj = _map_view->getWorld()->addM2AndGetInstance(pair.second.file_key, pair.second.pos,
pair.second.scale, pair.second.dir, nullptr);
pair.second.scale, pair.second.dir, nullptr, false, false);
obj->instance_model()->wait_until_loaded();
obj->instance_model()->waitForChildrenLoaded();
@@ -281,7 +281,7 @@ unsigned Noggit::Action::handleObjectAdded(unsigned uid, bool redo)
}
else
{
_map_view->getWorld()->deleteInstance(pair.first);
_map_view->getWorld()->deleteInstance(pair.first, false);
}
return new_uid;
@@ -304,10 +304,10 @@ unsigned Noggit::Action::handleObjectRemoved(unsigned uid, bool redo)
unsigned old_uid = pair.first;
SceneObject* obj;
if (pair.second.type == ActionObjectTypes::WMO)
obj = _map_view->getWorld()->addWMOAndGetInstance(pair.second.file_key, pair.second.pos, pair.second.dir);
obj = _map_view->getWorld()->addWMOAndGetInstance(pair.second.file_key, pair.second.pos, pair.second.dir, false);
else
obj = _map_view->getWorld()->addM2AndGetInstance(pair.second.file_key, pair.second.pos,
pair.second.scale, pair.second.dir, nullptr);
pair.second.scale, pair.second.dir, nullptr, false, false);
obj->instance_model()->wait_until_loaded();
obj->instance_model()->waitForChildrenLoaded();
@@ -345,7 +345,7 @@ unsigned Noggit::Action::handleObjectRemoved(unsigned uid, bool redo)
}
else
{
_map_view->getWorld()->deleteInstance(pair.first);
_map_view->getWorld()->deleteInstance(pair.first, false);
}
return new_uid;

View File

@@ -342,7 +342,7 @@ void MapTile::finishLoading()
for (auto const& object : lWMOInstances)
{
add_model(_world->add_wmo_instance(WMOInstance(mWMOFilenames[object.nameID],
&object, _context), _tile_is_being_reloaded));
&object, _context), _tile_is_being_reloaded, false));
}
// - Load M2s ------------------------------------------
@@ -350,7 +350,7 @@ void MapTile::finishLoading()
for (auto const& model : lModelInstances)
{
add_model(_world->add_model_instance(ModelInstance(mModelFilenames[model.nameID],
&model, _context), _tile_is_being_reloaded));
&model, _context), _tile_is_being_reloaded, false));
}
_world->need_model_updates = true;

View File

@@ -1441,7 +1441,7 @@ void MapView::setupAssistMenu()
makeCurrent();
OpenGL::context::scoped_setter const _ (::gl, context());
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_REMOVED);
_world->clearAllModelsOnADT(_camera.position);
_world->clearAllModelsOnADT(_camera.position, true);
NOGGIT_ACTION_MGR->endAction();
_rotation_editor_need_update = true;
}
@@ -6208,87 +6208,88 @@ void MapView::ShowContextMenu(QPoint pos)
action_replace.setEnabled(has_selected_objects && objectEditor->clipboardSize() == 1);
action_replace.setToolTip("Replace the currently selected objects by the object in the clipboard (There must only be one!). M2s can only be replaced by m2s");
QObject::connect(&action_replace, &QAction::triggered, [=]()
{
makeCurrent();
OpenGL::context::scoped_setter const _(::gl, context());
if (terrainMode != editing_mode::object && NOGGIT_CUR_ACTION)
return;
if (!objectEditor->clipboardSize())
return;
// verify this
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_ADDED | Noggit::ActionFlags::eOBJECTS_REMOVED); // Noggit::ActionFlags::eOBJECTS_TRANSFORMED
// get the model to replace by
auto replace_select = objectEditor->getClipboard().front();
auto replacement_obj = std::get<selected_object_type>(replace_select);
auto& replace_path = replacement_obj->instance_model()->file_key().filepath();
std::vector<SceneObject*> objects_to_delete;
// iterate selection (objects to replace)
std::vector<selected_object_type> selected_objects = _world->get_selected_objects();
for (SceneObject* old_obj : selected_objects)
{
makeCurrent();
OpenGL::context::scoped_setter const _(::gl, context());
if (old_obj->instance_model()->file_key().filepath() == replace_path)
continue;
if (terrainMode != editing_mode::object && NOGGIT_CUR_ACTION)
return;
math::degrees::vec3 source_rot(math::degrees(0)._, math::degrees(0)._, math::degrees(0)._);
source_rot = old_obj->dir;
float source_scale = old_obj->scale;
glm::vec3 source_pos = old_obj->pos;
if (!objectEditor->clipboardSize())
return;
// _world->deleteInstance(old_obj->uid);
objects_to_delete.emplace_back(old_obj);
// verify this
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_ADDED | Noggit::ActionFlags::eOBJECTS_REMOVED); // Noggit::ActionFlags::eOBJECTS_TRANSFORMED
// get the model to replace by
auto replace_select = objectEditor->getClipboard().front();
auto replacement_obj = std::get<selected_object_type>(replace_select);
auto& replace_path = replacement_obj->instance_model()->file_key().filepath();
std::vector<SceneObject*> objects_to_delete;
// iterate selection (objects to replace)
std::vector<selected_object_type> selected_objects = _world->get_selected_objects();
for (SceneObject* old_obj : selected_objects)
if (replacement_obj->which() == eWMO)
{
if (old_obj->instance_model()->file_key().filepath() == replace_path)
continue;
// auto replace_wmo = static_cast<WMOInstance*>(replacement_obj);
// auto source_wmo = static_cast<WMOInstance*>(old_obj);
math::degrees::vec3 source_rot(math::degrees(0)._, math::degrees(0)._, math::degrees(0)._);
source_rot = old_obj->dir;
float source_scale = old_obj->scale;
glm::vec3 source_pos = old_obj->pos;
// _world->deleteInstance(old_obj->uid);
objects_to_delete.emplace_back(old_obj);
if (replacement_obj->which() == eWMO)
{
// auto replace_wmo = static_cast<WMOInstance*>(replacement_obj);
// auto source_wmo = static_cast<WMOInstance*>(old_obj);
auto new_obj = _world->addWMOAndGetInstance(replace_path, source_pos, source_rot);
new_obj->wmo->wait_until_loaded();
new_obj->wmo->waitForChildrenLoaded();
new_obj->recalcExtents();
}
else if (replacement_obj->which() == eMODEL)
{
// auto replace_m2 = static_cast<ModelInstance*>(replacement_obj);
// auto source_m2 = static_cast<ModelInstance*>(source_obj);
// Just swapping model
// Issue : doesn't work with actions
// _world->updateTilesEntry(entry, model_update::remove);
// source_m2->model = scoped_model_reference(replace_path, _context);
// source_m2->recalcExtents();
// _world->updateTilesEntry(entry, model_update::add);
auto new_obj = _world->addM2AndGetInstance(replace_path
, source_pos
, source_scale
, source_rot
, &_object_paste_params
, true
);
new_obj->model->wait_until_loaded();
new_obj->model->waitForChildrenLoaded();
new_obj->recalcExtents();
}
auto new_obj = _world->addWMOAndGetInstance(replace_path, source_pos, source_rot, true);
new_obj->wmo->wait_until_loaded();
new_obj->wmo->waitForChildrenLoaded();
new_obj->recalcExtents();
}
// can cause the usual crash of deleting models overlapping unloaded tiles.
// _world->delete_selected_models();
// NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_REMOVED);
// this would also delete models that got skipped
// _world->delete_selected_models();
else if (replacement_obj->which() == eMODEL)
{
// auto replace_m2 = static_cast<ModelInstance*>(replacement_obj);
// auto source_m2 = static_cast<ModelInstance*>(source_obj);
_world->deleteObjects(objects_to_delete);
_world->reset_selection();
// Just swapping model
// Issue : doesn't work with actions
// _world->updateTilesEntry(entry, model_update::remove);
// source_m2->model = scoped_model_reference(replace_path, _context);
// source_m2->recalcExtents();
// _world->updateTilesEntry(entry, model_update::add);
auto new_obj = _world->addM2AndGetInstance(replace_path
, source_pos
, source_scale
, source_rot
, &_object_paste_params
, true
, true
);
new_obj->model->wait_until_loaded();
new_obj->model->waitForChildrenLoaded();
new_obj->recalcExtents();
}
}
// can cause the usual crash of deleting models overlapping unloaded tiles.
// _world->delete_selected_models();
// NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_REMOVED);
// this would also delete models that got skipped
// _world->delete_selected_models();
NOGGIT_ACTION_MGR->endAction();
});
_world->deleteObjects(objects_to_delete, true);
_world->reset_selection();
NOGGIT_ACTION_MGR->endAction();
});
QAction action_snap("Snap Selected To Ground", this);
menu->addAction(&action_snap);

View File

@@ -677,7 +677,7 @@ void World::delete_selected_models()
}
}
_model_instance_storage.delete_instances(get_selected_objects());
_model_instance_storage.delete_instances(get_selected_objects(), true);
need_model_updates = true;
reset_selection();
}
@@ -1155,10 +1155,10 @@ void World::clearHeight(glm::vec3 const& pos)
});
}
void World::clearAllModelsOnADT(TileIndex const& tile)
void World::clearAllModelsOnADT(TileIndex const& tile, bool action)
{
ZoneScoped;
_model_instance_storage.delete_instances_from_tile(tile);
_model_instance_storage.delete_instances_from_tile(tile, action);
// update_models_by_filename();
}
@@ -1776,40 +1776,40 @@ void World::convert_alphamap(QProgressDialog* progress_dialog, bool to_big_alpha
}
void World::deleteModelInstance(int uid)
void World::deleteModelInstance(int uid, bool action)
{
ZoneScoped;
auto instance = _model_instance_storage.get_model_instance(uid);
if (instance)
{
_model_instance_storage.delete_instance(uid);
_model_instance_storage.delete_instance(uid, action);
need_model_updates = true;
reset_selection();
}
}
void World::deleteWMOInstance(int uid)
void World::deleteWMOInstance(int uid, bool action)
{
ZoneScoped;
auto instance = _model_instance_storage.get_wmo_instance(uid);
if (instance)
{
_model_instance_storage.delete_instance(uid);
_model_instance_storage.delete_instance(uid, action);
need_model_updates = true;
reset_selection();
}
}
void World::deleteInstance(int uid)
void World::deleteInstance(int uid, bool action)
{
ZoneScoped;
auto instance = _model_instance_storage.get_instance(uid);
if (instance)
{
_model_instance_storage.delete_instance(uid);
_model_instance_storage.delete_instance(uid, action);
need_model_updates = true;
reset_selection();
}
@@ -1826,7 +1826,7 @@ void World::delete_duplicate_model_and_wmo_instances()
ZoneScoped;
reset_selection();
_model_instance_storage.clear_duplicates();
_model_instance_storage.clear_duplicates(false);
need_model_updates = true;
}
@@ -1845,6 +1845,7 @@ void World::addM2 ( BlizzardArchive::Listfile::FileKey const& file_key
, float scale
, glm::vec3 rotation
, Noggit::object_paste_params* paste_params
, bool action
)
{
ZoneScoped;
@@ -1884,7 +1885,7 @@ void World::addM2 ( BlizzardArchive::Listfile::FileKey const& file_key
model_instance.model->wait_until_loaded();
model_instance.recalcExtents();
std::uint32_t uid = _model_instance_storage.add_model_instance(std::move(model_instance), true);
std::uint32_t uid = _model_instance_storage.add_model_instance(std::move(model_instance), true, action);
// _models_by_filename[file_key.filepath()].push_back(_model_instance_storage.get_model_instance(uid).value());
}
@@ -1895,6 +1896,7 @@ ModelInstance* World::addM2AndGetInstance ( BlizzardArchive::Listfile::FileKey c
, math::degrees::vec3 rotation
, Noggit::object_paste_params* paste_params
, bool ignore_params
, bool action
)
{
ZoneScoped;
@@ -1934,7 +1936,7 @@ ModelInstance* World::addM2AndGetInstance ( BlizzardArchive::Listfile::FileKey c
model_instance.model->wait_until_loaded();
model_instance.recalcExtents();
std::uint32_t uid = _model_instance_storage.add_model_instance(std::move(model_instance), true);
std::uint32_t uid = _model_instance_storage.add_model_instance(std::move(model_instance), true, action);
auto instance = _model_instance_storage.get_model_instance(uid); // .value();
// _models_by_filename[file_key.filepath()].push_back(instance);
@@ -1945,6 +1947,7 @@ ModelInstance* World::addM2AndGetInstance ( BlizzardArchive::Listfile::FileKey c
void World::addWMO ( BlizzardArchive::Listfile::FileKey const& file_key
, glm::vec3 newPos
, math::degrees::vec3 rotation
, bool action
)
{
ZoneScoped;
@@ -1958,12 +1961,13 @@ void World::addWMO ( BlizzardArchive::Listfile::FileKey const& file_key
wmo_instance.wmo->wait_until_loaded();
wmo_instance.recalcExtents();
_model_instance_storage.add_wmo_instance(std::move(wmo_instance), true);
_model_instance_storage.add_wmo_instance(std::move(wmo_instance), true, action);
}
WMOInstance* World::addWMOAndGetInstance ( BlizzardArchive::Listfile::FileKey const& file_key
, glm::vec3 newPos
, math::degrees::vec3 rotation
, bool action
)
{
ZoneScoped;
@@ -1977,7 +1981,7 @@ WMOInstance* World::addWMOAndGetInstance ( BlizzardArchive::Listfile::FileKey co
wmo_instance.wmo->wait_until_loaded();
wmo_instance.recalcExtents();
std::uint32_t uid = _model_instance_storage.add_wmo_instance(std::move(wmo_instance), true);
std::uint32_t uid = _model_instance_storage.add_wmo_instance(std::move(wmo_instance), true, action);
auto instance = _model_instance_storage.get_wmo_instance(uid);
@@ -1985,16 +1989,16 @@ WMOInstance* World::addWMOAndGetInstance ( BlizzardArchive::Listfile::FileKey co
}
std::uint32_t World::add_model_instance(ModelInstance model_instance, bool from_reloading)
std::uint32_t World::add_model_instance(ModelInstance model_instance, bool from_reloading, bool action)
{
ZoneScoped;
return _model_instance_storage.add_model_instance(std::move(model_instance), from_reloading);
return _model_instance_storage.add_model_instance(std::move(model_instance), from_reloading, action);
}
std::uint32_t World::add_wmo_instance(WMOInstance wmo_instance, bool from_reloading)
std::uint32_t World::add_wmo_instance(WMOInstance wmo_instance, bool from_reloading, bool action)
{
ZoneScoped;
return _model_instance_storage.add_wmo_instance(std::move(wmo_instance), from_reloading);
return _model_instance_storage.add_wmo_instance(std::move(wmo_instance), from_reloading, action);
}
std::optional<selection_type> World::get_model(std::uint32_t uid)
@@ -2039,10 +2043,10 @@ void World::reload_tile(TileIndex const& tile)
mapIndex.reloadTile(tile);
}
void World::deleteObjects(std::vector<selected_object_type> const& types)
void World::deleteObjects(std::vector<selected_object_type> const& types, bool action)
{
ZoneScoped;
_model_instance_storage.delete_instances(types);
_model_instance_storage.delete_instances(types, action);
need_model_updates = true;
}

View File

@@ -283,31 +283,35 @@ public:
, glm::vec3 newPos
, float scale, math::degrees::vec3 rotation
, Noggit::object_paste_params*
, bool action
);
void addWMO ( BlizzardArchive::Listfile::FileKey const& file_key
, glm::vec3 newPos
, math::degrees::vec3 rotation
, bool action
);
ModelInstance* addM2AndGetInstance ( BlizzardArchive::Listfile::FileKey const& file_key
, glm::vec3 newPos
, float scale, math::degrees::vec3 rotation
, Noggit::object_paste_params*
, bool ignore_params = false
, bool ignore_params
, bool action
);
WMOInstance* addWMOAndGetInstance ( BlizzardArchive::Listfile::FileKey const& file_key
, glm::vec3 newPos
, math::degrees::vec3 rotation
, bool action
);
auto stamp(glm::vec3 const& pos, float dt, QImage const* img, float radiusOuter
, float radiusInner, int BrushType, bool sculpt) -> void;
// add a m2 instance to the world (needs to be positioned already), return the uid
std::uint32_t add_model_instance(ModelInstance model_instance, bool from_reloading);
std::uint32_t add_model_instance(ModelInstance model_instance, bool from_reloading, bool action);
// add a wmo instance to the world (needs to be positioned already), return the uid
std::uint32_t add_wmo_instance(WMOInstance wmo_instance, bool from_reloading);
std::uint32_t add_wmo_instance(WMOInstance wmo_instance, bool from_reloading, bool action);
std::optional<selection_type> get_model(std::uint32_t uid);
void remove_models_if_needed(std::vector<uint32_t> const& uids);
@@ -320,9 +324,9 @@ public:
void updateTilesModel(ModelInstance* m2, model_update type);
void wait_for_all_tile_updates();
void deleteModelInstance(int uid);
void deleteWMOInstance(int uid);
void deleteInstance(int uid);
void deleteModelInstance(int uid, bool action);
void deleteWMOInstance(int uid, bool action);
void deleteInstance(int uid, bool action);
bool uid_duplicates_found() const;
void delete_duplicate_model_and_wmo_instances();
@@ -334,7 +338,7 @@ public:
static bool IsWMOWorld(BlizzardDatabaseLib::Structures::BlizzardDatabaseRow& record);
void clearHeight(glm::vec3 const& pos);
void clearAllModelsOnADT(TileIndex const& tile);
void clearAllModelsOnADT(TileIndex const& tile, bool action);
// liquids
void paintLiquid( glm::vec3 const& pos
@@ -373,7 +377,7 @@ public:
void updateVertexCenter();
void clearVertexSelection();
void deleteObjects(std::vector<selected_object_type> const& types);
void deleteObjects(std::vector<selected_object_type> const& types, bool action);
float getMaxTileHeight(const TileIndex& tile);

View File

@@ -924,7 +924,7 @@ uid_fix_status MapIndex::fixUIDs (World* world, bool cancel_on_model_loading_err
std::size_t ex = std::min((std::size_t)(instance.extents[1].x / TILESIZE), (std::size_t)63);
std::size_t ez = std::min((std::size_t)(instance.extents[1].z / TILESIZE), (std::size_t)63);
auto const real_uid (world->add_model_instance (std::move(instance), false));
auto const real_uid (world->add_model_instance (std::move(instance), false, false));
for (std::size_t z = sz; z <= ez; ++z)
{
@@ -949,7 +949,7 @@ uid_fix_status MapIndex::fixUIDs (World* world, bool cancel_on_model_loading_err
std::size_t ex = std::min((std::size_t)(instance.extents[1].x / TILESIZE), (std::size_t)63);
std::size_t ez = std::min((std::size_t)(instance.extents[1].z / TILESIZE), (std::size_t)63);
auto const real_uid (world->add_wmo_instance (std::move(instance), false));
auto const real_uid (world->add_wmo_instance (std::move(instance), false, false));
for (std::size_t z = sz; z <= ez; ++z)
{

View File

@@ -1038,7 +1038,7 @@ void WorldRender::upload()
{
WMOInstance inst(_world->mWmoFilename, &_world->mWmoEntry, _world->_context);
_world->_model_instance_storage.add_wmo_instance(std::move(inst), false);
_world->_model_instance_storage.add_wmo_instance(std::move(inst), false, false);
}
else
{

View File

@@ -31,7 +31,7 @@ namespace Noggit {
p.minScale = scale;
p.maxScale = scale;
global->get_view()->_world.get()->
addM2(filename,pos,scale,math::degrees::vec3(rotation), &p);
addM2(filename,pos,scale,math::degrees::vec3(rotation), &p, false);
});
state->set_function("vec",[](float x, float y, float z){
@@ -46,7 +46,8 @@ namespace Noggit {
global->get_view()->_world.get()->addWMO(
filename
, pos
, math::degrees::vec3(rotation));
, math::degrees::vec3(rotation)
, false);
});
state->set_function("get_map_id",[global]()

View File

@@ -86,7 +86,7 @@ namespace Noggit
void model::remove()
{
std::vector<SceneObject*> type{_object};
world()->deleteObjects(type);
world()->deleteObjects(type, false);
}
void model::replace(std::string const& filename)
@@ -101,13 +101,13 @@ namespace Noggit
if (filename.ends_with(".wmo"))
{
_object =
world()->addWMOAndGetInstance(filename, get_pos(), math::degrees::vec3 {get_rot()});
world()->addWMOAndGetInstance(filename, get_pos(), math::degrees::vec3 {get_rot()}, false);
}
else
{
auto params = object_paste_params();
_object =
world()->addM2AndGetInstance(filename, get_pos(), get_scale(), math::degrees::vec3 {get_rot()}, &params);
world()->addM2AndGetInstance(filename, get_pos(), get_scale(), math::degrees::vec3 {get_rot()}, &params, false, false);
}
}

View File

@@ -666,6 +666,8 @@ namespace Noggit
, scale
, rotation
, paste_params
, false
, true
);
new_obj->model->wait_until_loaded();
@@ -701,7 +703,7 @@ namespace Noggit
rotation = obj->dir;
}
auto new_obj = world->addWMOAndGetInstance(obj->instance_model()->file_key(), pos, rotation);
auto new_obj = world->addWMOAndGetInstance(obj->instance_model()->file_key(), pos, rotation, true);
new_obj->wmo->wait_until_loaded();
new_obj->wmo->waitForChildrenLoaded();
new_obj->recalcExtents();

View File

@@ -332,7 +332,7 @@ void ChunkAddDetailDoodads::compute()
filename = filename.replace(".mdl", ".m2", Qt::CaseInsensitive);
world->addM2(filename.toStdString(), {chunk->xbase - inMinichunkCoords[0]
, 0, chunk->zbase - inMinichunkCoords[1]}, 1.0, {math::degrees(0)._, math::degrees(0)._, math::degrees(0)._ }, nullptr);
, 0, chunk->zbase - inMinichunkCoords[1]}, 1.0, {math::degrees(0)._, math::degrees(0)._, math::degrees(0)._ }, nullptr, false);
}
}

View File

@@ -58,11 +58,11 @@ void AddObjectInstanceNode::compute()
if (QString(path.c_str()).endsWith(".m2", Qt::CaseInsensitive))
{
Noggit::object_paste_params paste_params;
obj = world->addM2AndGetInstance(path, {pos.x, pos.y, pos.z}, scale, {math::degrees(dir.x)._, math::degrees(dir.y)._, math::degrees(dir.z)._ }, &paste_params);
obj = world->addM2AndGetInstance(path, {pos.x, pos.y, pos.z}, scale, {math::degrees(dir.x)._, math::degrees(dir.y)._, math::degrees(dir.z)._ }, &paste_params, false, false);
}
else if (QString(path.c_str()).endsWith(".wmo", Qt::CaseInsensitive))
{
obj = world->addWMOAndGetInstance(path, {pos.x, pos.y, pos.z}, {math::degrees(dir.x)._, math::degrees(dir.y)._, math::degrees(dir.z)._ });
obj = world->addWMOAndGetInstance(path, {pos.x, pos.y, pos.z}, {math::degrees(dir.x)._, math::degrees(dir.y)._, math::degrees(dir.z)._ }, false);
}
else
{

View File

@@ -13,14 +13,14 @@ namespace Noggit
}
std::uint32_t world_model_instances_storage::add_model_instance(ModelInstance instance, bool from_reloading)
std::uint32_t world_model_instances_storage::add_model_instance(ModelInstance instance, bool from_reloading, bool action)
{
std::uint32_t uid = instance.uid;
std::uint32_t uid_after;
{
std::lock_guard<std::mutex> const lock (_mutex);
uid_after = unsafe_add_model_instance_no_world_upd(std::move(instance));
uid_after = unsafe_add_model_instance_no_world_upd(std::move(instance), action);
}
if (from_reloading || uid_after != uid)
@@ -30,7 +30,7 @@ namespace Noggit
return uid_after;
}
std::uint32_t world_model_instances_storage::unsafe_add_model_instance_no_world_upd(ModelInstance instance)
std::uint32_t world_model_instances_storage::unsafe_add_model_instance_no_world_upd(ModelInstance instance, bool action)
{
std::uint32_t uid = instance.uid;
auto existing_instance = unsafe_get_model_instance(uid);
@@ -46,10 +46,9 @@ namespace Noggit
}
else if(!unsafe_uid_is_used(uid))
{
/* This causes a crash when undoing while loading a tile, those objects get registered to the action stack
if (NOGGIT_CUR_ACTION)
// This causes a crash when undoing while loading a tile, those objects get registered to the action stack
if (action && NOGGIT_CUR_ACTION)
NOGGIT_CUR_ACTION->registerObjectAdded(&instance);
*/
_m2s.emplace(uid, instance);
_instance_count_per_uid[uid] = 1;
return uid;
@@ -59,18 +58,18 @@ namespace Noggit
_uid_duplicates_found = true;
instance.uid = _world->mapIndex.newGUID();
return unsafe_add_model_instance_no_world_upd(std::move(instance));
return unsafe_add_model_instance_no_world_upd(std::move(instance), action);
}
std::uint32_t world_model_instances_storage::add_wmo_instance(WMOInstance instance, bool from_reloading)
std::uint32_t world_model_instances_storage::add_wmo_instance(WMOInstance instance, bool from_reloading, bool action)
{
std::uint32_t uid = instance.uid;
std::uint32_t uid_after;
{
std::lock_guard<std::mutex> const lock(_mutex);
uid_after = unsafe_add_wmo_instance_no_world_upd(std::move(instance));
uid_after = unsafe_add_wmo_instance_no_world_upd(std::move(instance), action);
}
if (from_reloading || uid_after != uid)
@@ -80,7 +79,7 @@ namespace Noggit
return uid_after;
}
std::uint32_t world_model_instances_storage::unsafe_add_wmo_instance_no_world_upd(WMOInstance instance)
std::uint32_t world_model_instances_storage::unsafe_add_wmo_instance_no_world_upd(WMOInstance instance, bool action)
{
std::uint32_t uid = instance.uid;
auto existing_instance = unsafe_get_wmo_instance(uid);
@@ -97,10 +96,8 @@ namespace Noggit
}
else if (!unsafe_uid_is_used(uid))
{
/*
if (NOGGIT_CUR_ACTION)
if (action && NOGGIT_CUR_ACTION)
NOGGIT_CUR_ACTION->registerObjectAdded(&instance);
*/
_wmos.emplace(uid, instance);
_instance_count_per_uid[uid] = 1;
return uid;
@@ -110,10 +107,10 @@ namespace Noggit
_uid_duplicates_found = true;
instance.uid = _world->mapIndex.newGUID();
return unsafe_add_wmo_instance_no_world_upd(std::move(instance));
return unsafe_add_wmo_instance_no_world_upd(std::move(instance), action);
}
void world_model_instances_storage::delete_instances_from_tile(TileIndex const& tile)
void world_model_instances_storage::delete_instances_from_tile(TileIndex const& tile, bool action)
{
// std::unique_lock<std::mutex> const lock (_mutex);
std::vector<selected_object_type> instances_to_remove;
@@ -132,35 +129,36 @@ namespace Noggit
instances_to_remove.push_back(&it->second);
}
}
delete_instances(instances_to_remove);
delete_instances(instances_to_remove, action);
}
void world_model_instances_storage::delete_instances(std::vector<selected_object_type> const& instances)
void world_model_instances_storage::delete_instances(std::vector<selected_object_type> const& instances, bool action)
{
for (auto& obj : instances)
{
// should be done in delete_instance
if (NOGGIT_CUR_ACTION)
NOGGIT_CUR_ACTION->registerObjectRemoved(obj);
// done in delete_instance
/*
if (action && NOGGIT_CUR_ACTION)
NOGGIT_CUR_ACTION->registerObjectRemoved(obj);*/
if (obj->which() == eMODEL)
{
auto instance = static_cast<ModelInstance*>(obj);
_world->updateTilesModel(instance, model_update::remove);
delete_instance(instance->uid);
delete_instance(instance->uid, action);
}
else if (obj->which() == eWMO)
{
auto instance = static_cast<WMOInstance*>(obj);
_world->updateTilesWMO(instance, model_update::remove);
delete_instance(instance->uid);
delete_instance(instance->uid, action);
}
}
}
void world_model_instances_storage::delete_instance(std::uint32_t uid)
void world_model_instances_storage::delete_instance(std::uint32_t uid, bool action)
{
std::unique_lock<std::mutex> const lock (_mutex);
@@ -176,8 +174,7 @@ namespace Noggit
selection_group.remove_member(obj->uid);
}
}
if (NOGGIT_CUR_ACTION)
if (action && NOGGIT_CUR_ACTION)
{
NOGGIT_CUR_ACTION->registerObjectRemoved(obj);
}
@@ -310,7 +307,7 @@ namespace Noggit
return _instance_count_per_uid.find(uid) != _instance_count_per_uid.end();
}
void world_model_instances_storage::clear_duplicates()
void world_model_instances_storage::clear_duplicates(bool action)
{
std::unique_lock<std::mutex> const lock (_mutex);
@@ -327,7 +324,7 @@ namespace Noggit
_world->updateTilesWMO(&rhs->second, model_update::remove);
_instance_count_per_uid.erase(rhs->second.uid);
if (NOGGIT_CUR_ACTION)
if (action && NOGGIT_CUR_ACTION)
NOGGIT_CUR_ACTION->registerObjectRemoved(&rhs->second);
rhs = _wmos.erase(rhs);
deleted_uids++;
@@ -351,7 +348,7 @@ namespace Noggit
_instance_count_per_uid.erase(rhs->second.uid);
if (NOGGIT_CUR_ACTION)
if (action && NOGGIT_CUR_ACTION)
NOGGIT_CUR_ACTION->registerObjectRemoved(&rhs->second);
rhs = _m2s.erase(rhs);
deleted_uids++;

View File

@@ -32,22 +32,22 @@ namespace Noggit
world_model_instances_storage& operator= (world_model_instances_storage&&) = delete;
// perform uid duplicate check, return the uid of the stored instance
std::uint32_t add_model_instance(ModelInstance instance, bool from_reloading);
std::uint32_t add_model_instance(ModelInstance instance, bool from_reloading, bool action);
// perform uid duplicate check, return the uid of the stored instance
std::uint32_t add_wmo_instance(WMOInstance instance, bool from_reloading);
std::uint32_t add_wmo_instance(WMOInstance instance, bool from_reloading, bool action);
std::optional<ModelInstance*> get_model_instance(std::uint32_t uid);
std::optional<WMOInstance*> get_wmo_instance(std::uint32_t uid);
std::optional<selection_type> get_instance(std::uint32_t uid, bool lock=true);
void delete_instances_from_tile(TileIndex const& tile);
void delete_instances(std::vector<selected_object_type> const& instances);
void delete_instance(std::uint32_t uid);
void delete_instances_from_tile(TileIndex const& tile, bool action);
void delete_instances(std::vector<selected_object_type> const& instances, bool action);
void delete_instance(std::uint32_t uid, bool action);
void unload_instance_and_remove_from_selection_if_necessary(std::uint32_t uid);
void clear();
void clear_duplicates();
void clear_duplicates(bool action);
bool uid_duplicates_found() const
{
@@ -62,8 +62,8 @@ namespace Noggit
private: // private functions aren't thread safe
inline bool unsafe_uid_is_used(std::uint32_t uid) const;
std::uint32_t unsafe_add_model_instance_no_world_upd(ModelInstance instance);
std::uint32_t unsafe_add_wmo_instance_no_world_upd(WMOInstance instance);
std::uint32_t unsafe_add_model_instance_no_world_upd(ModelInstance instance, bool action);
std::uint32_t unsafe_add_wmo_instance_no_world_upd(WMOInstance instance, bool action);
std::optional<ModelInstance*> unsafe_get_model_instance(std::uint32_t uid);
std::optional<WMOInstance*> unsafe_get_wmo_instance(std::uint32_t uid);