builtin/voxelworld, games/digger: Way more robust startup sequence
This commit is contained in:
parent
c0d87faab0
commit
261864ff42
@ -47,8 +47,7 @@ M.section_size_voxels = nil
|
||||
-- be triggered to reflect this value
|
||||
M.camera_far_clip = 1000
|
||||
|
||||
-- voxelworld is ready once the init and voxel_registry packets (and in the
|
||||
-- future possibly some other ones) have been received)
|
||||
-- client-side voxelworld is ready once the server tells it is
|
||||
local is_ready = false
|
||||
local on_ready_callbacks = {}
|
||||
|
||||
@ -71,7 +70,36 @@ function on_ready()
|
||||
on_ready_callbacks = nil
|
||||
end
|
||||
|
||||
local function sub_events()
|
||||
buildat.sub_packet("voxelworld:init", function(data)
|
||||
local values = cereal.binary_input(data, {"object",
|
||||
{"chunk_size_voxels", {"object",
|
||||
{"x", "int16_t"},
|
||||
{"y", "int16_t"},
|
||||
{"z", "int16_t"},
|
||||
}},
|
||||
{"section_size_chunks", {"object",
|
||||
{"x", "int16_t"},
|
||||
{"y", "int16_t"},
|
||||
{"z", "int16_t"},
|
||||
}},
|
||||
})
|
||||
log:info("voxelworld:init: "..dump(values))
|
||||
M.chunk_size_voxels = buildat.Vector3(values.chunk_size_voxels)
|
||||
M.section_size_chunks = buildat.Vector3(values.section_size_chunks)
|
||||
M.section_size_voxels =
|
||||
M.chunk_size_voxels:mul_components(M.section_size_chunks)
|
||||
end)
|
||||
|
||||
buildat.sub_packet("voxelworld:voxel_registry", function(data)
|
||||
voxel_reg:deserialize(data)
|
||||
end)
|
||||
|
||||
buildat.sub_packet("voxelworld:ready", function(data)
|
||||
sub_events()
|
||||
on_ready()
|
||||
end)
|
||||
|
||||
function sub_events()
|
||||
local node_update_queue = buildat.SpatialUpdateQueue()
|
||||
|
||||
local function queue_initial_node_update(node)
|
||||
@ -104,31 +132,6 @@ local function sub_events()
|
||||
})
|
||||
end
|
||||
|
||||
buildat.sub_packet("voxelworld:init", function(data)
|
||||
local values = cereal.binary_input(data, {"object",
|
||||
{"chunk_size_voxels", {"object",
|
||||
{"x", "int16_t"},
|
||||
{"y", "int16_t"},
|
||||
{"z", "int16_t"},
|
||||
}},
|
||||
{"section_size_chunks", {"object",
|
||||
{"x", "int16_t"},
|
||||
{"y", "int16_t"},
|
||||
{"z", "int16_t"},
|
||||
}},
|
||||
})
|
||||
log:info("voxelworld:init: "..dump(values))
|
||||
M.chunk_size_voxels = buildat.Vector3(values.chunk_size_voxels)
|
||||
M.section_size_chunks = buildat.Vector3(values.section_size_chunks)
|
||||
M.section_size_voxels =
|
||||
M.chunk_size_voxels:mul_components(M.section_size_chunks)
|
||||
end)
|
||||
|
||||
buildat.sub_packet("voxelworld:voxel_registry", function(data)
|
||||
voxel_reg:deserialize(data)
|
||||
on_ready() -- This is the last packet
|
||||
end)
|
||||
|
||||
buildat.sub_packet("voxelworld:node_volume_updated", function(data)
|
||||
local values = cereal.binary_input(data, {"object",
|
||||
{"node_id", "int32_t"},
|
||||
@ -520,7 +523,5 @@ function send_get_section(p)
|
||||
buildat.send_packet("voxelworld:get_section", data)
|
||||
end
|
||||
|
||||
sub_events()
|
||||
|
||||
return M
|
||||
-- vim: set noet ts=4 sw=4:
|
||||
|
@ -244,6 +244,9 @@ struct Module: public interface::Module, public voxelworld::Interface
|
||||
// (as a sorted array in descending node_id order)
|
||||
std::vector<QueuedNodePhysicsUpdate> m_nodes_needing_physics_update;
|
||||
|
||||
// Clients that are ready to receive things (by peer id)
|
||||
set_<int> m_clients_initialized;
|
||||
|
||||
Module(interface::Server *server):
|
||||
interface::Module(MODULE),
|
||||
m_server(server)
|
||||
@ -394,6 +397,7 @@ struct Module: public interface::Module, public voxelworld::Interface
|
||||
|
||||
void on_client_disconnected(const network::OldClient &old_client)
|
||||
{
|
||||
m_clients_initialized.erase(old_client.info.id);
|
||||
}
|
||||
|
||||
void on_tick(const interface::TickEvent &event)
|
||||
@ -431,6 +435,12 @@ struct Module: public interface::Module, public voxelworld::Interface
|
||||
// Unload stuff if needed
|
||||
maintain_maximum_buffer_limit();
|
||||
|
||||
// Send updated voxel registry if needed
|
||||
send_voxel_registry_if_dirty();
|
||||
}
|
||||
|
||||
void send_voxel_registry_if_dirty()
|
||||
{
|
||||
// Send updated voxel registry if needed
|
||||
// NOTE: This probably really only supports additions
|
||||
if(m_voxel_reg->is_dirty()){
|
||||
@ -442,6 +452,8 @@ struct Module: public interface::Module, public voxelworld::Interface
|
||||
network::access(m_server, [&](network::Interface *inetwork){
|
||||
sv_<network::PeerInfo::Id> peers = inetwork->list_peers();
|
||||
for(auto &peer: peers){
|
||||
if(!m_clients_initialized.count(peer))
|
||||
continue;
|
||||
inetwork->send(peer, "voxelworld:voxel_registry",
|
||||
voxel_reg_data);
|
||||
}
|
||||
@ -452,12 +464,12 @@ struct Module: public interface::Module, public voxelworld::Interface
|
||||
void on_files_transmitted(const client_file::FilesTransmitted &event)
|
||||
{
|
||||
int peer = event.recipient;
|
||||
// Load the client-side module
|
||||
network::access(m_server, [&](network::Interface *inetwork){
|
||||
// Load the module by calling require() on it so that it can start
|
||||
// receiving data
|
||||
inetwork->send(peer, "core:run_script",
|
||||
"require(\"buildat/module/voxelworld\")");
|
||||
});
|
||||
// Send initialization data and tell the client that it is now ready
|
||||
std::ostringstream os(std::ios::binary);
|
||||
{
|
||||
cereal::PortableBinaryOutputArchive ar(os);
|
||||
@ -468,7 +480,9 @@ struct Module: public interface::Module, public voxelworld::Interface
|
||||
inetwork->send(peer, "voxelworld:init", os.str());
|
||||
inetwork->send(peer, "voxelworld:voxel_registry",
|
||||
m_voxel_reg->serialize());
|
||||
inetwork->send(peer, "voxelworld:ready", "");
|
||||
});
|
||||
m_clients_initialized.insert(peer);
|
||||
}
|
||||
|
||||
// TODO: How should nodes be filtered for replication?
|
||||
@ -971,9 +985,11 @@ struct Module: public interface::Module, public voxelworld::Interface
|
||||
run_commit_hooks_in_scene(chunk_p, n);
|
||||
});
|
||||
|
||||
// Tell replicate to emit events once it has done its job
|
||||
// TODO: Have some way of invoking replication directly for this node;
|
||||
// this is too slow
|
||||
// First send updated voxel registry to clients so that they are ready
|
||||
// to generate stuff from the voxels
|
||||
send_voxel_registry_if_dirty();
|
||||
|
||||
// Then synchronize node and notify clients about it
|
||||
sv_<replicate::PeerId> peers;
|
||||
replicate::access(m_server, [&](replicate::Interface *ireplicate){
|
||||
ireplicate->sync_node_immediate(node_id);
|
||||
@ -986,6 +1002,8 @@ struct Module: public interface::Module, public voxelworld::Interface
|
||||
}
|
||||
network::access(m_server, [&](network::Interface *inetwork){
|
||||
for(auto &peer_id: peers){
|
||||
if(!m_clients_initialized.count(peer_id))
|
||||
continue;
|
||||
inetwork->send(peer_id, "voxelworld:node_volume_updated",
|
||||
os.str());
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ struct Module: public interface::Module
|
||||
{
|
||||
m_server->sub_event(this, Event::t("core:start"));
|
||||
m_server->sub_event(this, Event::t("core:continue"));
|
||||
m_server->sub_event(this, Event::t("worldgen:voxels_defined"));
|
||||
m_server->sub_event(this, Event::t("core:tick"));
|
||||
m_server->sub_event(this, Event::t("client_file:files_transmitted"));
|
||||
m_server->sub_event(this, Event::t(
|
||||
@ -85,6 +86,7 @@ struct Module: public interface::Module
|
||||
{
|
||||
EVENT_VOIDN("core:start", on_start)
|
||||
EVENT_VOIDN("core:continue", on_continue)
|
||||
EVENT_VOIDN("worldgen:voxels_defined", on_voxels_defined)
|
||||
EVENT_TYPEN("core:tick", on_tick, interface::TickEvent)
|
||||
EVENT_TYPEN("client_file:files_transmitted",
|
||||
on_files_transmitted, client_file::FilesTransmitted)
|
||||
@ -95,6 +97,14 @@ struct Module: public interface::Module
|
||||
}
|
||||
|
||||
void on_start()
|
||||
{
|
||||
}
|
||||
|
||||
void on_continue()
|
||||
{
|
||||
}
|
||||
|
||||
void on_voxels_defined()
|
||||
{
|
||||
voxelworld::access(m_server, [&](voxelworld::Interface *ivoxelworld)
|
||||
{
|
||||
@ -148,10 +158,6 @@ struct Module: public interface::Module
|
||||
});
|
||||
}
|
||||
|
||||
void on_continue()
|
||||
{
|
||||
}
|
||||
|
||||
void update_scene()
|
||||
{
|
||||
}
|
||||
@ -171,8 +177,10 @@ struct Module: public interface::Module
|
||||
{
|
||||
Scene *scene = imc->get_scene();
|
||||
Node *n = scene->GetChild("Testbox");
|
||||
n->SetRotation(Quaternion(30, 60, 90));
|
||||
n->SetPosition(Vector3(30.0f, 30.0f, 40.0f));
|
||||
if(n){
|
||||
n->SetRotation(Quaternion(30, 60, 90));
|
||||
n->SetPosition(Vector3(30.0f, 30.0f, 40.0f));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -207,6 +207,8 @@ struct Module: public interface::Module
|
||||
voxel_reg->add_voxel(vdef); // id 6
|
||||
}
|
||||
});
|
||||
|
||||
m_server->emit_event(Event("worldgen:voxels_defined"));
|
||||
}
|
||||
|
||||
void on_continue()
|
||||
|
Loading…
x
Reference in New Issue
Block a user