| 362 | } |
| 363 | |
| 364 | void WorldStorage::unloadAll(bool force) { |
| 365 | try { |
| 366 | auto storageConfig = Root::singleton().assets()->json("/worldstorage.config"); |
| 367 | auto sectors = m_sectorMetadata.keys(); |
| 368 | |
| 369 | // Entities can do some strange things during unload, such as repeatedly |
| 370 | // creating new entities during uninit, or setting their bounding box null |
| 371 | // or being entirely outside of the world geometry. This limits the number |
| 372 | // of tries to completely uninit and store all entities before giving up |
| 373 | // and just letting some entities not be stored. |
| 374 | if (m_entityMap) { |
| 375 | unsigned forceUnloadTries = storageConfig.getUInt("forceUnloadTries"); |
| 376 | for (unsigned i = 0; i < forceUnloadTries; ++i) { |
| 377 | for (auto& sector : sectors) |
| 378 | unloadSectorToLevel(sector, SectorLoadLevel::Tiles, force); |
| 379 | |
| 380 | if (!force || m_entityMap->size() == 0) |
| 381 | break; |
| 382 | } |
| 383 | } |
| 384 | for (auto& sector : sectors) |
| 385 | unloadSectorToLevel(sector, SectorLoadLevel::None, force); |
| 386 | |
| 387 | } catch (std::exception const& e) { |
| 388 | m_db.rollback(); |
| 389 | m_db.close(); |
| 390 | throw WorldStorageException("WorldStorage exception during unload", e); |
| 391 | } |
| 392 | } |
| 393 | |
| 394 | void WorldStorage::sync() { |
| 395 | try { |