| 193 | } |
| 194 | |
| 195 | void WorldServerThread::run() { |
| 196 | try { |
| 197 | auto& root = Root::singleton(); |
| 198 | double updateMeasureWindow = root.assets()->json("/universe_server.config:updateMeasureWindow").toDouble(); |
| 199 | double fidelityDecrementScore = root.assets()->json("/universe_server.config:fidelityDecrementScore").toDouble(); |
| 200 | double fidelityIncrementScore = root.assets()->json("/universe_server.config:fidelityIncrementScore").toDouble(); |
| 201 | |
| 202 | String serverFidelityMode = root.configuration()->get("serverFidelity").toString(); |
| 203 | Maybe<WorldServerFidelity> lockedFidelity; |
| 204 | if (!serverFidelityMode.equalsIgnoreCase("automatic")) |
| 205 | lockedFidelity = WorldServerFidelityNames.getLeft(serverFidelityMode); |
| 206 | |
| 207 | double storageInterval = root.assets()->json("/universe_server.config:worldStorageInterval").toDouble() / 1000.0; |
| 208 | Timer storageTimer = Timer::withTime(storageInterval); |
| 209 | |
| 210 | TickRateApproacher tickApproacher(1.0f / ServerGlobalTimestep, updateMeasureWindow); |
| 211 | double fidelityScore = 0.0; |
| 212 | WorldServerFidelity automaticFidelity = WorldServerFidelity::Medium; |
| 213 | |
| 214 | while (!m_stop && !m_errorOccurred) { |
| 215 | auto fidelity = lockedFidelity.value(automaticFidelity); |
| 216 | LogMap::set(strf("server_{}_fidelity", m_worldId), WorldServerFidelityNames.getRight(fidelity)); |
| 217 | LogMap::set(strf("server_{}_update", m_worldId), strf("{:4.2f}Hz", tickApproacher.rate())); |
| 218 | |
| 219 | update(fidelity); |
| 220 | tickApproacher.setTargetTickRate(1.0f / ServerGlobalTimestep); |
| 221 | tickApproacher.tick(); |
| 222 | |
| 223 | if (storageTimer.timeUp()) { |
| 224 | sync(); |
| 225 | storageTimer.restart(storageInterval); |
| 226 | } |
| 227 | |
| 228 | double spareTime = tickApproacher.spareTime(); |
| 229 | fidelityScore += spareTime; |
| 230 | |
| 231 | if (fidelityScore <= fidelityDecrementScore) { |
| 232 | if (automaticFidelity > WorldServerFidelity::Minimum) |
| 233 | automaticFidelity = (WorldServerFidelity)((int)automaticFidelity - 1); |
| 234 | fidelityScore = 0.0; |
| 235 | } |
| 236 | |
| 237 | if (fidelityScore >= fidelityIncrementScore) { |
| 238 | if (automaticFidelity < WorldServerFidelity::High) |
| 239 | automaticFidelity = (WorldServerFidelity)((int)automaticFidelity + 1); |
| 240 | fidelityScore = 0.0; |
| 241 | } |
| 242 | |
| 243 | int64_t spareMilliseconds = floor(spareTime * 1000); |
| 244 | if (spareMilliseconds > 0) |
| 245 | Thread::sleepPrecise(spareMilliseconds); |
| 246 | } |
| 247 | } catch (std::exception const& e) { |
| 248 | Logger::error("WorldServerThread exception caught: {}", outputException(e, true)); |
| 249 | m_errorOccurred = true; |
| 250 | } |
| 251 | } |
| 252 |
nothing calls this directly
no test coverage detected