Merge branch 'feature/safe_gobject' into feature/scripting

This commit is contained in:
2019-10-22 02:52:39 +07:00
3 changed files with 19 additions and 13 deletions

View File

@@ -19,6 +19,7 @@ namespace e2d
gobject() = default; gobject() = default;
explicit gobject(state_iptr state); explicit gobject(state_iptr state);
bool alive() const noexcept;
bool valid() const noexcept; bool valid() const noexcept;
explicit operator bool() const noexcept; explicit operator bool() const noexcept;
@@ -113,6 +114,7 @@ namespace e2d
public: public:
virtual ~state() noexcept {} virtual ~state() noexcept {}
virtual void destroy() noexcept = 0; virtual void destroy() noexcept = 0;
virtual bool destroyed() const noexcept = 0;
virtual bool invalided() const noexcept = 0; virtual bool invalided() const noexcept = 0;
virtual ecs::entity raw_entity() noexcept = 0; virtual ecs::entity raw_entity() noexcept = 0;
virtual ecs::const_entity raw_entity() const noexcept = 0; virtual ecs::const_entity raw_entity() const noexcept = 0;

View File

@@ -15,6 +15,10 @@ namespace e2d
gobject::gobject(state_iptr state) gobject::gobject(state_iptr state)
: state_(std::move(state)) {} : state_(std::move(state)) {}
bool gobject::alive() const noexcept {
return state_ && !state_->destroyed();
}
bool gobject::valid() const noexcept { bool gobject::valid() const noexcept {
return state_ && !state_->invalided(); return state_ && !state_->invalided();
} }
@@ -24,7 +28,7 @@ namespace e2d
} }
void gobject::destroy() noexcept { void gobject::destroy() noexcept {
if ( valid() ) { if ( alive() && valid() ) {
state_->destroy(); state_->destroy();
} }
} }

View File

@@ -15,31 +15,31 @@ namespace
class gobject_state final : public gobject::state { class gobject_state final : public gobject::state {
private: private:
enum flag_masks : u32 { enum flag_masks : u32 {
fm_invalided = 1u << 0, fm_destroyed = 1u << 0,
fm_destroying = 1u << 1, fm_invalided = 1u << 1,
}; };
public: public:
gobject_state(world& w, ecs::entity e) gobject_state(world& w, ecs::entity e)
: world_(w) : world_(w)
, entity_(std::move(e)) {} , entity_(std::move(e)) {}
void mark_destroyed() noexcept {
math::set_flags_inplace(flags_, fm_destroyed);
}
void mark_invalided() noexcept { void mark_invalided() noexcept {
math::set_flags_inplace(flags_, fm_invalided); math::set_flags_inplace(flags_, fm_invalided);
} }
void mark_destroying() noexcept {
math::set_flags_inplace(flags_, fm_destroying);
}
bool destroying() const noexcept {
return math::check_any_flags(flags_, fm_destroying);
}
public: public:
void destroy() noexcept final { void destroy() noexcept final {
gobject go{this}; gobject go{this};
world_.destroy_instance(go); world_.destroy_instance(go);
} }
bool destroyed() const noexcept final {
return math::check_any_flags(flags_, fm_destroyed);
}
bool invalided() const noexcept final { bool invalided() const noexcept final {
return math::check_any_flags(flags_, fm_invalided); return math::check_any_flags(flags_, fm_invalided);
} }
@@ -226,8 +226,8 @@ namespace e2d
auto gstate = inst auto gstate = inst
? dynamic_pointer_cast<gobject_state>(inst.internal_state()) ? dynamic_pointer_cast<gobject_state>(inst.internal_state())
: nullptr; : nullptr;
if ( gstate && !gstate->destroying() ) { if ( gstate && !gstate->destroyed() ) {
gstate->mark_destroying(); gstate->mark_destroyed();
destroying_states_.push_back(*gstate); destroying_states_.push_back(*gstate);
} }
} }