Started using ECS

This commit is contained in:
2024-09-28 05:23:24 +03:00
parent dfb24aa4b2
commit e19dbd7a4f
3 changed files with 184 additions and 68 deletions

View File

@@ -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();

View File

@@ -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;

View File

@@ -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;