From 8b67a492f459a47a1d2eeebc852c9741a77708d5 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Wed, 17 Jan 2024 10:59:44 +0100 Subject: a --- bench/dijkstra.cpp | 1 - compat/enum-bitset.hpp | 2 +- draw/anim.cpp | 8 +++--- draw/anim.hpp | 5 ++-- entity/accessor.hpp | 1 - loader/wall-atlas.cpp | 4 +-- main/ctor.cpp | 34 +++++++++++++++++++++++ main/draw.cpp | 3 +- main/main-impl.cpp | 2 +- main/main-impl.hpp | 7 ++--- main/setup.cpp | 27 ------------------ serialize/packbits-read.cpp | 9 ------ serialize/packbits-write.cpp | 2 +- serialize/scenery.hpp | 1 - serialize/wall-atlas.cpp | 13 +++++---- serialize/wall-atlas.hpp | 3 +- serialize/world-reader.cpp | 2 +- serialize/world-writer.cpp | 12 ++++---- src/wall-atlas.hpp | 1 + test/wall-atlas.cpp | 2 +- test/wall-atlas2.cpp | 66 +++++++++++++++++++++++++++++++++++--------- wall-tileset-tool/main.cpp | 18 ++++++++---- 22 files changed, 132 insertions(+), 91 deletions(-) create mode 100644 main/ctor.cpp diff --git a/bench/dijkstra.cpp b/bench/dijkstra.cpp index 5c9208e3..4296e71c 100644 --- a/bench/dijkstra.cpp +++ b/bench/dijkstra.cpp @@ -12,7 +12,6 @@ namespace { auto A = astar(); bool first_run = false; - void Dijkstra(benchmark::State& state) { (void)loader.wall_atlas_list(); diff --git a/compat/enum-bitset.hpp b/compat/enum-bitset.hpp index f1c23808..d50eeaf4 100644 --- a/compat/enum-bitset.hpp +++ b/compat/enum-bitset.hpp @@ -1,6 +1,6 @@ #pragma once #include "enum-bitset-fwd.hpp" -#include +#include // todo replace it namespace floormat { diff --git a/draw/anim.cpp b/draw/anim.cpp index ad71611a..56824cf1 100644 --- a/draw/anim.cpp +++ b/draw/anim.cpp @@ -5,7 +5,7 @@ #include "main/clickable.hpp" #include "src/chunk-scenery.hpp" #include "src/scenery.hpp" -#include +#include #include #include #include @@ -33,7 +33,7 @@ std::array anim_mesh::make_index_array() void anim_mesh::add_clickable(tile_shader& shader, const Vector2i& win_size, object* s_, const chunk::topo_sort_data& data, - std::vector& list) + Array& list) { const auto& s = *s_; const auto& a = *s.atlas; @@ -55,11 +55,11 @@ void anim_mesh::add_clickable(tile_shader& shader, const Vector2i& win_size, .stride = a.info().pixel_size[0], .mirrored = !g.mirror_from.isEmpty(), }; - list.push_back(item); + arrayAppend(list, item); } } -void anim_mesh::draw(tile_shader& shader, const Vector2i& win_size, chunk& c, std::vector& list, bool draw_vobjs) +void anim_mesh::draw(tile_shader& shader, const Vector2i& win_size, chunk& c, Array& list, bool draw_vobjs) { constexpr auto quad_index_count = 6; diff --git a/draw/anim.hpp b/draw/anim.hpp index c9420eb4..e9ac5f89 100644 --- a/draw/anim.hpp +++ b/draw/anim.hpp @@ -3,7 +3,6 @@ #include "src/rotation.hpp" #include "src/chunk.hpp" #include -#include #include #include #include @@ -27,12 +26,12 @@ struct anim_mesh { anim_mesh(); - void draw(tile_shader& shader, const Vector2i& win_size, chunk& c, std::vector& list, bool draw_vobjs); + void draw(tile_shader& shader, const Vector2i& win_size, chunk& c, Array& list, bool draw_vobjs); void draw(tile_shader& shader, anim_atlas& atlas, rotation r, size_t frame, const Vector3& pos, float depth); void draw(tile_shader& shader, anim_atlas& atlas, rotation r, size_t frame, local_coords xy, Vector2b offset, float dpeth); static void add_clickable(tile_shader& shader, const Vector2i& win_size, object* s_, const chunk::topo_sort_data& data, - std::vector& list); + Array& list); private: static std::array make_index_array(); diff --git a/entity/accessor.hpp b/entity/accessor.hpp index 468c51c3..732c3ad0 100644 --- a/entity/accessor.hpp +++ b/entity/accessor.hpp @@ -4,7 +4,6 @@ #include "name-of.hpp" #include #include -#include #include namespace floormat::erased_constraints { diff --git a/loader/wall-atlas.cpp b/loader/wall-atlas.cpp index 32bc9b7d..b2505fbc 100644 --- a/loader/wall-atlas.cpp +++ b/loader/wall-atlas.cpp @@ -59,8 +59,8 @@ const wall_info& loader_impl::make_invalid_wall_atlas() auto a = std::make_shared( wall_atlas_def { Wall::Info{.name = name, .depth = 8}, - {{ {}, frame_size}, }, - {{ {.index = 0, .count = 1, .pixel_size = frame_size, .is_defined = true, } } }, + array({{ {}, frame_size}, }), + array({{ {.index = 0, .count = 1, .pixel_size = frame_size, .is_defined = true, } } }), {{ {.val = 0}, {}, }}, {1u}, }, name, make_error_texture(frame_size)); diff --git a/main/ctor.cpp b/main/ctor.cpp new file mode 100644 index 00000000..11bc8cb9 --- /dev/null +++ b/main/ctor.cpp @@ -0,0 +1,34 @@ +#include "main-impl.hpp" +#include "compat/fpu.hpp" +#include "src/path-search.hpp" +#include + +namespace floormat { + +main_impl::main_impl(floormat_app& app, fm_settings&& se, int& argc, char** argv) noexcept : + Platform::Sdl2Application{Arguments{argc, argv}, + make_conf(se), make_gl_conf(se)}, + s{std::move(se)}, app{app}, _shader{_tuc} +{ + if (s.vsync) + { + (void)setSwapInterval(1); + if (const auto list = GL::Context::current().extensionStrings(); + std::find(list.cbegin(), list.cend(), "EXT_swap_control_tear") != list.cend()) + (void)setSwapInterval(-1); + } + else + (void)setSwapInterval(0); + set_fp_mask(); + arrayReserve(_clickable_scenery, 128); + timeline.start(); +} + +class world& main_impl::reset_world(class world&& w) noexcept +{ + arrayResize(_clickable_scenery, 0); + _world = std::move(w); + return _world; +} + +} // namespace floormat diff --git a/main/draw.cpp b/main/draw.cpp index 4de42473..dc476fe8 100644 --- a/main/draw.cpp +++ b/main/draw.cpp @@ -4,6 +4,7 @@ #include "src/anim-atlas.hpp" #include "main/clickable.hpp" #include "src/light.hpp" +#include #include #include #include @@ -134,7 +135,7 @@ void main_impl::draw_world() noexcept fm_debug_assert(1 + maxx - minx <= 8); fm_debug_assert(1 + maxy - miny <= 8); - _clickable_scenery.clear(); + arrayResize(_clickable_scenery, 0); #ifdef FM_USE_DEPTH32 framebuffer.fb.clearDepth(0); #else diff --git a/main/main-impl.cpp b/main/main-impl.cpp index 6875f751..0ce2b5fb 100644 --- a/main/main-impl.cpp +++ b/main/main-impl.cpp @@ -65,6 +65,6 @@ uint32_t main_impl::cursor() const noexcept struct texture_unit_cache& main_impl::texture_unit_cache() { return _tuc; } path_search& main_impl::search() { return *_search; } -astar& main_impl::astar() { return _astar; } +astar& main_impl::astar() { return *_astar; } } // namespace floormat diff --git a/main/main-impl.hpp b/main/main-impl.hpp index 522183e6..ecfa17f7 100644 --- a/main/main-impl.hpp +++ b/main/main-impl.hpp @@ -9,8 +9,7 @@ #include "shaders/shader.hpp" #include "shaders/lightmap.hpp" #include "main/clickable.hpp" -#include "src/path-search.hpp" -#include +#include #include #include #include @@ -109,7 +108,7 @@ private: floormat_app& app; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members) tile_shader _shader; struct lightmap_shader _lightmap_shader{_tuc}; - std::vector _clickable_scenery; + Array _clickable_scenery; class world _world{}; Magnum::Timeline timeline; uint32_t _mouse_cursor = (uint32_t)-1; @@ -120,7 +119,7 @@ private: Framebuffer framebuffer; #endif safe_ptr _search; - class astar _astar; + safe_ptr _astar; struct { float value = 0; diff --git a/main/setup.cpp b/main/setup.cpp index 6f794719..797fbfb0 100644 --- a/main/setup.cpp +++ b/main/setup.cpp @@ -1,30 +1,10 @@ #include "main-impl.hpp" -#include "compat/fpu.hpp" #include #include #include namespace floormat { -main_impl::main_impl(floormat_app& app, fm_settings&& se, int& argc, char** argv) noexcept : - Platform::Sdl2Application{Arguments{argc, argv}, - make_conf(se), make_gl_conf(se)}, - s{std::move(se)}, app{app}, _shader{_tuc} -{ - if (s.vsync) - { - (void)setSwapInterval(1); - if (const auto list = GL::Context::current().extensionStrings(); - std::find(list.cbegin(), list.cend(), "EXT_swap_control_tear") != list.cend()) - (void)setSwapInterval(-1); - } - else - (void)setSwapInterval(0); - set_fp_mask(); - _clickable_scenery.reserve(128); - timeline.start(); -} - auto main_impl::make_window_flags(const fm_settings& s) -> Configuration::WindowFlags { using flag = Configuration::WindowFlag; @@ -108,11 +88,4 @@ class world& main_impl::reset_world() noexcept return reset_world(floormat::world{}); } -class world& main_impl::reset_world(class world&& w) noexcept -{ - _clickable_scenery.clear(); - _world = std::move(w); - return _world; -} - } // namespace floormat diff --git a/serialize/packbits-read.cpp b/serialize/packbits-read.cpp index 9980ca63..cc3fc3bd 100644 --- a/serialize/packbits-read.cpp +++ b/serialize/packbits-read.cpp @@ -2,15 +2,6 @@ #include "compat/assert.hpp" #include "compat/exception.hpp" -namespace floormat::Pack_impl { - -void throw_on_read_nonzero() noexcept(false) -{ - throw std::runtime_error{"extra bits in pack_read()"}; -} - -} // namespace floormat::Pack_impl - namespace floormat { using namespace floormat::Pack_impl; diff --git a/serialize/packbits-write.cpp b/serialize/packbits-write.cpp index f485a72e..f261abe5 100644 --- a/serialize/packbits-write.cpp +++ b/serialize/packbits-write.cpp @@ -33,7 +33,7 @@ static_assert(pack_write(std::tuple{f8<2>{0b10}, f8<3>{0b011}, f8<3>{0b01}}) == //static_assert(pack_write(std::tuple{}) == 0); static_assert(pack_write(std::tuple{f8<1>{0b1}, f8<3>{0b101}, f8<2>{0b10}}) == 0b101011); -#if 0 // check disasembly +#if 0 // check disassembly u32 foo1(u32 a, u32 b, u32 c); u32 foo1(u32 a, u32 b, u32 c) { diff --git a/serialize/scenery.hpp b/serialize/scenery.hpp index f3ceb586..93ceeb57 100644 --- a/serialize/scenery.hpp +++ b/serialize/scenery.hpp @@ -1,6 +1,5 @@ #pragma once #include "src/scenery.hpp" -#include #include #include diff --git a/serialize/wall-atlas.cpp b/serialize/wall-atlas.cpp index 0ba1c297..b2e7c2f5 100644 --- a/serialize/wall-atlas.cpp +++ b/serialize/wall-atlas.cpp @@ -5,6 +5,7 @@ #include "loader/loader.hpp" #include "pass-mode.hpp" #include "json-helper.hpp" +#include "corrade-array.hpp" #include #include #include @@ -42,7 +43,7 @@ namespace { struct direction_triple { - std::vector array; + Array array; std::array map; std::bitset mask; }; @@ -53,7 +54,7 @@ direction_triple read_all_directions(const json& jroot) for (auto [str, _] : wall_atlas::directions) if (jroot.contains(str)) count++; - direction_triple ret = { std::vector{count}, + direction_triple ret = { Array{count}, std::array{}, std::bitset{0}, }; auto& [array, map, mask] = ret; @@ -108,7 +109,7 @@ wall_atlas_def wall_atlas_def::deserialize(StringView filename) fm_soft_assert(loader.check_atlas_name(atlas.header.name)); atlas.frames = read_all_frames(jroot); auto [dirs, dir_indexes, mask] = read_all_directions(jroot); - fm_soft_assert(!dirs.empty()); + fm_soft_assert(!dirs.isEmpty()); fm_soft_assert(dir_indexes != std::array{}); atlas.direction_array = std::move(dirs); atlas.direction_map = dir_indexes; @@ -155,17 +156,17 @@ void wall_atlas::serialize(StringView filename) const namespace floormat::Wall::detail { -std::vector read_all_frames(const json& jroot) +Array read_all_frames(const json& jroot) { if (!jroot.contains("frames")) return {}; - std::vector frames; + Array frames; const auto& jframes = jroot["frames"]; fm_assert(jframes.is_array()); const auto sz = jframes.size(); - frames = std::vector{sz}; + frames = Array{sz}; for (auto i = 0uz; i < sz; i++) { diff --git a/serialize/wall-atlas.hpp b/serialize/wall-atlas.hpp index e7e553ce..1381591d 100644 --- a/serialize/wall-atlas.hpp +++ b/serialize/wall-atlas.hpp @@ -2,13 +2,14 @@ #include "src/wall-atlas.hpp" #include #include +#include #include namespace floormat::Wall::detail { using nlohmann::json; -[[nodiscard]] std::vector read_all_frames(const json& jroot); +[[nodiscard]] Array read_all_frames(const json& jroot); [[nodiscard]] Group read_group_metadata(const json& jgroup); [[nodiscard]] Direction read_direction_metadata(const json& jroot, Direction_ dir); Info read_info_header(const json& jroot); diff --git a/serialize/world-reader.cpp b/serialize/world-reader.cpp index 366648d5..ac247553 100644 --- a/serialize/world-reader.cpp +++ b/serialize/world-reader.cpp @@ -24,7 +24,7 @@ using namespace floormat::Serialize; constexpr inline atlasid meta_short_scenery_bit_ = highbits; constexpr inline atlasid meta_rotation_bits_ = highbits; constexpr inline atlasid scenery_id_flag_mask_ = meta_short_scenery_bit_ | meta_rotation_bits_; -constexpr inline atlasid scenery_id_max_ = int_max & ~scenery_id_flag_mask_; +constexpr inline atlasid scenery_id_max_ = int_traits::max & ~scenery_id_flag_mask_; struct reader_state final { explicit reader_state(world& world) noexcept; diff --git a/serialize/world-writer.cpp b/serialize/world-writer.cpp index fd533cee..649c1e9f 100644 --- a/serialize/world-writer.cpp +++ b/serialize/world-writer.cpp @@ -6,7 +6,6 @@ #include "src/global-coords.hpp" #include "src/chunk.hpp" #include "src/world.hpp" -#include "src/emplacer.hpp" #include "loader/loader.hpp" #include "src/scenery.hpp" #include "src/critter.hpp" @@ -15,7 +14,6 @@ #include "src/light.hpp" #include "compat/strerror.hpp" #include -#include #include #include #include @@ -210,12 +208,12 @@ void write_object_flags(binary_writer& s, const U& e) void writer_state::serialize_atlases() { - fm_assert(tile_images.size() < int_max); + fm_assert(tile_images.size() < int_traits::max); const auto sz = (atlasid)tile_images.size(); const auto atlasbuf_size = sizeof(sz) + atlas_name_max*sz; atlas_buf.resize(atlasbuf_size); auto s = binary_writer{atlas_buf.begin()}; - fm_assert(sz <= int_max); + fm_assert(sz <= int_traits::max); s << sz; @@ -241,7 +239,7 @@ void writer_state::serialize_atlases() } constexpr auto atlasbuf_size0 = sizeof(atlasid) + sizeof(scenery); -constexpr auto atlasbuf_size1 = sizeof(uint8_t) + atlasbuf_size0*int_max + atlas_name_max; +constexpr auto atlasbuf_size1 = sizeof(uint8_t) + atlasbuf_size0*int_traits::max + atlas_name_max; void writer_state::serialize_scenery_names() { @@ -284,7 +282,7 @@ void writer_state::serialize_scenery_names() auto num = 1uz; for (auto j = i+1; j < sz && vec[j].s->name == sc->name; j++) num++; - fm_assert(num < int_max); + fm_assert(num < int_traits::max); s << (uint8_t)num; fm_assert(sc->name.size() < atlas_name_max); s.write_asciiz_string(sc->name); @@ -564,7 +562,7 @@ ArrayView writer_state::serialize_world() serialize_strings(); using proto_t = std::decay_t; - fm_assert(_world->size() <= int_max); + fm_assert(_world->size() <= int_traits::max); const auto len = fm_begin( auto len = 0uz; diff --git a/src/wall-atlas.hpp b/src/wall-atlas.hpp index 14e2ce55..df5c7deb 100644 --- a/src/wall-atlas.hpp +++ b/src/wall-atlas.hpp @@ -147,6 +147,7 @@ public: ArrayView frames(Direction_ dir, Group_ g) const noexcept(false); ArrayView raw_frame_array() const; + unsigned depth() const { return _info.depth; } // todo use it in more places const Info& info() const { return _info; } StringView name() const { return _info.name; } //StringView path() const { return _path; } diff --git a/test/wall-atlas.cpp b/test/wall-atlas.cpp index 14046a09..4a761cfe 100644 --- a/test/wall-atlas.cpp +++ b/test/wall-atlas.cpp @@ -107,7 +107,7 @@ void test_from_rotation(StringView filename) constexpr Frame frame_defaults; constexpr Group group_defaults; - fm_assert(!atlas.frames.empty()); + fm_assert(!atlas.frames.isEmpty()); fm_assert(atlas.frames[0].offset != frame_defaults.offset); auto dir_index = atlas.direction_map[(size_t)Direction_::W]; fm_assert(dir_index); diff --git a/test/wall-atlas2.cpp b/test/wall-atlas2.cpp index 7c64166c..ebfa3f54 100644 --- a/test/wall-atlas2.cpp +++ b/test/wall-atlas2.cpp @@ -7,22 +7,62 @@ namespace floormat { -void test_app::test_wall_atlas2() +namespace { + +void test_empty_wall() +{ + using enum Wall::Direction_; + + const auto& wall = *loader.wall_atlas("empty"_s); + constexpr auto wall_size = Vector2ui(Vector2i{iTILE_SIZE.x(), iTILE_SIZE.z()}); + fm_assert(wall_atlas::expected_size(wall.info().depth, Wall::Group_::wall) == wall_size); + fm_assert(wall.depth() == 8); + fm_assert(wall.direction_count() == 1); + fm_assert(wall.raw_frame_array().size() == 1); + fm_assert(wall.direction(N) != nullptr); + const auto& n = *wall.direction(N); + fm_assert(wall.direction(W) == nullptr); + fm_assert(&wall.calc_direction(N) == wall.direction(N)); + fm_assert(&wall.calc_direction(W) == wall.direction(N)); + fm_assert(n.side == Wall::Group{}); + fm_assert(n.top == Wall::Group{}); + fm_assert(n.corner == Wall::Group{}); + fm_assert(!n.wall.mirrored); + fm_assert(n.wall.pixel_size == wall_size); + fm_assert(wall.raw_frame_array()[0].offset.isZero()); + fm_assert(wall.raw_frame_array()[0].size == wall_atlas::expected_size(wall.info().depth, Wall::Group_::wall)); + fm_assert(wall.info().name == "empty"_s); + fm_assert(wall.info().passability == pass_mode::blocked); +} + +void test_concrete_wall() { using enum Wall::Direction_; + constexpr auto name = "concrete1"_s; - static constexpr auto name = "concrete1"_s; - auto& a = *loader.wall_atlas(name, false); - fm_assert(a.name() == name); - fm_assert(a.info().depth == 20); - fm_assert(a.raw_frame_array().size() >= 3); - fm_assert(!a.direction(W)); - fm_assert(a.direction(N)); - fm_assert(&a.calc_direction(W) == a.direction(N)); - fm_assert(&a.calc_direction(N) == a.direction(N)); - fm_assert(a.frames(N, Wall::Group_::wall).size() >= 3); - fm_assert(a.group(N, Wall::Group_::top)->is_defined); - fm_assert(a.frames(N, Wall::Group_::wall)[0].size == Vector2ui(Vector2i{iTILE_SIZE.x(), iTILE_SIZE.z()})); + auto& wall = *loader.wall_atlas(name, false); + fm_assert(wall.name() == name); + fm_assert(wall.info().depth == 20); + fm_assert(wall.raw_frame_array().size() >= 3); + fm_assert(!wall.direction(W)); + fm_assert(wall.direction(N)); + fm_assert(&wall.calc_direction(W) == wall.direction(N)); + fm_assert(&wall.calc_direction(N) == wall.direction(N)); + fm_assert(wall.frames(N, Wall::Group_::wall).size() >= 3); + fm_assert(wall.group(N, Wall::Group_::top)->is_defined); + fm_assert(wall.frames(N, Wall::Group_::wall)[0].size == Vector2ui(Vector2i{iTILE_SIZE.x(), iTILE_SIZE.z()})); + fm_assert(&wall.calc_direction(N) == wall.direction(N)); + fm_assert(&wall.calc_direction(W) == wall.direction(N)); } +} // namespace + +void test_app::test_wall_atlas2() +{ + test_empty_wall(); + test_concrete_wall(); +} + +// todo add test for wall-tileset-tool for making sure it generates the correct image pixels out of placeholder input + } // namespace floormat diff --git a/wall-tileset-tool/main.cpp b/wall-tileset-tool/main.cpp index f233941f..6287066c 100644 --- a/wall-tileset-tool/main.cpp +++ b/wall-tileset-tool/main.cpp @@ -11,6 +11,7 @@ #include "loader/loader.hpp" #include #include +#include #include #include #include @@ -86,7 +87,9 @@ bool convert_to_bgra32(const cv::Mat& src, cv::Mat4b& dest) bool save_image(state st) { - fm_assert(st.new_atlas.frames.empty()); + fm_assert(st.new_atlas.frames.isEmpty()); + arrayReserve(st.new_atlas.frames, 64); + uint32_t max_height = 0; for (const auto& group : st.groups) { @@ -136,7 +139,9 @@ bool save_image(state st) auto rect = cv::Rect{(int)frame.offset.x(), (int)frame.offset.y(), (int)frame.size.x(), (int)frame.size.y()}; frame.mat.copyTo(st.dest(rect)); - st.new_atlas.frames.push_back({.offset = frame.offset, .size = frame.size}); + arrayAppend(st.new_atlas.frames, Wall::Frame { + .offset = frame.offset, .size = frame.size + }); } } @@ -155,7 +160,7 @@ bool save_image(state st) bool save_json(state st) { using namespace floormat::Wall::detail; - fm_assert(!st.new_atlas.frames.empty()); + fm_assert(!st.new_atlas.frames.isEmpty()); fm_assert(st.new_atlas.header.depth > 0); auto filename = ""_s.join({Path::join(st.opts.output_dir, st.new_atlas.header.name), ".json"_s}); st.new_atlas.serialize(filename); @@ -286,7 +291,7 @@ bool do_direction(state& st, size_t i) return false; } - st.new_atlas.direction_array.push_back(std::move(dir)); + arrayAppend(st.new_atlas.direction_array, std::move(dir)); return true; } @@ -304,7 +309,8 @@ bool do_input_file(state& st) fm_assert(!atlas.frames.size()); fm_assert(!atlas.direction_mask.any()); fm_assert(atlas.direction_map == std::array{}); - fm_assert(atlas.direction_array.empty()); + fm_assert(atlas.direction_array.isEmpty()); + arrayReserve(atlas.direction_array, Direction_COUNT); for (auto i = 0uz; i < Direction_COUNT; i++) { @@ -399,7 +405,7 @@ int main(int argc, char** argv) uint32_t n_frames = 0; auto groups = std::vector{}; - groups.reserve(std::size(Wall::Direction::groups)); + groups.reserve(Wall::Group_COUNT); for (auto [name, ptr, val] : Wall::Direction::groups) { -- cgit v1.2.3