mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-14 16:09:06 +07:00
instantiate with meta calls
This commit is contained in:
@@ -9,26 +9,20 @@
|
|||||||
#include "../_high.hpp"
|
#include "../_high.hpp"
|
||||||
|
|
||||||
#include "../factory.hpp"
|
#include "../factory.hpp"
|
||||||
#include "../assets/script_asset.hpp"
|
|
||||||
|
|
||||||
namespace e2d
|
namespace e2d
|
||||||
{
|
{
|
||||||
class behaviour final {
|
class behaviour final {
|
||||||
public:
|
public:
|
||||||
behaviour() = default;
|
behaviour() = default;
|
||||||
behaviour(const script_asset::ptr& script);
|
|
||||||
|
|
||||||
behaviour& meta(sol::table&& value) noexcept;
|
behaviour& meta(sol::table value) noexcept;
|
||||||
behaviour& meta(const sol::table& value);
|
|
||||||
|
|
||||||
[[nodiscard]] sol::table& meta() noexcept;
|
[[nodiscard]] sol::table& meta() noexcept;
|
||||||
[[nodiscard]] const sol::table& meta() const noexcept;
|
[[nodiscard]] const sol::table& meta() const noexcept;
|
||||||
|
|
||||||
behaviour& script(const script_asset::ptr& value) noexcept;
|
|
||||||
[[nodiscard]] const script_asset::ptr& script() const noexcept;
|
|
||||||
private:
|
private:
|
||||||
|
str name_;
|
||||||
sol::table meta_;
|
sol::table meta_;
|
||||||
script_asset::ptr script_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
@@ -48,19 +42,11 @@ namespace e2d
|
|||||||
|
|
||||||
namespace e2d
|
namespace e2d
|
||||||
{
|
{
|
||||||
inline behaviour::behaviour(const script_asset::ptr& value)
|
inline behaviour& behaviour::meta(sol::table value) noexcept {
|
||||||
: script_(value) {}
|
|
||||||
|
|
||||||
inline behaviour& behaviour::meta(sol::table&& value) noexcept {
|
|
||||||
meta_ = std::move(value);
|
meta_ = std::move(value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline behaviour& behaviour::meta(const sol::table& value) {
|
|
||||||
meta_ = value;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline sol::table& behaviour::meta() noexcept {
|
inline sol::table& behaviour::meta() noexcept {
|
||||||
return meta_;
|
return meta_;
|
||||||
}
|
}
|
||||||
@@ -68,13 +54,39 @@ namespace e2d
|
|||||||
inline const sol::table& behaviour::meta() const noexcept {
|
inline const sol::table& behaviour::meta() const noexcept {
|
||||||
return meta_;
|
return meta_;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline behaviour& behaviour::script(const script_asset::ptr& value) noexcept {
|
namespace e2d::behaviours
|
||||||
script_ = value;
|
{
|
||||||
return *this;
|
enum class call_result {
|
||||||
}
|
failed,
|
||||||
|
success,
|
||||||
|
method_not_found,
|
||||||
|
};
|
||||||
|
|
||||||
inline const script_asset::ptr& behaviour::script() const noexcept {
|
template < typename... Args >
|
||||||
return script_;
|
call_result call_meta_method(behaviour& behaviour, str_view method, Args&&... args) {
|
||||||
|
if ( method.empty() || !behaviour.meta() || !behaviour.meta().valid() ) {
|
||||||
|
return call_result::method_not_found;
|
||||||
|
}
|
||||||
|
|
||||||
|
sol::optional<sol::protected_function> f = behaviour.meta()[method];
|
||||||
|
if ( !f ) {
|
||||||
|
return call_result::method_not_found;
|
||||||
|
}
|
||||||
|
|
||||||
|
sol::protected_function_result r = f->call(
|
||||||
|
behaviour.meta(),
|
||||||
|
std::forward<Args>(args)...);
|
||||||
|
if ( !r.valid() ) {
|
||||||
|
the<debug>().error("BEHAVIOUR: Behaviour method error:\n"
|
||||||
|
"--> Method: %0\n"
|
||||||
|
"--> Error: %1",
|
||||||
|
method,
|
||||||
|
sol::error(r).what());
|
||||||
|
return call_result::failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return call_result::success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,29 +25,16 @@ namespace e2d
|
|||||||
gobject instantiate();
|
gobject instantiate();
|
||||||
gobject instantiate(const prefab& prefab);
|
gobject instantiate(const prefab& prefab);
|
||||||
|
|
||||||
gobject instantiate(const gobject& parent);
|
|
||||||
gobject instantiate(const node_iptr& parent);
|
gobject instantiate(const node_iptr& parent);
|
||||||
|
|
||||||
gobject instantiate(const prefab& prefab, const gobject& parent);
|
|
||||||
gobject instantiate(const prefab& prefab, const node_iptr& parent);
|
gobject instantiate(const prefab& prefab, const node_iptr& parent);
|
||||||
|
|
||||||
gobject instantiate(const gobject& parent, const t3f& transform);
|
|
||||||
gobject instantiate(const node_iptr& parent, const t3f& transform);
|
gobject instantiate(const node_iptr& parent, const t3f& transform);
|
||||||
|
|
||||||
gobject instantiate(const prefab& prefab, const gobject& parent, const t3f& transform);
|
|
||||||
gobject instantiate(const prefab& prefab, const node_iptr& parent, const t3f& transform);
|
gobject instantiate(const prefab& prefab, const node_iptr& parent, const t3f& transform);
|
||||||
|
|
||||||
void destroy_instance(gobject& inst) noexcept;
|
void destroy_instance(gobject& inst) noexcept;
|
||||||
void finalize_instances() noexcept;
|
void finalize_instances() noexcept;
|
||||||
|
|
||||||
gobject resolve(ecs::entity_id ent) const noexcept;
|
|
||||||
gobject resolve(const ecs::const_entity& ent) const noexcept;
|
|
||||||
private:
|
|
||||||
void destroy_instances_() noexcept;
|
|
||||||
void finalize_instance_(gobject& inst) noexcept;
|
|
||||||
private:
|
private:
|
||||||
ecs::registry registry_;
|
ecs::registry registry_;
|
||||||
hash_map<ecs::entity_id, gobject> gobjects_;
|
|
||||||
gobject_destroying_states destroying_states_;
|
gobject_destroying_states destroying_states_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ namespace
|
|||||||
|
|
||||||
the<world>().instantiate(
|
the<world>().instantiate(
|
||||||
prefab,
|
prefab,
|
||||||
scene_i,
|
scene_i.component<actor>()->node(),
|
||||||
make_trs3(v3f{0,50.f,0}, q4f::identity(), v3f{20.f}));
|
make_trs3(v3f{0,50.f,0}, q4f::identity(), v3f{20.f}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ namespace
|
|||||||
|
|
||||||
the<world>().instantiate(
|
the<world>().instantiate(
|
||||||
prefab,
|
prefab,
|
||||||
scene_i,
|
scene_i.component<actor>()->node(),
|
||||||
math::make_translation_trs3(v3f{0,-50.f,0}));
|
math::make_translation_trs3(v3f{0,-50.f,0}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +139,10 @@ namespace
|
|||||||
{-80.f + j * 40.f, -200.f + i * 40.f, 0},
|
{-80.f + j * 40.f, -200.f + i * 40.f, 0},
|
||||||
q4f::identity(),
|
q4f::identity(),
|
||||||
{2.f,2.f,1.f}};
|
{2.f,2.f,1.f}};
|
||||||
gobject inst = the<world>().instantiate(prefab_a, scene_i, trans);
|
gobject inst = the<world>().instantiate(
|
||||||
|
prefab_a,
|
||||||
|
scene_i.component<actor>()->node(),
|
||||||
|
trans);
|
||||||
|
|
||||||
prefab prefab_b = prefab_a;
|
prefab prefab_b = prefab_a;
|
||||||
prefab_b.prototype()
|
prefab_b.prototype()
|
||||||
@@ -149,7 +152,9 @@ namespace
|
|||||||
q4f::identity(),
|
q4f::identity(),
|
||||||
v3f{0.3f,0.3f,3.f})));
|
v3f{0.3f,0.3f,3.f})));
|
||||||
|
|
||||||
the<world>().instantiate(prefab_b, inst);
|
the<world>().instantiate(
|
||||||
|
prefab_b,
|
||||||
|
inst.component<actor>()->node());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include <enduro2d/high/components/behaviour.hpp>
|
#include <enduro2d/high/components/behaviour.hpp>
|
||||||
|
|
||||||
|
#include <enduro2d/high/assets/script_asset.hpp>
|
||||||
|
|
||||||
namespace e2d
|
namespace e2d
|
||||||
{
|
{
|
||||||
const char* factory_loader<behaviour>::schema_source = R"json({
|
const char* factory_loader<behaviour>::schema_source = R"json({
|
||||||
@@ -24,6 +26,7 @@ namespace e2d
|
|||||||
if ( ctx.root.HasMember("script") ) {
|
if ( ctx.root.HasMember("script") ) {
|
||||||
auto script = ctx.dependencies.find_asset<script_asset>(
|
auto script = ctx.dependencies.find_asset<script_asset>(
|
||||||
path::combine(ctx.parent_address, ctx.root["script"].GetString()));
|
path::combine(ctx.parent_address, ctx.root["script"].GetString()));
|
||||||
|
|
||||||
if ( !script ) {
|
if ( !script ) {
|
||||||
the<debug>().error("BEHAVIOUR: Dependency 'script' is not found:\n"
|
the<debug>().error("BEHAVIOUR: Dependency 'script' is not found:\n"
|
||||||
"--> Parent address: %0\n"
|
"--> Parent address: %0\n"
|
||||||
@@ -32,7 +35,23 @@ namespace e2d
|
|||||||
ctx.root["script"].GetString());
|
ctx.root["script"].GetString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
component.script(script);
|
|
||||||
|
//TODO(BlackMat): thread safe?
|
||||||
|
sol::protected_function_result meta = script->content().call();
|
||||||
|
|
||||||
|
if ( !meta.valid() ) {
|
||||||
|
the<debug>().error("BEHAVIOUR: Behaviour script error:\n"
|
||||||
|
"--> Error: %0",
|
||||||
|
sol::error(meta).what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( meta.get_type() != sol::type::table ) {
|
||||||
|
the<debug>().error("BEHAVIOUR: Behaviour script must return the meta table");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
component.meta(std::move(meta));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include <enduro2d/high/world.hpp>
|
#include <enduro2d/high/world.hpp>
|
||||||
|
|
||||||
#include <enduro2d/high/components/actor.hpp>
|
#include <enduro2d/high/components/actor.hpp>
|
||||||
|
#include <enduro2d/high/components/behaviour.hpp>
|
||||||
|
#include <enduro2d/high/components/disabled.hpp>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -60,12 +62,104 @@ namespace
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
using namespace e2d;
|
||||||
|
|
||||||
|
void delete_instance(const gobject& inst) noexcept {
|
||||||
|
gcomponent<actor> inst_a{inst};
|
||||||
|
auto inst_n = inst_a ? inst_a->node() : nullptr;
|
||||||
|
|
||||||
|
if ( inst_n ) {
|
||||||
|
inst_n->for_each_child([](const node_iptr& child_n){
|
||||||
|
delete_instance(child_n->owner());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( inst ) {
|
||||||
|
auto inst_g = dynamic_pointer_cast<gobject_state>(inst.internal_state());
|
||||||
|
inst_g->raw_entity().destroy();
|
||||||
|
inst_g->mark_destroyed();
|
||||||
|
inst_g->mark_invalided();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gobject new_instance(world& world, const prefab& prefab) {
|
||||||
|
gobject inst;
|
||||||
|
ecs::entity ent = world.registry().create_entity(prefab.prototype());
|
||||||
|
|
||||||
|
try {
|
||||||
|
inst = gobject{make_intrusive<gobject_state>(world, ent)};
|
||||||
|
} catch (...) {
|
||||||
|
ent.destroy();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
auto n = node::create(inst);
|
||||||
|
gcomponent<actor> inst_a{inst};
|
||||||
|
if ( inst_a && inst_a->node() ) {
|
||||||
|
n->transform(inst_a->node()->transform());
|
||||||
|
}
|
||||||
|
inst_a.assign(std::move(n));
|
||||||
|
} catch (...) {
|
||||||
|
delete_instance(inst);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
for ( const auto& child_prefab : prefab.children() ) {
|
||||||
|
auto child = new_instance(world, child_prefab);
|
||||||
|
try {
|
||||||
|
gcomponent<actor> inst_a{inst};
|
||||||
|
gcomponent<actor> child_a{child};
|
||||||
|
inst_a->node()->add_child(child_a->node());
|
||||||
|
} catch (...) {
|
||||||
|
delete_instance(child);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
delete_instance(inst);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void shutdown_instance(gobject& inst) noexcept {
|
||||||
|
if ( gcomponent<actor> inst_a{inst}; inst_a ) {
|
||||||
|
nodes::for_extracted_nodes(inst_a->node(), [](const node_iptr& node){
|
||||||
|
if ( gcomponent<behaviour> inst_b{node->owner()}; inst_b ) {
|
||||||
|
behaviours::call_meta_method(
|
||||||
|
*inst_b,
|
||||||
|
"on_shutdown",
|
||||||
|
node->owner());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void start_instance(gobject& inst) {
|
||||||
|
if ( gcomponent<actor> inst_a{inst}; inst_a ) {
|
||||||
|
nodes::for_extracted_nodes(inst_a->node(), [&inst](const node_iptr& node){
|
||||||
|
if ( gcomponent<behaviour> inst_b{node->owner()}; inst_b ) {
|
||||||
|
const auto result = behaviours::call_meta_method(
|
||||||
|
*inst_b,
|
||||||
|
"on_start",
|
||||||
|
node->owner());
|
||||||
|
if ( result == behaviours::call_result::failed ) {
|
||||||
|
inst.component<disabled<behaviour>>().assign();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace e2d
|
namespace e2d
|
||||||
{
|
{
|
||||||
world::~world() noexcept {
|
world::~world() noexcept = default;
|
||||||
destroy_instances_();
|
|
||||||
finalize_instances();
|
|
||||||
}
|
|
||||||
|
|
||||||
ecs::registry& world::registry() noexcept {
|
ecs::registry& world::registry() noexcept {
|
||||||
return registry_;
|
return registry_;
|
||||||
@@ -76,157 +170,61 @@ namespace e2d
|
|||||||
}
|
}
|
||||||
|
|
||||||
gobject world::instantiate() {
|
gobject world::instantiate() {
|
||||||
gobject inst{make_intrusive<gobject_state>(
|
return instantiate(nullptr);
|
||||||
*this,
|
|
||||||
registry_.create_entity())};
|
|
||||||
gobjects_.emplace(inst.raw_entity().id(), inst);
|
|
||||||
|
|
||||||
try {
|
|
||||||
auto n = node::create(inst);
|
|
||||||
gcomponent<actor> inst_a{inst};
|
|
||||||
if ( inst_a && inst_a->node() ) {
|
|
||||||
n->transform(inst_a->node()->transform());
|
|
||||||
}
|
|
||||||
inst_a.assign(n);
|
|
||||||
} catch (...) {
|
|
||||||
finalize_instance_(inst);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
return inst;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gobject world::instantiate(const prefab& prefab) {
|
gobject world::instantiate(const prefab& prefab) {
|
||||||
gobject inst{make_intrusive<gobject_state>(
|
return instantiate(prefab, nullptr);
|
||||||
*this,
|
}
|
||||||
registry_.create_entity(prefab.prototype()))};
|
|
||||||
gobjects_.emplace(inst.raw_entity().id(), inst);
|
|
||||||
|
|
||||||
try {
|
gobject world::instantiate(const node_iptr& parent) {
|
||||||
auto n = node::create(inst);
|
return instantiate(prefab(), parent);
|
||||||
gcomponent<actor> inst_a{inst};
|
}
|
||||||
if ( inst_a && inst_a->node() ) {
|
|
||||||
n->transform(inst_a->node()->transform());
|
gobject world::instantiate(const prefab& prefab, const node_iptr& parent) {
|
||||||
}
|
gobject inst = new_instance(*this, prefab);
|
||||||
inst_a.assign(n);
|
|
||||||
} catch (...) {
|
if ( parent ) {
|
||||||
finalize_instance_(inst);
|
parent->add_child(inst.component<actor>()->node());
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for ( const auto& child_prefab : prefab.children() ) {
|
start_instance(inst);
|
||||||
auto child = instantiate(child_prefab);
|
|
||||||
try {
|
|
||||||
gcomponent<actor> inst_a{inst};
|
|
||||||
gcomponent<actor> child_a{child};
|
|
||||||
inst_a->node()->add_child(child_a->node());
|
|
||||||
} catch (...) {
|
|
||||||
finalize_instance_(child);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
finalize_instance_(inst);
|
delete_instance(inst);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
gobject world::instantiate(const gobject& parent) {
|
|
||||||
gobject go = instantiate();
|
|
||||||
if ( go && parent ) {
|
|
||||||
try {
|
|
||||||
gcomponent<actor> parent_a{parent};
|
|
||||||
if ( !parent_a ) {
|
|
||||||
parent_a.assign(node::create(parent));
|
|
||||||
}
|
|
||||||
if ( !parent_a->node() ) {
|
|
||||||
parent_a->node(node::create(parent));
|
|
||||||
}
|
|
||||||
parent_a->node()->add_child(gcomponent<actor>{go}->node());
|
|
||||||
} catch (...) {
|
|
||||||
finalize_instance_(go);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return go;
|
|
||||||
}
|
|
||||||
|
|
||||||
gobject world::instantiate(const node_iptr& parent) {
|
|
||||||
gobject go = instantiate();
|
|
||||||
if ( go && parent ) {
|
|
||||||
parent->add_child(gcomponent<actor>{go}->node());
|
|
||||||
}
|
|
||||||
return go;
|
|
||||||
}
|
|
||||||
|
|
||||||
gobject world::instantiate(const prefab& prefab, const gobject& parent) {
|
|
||||||
gobject go = instantiate(prefab);
|
|
||||||
if ( go && parent ) {
|
|
||||||
try {
|
|
||||||
gcomponent<actor> parent_a{parent};
|
|
||||||
if ( !parent_a ) {
|
|
||||||
parent_a.assign(node::create(parent));
|
|
||||||
}
|
|
||||||
if ( !parent_a->node() ) {
|
|
||||||
parent_a->node(node::create(parent));
|
|
||||||
}
|
|
||||||
parent_a->node()->add_child(gcomponent<actor>{go}->node());
|
|
||||||
} catch (...) {
|
|
||||||
finalize_instance_(go);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return go;
|
|
||||||
}
|
|
||||||
|
|
||||||
gobject world::instantiate(const prefab& prefab, const node_iptr& parent) {
|
|
||||||
gobject go = instantiate(prefab);
|
|
||||||
if ( go && parent ) {
|
|
||||||
parent->add_child(gcomponent<actor>{go}->node());
|
|
||||||
}
|
|
||||||
return go;
|
|
||||||
}
|
|
||||||
|
|
||||||
gobject world::instantiate(const gobject& parent, const t3f& transform) {
|
|
||||||
gobject go = instantiate(parent);
|
|
||||||
if ( go ) {
|
|
||||||
gcomponent<actor>{go}->node()->transform(transform);
|
|
||||||
}
|
|
||||||
return go;
|
|
||||||
}
|
|
||||||
|
|
||||||
gobject world::instantiate(const node_iptr& parent, const t3f& transform) {
|
gobject world::instantiate(const node_iptr& parent, const t3f& transform) {
|
||||||
gobject go = instantiate(parent);
|
return instantiate(prefab(), parent, transform);
|
||||||
if ( go ) {
|
|
||||||
gcomponent<actor>{go}->node()->transform(transform);
|
|
||||||
}
|
|
||||||
return go;
|
|
||||||
}
|
|
||||||
|
|
||||||
gobject world::instantiate(const prefab& prefab, const gobject& parent, const t3f& transform) {
|
|
||||||
gobject go = instantiate(prefab, parent);
|
|
||||||
if ( go ) {
|
|
||||||
gcomponent<actor>{go}->node()->transform(transform);
|
|
||||||
}
|
|
||||||
return go;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gobject world::instantiate(const prefab& prefab, const node_iptr& parent, const t3f& transform) {
|
gobject world::instantiate(const prefab& prefab, const node_iptr& parent, const t3f& transform) {
|
||||||
gobject go = instantiate(prefab, parent);
|
gobject inst = new_instance(*this, prefab);
|
||||||
if ( go ) {
|
inst.component<actor>()->node()->transform(transform);
|
||||||
gcomponent<actor>{go}->node()->transform(transform);
|
|
||||||
|
if ( parent ) {
|
||||||
|
parent->add_child(inst.component<actor>()->node());
|
||||||
}
|
}
|
||||||
return go;
|
|
||||||
|
try {
|
||||||
|
start_instance(inst);
|
||||||
|
} catch (...) {
|
||||||
|
delete_instance(inst);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
void world::destroy_instance(gobject& inst) noexcept {
|
void world::destroy_instance(gobject& inst) noexcept {
|
||||||
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->destroyed() ) {
|
if ( gstate && !gstate->destroyed() && !gstate->invalided() ) {
|
||||||
gstate->mark_destroyed();
|
gstate->mark_destroyed();
|
||||||
destroying_states_.push_back(*gstate);
|
destroying_states_.push_back(*gstate);
|
||||||
}
|
}
|
||||||
@@ -236,46 +234,8 @@ namespace e2d
|
|||||||
while ( !destroying_states_.empty() ) {
|
while ( !destroying_states_.empty() ) {
|
||||||
gobject inst{&destroying_states_.front()};
|
gobject inst{&destroying_states_.front()};
|
||||||
destroying_states_.pop_front();
|
destroying_states_.pop_front();
|
||||||
finalize_instance_(inst);
|
shutdown_instance(inst);
|
||||||
}
|
delete_instance(inst);
|
||||||
}
|
|
||||||
|
|
||||||
gobject world::resolve(ecs::entity_id ent) const noexcept {
|
|
||||||
E2D_ASSERT(registry_.valid_entity(ent));
|
|
||||||
const auto iter = gobjects_.find(ent);
|
|
||||||
return iter != gobjects_.end()
|
|
||||||
? iter->second
|
|
||||||
: gobject();
|
|
||||||
}
|
|
||||||
|
|
||||||
gobject world::resolve(const ecs::const_entity& ent) const noexcept {
|
|
||||||
E2D_ASSERT(registry_.valid_entity(ent));
|
|
||||||
const auto iter = gobjects_.find(ent.id());
|
|
||||||
return iter != gobjects_.end()
|
|
||||||
? iter->second
|
|
||||||
: gobject();
|
|
||||||
}
|
|
||||||
|
|
||||||
void world::destroy_instances_() noexcept {
|
|
||||||
for ( auto& [_, go] : gobjects_ ) {
|
|
||||||
destroy_instance(go);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void world::finalize_instance_(gobject& inst) noexcept {
|
|
||||||
gcomponent<actor> inst_a{inst};
|
|
||||||
auto inst_n = inst_a ? inst_a->node() : nullptr;
|
|
||||||
|
|
||||||
if ( inst_n ) {
|
|
||||||
inst_n->for_each_child([this](const node_iptr& child_n){
|
|
||||||
destroy_instance(child_n->owner());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( inst ) {
|
|
||||||
inst.raw_entity().destroy();
|
|
||||||
gobjects_.erase(inst.raw_entity().id());
|
|
||||||
dynamic_pointer_cast<gobject_state>(inst.internal_state())->mark_invalided();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,20 +31,20 @@ TEST_CASE("luasol") {
|
|||||||
SECTION("vec2/vec3/vec4") {
|
SECTION("vec2/vec3/vec4") {
|
||||||
v2f r0 = l.with_state([](sol::state& lua){
|
v2f r0 = l.with_state([](sol::state& lua){
|
||||||
return lua.script(R"lua(
|
return lua.script(R"lua(
|
||||||
local v = v2f.new(1,2)
|
local v = e2d.v2f.new(1,2)
|
||||||
return v2f.new((v + v + 2).y)
|
return e2d.v2f.new((v + v + 2).y)
|
||||||
)lua");
|
)lua");
|
||||||
});
|
});
|
||||||
v3f r1 = l.with_state([](sol::state& lua){
|
v3f r1 = l.with_state([](sol::state& lua){
|
||||||
return lua.script(R"lua(
|
return lua.script(R"lua(
|
||||||
local v = v3f.new(1,2,3)
|
local v = e2d.v3f.new(1,2,3)
|
||||||
return v3f.new((v + v + 2).y)
|
return e2d.v3f.new((v + v + 2).y)
|
||||||
)lua");
|
)lua");
|
||||||
});
|
});
|
||||||
v4f r2 = l.with_state([](sol::state& lua){
|
v4f r2 = l.with_state([](sol::state& lua){
|
||||||
return lua.script(R"lua(
|
return lua.script(R"lua(
|
||||||
local v = v4f.new(1,2,3,4)
|
local v = e2d.v4f.new(1,2,3,4)
|
||||||
return v4f.new((v + v + 2).y)
|
return e2d.v4f.new((v + v + 2).y)
|
||||||
)lua");
|
)lua");
|
||||||
});
|
});
|
||||||
REQUIRE(r0 == v2f(6));
|
REQUIRE(r0 == v2f(6));
|
||||||
@@ -55,7 +55,7 @@ TEST_CASE("luasol") {
|
|||||||
SECTION("quat") {
|
SECTION("quat") {
|
||||||
v3f r0 = l.with_state([](sol::state& lua){
|
v3f r0 = l.with_state([](sol::state& lua){
|
||||||
return lua.script(R"lua(
|
return lua.script(R"lua(
|
||||||
return v3f.new(1,2,3) * q4f.make_quat_from_axis_angle(radf.new(10), v3f.new(1,2,3))
|
return e2d.v3f.new(1,2,3) * e2d.q4f.make_quat_from_axis_angle(e2d.radf.new(10), e2d.v3f.new(1,2,3))
|
||||||
)lua");
|
)lua");
|
||||||
});
|
});
|
||||||
REQUIRE(r0 == v3f(1,2,3) * math::make_quat_from_axis_angle(radf(10.f), v3f(1,2,3)));
|
REQUIRE(r0 == v3f(1,2,3) * math::make_quat_from_axis_angle(radf(10.f), v3f(1,2,3)));
|
||||||
@@ -64,23 +64,23 @@ TEST_CASE("luasol") {
|
|||||||
SECTION("mat2/mat2/mat3") {
|
SECTION("mat2/mat2/mat3") {
|
||||||
std::pair<m2f, bool> r0 = l.with_state([](sol::state& lua){
|
std::pair<m2f, bool> r0 = l.with_state([](sol::state& lua){
|
||||||
return lua.script(R"lua(
|
return lua.script(R"lua(
|
||||||
local m = m2f.make_scale_matrix2(2,3)
|
local m = e2d.m2f.make_scale_matrix2(2,3)
|
||||||
local rm, s = m2f.inversed(m)
|
local rm, s = e2d.m2f.inversed(m)
|
||||||
return rm * m2f.identity(), s
|
return rm * e2d.m2f.identity(), s
|
||||||
)lua");
|
)lua");
|
||||||
});
|
});
|
||||||
std::pair<m3f, bool> r1 = l.with_state([](sol::state& lua){
|
std::pair<m3f, bool> r1 = l.with_state([](sol::state& lua){
|
||||||
return lua.script(R"lua(
|
return lua.script(R"lua(
|
||||||
local m = m3f.make_rotation_matrix3(degf.new(45),2,3,4)
|
local m = e2d.m3f.make_rotation_matrix3(e2d.degf.new(45),2,3,4)
|
||||||
local rm, s = m3f.inversed(m)
|
local rm, s = e2d.m3f.inversed(m)
|
||||||
return rm * m3f.identity(), s
|
return rm * e2d.m3f.identity(), s
|
||||||
)lua");
|
)lua");
|
||||||
});
|
});
|
||||||
std::pair<m4f, bool> r2 = l.with_state([](sol::state& lua){
|
std::pair<m4f, bool> r2 = l.with_state([](sol::state& lua){
|
||||||
return lua.script(R"lua(
|
return lua.script(R"lua(
|
||||||
local m = m4f.make_translation_matrix4(2,3,4)
|
local m = e2d.m4f.make_translation_matrix4(2,3,4)
|
||||||
local rm, s = m4f.inversed(m)
|
local rm, s = e2d.m4f.inversed(m)
|
||||||
return rm * m4f.identity(), s
|
return rm * e2d.m4f.identity(), s
|
||||||
)lua");
|
)lua");
|
||||||
});
|
});
|
||||||
REQUIRE(r0.second);
|
REQUIRE(r0.second);
|
||||||
@@ -94,15 +94,15 @@ TEST_CASE("luasol") {
|
|||||||
SECTION("rect/aabb") {
|
SECTION("rect/aabb") {
|
||||||
bool r0 = l.with_state([](sol::state& lua){
|
bool r0 = l.with_state([](sol::state& lua){
|
||||||
return lua.script(R"lua(
|
return lua.script(R"lua(
|
||||||
local b = b2f.unit() * 2
|
local b = e2d.b2f.unit() * 2
|
||||||
return b:inside(v2f.new(1.5,1.5))
|
return b:inside(e2d.v2f.new(1.5,1.5))
|
||||||
)lua");
|
)lua");
|
||||||
});
|
});
|
||||||
REQUIRE(r0);
|
REQUIRE(r0);
|
||||||
bool r1 = l.with_state([](sol::state& lua){
|
bool r1 = l.with_state([](sol::state& lua){
|
||||||
return lua.script(R"lua(
|
return lua.script(R"lua(
|
||||||
local b = b3f.unit() * 2
|
local b = e2d.b3f.unit() * 2
|
||||||
return b:overlaps(b3f.new(1.5,1.5,1.5,2,2,2))
|
return b:overlaps(e2d.b3f.new(1.5,1.5,1.5,2,2,2))
|
||||||
)lua");
|
)lua");
|
||||||
});
|
});
|
||||||
REQUIRE(r1);
|
REQUIRE(r1);
|
||||||
@@ -111,14 +111,14 @@ TEST_CASE("luasol") {
|
|||||||
SECTION("trs2/trs3") {
|
SECTION("trs2/trs3") {
|
||||||
radf r0 = l.with_state([](sol::state& lua){
|
radf r0 = l.with_state([](sol::state& lua){
|
||||||
return lua.script(R"lua(
|
return lua.script(R"lua(
|
||||||
local t = t2f.make_rotation_trs2(degf.new(45))
|
local t = e2d.t2f.make_rotation_trs2(e2d.degf.new(45))
|
||||||
return t.rotation
|
return t.rotation
|
||||||
)lua");
|
)lua");
|
||||||
});
|
});
|
||||||
REQUIRE(r0 == math::to_rad(degf(45.f)));
|
REQUIRE(r0 == math::to_rad(degf(45.f)));
|
||||||
v3f r1 = l.with_state([](sol::state& lua){
|
v3f r1 = l.with_state([](sol::state& lua){
|
||||||
return lua.script(R"lua(
|
return lua.script(R"lua(
|
||||||
local t = t3f.make_translation_trs3(v3f.new(1,2,3))
|
local t = e2d.t3f.make_translation_trs3(e2d.v3f.new(1,2,3))
|
||||||
return t.translation
|
return t.translation
|
||||||
)lua");
|
)lua");
|
||||||
});
|
});
|
||||||
@@ -128,13 +128,13 @@ TEST_CASE("luasol") {
|
|||||||
SECTION("color/color32") {
|
SECTION("color/color32") {
|
||||||
color r0 = l.with_state([](sol::state& lua){
|
color r0 = l.with_state([](sol::state& lua){
|
||||||
return lua.script(R"lua(
|
return lua.script(R"lua(
|
||||||
return color.white() * 0.5
|
return e2d.color.white() * 0.5
|
||||||
)lua");
|
)lua");
|
||||||
});
|
});
|
||||||
REQUIRE(r0 == color(0.5f,0.5f,0.5f,0.5f));
|
REQUIRE(r0 == color(0.5f,0.5f,0.5f,0.5f));
|
||||||
color32 r1 = l.with_state([](sol::state& lua){
|
color32 r1 = l.with_state([](sol::state& lua){
|
||||||
return lua.script(R"lua(
|
return lua.script(R"lua(
|
||||||
return color32.white() - 1
|
return e2d.color32.white() - 1
|
||||||
)lua");
|
)lua");
|
||||||
});
|
});
|
||||||
REQUIRE(r1 == color32(254,254,254,254));
|
REQUIRE(r1 == color32(254,254,254,254));
|
||||||
|
|||||||
@@ -617,13 +617,13 @@ TEST_CASE("node") {
|
|||||||
const vector<node_iptr> ns{p, c1, c2, c3};
|
const vector<node_iptr> ns{p, c1, c2, c3};
|
||||||
{
|
{
|
||||||
vector<node_iptr> ns2;
|
vector<node_iptr> ns2;
|
||||||
REQUIRE(4u == p->extract_all_nodes(std::back_inserter(ns2)));
|
REQUIRE(4u == nodes::extract_nodes(p, std::back_inserter(ns2)));
|
||||||
REQUIRE(ns == ns2);
|
REQUIRE(ns == ns2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const_node_iptr cp = p;
|
const_node_iptr cp = p;
|
||||||
vector<const_node_iptr> ns2;
|
vector<const_node_iptr> ns2;
|
||||||
REQUIRE(4u == cp->extract_all_nodes(std::back_inserter(ns2)));
|
REQUIRE(4u == nodes::extract_nodes(cp, std::back_inserter(ns2)));
|
||||||
REQUIRE(ns.size() == ns2.size());
|
REQUIRE(ns.size() == ns2.size());
|
||||||
for ( std::size_t i = 0; i < ns.size(); ++i ) {
|
for ( std::size_t i = 0; i < ns.size(); ++i ) {
|
||||||
REQUIRE(ns[i] == ns2[i]);
|
REQUIRE(ns[i] == ns2[i]);
|
||||||
|
|||||||
Reference in New Issue
Block a user