QtCraft API C++ classes QML types Handbook

QcTickScheduler Class

Deadline-based tick schedule (decision E-090): tick n is due at start + n * interval on a monotonic clock, so late timers never shift the grid. More...

Header: #include <server/tick/QcTickScheduler.h>

Public Types

struct SprintEnd
Clock

Public Functions

qint64 currentIntervalNs() const
qint64 currentLateNs() const
double measuredRate() const
qint64 nextDueNs() const
double rate() const
qint64 runDue(const std::function<void ()> &tick)
void setRate(double ticksPerSecond)
void skipCurrentTick()
quint64 sprintDone() const
double sprintRate() const
quint64 sprintRemaining() const
bool sprinting() const
void start()
void startSprint(quint64 ticks)
QcTickStats &stats()
const QcTickStats &stats() const
void stop()
void stopSprint()
std::optional<QcTickScheduler::SprintEnd> takeSprintEnded()
qint64 tickRealNs() const
qint64 untilDueNs() const

Static Public Members

const double defaultRate
const qint64 intervalNs
const int maxCatchUpTicks
const double maxRate
const double minRate
const qint64 sprintSliceNs
QcTickScheduler::Clock steadyClock()
const qint64 timerLeadNs

Detailed Description

Due ticks are caught up, at most maxCatchUpTicks in a row; an older backlog is dropped (logged) so an overloaded server cannot fall ever further behind. The interval follows the tick rate (/tick rate, decision E-249); a sprint runs a number of ticks back to back in slices of sprintSliceNs and then starts a new grid, so it leaves no backlog. tickRealNs() says how much real time a tick stands for, so what follows real time (the players' budgets and limits, autosaves, messages to the clients) keeps its pace at every rate and during a sprint. Not thread-safe: lives in the server's thread; only the stats may be read from elsewhere.

Member Type Documentation

[alias] QcTickScheduler::Clock

Monotonic time in nanoseconds.

Member Function Documentation

qint64 QcTickScheduler::currentIntervalNs() const

Returns the interval of the current rate in nanoseconds.

qint64 QcTickScheduler::currentLateNs() const

Returns how late the tick that runDue() is running now started against its due time; 0 outside.

double QcTickScheduler::measuredRate() const

Returns the ticks per second over the latest ticks (up to measureTicks), 0 before two ticks ran.

qint64 QcTickScheduler::nextDueNs() const

Returns the clock time at which the next tick is due.

double QcTickScheduler::rate() const

Returns the rate in ticks per second.

See also setRate().

qint64 QcTickScheduler::runDue(const std::function<void ()> &tick)

Runs the due ticks with tick (see the class comment). Returns the nanoseconds until the next one is due (0 when it already is).

void QcTickScheduler::setRate(double ticksPerSecond)

Sets the rate to ticksPerSecond (clamped to minRate..maxRate); the next tick is due one new interval from now.

See also rate().

void QcTickScheduler::skipCurrentTick()

Called from the running tick when it did nothing (a paused server, decision E-877): it counts neither in the stats nor as a tick of a sprint, and a sprint waits for the next due time.

quint64 QcTickScheduler::sprintDone() const

Returns the ticks the running sprint has run so far.

double QcTickScheduler::sprintRate() const

Returns the ticks per second of the running sprint so far (0 before its first tick).

quint64 QcTickScheduler::sprintRemaining() const

Returns the ticks the running sprint has still to run.

bool QcTickScheduler::sprinting() const

Returns whether a sprint runs.

void QcTickScheduler::start()

The first tick is due one interval from now. From start() to stop() the system's timers run to the millisecond (QcTimerResolution, Windows).

void QcTickScheduler::startSprint(quint64 ticks)

Runs ticks ticks as fast as possible with the next runDue() calls; replaces a running sprint.

QcTickStats &QcTickScheduler::stats()

Returns the timing of the ticks.

const QcTickStats &QcTickScheduler::stats() const

Returns the timing of the ticks.

[static] QcTickScheduler::Clock QcTickScheduler::steadyClock()

Returns the steady clock (the default clock).

void QcTickScheduler::stop()

Gives back the millisecond timer resolution taken by start().

void QcTickScheduler::stopSprint()

Ends a sprint early; the normal schedule starts one interval from now.

std::optional<QcTickScheduler::SprintEnd> QcTickScheduler::takeSprintEnded()

Returns the sprint that ended (finished or stopped), once; else std::nullopt.

qint64 QcTickScheduler::tickRealNs() const

Returns the real time the running tick stands for: one interval, during a sprint the real time since the previous tick of the sprint began (at most one interval). Outside runDue() (tests run ticks directly) one interval.

qint64 QcTickScheduler::untilDueNs() const

Returns the nanoseconds until the next tick is due; negative when it is overdue.

Member Variable Documentation

const qint64 QcTickScheduler::intervalNs

The interval at the normal rate of 20 ticks per second.

const int QcTickScheduler::maxCatchUpTicks

Due ticks caught up in a row at most; an older backlog is dropped.

const qint64 QcTickScheduler::sprintSliceNs

A sprint returns to the event loop after this long, so messages are still handled.

const qint64 QcTickScheduler::timerLeadNs

How much earlier than due the event loop's timer is armed: on macOS it fires 1-3 ms after the requested time (millisecond poll plus timer coalescing), so the rest is slept (untilDueNs).