From e5a80257216d76f5033b4120f348f309ca7764f1 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Fri, 3 May 2024 18:42:09 +0200 Subject: a wip --- src/critter-script-empty.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++++ src/critter-script-walk.cpp | 62 +++++++++++++++++++++++++++++++++++++++ src/critter-script.cpp | 64 ---------------------------------------- src/critter-script.hpp | 8 ++++- src/critter-script.inl | 1 - src/critter.cpp | 8 ----- src/critter.hpp | 1 - src/script.cpp | 10 ++++++- src/script.hpp | 6 ++-- src/script.inl | 25 ++++++++-------- 10 files changed, 165 insertions(+), 90 deletions(-) create mode 100644 src/critter-script-empty.cpp create mode 100644 src/critter-script-walk.cpp delete mode 100644 src/critter-script.cpp diff --git a/src/critter-script-empty.cpp b/src/critter-script-empty.cpp new file mode 100644 index 00000000..180189f8 --- /dev/null +++ b/src/critter-script-empty.cpp @@ -0,0 +1,70 @@ +#include "critter-script.inl" +#include "entity/name-of.hpp" + +namespace floormat { + +namespace { + +CORRADE_ALWAYS_INLINE +void touch_ptr(const std::shared_ptr& p) +{ + (void)p; +#if fm_ASAN + volatile char foo = *reinterpret_cast(&*p); + (void)foo; +//#else +// fm_debug_assert(p); +#endif +} + +struct empty_critter_script final : critter_script +{ + const void* type_id() const override; + void on_init(const std::shared_ptr& c) override; + void on_update(const std::shared_ptr& c, size_t& i, const Ns& dt) override; + void on_destroy(const std::shared_ptr& c, script_destroy_reason reason) override; + void delete_self() noexcept override; +}; + +constexpr StringView script_name = name_of; + +const void* empty_critter_script::type_id() const +{ + return &script_name; +} + +void empty_critter_script::on_init(const std::shared_ptr& p) +{ + DBG_nospace << "> init critter:" << (void*)&*p << " id:" << p->id << (p->name ? " name:" : "") << p->name; + touch_ptr(p); +} +void empty_critter_script::on_update(const std::shared_ptr& p, size_t&, const Ns&) +{ + //DBG_nospace << " update critter:" << (void*)&*p << " id:" << p->id << (p->name ? " name:" : "") << p->name; + touch_ptr(p); +} +void empty_critter_script::on_destroy(const std::shared_ptr& p, script_destroy_reason r) +{ + DBG_nospace << " destroy critter:" << (void*)&*p << " id:" << p->id << " reason:" << (int)r << (p->name ? " name:" : "") << p->name; + touch_ptr(p); +} +void empty_critter_script::delete_self() noexcept +{ + DBG_nospace << "< delete critter"; +} + +constinit empty_critter_script empty_script_ = {}; + +} // namespace + +template <> +critter_script* Script::make_empty() +{ + return &empty_script_; +} + +template class Script; + +critter_script::~critter_script() noexcept = default; + +} // namespace floormat diff --git a/src/critter-script-walk.cpp b/src/critter-script-walk.cpp new file mode 100644 index 00000000..9c92798c --- /dev/null +++ b/src/critter-script-walk.cpp @@ -0,0 +1,62 @@ +#include "critter-script.hpp" +//#include "raycast.hpp" +#include "point.hpp" +#include "critter.hpp" +#include "search-result.hpp" +#include "search-astar.hpp" +#include "entity/name-of.hpp" + +namespace floormat { + +namespace { + +enum class walk_mode : uint8_t +{ + none, line, path, +}; + +struct walk_script final : critter_script +{ + const void* type_id() const override; + void on_init(const std::shared_ptr& c) override; + void on_update(const std::shared_ptr& c, size_t& i, const Ns& dt) override; + void on_destroy(const std::shared_ptr& c, script_destroy_reason reason) override; + void delete_self() noexcept override; + + point to; + path_search_result path; + walk_mode mode = walk_mode::none; +}; + +constexpr StringView script_name = name_of; + +const void* walk_script::type_id() const +{ + return &script_name; +} + +void walk_script::on_init(const std::shared_ptr& c) +{ +} + +void walk_script::on_update(const std::shared_ptr& c, size_t& i, const Ns& dt) +{ +} + +void walk_script::on_destroy(const std::shared_ptr& c, script_destroy_reason reason) +{ +} + +void walk_script::delete_self() noexcept +{ + delete this; +} + +} // namespace + +critter_script* critter_script::make_walk_script(point to, path_search_result path) +{ + return new walk_script{}; +} + +} // namespace floormat diff --git a/src/critter-script.cpp b/src/critter-script.cpp deleted file mode 100644 index 9ab58aae..00000000 --- a/src/critter-script.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "critter-script.inl" -#include "compat/assert.hpp" - -namespace floormat { - -namespace { - -CORRADE_ALWAYS_INLINE -void touch_ptr(const std::shared_ptr& p) -{ - (void)p; -#if fm_ASAN - volatile char foo = *reinterpret_cast(&*p); - (void)foo; -//#else -// fm_debug_assert(p); -#endif -} - -struct empty_critter_script final : critter_script -{ - empty_critter_script(); - void on_init(const std::shared_ptr& c) override; - void on_update(const std::shared_ptr& c, size_t& i, const Ns& dt) override; - void on_destroy(const std::shared_ptr& c, script_destroy_reason reason) override; - void delete_self() noexcept override; -}; - -empty_critter_script::empty_critter_script() : critter_script{} {} -void empty_critter_script::on_init(const std::shared_ptr& p) -{ - DBG_nospace << "> init critter:" << (void*)&*p << " id:" << p->id << (p->name ? " name:" : "") << p->name; - touch_ptr(p); -} -void empty_critter_script::on_update(const std::shared_ptr& p, size_t&, const Ns&) -{ - //DBG_nospace << " update critter:" << (void*)&*p << " id:" << p->id << (p->name ? " name:" : "") << p->name; - touch_ptr(p); -} -void empty_critter_script::on_destroy(const std::shared_ptr& p, script_destroy_reason r) -{ - DBG_nospace << " destroy critter:" << (void*)&*p << " id:" << p->id << " reason:" << (int)r << (p->name ? " name:" : "") << p->name; - touch_ptr(p); -} -void empty_critter_script::delete_self() noexcept -{ - DBG_nospace << "< delete critter"; -} - -empty_critter_script empty_script_ = {}; - -} // namespace - -template <> -critter_script* Script::make_empty() -{ - return &empty_script_; -} - -template class Script; - -critter_script::~critter_script() noexcept = default; - -} // namespace floormat diff --git a/src/critter-script.hpp b/src/critter-script.hpp index 934e9154..dbfe9dd8 100644 --- a/src/critter-script.hpp +++ b/src/critter-script.hpp @@ -7,15 +7,21 @@ namespace floormat { struct critter; struct Ns; +struct point; +struct path_search_result; + struct critter_script : base_script { + constexpr critter_script() noexcept = default; ~critter_script() noexcept override; virtual void on_init(const std::shared_ptr& c) = 0; + // todo can_activate, activate virtual void on_update(const std::shared_ptr& c, size_t& i, const Ns& dt) = 0; virtual void on_destroy(const std::shared_ptr& c, script_destroy_reason reason) = 0; virtual void delete_self() = 0; - // todo can_activate, activate + + [[nodiscard]] static critter_script* make_walk_script(point to, path_search_result path); }; } // namespace floormat diff --git a/src/critter-script.inl b/src/critter-script.inl index 01ce1e46..a9ce6561 100644 --- a/src/critter-script.inl +++ b/src/critter-script.inl @@ -2,7 +2,6 @@ #include "critter-script.hpp" #include "script.inl" #include "critter.hpp" -#include "compat/assert.hpp" namespace floormat { diff --git a/src/critter.cpp b/src/critter.cpp index b08c083c..b25aaea4 100644 --- a/src/critter.cpp +++ b/src/critter.cpp @@ -391,13 +391,6 @@ void critter::update(const std::shared_ptr& ptrʹ, size_t& i, const Ns& update_movement(i, dt, new_r); } } - else - update_nonplayable(i, dt); -} - -void critter::update_nonplayable(size_t& i, const Ns& dt) -{ - (void)i; (void)dt; (void)playable; } void critter::update_movement(size_t& i, const Ns& dt, rotation new_r) @@ -531,7 +524,6 @@ auto critter::move_toward(size_t& index, const Ns& dt, const point& dest) -> mov return { .blocked = false, .moved = moved }; } - object_type critter::type() const noexcept { return object_type::critter; } critter::operator critter_proto() const diff --git a/src/critter.hpp b/src/critter.hpp index 4b919122..c1e8ded0 100644 --- a/src/critter.hpp +++ b/src/critter.hpp @@ -34,7 +34,6 @@ struct critter final : object void update(const std::shared_ptr& ptr, size_t& i, const Ns& dt) override; void update_movement(size_t& i, const Ns& dt, rotation r); - void update_nonplayable(size_t& i, const Ns& dt); struct move_result { bool blocked, moved; }; [[nodiscard]] move_result move_toward(size_t& i, const Ns& dt, const point& dest); diff --git a/src/script.cpp b/src/script.cpp index 57df6e58..df9ba473 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -20,7 +20,15 @@ StringView base_script::state_name(script_lifecycle x) return names[(uint32_t)x]; } +void base_script::_assert_state(script_lifecycle old_state, script_lifecycle s, const char* file, int line) +{ + if (old_state != s) [[unlikely]] + fm_emit_abort(file, line, + "invalid state transition from '%s' to '%s'", + state_name(old_state).data(), + state_name(s).data()); +} + base_script::~base_script() noexcept = default; -base_script::base_script() noexcept = default; } // namespace floormat diff --git a/src/script.hpp b/src/script.hpp index b67553ec..755a40df 100644 --- a/src/script.hpp +++ b/src/script.hpp @@ -13,10 +13,12 @@ struct base_script fm_DECLARE_DELETED_COPY_ASSIGNMENT(base_script); fm_DECLARE_DELETED_MOVE_ASSIGNMENT(base_script); - base_script() noexcept; + constexpr base_script() noexcept = default; virtual ~base_script() noexcept; + virtual const void* type_id() const = 0; static StringView state_name(script_lifecycle x); + static void _assert_state(script_lifecycle old_state, script_lifecycle s, const char* file, int line); }; template @@ -24,7 +26,6 @@ class Script final { S* ptr; script_lifecycle _state; - void _assert_state(script_lifecycle s, const char* file, int line); static S* make_empty(); public: @@ -51,6 +52,7 @@ public: void do_create(S* ptr); void do_initialize(const std::shared_ptr& obj); void do_reassign(S* ptr, const std::shared_ptr& obj); + void do_clear(const std::shared_ptr& obj); void do_destroy_pre(const std::shared_ptr& obj, script_destroy_reason r); void do_finish_destroy(); void do_ensure_torn_down(); diff --git a/src/script.inl b/src/script.inl index a6c93588..afa84e65 100644 --- a/src/script.inl +++ b/src/script.inl @@ -33,7 +33,7 @@ void concept_check() {} namespace floormat { -#define FM_ASSERT_SCRIPT_STATE(new_state) (Script::_assert_state((new_state), __FILE__, __LINE__)) +#define FM_ASSERT_SCRIPT_STATE(new_state) (base_script::_assert_state(_state, (new_state), __FILE__, __LINE__)) template Script::~Script() noexcept { @@ -60,16 +60,6 @@ Script::Script(): ptr{nullptr}, _state{script_lifecycle::no_init} detail_Script::concept_check(); } -template -void Script::_assert_state(script_lifecycle s, const char* file, int line) -{ - if (_state != s) [[unlikely]] - fm_emit_abort(file, line, - "invalid state transition from '%s' to '%s'", - base_script::state_name(_state).data(), - base_script::state_name(s).data()); -} - template script_lifecycle Script::state() const { return _state; } template @@ -111,7 +101,8 @@ void Script::do_initialize(const std::shared_ptr& obj) template void Script::do_reassign(S* p, const std::shared_ptr& obj) { - fm_assert(p); + if (!p) [[unlikely]] + return do_clear(obj); FM_ASSERT_SCRIPT_STATE(script_lifecycle::created); fm_debug_assert(ptr); ptr->on_destroy(obj, script_destroy_reason::unassign); @@ -120,6 +111,16 @@ void Script::do_reassign(S* p, const std::shared_ptr& obj) p->on_init(obj); } +template +void Script::do_clear(const std::shared_ptr& obj) +{ + FM_ASSERT_SCRIPT_STATE(script_lifecycle::created); + fm_debug_assert(ptr); + ptr->on_destroy(obj, script_destroy_reason::unassign); + ptr->delete_self(); + ptr = make_empty(); +} + template void Script::do_destroy_pre(const std::shared_ptr& obj, script_destroy_reason r) { -- cgit v1.2.3