summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-04-08 17:05:16 +0200
committerStanislaw Halik <sthalik@misaki.pl>2024-04-08 19:40:10 +0200
commit064379bd0bd929f6b87c50f740e9a783b4d9e054 (patch)
treeb717428ace85bde06fff19ac96b11d95787b538f
parent4eefaf4e12199c071d2e6ee0d99b46d2e1d45557 (diff)
a
-rw-r--r--editor/draw.cpp2
-rw-r--r--editor/inspect-types.cpp10
-rw-r--r--editor/inspect.cpp6
-rw-r--r--editor/update.cpp7
-rw-r--r--editor/wall-editor.cpp4
-rw-r--r--entity/accessor.hpp2
-rw-r--r--entity/erased-constraints.cpp14
-rw-r--r--loader/atlas-loader.inl40
-rw-r--r--loader/policy.hpp2
-rw-r--r--serialize/anim.cpp5
-rw-r--r--serialize/atlas-type.hpp2
-rw-r--r--serialize/old-savegame.cpp27
-rw-r--r--serialize/savegame.cpp36
-rw-r--r--serialize/scenery.cpp6
-rw-r--r--shaders/lightmap.cpp3
-rw-r--r--src/anim.cpp5
-rw-r--r--src/anim.hpp2
-rw-r--r--src/chunk-collision.cpp3
-rw-r--r--src/chunk-walls.cpp5
-rw-r--r--src/critter.cpp6
-rw-r--r--src/light-falloff.hpp3
-rw-r--r--src/object.hpp4
-rw-r--r--src/pass-mode.hpp3
-rw-r--r--src/rotation.hpp2
-rw-r--r--src/scenery.cpp15
-rw-r--r--src/scenery.hpp2
-rw-r--r--src/wall-atlas.cpp6
-rw-r--r--test/serializer.cpp8
28 files changed, 123 insertions, 107 deletions
diff --git a/editor/draw.cpp b/editor/draw.cpp
index 63bc02e8..249bf72c 100644
--- a/editor/draw.cpp
+++ b/editor/draw.cpp
@@ -60,7 +60,7 @@ void app::draw_cursor()
{
case rotation::N: draw(_wireframe->wall_n, TILE_SIZE); break;
case rotation::W: draw(_wireframe->wall_w, TILE_SIZE); break;
- default: std::unreachable();
+ default: fm_assert(false);
}
}
else if (const auto* ed = _editor->current_scenery_editor())
diff --git a/editor/inspect-types.cpp b/editor/inspect-types.cpp
index 331b82a7..be8851ce 100644
--- a/editor/inspect-types.cpp
+++ b/editor/inspect-types.cpp
@@ -277,13 +277,17 @@ template bool inspect_type(light&, inspect_intent_t);
bool inspect_object_subtype(object& x)
{
- switch (auto type = x.type())
+ const auto type = x.type();
+ switch (type)
{
- default: fm_warn_once("unknown object subtype '%d'", (int)type); return false;
case object_type::scenery: return inspect_type(static_cast<scenery&>(x), inspect_intent_t{});
case object_type::critter: return inspect_type(static_cast<critter&>(x), inspect_intent_t{});
- case object_type::light: return inspect_type(static_cast<light&>(x), inspect_intent_t{});
+ case object_type::light: return inspect_type(static_cast<light&>(x), inspect_intent_t{});
+ case object_type::COUNT: break;
+ case object_type::none: break;
}
+ fm_warn_once("unknown object subtype '%d'", (int)type);
+ return false;
}
} // namespace floormat::entities
diff --git a/editor/inspect.cpp b/editor/inspect.cpp
index c4345bcf..470c5bd2 100644
--- a/editor/inspect.cpp
+++ b/editor/inspect.cpp
@@ -75,13 +75,15 @@ bool do_inspect_field(void* datum, const erased_accessor& accessor, field_repr r
char buf[128];
bool should_disable = false;
- switch (accessor.is_enabled(datum))
+ const auto enabled = accessor.is_enabled(datum);
+ fm_assert(enabled < field_status::COUNT);
+ switch (enabled)
{
using enum field_status;
+ case COUNT: fm_assert(false);
case hidden: return false;
case readonly: should_disable = true; break;
case enabled: should_disable = false; break;
- default: fm_assert(false);
}
should_disable = should_disable || !accessor.can_write();
[[maybe_unused]] auto disabler = begin_disabled(should_disable);
diff --git a/editor/update.cpp b/editor/update.cpp
index a4b9bbcd..823c8c01 100644
--- a/editor/update.cpp
+++ b/editor/update.cpp
@@ -55,7 +55,7 @@ void app::do_mouse_up_down(uint8_t button, bool is_down, int mods)
{
switch (_editor->mode())
{
- default:
+ case editor_mode::tests:
break;
case editor_mode::none:
if (button == mouse_button_left)
@@ -78,8 +78,8 @@ void app::do_mouse_up_down(uint8_t button, bool is_down, int mods)
case editor_mode::floor:
case editor_mode::walls:
case editor_mode::scenery:
- case editor_mode::vobj:
- auto pos = *cursor.tile;
+ case editor_mode::vobj: {
+ const auto pos = *cursor.tile;
switch (button)
{
case mouse_button_left:
@@ -92,6 +92,7 @@ void app::do_mouse_up_down(uint8_t button, bool is_down, int mods)
}
break;
}
+ }
}
_editor->on_release();
}
diff --git a/editor/wall-editor.cpp b/editor/wall-editor.cpp
index 58054b15..99d47643 100644
--- a/editor/wall-editor.cpp
+++ b/editor/wall-editor.cpp
@@ -83,7 +83,7 @@ void wall_editor::place_tile(world& w, global_coords coords, const std::shared_p
{
case rotation::N: t.wall_north() = { atlas, (variant_t)-1 }; break;
case rotation::W: t.wall_west() = { atlas, (variant_t)-1 }; break;
- default: std::unreachable();
+ default: fm_assert(false);
}
//c.mark_walls_modified();
for (int y = -1; y <= 1; y++)
@@ -102,7 +102,7 @@ editor_snap_mode wall_editor::check_snap(int mods) const
else if (_r == rotation::W)
return editor_snap_mode::vertical;
else
- std::unreachable();
+ fm_assert(false);
}
} // namespace floormat
diff --git a/entity/accessor.hpp b/entity/accessor.hpp
index 6bd512f4..9dd9c3b6 100644
--- a/entity/accessor.hpp
+++ b/entity/accessor.hpp
@@ -15,7 +15,7 @@ struct group;
namespace floormat::entities {
-enum class field_status : unsigned char { hidden, readonly, enabled, };
+enum class field_status : unsigned char { hidden, readonly, enabled, COUNT, };
struct erased_accessor final {
using reader_t = void;
diff --git a/entity/erased-constraints.cpp b/entity/erased-constraints.cpp
index bb665307..6e81820a 100644
--- a/entity/erased-constraints.cpp
+++ b/entity/erased-constraints.cpp
@@ -151,15 +151,15 @@ bool operator==(const range& a, const range& b)
switch (a.type)
{
- default: return false;
- case range::type_none: return true;
- case range::type_float: return std::fabs(a.min.f - b.min.f) < eps && std::fabs(a.max.f - b.max.f) < eps;
- case range::type_uint: return a.min.u == b.min.u && a.max.u == b.max.u;
- case range::type_int: return a.min.i == b.min.i && a.max.i == b.max.i;
+ case range::type_none: return true;
+ case range::type_float: return std::fabs(a.min.f - b.min.f) < eps && std::fabs(a.max.f - b.max.f) < eps;
+ case range::type_uint: return a.min.u == b.min.u && a.max.u == b.max.u;
+ case range::type_int: return a.min.i == b.min.i && a.max.i == b.max.i;
case range::type_float4: return a.min.f4 == b.min.f4 && a.max.f4 == b.max.f4;
- case range::type_uint4: return a.min.u4 == b.min.u4 && a.max.u4 == b.max.u4;
- case range::type_int4: return a.min.i4 == b.min.i4 && a.max.i4 == b.max.i4;
+ case range::type_uint4: return a.min.u4 == b.min.u4 && a.max.u4 == b.max.u4;
+ case range::type_int4: return a.min.i4 == b.min.i4 && a.max.i4 == b.max.i4;
}
+ fm_assert(false);
}
} // namespace floormat::entities::erased_constraints
diff --git a/loader/atlas-loader.inl b/loader/atlas-loader.inl
index 55691597..8f1d1db6 100644
--- a/loader/atlas-loader.inl
+++ b/loader/atlas-loader.inl
@@ -10,6 +10,11 @@
#include <cr/Optional.h>
#include <cr/GrowableArray.h>
+#ifdef __GNUG__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wswitch-default"
+#endif
+
namespace floormat::loader_detail {
template<typename ATLAS, typename TRAITS>
@@ -68,30 +73,21 @@ auto atlas_loader<ATLAS, TRAITS>::get_atlas(StringView name, const loader_policy
atlas_list();
const AtlasPtr& invalid_atlas = t.atlas_of(get_invalid_atlas());
- switch (p)
- {
- using enum loader_policy;
- case error:
- case ignore:
- case warn:
- break;
- default:
- fm_abort("invalid loader_policy (%d)", (int)p);
- }
- CORRADE_ASSUME(p <= loader_policy::ignore);
-
+ fm_assert(p < loader_policy::COUNT);
if (name == loader.INVALID) [[unlikely]]
+ {
switch (p)
{
using enum loader_policy;
- default:
- std::unreachable();
+ case COUNT: std::unreachable();
case error:
goto error;
case ignore:
case warn:
return invalid_atlas;
}
+ std::unreachable();
+ }
fm_soft_assert(loader.check_atlas_name(name));
@@ -102,14 +98,14 @@ auto atlas_loader<ATLAS, TRAITS>::get_atlas(StringView name, const loader_policy
switch (p)
{
using enum loader_policy;
- default:
- std::unreachable();
+ case COUNT: std::unreachable();
case error:
goto error;
case warn:
case ignore:
return invalid_atlas;
}
+ std::unreachable();
}
else
{
@@ -147,11 +143,12 @@ auto atlas_loader<ATLAS, TRAITS>::get_atlas(StringView name, const loader_policy
return t.atlas_of(c);
}
else
+ {
+ fm_assert(p < loader_policy::COUNT);
switch (p)
{
using enum loader_policy;
- default:
- std::unreachable();
+ case COUNT: std::unreachable();
case error:
goto error;
case warn:
@@ -159,7 +156,8 @@ auto atlas_loader<ATLAS, TRAITS>::get_atlas(StringView name, const loader_policy
case ignore:
return invalid_atlas;
}
-
+ std::unreachable();
+ }
std::unreachable();
fm_assert(false);
@@ -228,3 +226,7 @@ void atlas_loader<ATLAS, TRAITS>::register_cell(Cell&& c)
}
} // namespace floormat::loader_detail
+
+#ifdef __GNUG__
+#pragma GCC diagnostic pop
+#endif
diff --git a/loader/policy.hpp b/loader/policy.hpp
index 438b4248..9815886b 100644
--- a/loader/policy.hpp
+++ b/loader/policy.hpp
@@ -4,7 +4,7 @@ namespace floormat {
enum class loader_policy : uint8_t
{
- error, warn, ignore, DEFAULT = error,
+ error, warn, ignore, COUNT, DEFAULT = error,
};
} // namespace floormat
diff --git a/serialize/anim.cpp b/serialize/anim.cpp
index cd1f5e5c..5e2ed388 100644
--- a/serialize/anim.cpp
+++ b/serialize/anim.cpp
@@ -133,10 +133,11 @@ namespace nlohmann {
void adl_serializer<floormat::anim_scale>::to_json(json& j, const anim_scale val)
{
+ if (val.type >= anim_scale_type::COUNT) [[unlikely]]
+ fm_throw("invalid anim_scale_type '{}"_cf, (unsigned)val.type);
switch (val.type)
{
- default:
- fm_throw("invalid anim_scale_type '{}"_cf, (unsigned)val.type);
+ case anim_scale_type::COUNT: std::unreachable();
case anim_scale_type::invalid:
fm_throw("anim_scale is invalid"_cf);
case anim_scale_type::fixed:
diff --git a/serialize/atlas-type.hpp b/serialize/atlas-type.hpp
index 1d3ea5aa..ef8bf440 100644
--- a/serialize/atlas-type.hpp
+++ b/serialize/atlas-type.hpp
@@ -3,6 +3,6 @@
namespace floormat::Serialize {
enum class atlas_type : uint8_t
{
- none, ground, wall, anim, vobj,
+ none, ground, wall, anim, vobj, COUNT,
};
} // namespace floormat::Serialize
diff --git a/serialize/old-savegame.cpp b/serialize/old-savegame.cpp
index 111d29f3..46b83590 100644
--- a/serialize/old-savegame.cpp
+++ b/serialize/old-savegame.cpp
@@ -309,11 +309,11 @@ void reader_state::read_chunks(reader_t& s)
tile_ref t = c[i];
using uchar = uint8_t;
const auto make_atlas = [&]<typename T>() -> image_proto_<T> {
- atlasid id;
+ atlasid atlas_id;
if (PROTO < 8) [[unlikely]]
- id = flags & meta_short_atlasid_ ? atlasid{s.read<uchar>()} : s.read<atlasid>();
+ atlas_id = flags & meta_short_atlasid_ ? atlasid{s.read<uchar>()} : s.read<atlasid>();
else
- id << s;
+ atlas_id << s;
uint8_t v;
if (PROTO >= 2) [[likely]]
v << s;
@@ -321,20 +321,24 @@ void reader_state::read_chunks(reader_t& s)
v = flags & meta_short_variant_
? s.read<uint8_t>()
: uint8_t(s.read<uint16_t>());
- auto name = lookup_atlas(id);
+ auto name = lookup_atlas(atlas_id);
if constexpr(std::is_same_v<ground_atlas, T>)
{
auto atlas = loader.ground_atlas(name, asset_policy);
fm_soft_assert(v < atlas->num_tiles());
return { atlas, v };
}
- else if (std::is_same_v<wall_atlas, T>)
+ else if constexpr(std::is_same_v<wall_atlas, T>)
{
auto atlas = loader.wall_atlas(name, asset_policy);
return { atlas, v };
}
else
+ {
+ static_assert(sizeof T{} != (size_t)-1);
+ static_assert(sizeof T{} == (size_t)-1);
std::unreachable();
+ }
};
SET_CHUNK_SIZE();
//t.passability() = pass_mode(flags & pass_mask);
@@ -364,7 +368,6 @@ void reader_state::read_chunks(reader_t& s)
oid << s;
fm_soft_assert((oid & lowbits<collision_data_BITS, object_id>) == oid);
type = object_type(s.read<std::underlying_type_t<object_type>>());
- fm_soft_assert(type < object_type::COUNT);
}
else
{
@@ -373,6 +376,9 @@ void reader_state::read_chunks(reader_t& s)
fm_soft_assert(oid != 0);
type = object_type(_id >> 61);
}
+ if (type >= object_type::COUNT || type == object_type::none) [[unlikely]]
+ fm_throw("invalid_object_type '{}'"_cf, (int)type);
+
const auto local = local_coords{s.read<uint8_t>()};
Vector2b offset;
@@ -388,6 +394,7 @@ void reader_state::read_chunks(reader_t& s)
s >> e.bbox_size[1];
};
SET_CHUNK_SIZE();
+
switch (type)
{
case object_type::critter: {
@@ -409,8 +416,8 @@ void reader_state::read_chunks(reader_t& s)
if (PROTO >= 9) [[likely]]
{
- uint32_t id; id << s;
- auto name = lookup_string(id);
+ uint32_t string_id; string_id << s;
+ auto name = lookup_string(string_id);
fm_soft_assert(name.size() < critter_name_max);
proto.name = name;
}
@@ -527,8 +534,8 @@ void reader_state::read_chunks(reader_t& s)
(void)L;
break;
}
- default:
- fm_throw("invalid_object_type '{}'"_cf, (int)type);
+ case object_type::none:
+ case object_type::COUNT: std::unreachable();
}
}
diff --git a/serialize/savegame.cpp b/serialize/savegame.cpp
index 912bb2c5..5a77db0f 100644
--- a/serialize/savegame.cpp
+++ b/serialize/savegame.cpp
@@ -150,9 +150,12 @@ struct visitor_
template<typename F>
void visit_object_internal(object& obj, F&& f, object_id id, object_type type, chunk_coords_ ch)
{
- non_const(obj.id) = id;
+ if (type >= object_type::COUNT || type == object_type::none) [[unlikely]]
+ fm_throw("invalid object type {}"_cf, (int)type);
switch (type)
{
+ case object_type::none:
+ case object_type::COUNT: std::unreachable();
case object_type::light:
static_cast<Derived&>(*this).visit(non_const(obj.atlas), atlas_type::vobj, f);
break;
@@ -160,19 +163,15 @@ struct visitor_
case object_type::critter:
static_cast<Derived&>(*this).visit(non_const(obj.atlas), atlas_type::anim, f);
break;
- case object_type::none:
- case object_type::COUNT:
- default:
- break;
+
}
- if (!obj.atlas)
- fm_throw("invalid object type {}"_cf, (int)type);
- //do_visit(*obj.c, f);
+ fm_debug_assert(obj.atlas);
{ auto pt = obj.coord.local();
do_visit(pt, f);
non_const(obj.coord) = {ch, pt};
}
+ non_const(obj.id) = id;
do_visit_nonconst(obj.offset, f);
do_visit_nonconst(obj.bbox_offset, f);
do_visit_nonconst(obj.bbox_size, f);
@@ -190,14 +189,10 @@ struct visitor_
switch (type)
{
+ default: break;
case object_type::critter: do_visit(static_cast<critter&>(obj), f); return;
case object_type::scenery: do_visit(static_cast<scenery&>(obj), f); return;
case object_type::light: do_visit(static_cast<light&>(obj), f); return;
- case object_type::COUNT:
- case object_type::none:
- break;
- default:
- fm_abort("invalid object type '%d'", (int)type);
}
}
@@ -455,16 +450,19 @@ struct writer final : visitor_<writer>
StringView name;
+ if (type >= atlas_type::COUNT || type == atlas_type::none) [[unlikely]]
+ fm_abort("invalid atlas type '%d'", (int)type);
switch (type)
{
- case atlas_type::ground: name = static_cast<const ground_atlas*>(atlas)->name(); break;
- case atlas_type::wall: name = static_cast<const wall_atlas*>(atlas)->name(); break;
+ case atlas_type::ground:
+ name = static_cast<const ground_atlas*>(atlas)->name(); break;
+ case atlas_type::wall:
+ name = static_cast<const wall_atlas*>(atlas)->name(); break;
case atlas_type::vobj:
case atlas_type::anim:
- name = static_cast<const anim_atlas*>(atlas)->name();
- break;
- default:
- fm_abort("invalid atlas type '%d'", (int)type);
+ name = static_cast<const anim_atlas*>(atlas)->name(); break;
+ case atlas_type::none:
+ case atlas_type::COUNT: std::unreachable();
}
do_visit(intern_string(name), f);
}
diff --git a/serialize/scenery.cpp b/serialize/scenery.cpp
index 080d0f71..5950ddf3 100644
--- a/serialize/scenery.cpp
+++ b/serialize/scenery.cpp
@@ -151,10 +151,12 @@ void adl_serializer<scenery_proto>::from_json(const json& j, scenery_proto& f)
fm_soft_assert(bbox_offset == Vector2i(Vector2b(bbox_offset)));
fm_soft_assert(bbox_size == Vector2ui(Vector2ub(bbox_size)));
+
+ fm_assert(type < scenery_type::COUNT);
switch (type)
{
- default:
- fm_throw("unhandled scenery type '{}'"_cf, (unsigned)type);
+ case scenery_type::none:
+ case scenery_type::COUNT: std::unreachable();
case scenery_type::generic: {
constexpr generic_scenery_proto G;
auto s = G;
diff --git a/shaders/lightmap.cpp b/shaders/lightmap.cpp
index bca81c6a..b3cd1e60 100644
--- a/shaders/lightmap.cpp
+++ b/shaders/lightmap.cpp
@@ -227,9 +227,10 @@ void lightmap_shader::add_light(Vector2 neighbor_offset, const light_s& light)
constexpr auto tile_size = TILE_SIZE2.sum()/2;
float range;
+ fm_assert(light.falloff < light_falloff::COUNT);
switch (light.falloff)
{
- default:
+ case light_falloff::COUNT: std::unreachable();
case light_falloff::constant:
range = TILE_MAX_DIM;
break;
diff --git a/src/anim.cpp b/src/anim.cpp
index cf2317bc..717b3ee6 100644
--- a/src/anim.cpp
+++ b/src/anim.cpp
@@ -8,10 +8,11 @@ Vector2 anim_scale::scale_to_(Vector2ui image_size) const
{
fm_soft_assert(image_size.product() > 0);
Vector2 ret;
+ if (type >= anim_scale_type::COUNT) [[unlikely]]
+ fm_throw("invalid anim_scale_type '{}'"_cf, (unsigned)type);
switch (type)
{
- default:
- fm_throw("invalid anim_scale_type '{}'"_cf, (unsigned)type);
+ case anim_scale_type::COUNT: std::unreachable();
case anim_scale_type::invalid:
fm_throw("anim_scale is invalid"_cf);
case anim_scale_type::fixed:
diff --git a/src/anim.hpp b/src/anim.hpp
index e22d1e6b..e850097f 100644
--- a/src/anim.hpp
+++ b/src/anim.hpp
@@ -29,7 +29,7 @@ struct anim_group final
Vector3b offset{};
};
-enum class anim_scale_type : unsigned char { invalid, ratio, fixed, };
+enum class anim_scale_type : unsigned char { invalid, ratio, fixed, COUNT, };
struct anim_scale final
{
diff --git a/src/chunk-collision.cpp b/src/chunk-collision.cpp
index 567be0ad..a7df3032 100644
--- a/src/chunk-collision.cpp
+++ b/src/chunk-collision.cpp
@@ -138,9 +138,10 @@ bool chunk::can_place_object(const object_proto& proto, local_coords pos)
{
(void)ensure_scenery_mesh();
+ fm_assert(proto.pass < pass_mode::COUNT);
switch (proto.pass)
{
- default:
+ case pass_mode::COUNT: std::unreachable();
case pass_mode::blocked:
case pass_mode::see_through:
break;
diff --git a/src/chunk-walls.cpp b/src/chunk-walls.cpp
index 13f42ead..c1214cb4 100644
--- a/src/chunk-walls.cpp
+++ b/src/chunk-walls.cpp
@@ -41,11 +41,11 @@ constexpr Quads::quad get_quad(Direction_ D, Group_ G, float depth)
constexpr float X = half_tile.x(), Y = half_tile.y(), Z = TILE_SIZE.z();
const bool is_west = D == Wall::Direction_::W;
+ fm_assert(G < Group_::COUNT);
switch (G)
{
using enum Group_;
- default:
- fm_abort("invalid wall_atlas group '%d'", (int)G);
+ case COUNT: std::unreachable();
case wall:
if (!is_west)
return {{
@@ -107,6 +107,7 @@ constexpr Quads::quad get_quad(Direction_ D, Group_ G, float depth)
{-X, -Y, Z },
}};
}
+ std::unreachable();
}
Array<Quads::indexes> make_indexes_()
diff --git a/src/critter.cpp b/src/critter.cpp
index d7fc8627..0fb3e406 100644
--- a/src/critter.cpp
+++ b/src/critter.cpp
@@ -26,7 +26,6 @@ constexpr auto arrows_to_dir(bool left, bool right, bool up, bool down)
switch (bits)
{
- default: std::unreachable(); // -Wswitch-default
using enum rotation;
case L | U: return W;
case L | D: return S;
@@ -47,6 +46,7 @@ constexpr auto arrows_to_dir(bool left, bool right, bool up, bool down)
case L|R:
return rotation{rotation_COUNT};
}
+ std::unreachable();
}
#if 0
static_assert(arrows_to_dir(true, false, false, false) == rotation::SW);
@@ -93,10 +93,8 @@ constexpr std::array<rotation, 3> rotation_to_similar(rotation r)
case SW: return { SW, S, W };
case W: return { W, SW, NW };
case NW: return { NW, W, N };
- default:
- std::unreachable();
- fm_assert(false);
}
+ std::unreachable();
}
template<rotation r> constexpr uint8_t get_length_axis()
diff --git a/src/light-falloff.hpp b/src/light-falloff.hpp
index f814cc5f..849ad92b 100644
--- a/src/light-falloff.hpp
+++ b/src/light-falloff.hpp
@@ -3,10 +3,9 @@
namespace floormat {
enum class light_falloff : uint8_t {
- constant = 1, linear = 0, quadratic = 2,
+ constant = 1, linear = 0, quadratic = 2, COUNT,
};
-constexpr inline light_falloff light_falloff_COUNT{3};
constexpr inline uint8_t light_falloff_BITS = 3;
constexpr inline uint8_t light_falloff_MASK = (1 << light_falloff_BITS)-1;
diff --git a/src/object.hpp b/src/object.hpp
index 4d2279e1..4c535340 100644
--- a/src/object.hpp
+++ b/src/object.hpp
@@ -24,8 +24,8 @@ struct object_proto
uint32_t delta = 0;
uint16_t frame = 0;
object_type type : 3 = object_type::none;
- rotation r : rotation_BITS = rotation::N;
- pass_mode pass : pass_mode_BITS = pass_mode::see_through; // todo move to struct scenery, add inherit bit
+ rotation r = rotation::N;
+ pass_mode pass = pass_mode::see_through; // todo move to struct scenery, add inherit bit
object_proto& operator=(const object_proto&);
object_proto();
diff --git a/src/pass-mode.hpp b/src/pass-mode.hpp
index 0bf8d867..60708a47 100644
--- a/src/pass-mode.hpp
+++ b/src/pass-mode.hpp
@@ -2,8 +2,7 @@
namespace floormat {
-enum class pass_mode : unsigned char { blocked, see_through, shoot_through, pass, };
-constexpr inline pass_mode pass_mode_COUNT{4};
+enum class pass_mode : unsigned char { blocked, see_through, shoot_through, pass, COUNT };
constexpr inline unsigned char pass_mode_BITS = 2;
} // namespace floormat
diff --git a/src/rotation.hpp b/src/rotation.hpp
index 471007c3..99f8c4a3 100644
--- a/src/rotation.hpp
+++ b/src/rotation.hpp
@@ -8,6 +8,6 @@ enum class rotation : unsigned char {
constexpr inline size_t rotation_BITS = 3;
constexpr inline size_t rotation_MASK = (1 << rotation_BITS)-1;
-constexpr inline rotation rotation_COUNT = rotation{1 << rotation_BITS};
+constexpr inline rotation rotation_COUNT = rotation{1 << rotation_BITS}; // todo! remove
} // namespace floormat
diff --git a/src/scenery.cpp b/src/scenery.cpp
index c5575f6a..484a84e9 100644
--- a/src/scenery.cpp
+++ b/src/scenery.cpp
@@ -181,14 +181,11 @@ bool scenery_proto::operator==(const object_proto& e0) const
return false;
return std::visit(
- [](const auto& a, const auto& b) {
- if constexpr(std::is_same_v< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >)
+ [](const auto& a, const auto& b) -> bool {
+ if constexpr(std::is_same_v<std::decay_t<decltype(a)>, std::decay_t<decltype(b)>>)
return a == b;
else
- {
- std::unreachable();
- return false;
- }
+ fm_assert(false);
},
subtype, sc.subtype
);
@@ -229,13 +226,13 @@ scenery_variants scenery::subtype_from_scenery_type(object_id id, class chunk& c
{
switch (type)
{
+ case scenery_type::none:
+ case scenery_type::COUNT:
+ break;
case scenery_type::generic:
return generic_scenery{id, c, {}};
case scenery_type::door:
return door_scenery{id, c, {}};
- case scenery_type::none:
- default:
- break;
}
fm_throw("invalid scenery type"_cf, (int)type);
}
diff --git a/src/scenery.hpp b/src/scenery.hpp
index e668f7a2..c7d2a92a 100644
--- a/src/scenery.hpp
+++ b/src/scenery.hpp
@@ -16,7 +16,7 @@ class anim_atlas;
class world;
enum class scenery_type : unsigned char {
- none, generic, door,
+ none, generic, door, COUNT,
};
struct generic_scenery_proto
diff --git a/src/wall-atlas.cpp b/src/wall-atlas.cpp
index d82aace3..8ea687e4 100644
--- a/src/wall-atlas.cpp
+++ b/src/wall-atlas.cpp
@@ -95,10 +95,10 @@ Vector2ui wall_atlas::expected_size(unsigned depth, Group_ group)
case side:
case corner:
return { depth, size.z() };
- default:
- std::unreachable();
- fm_assert(false);
+ case COUNT:
+ break;
}
+ fm_assert(false);
}
wall_atlas::wall_atlas(wall_atlas_def def, String path, const ImageView2D& img)
diff --git a/test/serializer.cpp b/test/serializer.cpp
index 86105d3b..c933a12f 100644
--- a/test/serializer.cpp
+++ b/test/serializer.cpp
@@ -85,9 +85,13 @@ void assert_chunks_equal(const chunk& a, const chunk& b)
{
const auto& ae = *a.objects()[i];
const auto& be = *b.objects()[i];
+ const auto type = ae.type();
fm_assert(ae.type() == be.type());
- switch (ae.type())
+ fm_assert(type < object_type::COUNT && type != object_type::none);
+ switch (type)
{
+ case object_type::none:
+ case object_type::COUNT: std::unreachable();
case object_type::critter: {
const auto& e1 = static_cast<const critter&>(ae);
const auto& e2 = static_cast<const critter&>(be);
@@ -109,8 +113,6 @@ void assert_chunks_equal(const chunk& a, const chunk& b)
fm_assert(p1 == p2);
break;
}
- default:
- fm_abort("invalid object type '%d'", (int)ae.type());
}
}
}