summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-05-03 18:42:09 +0200
committerStanislaw Halik <sthalik@misaki.pl>2024-05-05 03:16:22 +0200
commite5a80257216d76f5033b4120f348f309ca7764f1 (patch)
tree6544f3ada808214beb7915704f317aba98966e88
parentba91cb1393274072721e1c31db0c7f73dc9c9db7 (diff)
a wip
-rw-r--r--src/critter-script-empty.cpp (renamed from src/critter-script.cpp)14
-rw-r--r--src/critter-script-walk.cpp62
-rw-r--r--src/critter-script.hpp8
-rw-r--r--src/critter-script.inl1
-rw-r--r--src/critter.cpp8
-rw-r--r--src/critter.hpp1
-rw-r--r--src/script.cpp10
-rw-r--r--src/script.hpp6
-rw-r--r--src/script.inl25
9 files changed, 105 insertions, 30 deletions
diff --git a/src/critter-script.cpp b/src/critter-script-empty.cpp
index 9ab58aae..180189f8 100644
--- a/src/critter-script.cpp
+++ b/src/critter-script-empty.cpp
@@ -1,5 +1,5 @@
#include "critter-script.inl"
-#include "compat/assert.hpp"
+#include "entity/name-of.hpp"
namespace floormat {
@@ -19,14 +19,20 @@ void touch_ptr(const std::shared_ptr<critter>& p)
struct empty_critter_script final : critter_script
{
- empty_critter_script();
+ const void* type_id() const override;
void on_init(const std::shared_ptr<critter>& c) override;
void on_update(const std::shared_ptr<critter>& c, size_t& i, const Ns& dt) override;
void on_destroy(const std::shared_ptr<critter>& c, script_destroy_reason reason) override;
void delete_self() noexcept override;
};
-empty_critter_script::empty_critter_script() : critter_script{} {}
+constexpr StringView script_name = name_of<empty_critter_script>;
+
+const void* empty_critter_script::type_id() const
+{
+ return &script_name;
+}
+
void empty_critter_script::on_init(const std::shared_ptr<critter>& p)
{
DBG_nospace << "> init critter:" << (void*)&*p << " id:" << p->id << (p->name ? " name:" : "") << p->name;
@@ -47,7 +53,7 @@ void empty_critter_script::delete_self() noexcept
DBG_nospace << "< delete critter";
}
-empty_critter_script empty_script_ = {};
+constinit empty_critter_script empty_script_ = {};
} // namespace
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<critter>& c) override;
+ void on_update(const std::shared_ptr<critter>& c, size_t& i, const Ns& dt) override;
+ void on_destroy(const std::shared_ptr<critter>& 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<walk_script>;
+
+const void* walk_script::type_id() const
+{
+ return &script_name;
+}
+
+void walk_script::on_init(const std::shared_ptr<critter>& c)
+{
+}
+
+void walk_script::on_update(const std::shared_ptr<critter>& c, size_t& i, const Ns& dt)
+{
+}
+
+void walk_script::on_destroy(const std::shared_ptr<critter>& 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.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<critter>& c) = 0;
+ // todo can_activate, activate
virtual void on_update(const std::shared_ptr<critter>& c, size_t& i, const Ns& dt) = 0;
virtual void on_destroy(const std::shared_ptr<critter>& 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<object>& 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<object>& 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<typename S, typename Obj>
@@ -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>& obj);
void do_reassign(S* ptr, const std::shared_ptr<Obj>& obj);
+ void do_clear(const std::shared_ptr<Obj>& obj);
void do_destroy_pre(const std::shared_ptr<Obj>& 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<S, Obj>::_assert_state((new_state), __FILE__, __LINE__))
+#define FM_ASSERT_SCRIPT_STATE(new_state) (base_script::_assert_state(_state, (new_state), __FILE__, __LINE__))
template <typename S, typename Obj> Script<S, Obj>::~Script() noexcept
{
@@ -60,16 +60,6 @@ Script<S, Obj>::Script(): ptr{nullptr}, _state{script_lifecycle::no_init}
detail_Script::concept_check<S, Obj>();
}
-template <typename S, typename Obj>
-void Script<S, Obj>::_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 <typename S, typename Obj> script_lifecycle Script<S, Obj>::state() const { return _state; }
template <typename S, typename Obj>
@@ -111,7 +101,8 @@ void Script<S, Obj>::do_initialize(const std::shared_ptr<Obj>& obj)
template <typename S, typename Obj>
void Script<S, Obj>::do_reassign(S* p, const std::shared_ptr<Obj>& 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);
@@ -121,6 +112,16 @@ void Script<S, Obj>::do_reassign(S* p, const std::shared_ptr<Obj>& obj)
}
template <typename S, typename Obj>
+void Script<S, Obj>::do_clear(const std::shared_ptr<Obj>& 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 <typename S, typename Obj>
void Script<S, Obj>::do_destroy_pre(const std::shared_ptr<Obj>& obj, script_destroy_reason r)
{
FM_ASSERT_SCRIPT_STATE(script_lifecycle::created);