Make the server automatically tick and send diffs periodically
This commit is contained in:
@@ -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());
|
||||||
|
|||||||
@@ -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_);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user