diff options
-rw-r--r-- | source/game/StarCelestialDatabase.cpp | 22 | ||||
-rw-r--r-- | source/game/StarCelestialDatabase.hpp | 3 | ||||
-rw-r--r-- | source/game/StarSystemWorldServerThread.cpp | 7 |
3 files changed, 23 insertions, 9 deletions
diff --git a/source/game/StarCelestialDatabase.cpp b/source/game/StarCelestialDatabase.cpp index d5ba7df..dd0bc51 100644 --- a/source/game/StarCelestialDatabase.cpp +++ b/source/game/StarCelestialDatabase.cpp @@ -206,9 +206,6 @@ bool CelestialMasterDatabase::coordinateValid(CelestialCoordinate const& coordin Maybe<CelestialCoordinate> CelestialMasterDatabase::findRandomWorld(unsigned tries, unsigned trySpatialRange, function<bool(CelestialCoordinate)> filter, Maybe<uint64_t> seed) { - //RecursiveMutexLocker locker(m_mutex); - // We don't need this lock, the other calls are locking anyway. - // Having this here is just stopping other threads from having a go in here until we've found a world. RandomSource randSource; if (seed) randSource.init(*seed); @@ -299,7 +296,12 @@ List<CelestialCoordinate> CelestialMasterDatabase::scanSystems(RectI const& regi List<CelestialCoordinate> systems; for (auto const& chunkLocation : chunkIndexesFor(region)) { - auto const& chunkData = getChunk(chunkLocation); + auto const& chunkData = getChunk(chunkLocation, [&](std::function<void()>&& func) { + locker.unlock(); + func(); + locker.lock(); + }); + locker.unlock(); for (auto const& pair : chunkData.systemParameters) { Vec3I systemLocation = pair.first; if (region.contains(systemLocation.vec2())) { @@ -311,6 +313,7 @@ List<CelestialCoordinate> CelestialMasterDatabase::scanSystems(RectI const& regi systems.append(CelestialCoordinate(systemLocation)); } } + locker.lock(); } return systems; } @@ -378,8 +381,8 @@ Maybe<CelestialOrbitRegion> CelestialMasterDatabase::orbitRegion( return {}; } -CelestialChunk const& CelestialMasterDatabase::getChunk(Vec2I const& chunkIndex) { - return m_chunkCache.get(chunkIndex, [this](Vec2I const& chunkIndex) -> CelestialChunk { +CelestialChunk const& CelestialMasterDatabase::getChunk(Vec2I const& chunkIndex, UnlockDuringFunction unlockDuring) { + return m_chunkCache.get(chunkIndex, [&](Vec2I const& chunkIndex) -> CelestialChunk { auto versioningDatabase = Root::singleton().versioningDatabase(); if (m_database.isOpen()) { @@ -394,7 +397,12 @@ CelestialChunk const& CelestialMasterDatabase::getChunk(Vec2I const& chunkIndex) } } - auto newChunk = produceChunk(chunkIndex); + CelestialChunk newChunk; + auto producer = [&]() { newChunk = produceChunk(chunkIndex); }; + if (unlockDuring) + unlockDuring(producer); + else + producer(); if (m_database.isOpen()) { auto versionedChunk = versioningDatabase->makeCurrentVersionedJson("CelestialChunk", newChunk.toJson()); m_database.insert(DataStreamBuffer::serialize(chunkIndex), diff --git a/source/game/StarCelestialDatabase.hpp b/source/game/StarCelestialDatabase.hpp index ac5b42b..22bac88 100644 --- a/source/game/StarCelestialDatabase.hpp +++ b/source/game/StarCelestialDatabase.hpp @@ -162,7 +162,8 @@ protected: static Maybe<CelestialOrbitRegion> orbitRegion( List<CelestialOrbitRegion> const& orbitRegions, int planetaryOrbitNumber); - CelestialChunk const& getChunk(Vec2I const& chunkLocation); + typedef std::function<void(std::function<void()>&&)>&& UnlockDuringFunction; + CelestialChunk const& getChunk(Vec2I const& chunkLocation, UnlockDuringFunction unlockDuring = {}); CelestialChunk produceChunk(Vec2I const& chunkLocation) const; Maybe<pair<CelestialParameters, HashMap<int, CelestialPlanet>>> produceSystem( diff --git a/source/game/StarSystemWorldServerThread.cpp b/source/game/StarSystemWorldServerThread.cpp index 8035975..83210a2 100644 --- a/source/game/StarSystemWorldServerThread.cpp +++ b/source/game/StarSystemWorldServerThread.cpp @@ -101,7 +101,12 @@ void SystemWorldServerThread::update() { for (auto clientId : m_clients) { m_outgoingPacketQueue[clientId].appendAll(m_systemWorld->pullOutgoingPackets(clientId)); - m_clientShipLocations.set(clientId, {m_systemWorld->clientShipLocation(clientId), m_systemWorld->clientSkyParameters(clientId)}); + auto shipSystemLocation = m_systemWorld->clientShipLocation(clientId); + auto& shipLocation = m_clientShipLocations[clientId]; + if (shipLocation.first != shipSystemLocation) { + shipLocation.first = shipSystemLocation; + shipLocation.second = m_systemWorld->clientSkyParameters(clientId); + } if (auto warpAction = m_systemWorld->clientWarpAction(clientId)) m_clientWarpActions.set(clientId, *warpAction); else if (m_clientWarpActions.contains(clientId)) |