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

View File

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

View File

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