Make the server automatically tick and send diffs periodically

This commit is contained in:
2024-02-26 15:19:15 -05:00
parent 7f7bd5a781
commit 4d8d9565a4
2 changed files with 30 additions and 3 deletions

View File

@@ -234,7 +234,7 @@ public:
void receive_diff_from_server(StreamBuffer *sb) { void receive_diff_from_server(StreamBuffer *sb) {
world_to_synchronous(); world_to_synchronous();
try { try {
DebugCollector dbc(""); DebugCollector dbc("");
int64_t nactor = world_->patch_everything(sb, &dbc); int64_t nactor = world_->patch_everything(sb, &dbc);
if (nactor != actor_id_) change_actor_id(nactor); if (nactor != actor_id_) change_actor_id(nactor);
dbc.dump(stdostream()); dbc.dump(stdostream());

View File

@@ -14,6 +14,8 @@ public:
int64_t actor_id_; int64_t actor_id_;
SharedChannel channel_; SharedChannel channel_;
UniqueWorld sync_; UniqueWorld sync_;
double last_diff_;
bool async_diff_;
}; };
using UniqueClient = std::unique_ptr<Client>; using UniqueClient = std::unique_ptr<Client>;
using ClientVector = eng::vector<UniqueClient>; using ClientVector = eng::vector<UniqueClient>;
@@ -29,6 +31,8 @@ public:
HttpChannelVec http_server_channels_; HttpChannelVec http_server_channels_;
int64_t admin_id_; int64_t admin_id_;
Gui gui_; Gui gui_;
int next_diff_chan_;
double next_tick_;
public: public:
virtual void event_init(std::string_view srcpk, int argc, char *argv[]) override { virtual void event_init(std::string_view srcpk, int argc, char *argv[]) override {
@@ -57,6 +61,9 @@ public:
// Export stuff to the graphics engine. // Export stuff to the graphics engine.
set_visible_world_and_actor(master_.get(), admin_id_); set_visible_world_and_actor(master_.get(), admin_id_);
// for ticking.
next_tick_ = 0.0;
} }
void do_luainvoke_command(const util::StringVec &words) { void do_luainvoke_command(const util::StringVec &words) {
@@ -165,11 +172,14 @@ public:
client->channel_->out()->write_uint8(util::MSG_ACK); client->channel_->out()->write_uint8(util::MSG_ACK);
client->channel_->out()->write_uint32(0); client->channel_->out()->write_uint32(0);
client->sync_->invoke(inv); client->sync_->invoke(inv);
send_diffs(client); client->async_diff_ = true;
return true; return true;
} }
virtual void event_update() override { virtual void event_update() override {
// Get the clock.
double clock = get_clock();
// Execute any queued invocations. // Execute any queued invocations.
// We just feed these directly into the master model. // We just feed these directly into the master model.
eng::vector<UniqueInvocation> invocations = get_queued_invocations(); eng::vector<UniqueInvocation> invocations = get_queued_invocations();
@@ -200,13 +210,14 @@ public:
client->actor_id_ = master_->create_login_actor(); client->actor_id_ = master_->create_login_actor();
// TODO: initialize the login actor on the master. // TODO: initialize the login actor on the master.
client->channel_ = std::move(chan); client->channel_ = std::move(chan);
client->async_diff_ = true;
client->last_diff_ = -100.0;
client->sync_.reset(new World(WORLD_TYPE_PREDICTIVE)); client->sync_.reset(new World(WORLD_TYPE_PREDICTIVE));
// This login actor is never used, it is just to preserve the invariant that // This login actor is never used, it is just to preserve the invariant that
// the client model and the server synchronous model are identical. // the client model and the server synchronous model are identical.
client->sync_->create_login_actor(); client->sync_->create_login_actor();
clients_.emplace_back(client); clients_.emplace_back(client);
stdostream() << "New client: actor id=" << client->actor_id_ << std::endl; stdostream() << "New client: actor id=" << client->actor_id_ << std::endl;
send_diffs(clients_.back());
} else if (chan->port() == 8080) { } else if (chan->port() == 8080) {
HttpChannel htchan; HttpChannel htchan;
htchan.channel_ = chan; htchan.channel_ = chan;
@@ -214,6 +225,13 @@ public:
} }
} }
// If the clock has advanced far enough, tick the master model.
if (clock >= next_tick_) {
master_->invoke(Invocation(Invocation::KIND_TICK, 0, 0, ""));
next_tick_ += 1.0;
if (next_tick_ < clock + 0.3) next_tick_ = clock + 0.3;
}
// Traverse all existing channels, process any communication. // Traverse all existing channels, process any communication.
for (UniqueClient &client : clients_) { for (UniqueClient &client : clients_) {
if (client->channel_->closed()) { if (client->channel_->closed()) {
@@ -223,6 +241,15 @@ public:
// Check for received invocations. // Check for received invocations.
while (handle_invocation(client)); while (handle_invocation(client));
// Possibly send a diff.
double diffdelay = 5.0;
if (client->async_diff_) diffdelay = 0.1;
if (clock >= client->last_diff_ + diffdelay) {
send_diffs(client);
client->last_diff_ = clock;
client->async_diff_ = false;
}
} }
util::remove_nullptrs(clients_); util::remove_nullptrs(clients_);