Started using ECS
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
#include <algorithm>
|
||||||
#include <core/os/memory.h>
|
#include <core/os/memory.h>
|
||||||
#include <core/io/json.h>
|
#include <core/io/json.h>
|
||||||
#include <core/os/time.h>
|
#include <core/os/time.h>
|
||||||
@@ -7,12 +8,23 @@
|
|||||||
#include <scene/3d/spatial.h>
|
#include <scene/3d/spatial.h>
|
||||||
#include <scene/3d/mesh_instance.h>
|
#include <scene/3d/mesh_instance.h>
|
||||||
#include "from_string.h"
|
#include "from_string.h"
|
||||||
#include <flecs/flecs.h>
|
#include "flecs/flecs.h"
|
||||||
#include "buildings_data.h"
|
#include "buildings_data.h"
|
||||||
|
|
||||||
BuildingsData *BuildingsData::singleton;
|
BuildingsData *BuildingsData::singleton;
|
||||||
|
|
||||||
static ConfigFile config;
|
static ConfigFile config;
|
||||||
|
static flecs::world ecs;
|
||||||
|
struct scene_data {
|
||||||
|
Ref<PackedScene> packed_scene;
|
||||||
|
String path;
|
||||||
|
Ref<ResourceInteractiveLoader> loader;
|
||||||
|
std::vector<int> buildings;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CSceneData {
|
||||||
|
struct scene_data sd;
|
||||||
|
};
|
||||||
|
|
||||||
BuildingsData::BuildingsData()
|
BuildingsData::BuildingsData()
|
||||||
: undo_log_size(64)
|
: undo_log_size(64)
|
||||||
@@ -395,6 +407,138 @@ func fill_door_locations():
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BuildingsData::get_scene_keys_list(List<String> *keys) const
|
||||||
|
{
|
||||||
|
ecs.each([keys](flecs::entity e, const CSceneData &d) {
|
||||||
|
keys->push_back(String(e.name()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BuildingsData::has_scene(const String &key) const
|
||||||
|
{
|
||||||
|
flecs::entity e = ecs.lookup(key.ascii().ptr());
|
||||||
|
return e.is_valid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildingsData::remove_scene_item(const String &key, int item)
|
||||||
|
{
|
||||||
|
flecs::entity e = ecs.lookup(key.ascii().ptr());
|
||||||
|
assert(e.is_valid());
|
||||||
|
CSceneData *d = e.get_mut<CSceneData>();
|
||||||
|
assert(d);
|
||||||
|
std::vector<int>::iterator b = d->sd.buildings.begin();
|
||||||
|
std::vector<int>::iterator h = d->sd.buildings.end();
|
||||||
|
// if (item_nodes.has(item))
|
||||||
|
// item_nodes[item]->queue_delete();
|
||||||
|
d->sd.buildings.erase(std::remove(b, h, item), d->sd.buildings.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildingsData::add_scene_item(const String &key, int item)
|
||||||
|
{
|
||||||
|
flecs::entity e = ecs.lookup(key.ascii().ptr());
|
||||||
|
assert(e.is_valid());
|
||||||
|
CSceneData *d = e.get_mut<CSceneData>();
|
||||||
|
assert(d);
|
||||||
|
if (std::find(d->sd.buildings.begin(), d->sd.buildings.end(), item) ==
|
||||||
|
d->sd.buildings.end())
|
||||||
|
d->sd.buildings.push_back(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildingsData::create_scene_data(const String &key, int item)
|
||||||
|
{
|
||||||
|
if (!has_scene(key)) {
|
||||||
|
flecs::entity e = ecs.entity(key.ascii().ptr());
|
||||||
|
String path = building_data[key];
|
||||||
|
print_line("Requesting " + itos(item) + " " + path);
|
||||||
|
struct scene_data sd;
|
||||||
|
sd.path = path;
|
||||||
|
sd.loader = ResourceLoader::load_interactive(
|
||||||
|
path, "PackedScene", true);
|
||||||
|
if (std::find(sd.buildings.begin(), sd.buildings.end(), item) ==
|
||||||
|
sd.buildings.end())
|
||||||
|
sd.buildings.push_back(item);
|
||||||
|
e.set<CSceneData>({ sd });
|
||||||
|
assert(e.get_mut<CSceneData>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<PackedScene> BuildingsData::scene_get_packed_scene(const String &key) const
|
||||||
|
{
|
||||||
|
flecs::entity e = ecs.lookup(key.ascii().ptr());
|
||||||
|
if (!e.is_valid())
|
||||||
|
return Ref<PackedScene>();
|
||||||
|
if (!e.get<CSceneData>())
|
||||||
|
return Ref<PackedScene>();
|
||||||
|
assert(e.is_valid());
|
||||||
|
const CSceneData *d = e.get<CSceneData>();
|
||||||
|
assert(d);
|
||||||
|
return d->sd.packed_scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BuildingsData::scene_get_item_count(const String &key) const
|
||||||
|
{
|
||||||
|
flecs::entity e = ecs.lookup(key.ascii().ptr());
|
||||||
|
if (!e.is_valid())
|
||||||
|
return 0;
|
||||||
|
if (!e.get<CSceneData>())
|
||||||
|
return 0;
|
||||||
|
assert(e.is_valid());
|
||||||
|
const CSceneData *d = e.get<CSceneData>();
|
||||||
|
assert(d);
|
||||||
|
return d->sd.buildings.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int BuildingsData::scene_get_item(const String &key, int index) const
|
||||||
|
{
|
||||||
|
flecs::entity e = ecs.lookup(key.ascii().ptr());
|
||||||
|
if (!e.is_valid())
|
||||||
|
return -1;
|
||||||
|
if (!e.get<CSceneData>())
|
||||||
|
return -1;
|
||||||
|
assert(e.is_valid());
|
||||||
|
const CSceneData *d = e.get<CSceneData>();
|
||||||
|
assert(d);
|
||||||
|
return d->sd.buildings[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
Error BuildingsData::scene_loader_poll(const String &key)
|
||||||
|
{
|
||||||
|
if (has_scene(key)) {
|
||||||
|
flecs::entity e = ecs.lookup(key.ascii().ptr());
|
||||||
|
assert(e.is_valid());
|
||||||
|
CSceneData *d = e.get_mut<CSceneData>();
|
||||||
|
assert(d);
|
||||||
|
Error err = d->sd.loader->poll();
|
||||||
|
if (err == ERR_FILE_EOF) {
|
||||||
|
Ref<PackedScene> sc = d->sd.loader->get_resource();
|
||||||
|
d->sd.packed_scene = sc;
|
||||||
|
print_line("Loaded scene: " + d->sd.path + " OK");
|
||||||
|
return OK;
|
||||||
|
} else {
|
||||||
|
print_error("Could not load the resource :( " +
|
||||||
|
d->sd.path + " " + itos(err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildingsData::scene_update()
|
||||||
|
{
|
||||||
|
List<String> keys;
|
||||||
|
get_scene_keys_list(&keys);
|
||||||
|
List<String>::Element *e = keys.front();
|
||||||
|
while (e) {
|
||||||
|
const String &key = e->get();
|
||||||
|
if (scene_get_packed_scene(key).is_valid()) {
|
||||||
|
e = e->next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
scene_loader_poll(key);
|
||||||
|
e = e->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int BuildingsData::get_building_count() const
|
int BuildingsData::get_building_count() const
|
||||||
{
|
{
|
||||||
return buildings.size();
|
return buildings.size();
|
||||||
|
|||||||
@@ -22,13 +22,24 @@ public:
|
|||||||
String line_name;
|
String line_name;
|
||||||
};
|
};
|
||||||
/* Scene objects data */
|
/* Scene objects data */
|
||||||
struct scene_data {
|
//private:
|
||||||
Ref<PackedScene> packed_scene;
|
// HashMap<String, struct scene_data> scenes;
|
||||||
String path;
|
|
||||||
Ref<ResourceInteractiveLoader> loader;
|
public:
|
||||||
std::vector<int> buildings;
|
void get_scene_keys_list(List<String> *keys) const;
|
||||||
};
|
bool has_scene(const String &key) const;
|
||||||
HashMap<String, struct scene_data> scenes;
|
void remove_scene_item(const String &key, int item);
|
||||||
|
void add_scene_item(const String &key, int item);
|
||||||
|
void create_scene_data(const String &key, int item);
|
||||||
|
Ref<PackedScene> scene_get_packed_scene(const String &key) const;
|
||||||
|
int scene_get_item_count(const String &key) const;
|
||||||
|
int scene_get_item(const String &key, int index) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Error scene_loader_poll(const String &key);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void scene_update();
|
||||||
/* Path for each building type */
|
/* Path for each building type */
|
||||||
HashMap<String, String> building_data;
|
HashMap<String, String> building_data;
|
||||||
HashMap<String, Vector<Transform> > building_doors;
|
HashMap<String, Vector<Transform> > building_doors;
|
||||||
|
|||||||
@@ -169,39 +169,17 @@ void StreamWorld::request_item(int type, int item)
|
|||||||
String id = data()->get_building(item).id;
|
String id = data()->get_building(item).id;
|
||||||
if (id == "empty")
|
if (id == "empty")
|
||||||
return;
|
return;
|
||||||
String path = data()->building_data[id];
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0:
|
case 0:
|
||||||
if (!data()->scenes.has(id)) {
|
if (!data()->has_scene(id))
|
||||||
print_line("Requesting " + itos(item) + " " + path);
|
data()->create_scene_data(id, item);
|
||||||
struct BuildingsData::scene_data sd;
|
else
|
||||||
sd.path = path;
|
data()->add_scene_item(id, item);
|
||||||
sd.loader = ResourceLoader::load_interactive(
|
|
||||||
path, "PackedScene", true);
|
|
||||||
if (std::find(sd.buildings.begin(), sd.buildings.end(),
|
|
||||||
item) == sd.buildings.end())
|
|
||||||
sd.buildings.push_back(item);
|
|
||||||
data()->scenes[id] = sd;
|
|
||||||
} else {
|
|
||||||
struct BuildingsData::scene_data &sd =
|
|
||||||
data()->scenes[id];
|
|
||||||
if (std::find(sd.buildings.begin(), sd.buildings.end(),
|
|
||||||
item) == sd.buildings.end())
|
|
||||||
sd.buildings.push_back(item);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
print_line("Removing " + itos(item) + " " + path);
|
print_line("Removing " + itos(item));
|
||||||
if (data()->scenes.has(id)) {
|
if (data()->has_scene(id)) {
|
||||||
std::vector<int>::iterator b =
|
data()->remove_scene_item(id, item);
|
||||||
data()->scenes[id].buildings.begin();
|
|
||||||
std::vector<int>::iterator e =
|
|
||||||
data()->scenes[id].buildings.end();
|
|
||||||
// if (item_nodes.has(item))
|
|
||||||
// item_nodes[item]->queue_delete();
|
|
||||||
data()->scenes[id].buildings.erase(
|
|
||||||
std::remove(b, e, item),
|
|
||||||
data()->scenes[id].buildings.end());
|
|
||||||
if (item_nodes.has(item)) {
|
if (item_nodes.has(item)) {
|
||||||
item_nodes[item]->queue_delete();
|
item_nodes[item]->queue_delete();
|
||||||
item_nodes.erase(item);
|
item_nodes.erase(item);
|
||||||
@@ -214,27 +192,29 @@ void StreamWorld::request_item(int type, int item)
|
|||||||
void StreamWorld::update_items()
|
void StreamWorld::update_items()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const String *key = data()->scenes.next(nullptr);
|
List<String> keys;
|
||||||
while (key) {
|
data()->get_scene_keys_list(&keys);
|
||||||
if (!data()->scenes[*key].packed_scene.is_valid()) {
|
List<String>::Element *e = keys.front();
|
||||||
key = data()->scenes.next(key);
|
while (e) {
|
||||||
|
const String &key = e->get();
|
||||||
|
if (!data()->scene_get_packed_scene(key).is_valid()) {
|
||||||
|
e = e->next();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (i = 0; i < (int)data()->scenes[*key].buildings.size();
|
for (i = 0; i < (int)data()->scene_get_item_count(key); i++) {
|
||||||
i++) {
|
if (item_nodes.has(data()->scene_get_item(key, i)))
|
||||||
if (item_nodes.has(data()->scenes[*key].buildings[i]))
|
|
||||||
continue;
|
continue;
|
||||||
Node *psc =
|
Node *psc =
|
||||||
data()->scenes[*key].packed_scene->instance();
|
data()->scene_get_packed_scene(key)->instance();
|
||||||
Spatial *psp = Object::cast_to<Spatial>(psc);
|
Spatial *psp = Object::cast_to<Spatial>(psc);
|
||||||
item_nodes[data()->scenes[*key].buildings[i]] = psc;
|
item_nodes[data()->scene_get_item(key, i)] = psc;
|
||||||
current_scene->add_child(psp);
|
current_scene->add_child(psp);
|
||||||
psp->set_global_transform(
|
psp->set_global_transform(
|
||||||
data()->get_building(
|
data()->get_building(
|
||||||
data()->scenes[*key].buildings[i])
|
data()->scene_get_item(key, i))
|
||||||
.xform);
|
.xform);
|
||||||
}
|
}
|
||||||
key = data()->scenes.next(key);
|
e = e->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,26 +402,7 @@ void StreamWorld::_notification(int which)
|
|||||||
if (Engine::get_singleton()->is_editor_hint())
|
if (Engine::get_singleton()->is_editor_hint())
|
||||||
break;
|
break;
|
||||||
update_view();
|
update_view();
|
||||||
const String *key = data()->scenes.next(nullptr);
|
data()->scene_update();
|
||||||
while (key) {
|
|
||||||
if (data()->scenes[*key].packed_scene.is_valid()) {
|
|
||||||
key = data()->scenes.next(key);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Error result = data()->scenes[*key].loader->poll();
|
|
||||||
if (result == ERR_FILE_EOF) {
|
|
||||||
Ref<PackedScene> sc =
|
|
||||||
data()->scenes[*key]
|
|
||||||
.loader->get_resource();
|
|
||||||
data()->scenes[*key].packed_scene = sc;
|
|
||||||
print_line("Loaded scene: " +
|
|
||||||
data()->scenes[*key].path + " OK");
|
|
||||||
} else if (result != OK)
|
|
||||||
print_error("Could not load the resource :( " +
|
|
||||||
data()->scenes[*key].path + " " +
|
|
||||||
itos(result));
|
|
||||||
key = data()->scenes.next(key);
|
|
||||||
}
|
|
||||||
update_items();
|
update_items();
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
Reference in New Issue
Block a user