diff --git a/res/scripts/classes.lua b/res/scripts/classes.lua index 950544bf..9076808c 100644 --- a/res/scripts/classes.lua +++ b/res/scripts/classes.lua @@ -171,73 +171,6 @@ local function clean(iterable, checkFun, ...) end end -local updating_blocks = {} -local TYPE_REGISTER = 0 -local TYPE_UNREGISTER = 1 - -block.__perform_ticks = function(delta) - for id, entry in pairs(updating_blocks) do - entry.timer = entry.timer + delta - local steps = math.floor(entry.timer / entry.delta * #entry / 3) - if steps == 0 then - goto continue - end - entry.timer = 0.0 - local event = entry.event - local tps = entry.tps - for i=1, steps do - local x = entry[entry.pointer + 1] - local y = entry[entry.pointer + 2] - local z = entry[entry.pointer + 3] - entry.pointer = (entry.pointer + 3) % #entry - events.emit(event, x, y, z, tps) - end - ::continue:: - end -end - -block.__process_register_events = function() - local register_events = block.__pull_register_events() - if not register_events then - return - end - for i=1, #register_events, 4 do - local header = register_events[i] - local type = bit.band(header, 0xFFFF) - local id = bit.rshift(header, 16) - local x = register_events[i + 1] - local y = register_events[i + 2] - local z = register_events[i + 3] - - local list = updating_blocks[id] - if type == TYPE_REGISTER then - if not list then - list = {} - list.event = block.name(id) .. ".blocktick" - list.tps = 20 / (block.properties[id]["tick-interval"] or 1) - list.delta = 1.0 / list.tps - list.timer = 0.0 - list.pointer = 0 - updating_blocks[id] = list - end - table.insert(list, x) - table.insert(list, y) - table.insert(list, z) - elseif type == TYPE_UNREGISTER then - if list then - for j=1, #list, 3 do - if list[j] == x and list[j + 1] == y and list[j + 2] == z then - for k=1,3 do - table.remove(list, j) - end - j = j - 3 - end - end - end - end - end -end - network.__process_events = function() local CLIENT_CONNECTED = 1 local CONNECTED_TO_SERVER = 2 diff --git a/res/scripts/internal_events.lua b/res/scripts/internal_events.lua new file mode 100644 index 00000000..06666d04 --- /dev/null +++ b/res/scripts/internal_events.lua @@ -0,0 +1,66 @@ +local updating_blocks = {} +local TYPE_REGISTER = 0 +local TYPE_UNREGISTER = 1 + +block.__perform_ticks = function(delta) + for id, entry in pairs(updating_blocks) do + entry.timer = entry.timer + delta + local steps = math.floor(entry.timer / entry.delta * #entry / 3) + if steps == 0 then + goto continue + end + entry.timer = 0.0 + local event = entry.event + local tps = entry.tps + for i=1, steps do + local x = entry[entry.pointer + 1] + local y = entry[entry.pointer + 2] + local z = entry[entry.pointer + 3] + entry.pointer = (entry.pointer + 3) % #entry + events.emit(event, x, y, z, tps) + end + ::continue:: + end +end + +block.__process_register_events = function() + local register_events = block.__pull_register_events() + if not register_events then + return + end + for i=1, #register_events, 4 do + local header = register_events[i] + local event_bits = bit.band(header, 0xFFFF) + local id = bit.rshift(header, 16) + local x = register_events[i + 1] + local y = register_events[i + 2] + local z = register_events[i + 3] + + local list = updating_blocks[id] + if bit.band(event_bits, TYPE_REGISTER) ~= 0 then + if not list then + list = {} + list.event = block.name(id) .. ".blocktick" + list.tps = 20 / (block.properties[id]["tick-interval"] or 1) + list.delta = 1.0 / list.tps + list.timer = 0.0 + list.pointer = 0 + updating_blocks[id] = list + end + table.insert(list, x) + table.insert(list, y) + table.insert(list, z) + elseif bit.band(event_bits, TYPE_UNREGISTER) ~= 0 then + if list then + for j=1, #list, 3 do + if list[j] == x and list[j + 1] == y and list[j + 2] == z then + for k=1,3 do + table.remove(list, j) + end + j = j - 3 + end + end + end + end + end +end diff --git a/src/logic/scripting/lua/libs/libblock.cpp b/src/logic/scripting/lua/libs/libblock.cpp index 8ac548e5..fa525eb0 100644 --- a/src/logic/scripting/lua/libs/libblock.cpp +++ b/src/logic/scripting/lua/libs/libblock.cpp @@ -730,7 +730,7 @@ static int l_pull_register_events(lua::State* L) { lua::createtable(L, events.size() * 4, 0); for (int i = 0; i < events.size(); i++) { const auto& event = events[i]; - lua::pushinteger(L, static_cast(event.type) | event.id << 16); + lua::pushinteger(L, static_cast(event.bits) | event.id << 16); lua::rawseti(L, i * 4 + 1); for (int j = 0; j < 3; j++) { diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 19accc89..07b35d1e 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -72,6 +72,7 @@ void scripting::initialize(Engine* engine) { load_script(io::path("stdlib.lua"), true); load_script(io::path("classes.lua"), true); + load_script(io::path("internal_events.lua"), true); } class LuaCoroutine : public Process { diff --git a/src/voxels/blocks_agent.cpp b/src/voxels/blocks_agent.cpp index d64f7727..e4e17e27 100644 --- a/src/voxels/blocks_agent.cpp +++ b/src/voxels/blocks_agent.cpp @@ -14,39 +14,46 @@ std::vector blocks_agent::pull_register_events() { return events; } +static uint16_t get_events_bits(bool present, const Block& def) { + uint16_t bits = 0; + if (def.rt.funcsset.onblocktick) { + bits |= present ? BlockRegisterEvent::REGISTER_UPDATING_BIT + : BlockRegisterEvent::UNREGISTER_UPDATING_BIT; + } + return bits; +} + static void on_chunk_register_event( const ContentIndices& indices, const Chunk& chunk, - BlockRegisterEvent::Type type + bool present ) { for (int i = 0; i < CHUNK_VOL; i++) { const auto& def = indices.blocks.require(chunk.voxels[i].id); - if (def.rt.funcsset.onblocktick) { - int x = i % CHUNK_W + chunk.x * CHUNK_W; - int z = (i / CHUNK_W) % CHUNK_D + chunk.z * CHUNK_D; - int y = (i / CHUNK_W / CHUNK_D); - block_register_events.push_back(BlockRegisterEvent { - type, def.rt.id, {x, y, z} - }); + uint16_t bits = get_events_bits(present, def); + if (bits == 0) { + continue; } + int x = i % CHUNK_W + chunk.x * CHUNK_W; + int z = (i / CHUNK_W) % CHUNK_D + chunk.z * CHUNK_D; + int y = (i / CHUNK_W / CHUNK_D); + block_register_events.push_back(BlockRegisterEvent { + bits, def.rt.id, {x, y, z} + }); } } void blocks_agent::on_chunk_present( const ContentIndices& indices, const Chunk& chunk ) { - on_chunk_register_event( - indices, chunk, BlockRegisterEvent::Type::REGISTER_UPDATING - ); + on_chunk_register_event(indices, chunk, true); } void blocks_agent::on_chunk_remove( const ContentIndices& indices, const Chunk& chunk ) { - on_chunk_register_event( - indices, chunk, BlockRegisterEvent::Type::UNREGISTER_UPDATING - ); + on_chunk_register_event(indices, chunk, false); } template @@ -101,11 +108,14 @@ static void finalize_block( chunk.flags.blocksData = true; } } - if (def.rt.funcsset.onblocktick) { - block_register_events.push_back(BlockRegisterEvent { - BlockRegisterEvent::Type::UNREGISTER_UPDATING, def.rt.id, {x, y, z} - }); + + uint16_t bits = get_events_bits(false, def); + if (bits == 0) { + return; } + block_register_events.push_back(BlockRegisterEvent { + bits, def.rt.id, {x, y, z} + }); } template @@ -131,9 +141,17 @@ static void initialize_block( refresh_chunk_heights(chunk, id == BLOCK_AIR, y); mark_neighboirs_modified(chunks, cx, cz, lx, lz); + uint16_t bits = get_events_bits(true, def); + if (bits == 0) { + return; + } + block_register_events.push_back(BlockRegisterEvent { + bits, def.rt.id, {x, y, z} + }); + if (def.rt.funcsset.onblocktick) { block_register_events.push_back(BlockRegisterEvent { - BlockRegisterEvent::Type::REGISTER_UPDATING, def.rt.id, {x, y, z} + bits, def.rt.id, {x, y, z} }); } } diff --git a/src/voxels/blocks_agent.hpp b/src/voxels/blocks_agent.hpp index ab798133..b5ca82a6 100644 --- a/src/voxels/blocks_agent.hpp +++ b/src/voxels/blocks_agent.hpp @@ -25,11 +25,10 @@ struct AABB; namespace blocks_agent { struct BlockRegisterEvent { - enum class Type : uint16_t { - REGISTER_UPDATING, - UNREGISTER_UPDATING, - }; - Type type; + static inline constexpr uint16_t REGISTER_UPDATING_BIT = 0x1; + static inline constexpr uint16_t UNREGISTER_UPDATING_BIT = 0x2; + static inline constexpr uint16_t PRESENT_EVENT_BIT = 0x4; + uint16_t bits; blockid_t id; glm::ivec3 coord; };