summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-05-02 18:32:22 +0200
committerStanislaw Halik <sthalik@misaki.pl>2024-05-02 22:54:16 +0200
commitb93032e49cd69da178984f9912205d182f12f61e (patch)
tree2caae8f9db5776a39a731e8fb82ed30ec7fb6b06
parent6abcd7d52cda334c58ec999d212491fc24f13c9d (diff)
now call script update
-rw-r--r--editor/update.cpp28
-rw-r--r--src/critter-script.cpp2
-rw-r--r--src/critter.cpp12
-rw-r--r--src/critter.hpp2
-rw-r--r--src/light.cpp2
-rw-r--r--src/light.hpp2
-rw-r--r--src/object.cpp35
-rw-r--r--src/object.hpp7
-rw-r--r--src/scenery.cpp4
-rw-r--r--src/scenery.hpp4
-rw-r--r--src/script-enums.hpp18
-rw-r--r--src/script.hpp18
-rw-r--r--src/script.inl31
-rw-r--r--src/world.hpp2
-rw-r--r--test/save.cpp4
15 files changed, 116 insertions, 55 deletions
diff --git a/editor/update.cpp b/editor/update.cpp
index 0fe064c0..1e47d197 100644
--- a/editor/update.cpp
+++ b/editor/update.cpp
@@ -240,20 +240,24 @@ void app::update_world(Ns dt)
continue;
auto& c = *cʹ;
const auto& es = c.objects();
- auto size = es.size();
- for (auto i = 0uz; i < size; i++)
+ auto size = (uint32_t)es.size();
+ for (auto i = 0u; i < size; i++)
{
- auto& e = *es[i];
- if (e.last_frame_no == frame_no) [[unlikely]]
- continue;
- e.last_frame_no = frame_no;
- const auto* const ch = &e.chunk();
- size_t index = i;
- e.update(index, dt);
- if (&e.chunk() != ch || (uint32_t)index > i) [[unlikely]]
+ auto eʹ = es[i];
+ auto index = size_t{i};
+ {
+ auto& e = *eʹ;
+ if (e.last_frame_no == frame_no) [[unlikely]]
+ continue;
+ e.last_frame_no = frame_no;
+ }
{
- i--;
- size = es.size();
+ eʹ->update(eʹ, index, dt);
+ if (&eʹ->chunk() != cʹ || index > i) [[unlikely]]
+ {
+ i--;
+ size = (uint32_t)es.size();
+ }
}
}
}
diff --git a/src/critter-script.cpp b/src/critter-script.cpp
index b222f628..a10694fd 100644
--- a/src/critter-script.cpp
+++ b/src/critter-script.cpp
@@ -34,7 +34,7 @@ void empty_critter_script::on_init(const std::shared_ptr<critter>& p)
}
void empty_critter_script::on_update(const std::shared_ptr<critter>& p, size_t&, const Ns&)
{
- DBG_nospace << " update critter:" << (void*)&*p << " id:" << p->id << (p->name ? " name:" : "") << p->name;
+ //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<critter>& p, script_destroy_reason r)
diff --git a/src/critter.cpp b/src/critter.cpp
index f743f614..18f91797 100644
--- a/src/critter.cpp
+++ b/src/critter.cpp
@@ -1,4 +1,6 @@
#include "critter.hpp"
+
+#include "critter-script.hpp"
#include "compat/limits.hpp"
#include "tile-constants.hpp"
#include "src/point.inl"
@@ -361,8 +363,15 @@ Vector2 critter::ordinal_offset(Vector2b offset) const
return Vector2(offset);
}
-void critter::update(size_t& i, const Ns& dt)
+void critter::update(const std::shared_ptr<object>& ptrʹ, size_t& i, const Ns& dt)
{
+ fm_debug_assert(&*ptrʹ == this);
+
+ check_script_update_1(script.state());
+ script->on_update(std::static_pointer_cast<critter>(ptrʹ), i, dt);
+ if (check_script_update_2(script.state())) [[unlikely]]
+ return;
+
if (playable) [[unlikely]]
{
movement.AUTO &= !(movement.L | movement.R | movement.U | movement.D);
@@ -546,7 +555,6 @@ critter::critter(object_id id, class chunk& c, critter_proto proto) :
critter::~critter() noexcept
{
- //fm_assert(!script);
}
void critter::init_script(const std::shared_ptr<object>& ptrʹ)
diff --git a/src/critter.hpp b/src/critter.hpp
index 954499c3..4b919122 100644
--- a/src/critter.hpp
+++ b/src/critter.hpp
@@ -32,7 +32,7 @@ struct critter final : object
object_type type() const noexcept override;
explicit operator critter_proto() const;
- void update(size_t& i, const Ns& dt) override;
+ 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);
diff --git a/src/light.cpp b/src/light.cpp
index 4f280d97..e6de08a6 100644
--- a/src/light.cpp
+++ b/src/light.cpp
@@ -56,7 +56,7 @@ light::operator light_proto() const
}
object_type light::type() const noexcept { return object_type::light; }
-void light::update(size_t&, const Ns&) {}
+void light::update(const std::shared_ptr<object>&, size_t&, const Ns&) {}
bool light::is_dynamic() const { return true; }
bool light::is_virtual() const { return true; }
diff --git a/src/light.hpp b/src/light.hpp
index ea65a23f..aeee5d88 100644
--- a/src/light.hpp
+++ b/src/light.hpp
@@ -35,7 +35,7 @@ struct light final : object
Vector2 ordinal_offset(Vector2b offset) const override;
float depth_offset() const override;
object_type type() const noexcept override;
- void update(size_t& i, const Ns& dt) override;
+ void update(const std::shared_ptr<object>& ptr, size_t& i, const Ns& dt) override;
bool is_dynamic() const override;
bool is_virtual() const override;
diff --git a/src/object.cpp b/src/object.cpp
index f4c803b7..1bc6e015 100644
--- a/src/object.cpp
+++ b/src/object.cpp
@@ -365,4 +365,39 @@ void object::init_script(const std::shared_ptr<object>&) {}
void object::destroy_script_pre(const std::shared_ptr<object>&, script_destroy_reason) {}
void object::destroy_script_post() {}
+void object::check_script_update_1(script_lifecycle state)
+{
+ switch (state)
+ {
+ case script_lifecycle::no_init:
+ //return; // for tests?
+ case script_lifecycle::COUNT:
+ case script_lifecycle::destroying:
+ case script_lifecycle::initializing:
+ case script_lifecycle::torn_down:
+ break;
+ case script_lifecycle::created:
+ return;
+ }
+ fm_abort("bad script state %d in update() #1", (int)state);
+}
+
+bool object::check_script_update_2(script_lifecycle state)
+{
+ switch (state)
+ {
+ case script_lifecycle::no_init:
+ // bad = false; break; // for tests?
+ case script_lifecycle::COUNT:
+ case script_lifecycle::destroying:
+ case script_lifecycle::initializing:
+ break;
+ case script_lifecycle::torn_down:
+ return true;
+ case script_lifecycle::created:
+ return false;
+ }
+ fm_abort("bad script state %d in update() #2", (int)state);
+}
+
} // namespace floormat
diff --git a/src/object.hpp b/src/object.hpp
index d2607626..9de6e880 100644
--- a/src/object.hpp
+++ b/src/object.hpp
@@ -6,7 +6,7 @@
#include "src/object-type.hpp"
#include "src/object-id.hpp"
#include "src/point.hpp"
-#include "src/script.hpp"
+#include "src/script-enums.hpp"
#include <memory>
namespace floormat {
@@ -75,7 +75,7 @@ struct object
virtual object_type type() const noexcept = 0;
virtual bool can_activate(size_t i) const;
virtual bool activate(size_t i);
- virtual void update(size_t& i, const Ns& dt) = 0;
+ virtual void update(const std::shared_ptr<object>& self, size_t& i, const Ns& dt) = 0;
void rotate(size_t i, rotation r);
bool can_rotate(global_coords coord, rotation new_r, rotation old_r, Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_size);
bool can_move_to(Vector2i delta, global_coords coord, Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_aize);
@@ -104,6 +104,9 @@ struct object
protected:
object(object_id id, class chunk& c, const object_proto& proto);
void set_bbox_(Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_size, pass_mode pass);
+
+ static void check_script_update_1(script_lifecycle state);
+ [[nodiscard]] static bool check_script_update_2(script_lifecycle state);
};
} // namespace floormat
diff --git a/src/scenery.cpp b/src/scenery.cpp
index 442b712c..c7d3b51d 100644
--- a/src/scenery.cpp
+++ b/src/scenery.cpp
@@ -47,7 +47,7 @@ scenery::scenery(object_id id, class chunk& c, const scenery_proto& proto) :
// ---------- generic_scenery ----------
-void generic_scenery::update(size_t&, const Ns&) {}
+void generic_scenery::update(const std::shared_ptr<object>&, size_t&, const Ns&) {}
Vector2 generic_scenery::ordinal_offset(Vector2b offset) const { return Vector2(offset); }
bool generic_scenery::can_activate(size_t) const { return interactive; }
bool generic_scenery::activate(size_t) { return false; }
@@ -76,7 +76,7 @@ generic_scenery::generic_scenery(object_id id, class chunk& c, const generic_sce
enum scenery_type door_scenery::scenery_type() const { return scenery_type::door; }
-void door_scenery::update(size_t&, const Ns& dt)
+void door_scenery::update(const std::shared_ptr<object>&, size_t&, const Ns& dt)
{
if (!atlas || !active)
return;
diff --git a/src/scenery.hpp b/src/scenery.hpp
index beb06db5..56675a93 100644
--- a/src/scenery.hpp
+++ b/src/scenery.hpp
@@ -27,7 +27,7 @@ struct generic_scenery final : scenery
bool active : 1 = false;
bool interactive : 1 = false;
- void update(size_t& i, const Ns& dt) override;
+ void update(const std::shared_ptr<object>& ptr, size_t& i, const Ns& dt) override;
Vector2 ordinal_offset(Vector2b offset) const override;
bool can_activate(size_t i) const override;
bool activate(size_t i) override;
@@ -47,7 +47,7 @@ struct door_scenery final : scenery
bool active : 1 = false;
bool interactive : 1 = false;
- void update(size_t& i, const Ns& dt) override;
+ void update(const std::shared_ptr<object>& ptr, size_t& i, const Ns& dt) override;
Vector2 ordinal_offset(Vector2b offset) const override;
bool can_activate(size_t i) const override;
bool activate(size_t i) override;
diff --git a/src/script-enums.hpp b/src/script-enums.hpp
new file mode 100644
index 00000000..0cf9548d
--- /dev/null
+++ b/src/script-enums.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+namespace floormat {
+
+enum class script_lifecycle : uint8_t
+{
+ no_init, initializing, created, destroying, torn_down, COUNT,
+};
+
+enum class script_destroy_reason : uint8_t
+{
+ quit, // game is being shut down
+ kill, // object is being deleted from the gameworld
+ unassign, // script is unassigned from object
+ COUNT,
+};
+
+} // namespace floormat
diff --git a/src/script.hpp b/src/script.hpp
index 5f657e28..b67553ec 100644
--- a/src/script.hpp
+++ b/src/script.hpp
@@ -1,4 +1,5 @@
#pragma once
+#include "script-enums.hpp"
#include "compat/defs.hpp"
#include <memory>
@@ -7,11 +8,6 @@ namespace floormat
struct object;
struct Ns;
-enum class script_lifecycle : uint8_t
-{
- no_init, initializing, created, destroying, torn_down, COUNT,
-};
-
struct base_script
{
fm_DECLARE_DELETED_COPY_ASSIGNMENT(base_script);
@@ -23,19 +19,11 @@ struct base_script
static StringView state_name(script_lifecycle x);
};
-enum class script_destroy_reason : uint8_t
-{
- quit, // game is being shut down
- kill, // object is being deleted from the gameworld
- unassign, // script is unassigned from object
- COUNT,
-};
-
template<typename S, typename Obj>
class Script final
{
S* ptr;
- script_lifecycle state;
+ script_lifecycle _state;
void _assert_state(script_lifecycle s, const char* file, int line);
static S* make_empty();
@@ -55,7 +43,9 @@ public:
// [torn-down] -> do_ensure_torn_down() -> [torn-down]
// * -> do_error_unwind() -> [torn-down]
// [torn-down] -> ~script()
+ // [no-init] -> ~script() // for tests
+ script_lifecycle state() const;
S* operator->();
void do_create(S* ptr);
diff --git a/src/script.inl b/src/script.inl
index a756bb08..e5057039 100644
--- a/src/script.inl
+++ b/src/script.inl
@@ -37,12 +37,12 @@ namespace floormat {
template <typename S, typename Obj> Script<S, Obj>::~Script() noexcept
{
- fm_assert(state < script_lifecycle::COUNT);
- switch (state)
+ fm_assert(_state < script_lifecycle::COUNT);
+ switch (_state)
{
case script_lifecycle::no_init:
case script_lifecycle::torn_down:
- state = (script_lifecycle)-1;
+ _state = (script_lifecycle)-1;
break;
case script_lifecycle::COUNT:
std::unreachable();
@@ -50,13 +50,12 @@ template <typename S, typename Obj> Script<S, Obj>::~Script() noexcept
case script_lifecycle::destroying:
case script_lifecycle::initializing:
fm_abort("invalid state '%s' in script destructor",
- base_script::state_name(state).data());
+ base_script::state_name(_state).data());
}
}
template <typename S, typename Obj>
-
-Script<S, Obj>::Script(): ptr{nullptr}, state{script_lifecycle::no_init}
+Script<S, Obj>::Script(): ptr{nullptr}, _state{script_lifecycle::no_init}
{
detail_Script::concept_check<S, Obj>();
}
@@ -64,17 +63,19 @@ Script<S, Obj>::Script(): ptr{nullptr}, state{script_lifecycle::no_init}
template <typename S, typename Obj>
void Script<S, Obj>::_assert_state(script_lifecycle s, const char* file, int line)
{
- if (state != s)
+ if (_state != s)
{
fm_EMIT_DEBUG2("fatal: ",
"invalid state transition from '%s' to '%s'",
- base_script::state_name(state).data(),
+ base_script::state_name(_state).data(),
base_script::state_name(s).data());
fm_EMIT_DEBUG("", " in %s:%d", file, line);
fm_EMIT_ABORT();
}
}
+template <typename S, typename Obj> script_lifecycle Script<S, Obj>::state() const { return _state; }
+
template <typename S, typename Obj>
S* Script<S, Obj>::operator->()
{
@@ -88,14 +89,14 @@ void Script<S, Obj>::do_create(S* p)
{
fm_assert(p);
FM_ASSERT_SCRIPT_STATE(script_lifecycle::no_init);
- state = script_lifecycle::initializing;
+ _state = script_lifecycle::initializing;
ptr = p;
}
template <typename S, typename Obj>
void Script<S, Obj>::do_initialize(const std::shared_ptr<Obj>& obj)
{
- switch (state)
+ switch (_state)
{
default:
FM_ASSERT_SCRIPT_STATE(script_lifecycle::initializing);
@@ -104,7 +105,7 @@ void Script<S, Obj>::do_initialize(const std::shared_ptr<Obj>& obj)
ptr = make_empty();
[[fallthrough]];
case script_lifecycle::initializing:
- state = script_lifecycle::created;
+ _state = script_lifecycle::created;
ptr->on_init(obj);
return;
}
@@ -127,7 +128,7 @@ 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);
- state = script_lifecycle::destroying;
+ _state = script_lifecycle::destroying;
ptr->on_destroy(obj, r);
}
@@ -135,7 +136,7 @@ template <typename S, typename Obj>
void Script<S, Obj>::do_finish_destroy()
{
FM_ASSERT_SCRIPT_STATE(script_lifecycle::destroying);
- state = script_lifecycle::torn_down;
+ _state = script_lifecycle::torn_down;
ptr->delete_self();
ptr = nullptr;
}
@@ -149,8 +150,8 @@ void Script<S, Obj>::do_ensure_torn_down()
template <typename S, typename Obj>
void Script<S, Obj>::do_error_unwind()
{
- fm_assert(state < script_lifecycle::COUNT);
- switch (state)
+ fm_assert(_state < script_lifecycle::COUNT);
+ switch (_state)
{
using enum script_lifecycle;
case COUNT: std::unreachable();
diff --git a/src/world.hpp b/src/world.hpp
index 2a3a26f1..91df9f8d 100644
--- a/src/world.hpp
+++ b/src/world.hpp
@@ -105,6 +105,8 @@ public:
void init_scripts();
void finish_scripts();
+ void ensure_scripts_created(); // todo!
+ void ensure_scripts_town_down(); // todo!
bool is_teardown() const;
object_id object_counter() const { return _object_counter; }
[[nodiscard]] object_id make_id() { return ++_object_counter; }
diff --git a/test/save.cpp b/test/save.cpp
index 675041c7..2df1d296 100644
--- a/test/save.cpp
+++ b/test/save.cpp
@@ -61,10 +61,10 @@ chunk& test_app::make_test_chunk(world& w, chunk_coords_ ch)
{ fm_assert(!e.active);
e.activate(e.index());
fm_assert(e.active);
- { auto index = e.index(); e.update(index, dt); }
+ { auto index = e.index(); e.update(eʹ, index, dt); }
fm_assert(e.frame != end);
for (int i = 0; i < 60*3; i++)
- { auto index = e.index(); e.update(index, dt); }
+ { auto index = e.index(); e.update(eʹ, index, dt); }
fm_assert(e.frame == 0);
fm_assert(!e.active);
}