diff --git a/builtin/ground_plane_lighting/api.h b/builtin/ground_plane_lighting/api.h index 199944d..2360350 100644 --- a/builtin/ground_plane_lighting/api.h +++ b/builtin/ground_plane_lighting/api.h @@ -4,34 +4,32 @@ #include "interface/event.h" #include "interface/server.h" #include "interface/module.h" -// TODO: Clean up -#include "interface/voxel.h" -#include -#include -#include #include -// TODO: Clean up -namespace Urho3D +namespace main_context { - class Context; - class Scene; - class Node; -} + struct OpaqueSceneReference; + typedef OpaqueSceneReference* SceneReference; +}; namespace ground_plane_lighting { - // TODO: Clean up - namespace magic = Urho3D; - namespace pv = PolyVox; - using interface::VoxelInstance; + using main_context::SceneReference; - struct Interface + struct Instance { virtual void set_yst(int32_t x, int32_t z, int32_t yst) = 0; virtual int32_t get_yst(int32_t x, int32_t z) = 0; }; + struct Interface + { + virtual void create_instance(SceneReference scene_ref) = 0; + virtual void delete_instance(SceneReference scene_ref) = 0; + + virtual Instance* get_instance(SceneReference scene_ref) = 0; + }; + inline bool access(interface::Server *server, std::function cb) { diff --git a/builtin/ground_plane_lighting/client_lua/module.lua b/builtin/ground_plane_lighting/client_lua/module.lua index 588c687..bef64c4 100644 --- a/builtin/ground_plane_lighting/client_lua/module.lua +++ b/builtin/ground_plane_lighting/client_lua/module.lua @@ -30,6 +30,8 @@ local function setup_sizes(sector_size) log:info("zone_size: "..M.zone_size:dump()) end +local dark_zones = {} -- {sector_y: {sector_x: {zone nodes}}} + buildat.sub_packet("ground_plane_lighting:init", function(data) local values = cereal.binary_input(data, {"object", {"sector_size", {"object", @@ -39,9 +41,17 @@ buildat.sub_packet("ground_plane_lighting:init", function(data) }) log:info("ground_plane_lighting:init: "..dump(values)) setup_sizes(buildat.Vector2(values.sector_size)) -end) -local dark_zones = {} -- {sector_y: {sector_x: {zone nodes}}} + -- Clear existing zone nodes + for sector_y, x_list in pairs(dark_zones) do + for sector_x, zone_node_list in pairs(x_lists) do + for _, node in ipairs(zone_node_list) do + node:Remove() + end + end + end + dark_zones = {} +end) local function get_sector_zones(x, y) local ytable = dark_zones[y] diff --git a/builtin/ground_plane_lighting/ground_plane_lighting.cpp b/builtin/ground_plane_lighting/ground_plane_lighting.cpp index c066029..aab6d47 100644 --- a/builtin/ground_plane_lighting/ground_plane_lighting.cpp +++ b/builtin/ground_plane_lighting/ground_plane_lighting.cpp @@ -163,58 +163,56 @@ struct GlobalYSTMap } }; -struct Module: public interface::Module, public ground_plane_lighting::Interface +struct CInstance: public ground_plane_lighting::Instance { interface::Server *m_server; - + SceneReference m_scene_ref; up_ m_global_yst; - Module(interface::Server *server): - interface::Module(MODULE), - m_server(server) - { - } + // Clients that are ready to receive things (by peer id) + set_ m_clients_initialized; - ~Module() + CInstance(interface::Server *server, SceneReference scene_ref): + m_server(server), + m_scene_ref(scene_ref) { - } - - void init() - { - m_server->sub_event(this, Event::t("core:start")); - m_server->sub_event(this, Event::t("core:unload")); - m_server->sub_event(this, Event::t("core:continue")); - m_server->sub_event(this, Event::t("core:tick")); - m_server->sub_event(this, Event::t("network:client_connected")); - m_server->sub_event(this, Event::t("client_file:files_transmitted")); - m_server->sub_event(this, Event::t("voxelworld:node_volume_updated")); - voxelworld::access(m_server, [&](voxelworld::Interface *ivoxelworld) { - pv::Vector3DInt16 section_size = - ivoxelworld->get_section_size_voxels(); + voxelworld::Instance *world = + ivoxelworld->get_instance(m_scene_ref); + pv::Vector3DInt16 section_size = world->get_section_size_voxels(); pv::Vector<2, int16_t> sector_size( section_size.getX(), section_size.getZ()); m_global_yst.reset(new GlobalYSTMap(sector_size)); }); } + ~CInstance() + { + } + void event(const Event::Type &type, const Event::Private *p) { EVENT_VOIDN("core:start", on_start) EVENT_VOIDN("core:unload", on_unload) EVENT_VOIDN("core:continue", on_continue) EVENT_TYPEN("core:tick", on_tick, interface::TickEvent) - EVENT_TYPEN("network:client_connected", on_client_connected, - network::NewClient) - EVENT_TYPEN("client_file:files_transmitted", on_files_transmitted, - client_file::FilesTransmitted) + EVENT_TYPEN("replicate:peer_joined_scene", on_peer_joined_scene, + replicate::PeerJoinedScene); + EVENT_TYPEN("replicate:peer_left_scene", on_peer_left_scene, + replicate::PeerLeftScene); EVENT_TYPEN("voxelworld:node_volume_updated", on_node_volume_updated, voxelworld::NodeVolumeUpdated) } + void initial_update() + { + // TODO + } + void on_start() { + initial_update(); } void on_unload() @@ -223,6 +221,7 @@ struct Module: public interface::Module, public ground_plane_lighting::Interface void on_continue() { + initial_update(); } void on_tick(const interface::TickEvent &event) @@ -239,8 +238,7 @@ struct Module: public interface::Module, public ground_plane_lighting::Interface ar(s); } network::access(m_server, [&](network::Interface *inetwork){ - sv_ peers = inetwork->list_peers(); - for(auto &peer: peers){ + for(auto &peer : m_clients_initialized){ inetwork->send(peer, "ground_plane_lighting:update", os.str()); } @@ -249,13 +247,9 @@ struct Module: public interface::Module, public ground_plane_lighting::Interface } } - void on_client_connected(const network::NewClient &client_connected) + void on_peer_joined_scene(const replicate::PeerJoinedScene &event) { - } - - void on_files_transmitted(const client_file::FilesTransmitted &event) - { - int peer = event.recipient; + int peer = event.peer; network::access(m_server, [&](network::Interface *inetwork){ inetwork->send(peer, "core:run_script", "require(\"buildat/module/ground_plane_lighting\")"); @@ -269,22 +263,32 @@ struct Module: public interface::Module, public ground_plane_lighting::Interface inetwork->send(peer, "ground_plane_lighting:init", os.str()); }); + m_clients_initialized.insert(peer); send_initial_sectors(peer); } + void on_peer_left_scene(const replicate::PeerLeftScene &event) + { + m_clients_initialized.erase(event.peer); + } + void on_node_volume_updated(const voxelworld::NodeVolumeUpdated &event) { if(!event.is_static_chunk) return; + if(event.scene != m_scene_ref) + return; log_v(MODULE, "Checking ground level in chunk " PV3I_FORMAT, PV3I_PARAMS(event.chunk_p)); const pv::Vector3DInt32 &chunk_p = event.chunk_p; voxelworld::access(m_server, [&](voxelworld::Interface *ivoxelworld) { - interface::VoxelRegistry *voxel_reg = ivoxelworld->get_voxel_reg(); - //const auto &chunk_size_voxels = ivoxelworld->get_chunk_size_voxels(); + voxelworld::Instance *world = + ivoxelworld->get_instance(m_scene_ref); + interface::VoxelRegistry *voxel_reg = world->get_voxel_reg(); + //const auto &chunk_size_voxels = world->get_chunk_size_voxels(); pv::Region chunk_region = - ivoxelworld->get_chunk_region_voxels(chunk_p); + world->get_chunk_region_voxels(chunk_p); auto lc = chunk_region.getLowerCorner(); auto uc = chunk_region.getUpperCorner(); @@ -298,7 +302,7 @@ struct Module: public interface::Module, public ground_plane_lighting::Interface } int y = uc.getY(); for(;; y--){ - VoxelInstance v = ivoxelworld->get_voxel( + VoxelInstance v = world->get_voxel( pv::Vector3DInt32(x, y, z), true); if(v.get_id() == interface::VOXELTYPEID_UNDEFINED){ // NOTE: This leaves the chunks below unhandled; @@ -355,6 +359,100 @@ struct Module: public interface::Module, public ground_plane_lighting::Interface { return m_global_yst->get_yst(x, z); } +}; + +struct Module: public interface::Module, public ground_plane_lighting::Interface +{ + interface::Server *m_server; + + sm_> m_instances; + + Module(interface::Server *server): + interface::Module(MODULE), + m_server(server) + { + } + + ~Module() + { + } + + void init() + { + m_server->sub_event(this, Event::t("core:start")); + m_server->sub_event(this, Event::t("core:unload")); + m_server->sub_event(this, Event::t("core:continue")); + m_server->sub_event(this, Event::t("core:tick")); + m_server->sub_event(this, Event::t("replicate:peer_joined_scene")); + m_server->sub_event(this, Event::t("replicate:peer_left_scene")); + m_server->sub_event(this, Event::t("client_file:files_transmitted")); + m_server->sub_event(this, Event::t("voxelworld:node_volume_updated")); + } + + void event(const Event::Type &type, const Event::Private *p) + { + EVENT_VOIDN("core:start", on_start) + EVENT_VOIDN("core:unload", on_unload) + EVENT_VOIDN("core:continue", on_continue) + EVENT_TYPEN("core:tick", on_tick, interface::TickEvent) + EVENT_TYPEN("client_file:files_transmitted", on_files_transmitted, + client_file::FilesTransmitted) + EVENT_TYPEN("voxelworld:node_volume_updated", + on_node_volume_updated, voxelworld::NodeVolumeUpdated) + } + + void on_start() + { + } + + void on_unload() + { + } + + void on_continue() + { + } + + void on_tick(const interface::TickEvent &event) + { + } + + void on_files_transmitted(const client_file::FilesTransmitted &event) + { + } + + void on_node_volume_updated(const voxelworld::NodeVolumeUpdated &event) + { + } + + // Interface + + void create_instance(SceneReference scene_ref) + { + auto it = m_instances.find(scene_ref); + // TODO: Is an exception the best way to handle this? + if(it != m_instances.end()) + throw Exception("create_instance(): Scene already has gpl"); + + up_ instance(new CInstance(m_server, scene_ref)); + m_instances[scene_ref] = std::move(instance); + } + + void delete_instance(SceneReference scene_ref) + { + auto it = m_instances.find(scene_ref); + if(it == m_instances.end()) + throw Exception("delete_instance(): Scene does not have gpl"); + m_instances.erase(it); + } + + Instance* get_instance(SceneReference scene_ref) + { + auto it = m_instances.find(scene_ref); + if(it == m_instances.end()) + throw Exception("get_instance(): Scene does not have gpl"); + return it->second.get(); + } void* get_interface() {