Implemented instance pooling

This commit is contained in:
Segey Lapin
2021-10-30 02:16:06 +03:00
parent 4882866bd9
commit 6ad88e497f
2 changed files with 40 additions and 4 deletions

View File

@@ -60,6 +60,7 @@ void Spawner::place_scene(const StringName &name, const Transform &place)
struct spawn_object obj; struct spawn_object obj;
obj.xform = place; obj.xform = place;
obj.active = false; obj.active = false;
obj.pooled = false;
obj.instance = -1; obj.instance = -1;
PoolVector<struct spawn_object> pos = positions[name]; PoolVector<struct spawn_object> pos = positions[name];
pos.resize(pos.size() + 1); pos.resize(pos.size() + 1);
@@ -106,15 +107,39 @@ void Spawner::update_view(Node *node, float distance)
if (!pos[i].active) { if (!pos[i].active) {
Transform x = pos[i].xform; Transform x = pos[i].xform;
float d = org.distance_squared_to(x.origin); float d = org.distance_squared_to(x.origin);
if (d < distance * distance) { if (d < distance * distance && pos[i].instance < 0) {
Node *pn = scenes[*key]->instance(); int j;
Node *pn = NULL;
bool pooling = false;
for (j = 0; j < pos.size(); j++) {
if (j == i)
continue;
if (!pos[j].active && pos[j].instance >= 0 && pos[j].pooled) {
pos.write()[i].instance = pos[j].instance;
pos.write()[j].instance = -1;
pos.write()[j].pooled = false;
Object *po = ObjectDB::get_instance(pos[i].instance);
if (po) {
pn = Object::cast_to<Node>(po);
if (pn) {
pooling = true;
break;
}
}
}
}
if (!pn)
pn = scenes[*key]->instance();
if (pn) { if (pn) {
Spatial *sp = Object::cast_to<Spatial>(pn); Spatial *sp = Object::cast_to<Spatial>(pn);
if (sp) { if (sp) {
if (!pooling)
view->add_child(sp); view->add_child(sp);
sp->set_global_transform(x); sp->set_global_transform(x);
pos.write()[i].instance = sp->get_instance_id(); pos.write()[i].instance = sp->get_instance_id();
pos.write()[i].active = true; pos.write()[i].active = true;
pos.write()[i].pooled = false;
sp->show();
} else } else
memfree(pn); memfree(pn);
} }
@@ -122,7 +147,7 @@ void Spawner::update_view(Node *node, float distance)
} else { } else {
Transform x = pos[i].xform; Transform x = pos[i].xform;
float d = org.distance_squared_to(x.origin); float d = org.distance_squared_to(x.origin);
if (d > distance * distance + 600.0f) { if (d > distance * distance + 2500.0f) {
Object *po = ObjectDB::get_instance(pos[i].instance); Object *po = ObjectDB::get_instance(pos[i].instance);
if (po) { if (po) {
Node *pn = Object::cast_to<Node>(po); Node *pn = Object::cast_to<Node>(po);
@@ -130,6 +155,16 @@ void Spawner::update_view(Node *node, float distance)
pn->queue_delete(); pn->queue_delete();
} }
pos.write()[i].active = false; pos.write()[i].active = false;
pos.write()[i].instance = -1;
pos.write()[i].pooled = false;
} else if (d > distance * distance + 600.0f) {
Object *po = ObjectDB::get_instance(pos[i].instance);
if (po) {
Spatial *pn = Object::cast_to<Spatial>(po);
pn->hide();
}
pos.write()[i].active = false;
pos.write()[i].pooled = true;
} }
} }

View File

@@ -9,6 +9,7 @@ protected:
struct spawn_object { struct spawn_object {
Transform xform; Transform xform;
bool active; bool active;
bool pooled;
int instance; int instance;
}; };
HashMap<String, PoolVector<struct spawn_object> > positions; HashMap<String, PoolVector<struct spawn_object> > positions;