Started using ECS
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
#include <algorithm>
|
||||
#include <core/os/memory.h>
|
||||
#include <core/io/json.h>
|
||||
#include <core/os/time.h>
|
||||
@@ -7,12 +8,23 @@
|
||||
#include <scene/3d/spatial.h>
|
||||
#include <scene/3d/mesh_instance.h>
|
||||
#include "from_string.h"
|
||||
#include <flecs/flecs.h>
|
||||
#include "flecs/flecs.h"
|
||||
#include "buildings_data.h"
|
||||
|
||||
BuildingsData *BuildingsData::singleton;
|
||||
|
||||
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()
|
||||
: 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
|
||||
{
|
||||
return buildings.size();
|
||||
|
||||
@@ -22,13 +22,24 @@ public:
|
||||
String line_name;
|
||||
};
|
||||
/* Scene objects data */
|
||||
struct scene_data {
|
||||
Ref<PackedScene> packed_scene;
|
||||
String path;
|
||||
Ref<ResourceInteractiveLoader> loader;
|
||||
std::vector<int> buildings;
|
||||
};
|
||||
HashMap<String, struct scene_data> scenes;
|
||||
//private:
|
||||
// HashMap<String, struct scene_data> scenes;
|
||||
|
||||
public:
|
||||
void get_scene_keys_list(List<String> *keys) const;
|
||||
bool has_scene(const String &key) const;
|
||||
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 */
|
||||
HashMap<String, String> building_data;
|
||||
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;
|
||||
if (id == "empty")
|
||||
return;
|
||||
String path = data()->building_data[id];
|
||||
switch (type) {
|
||||
case 0:
|
||||
if (!data()->scenes.has(id)) {
|
||||
print_line("Requesting " + itos(item) + " " + path);
|
||||
struct BuildingsData::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);
|
||||
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);
|
||||
}
|
||||
if (!data()->has_scene(id))
|
||||
data()->create_scene_data(id, item);
|
||||
else
|
||||
data()->add_scene_item(id, item);
|
||||
break;
|
||||
case 1:
|
||||
print_line("Removing " + itos(item) + " " + path);
|
||||
if (data()->scenes.has(id)) {
|
||||
std::vector<int>::iterator b =
|
||||
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());
|
||||
print_line("Removing " + itos(item));
|
||||
if (data()->has_scene(id)) {
|
||||
data()->remove_scene_item(id, item);
|
||||
if (item_nodes.has(item)) {
|
||||
item_nodes[item]->queue_delete();
|
||||
item_nodes.erase(item);
|
||||
@@ -214,27 +192,29 @@ void StreamWorld::request_item(int type, int item)
|
||||
void StreamWorld::update_items()
|
||||
{
|
||||
int i;
|
||||
const String *key = data()->scenes.next(nullptr);
|
||||
while (key) {
|
||||
if (!data()->scenes[*key].packed_scene.is_valid()) {
|
||||
key = data()->scenes.next(key);
|
||||
List<String> keys;
|
||||
data()->get_scene_keys_list(&keys);
|
||||
List<String>::Element *e = keys.front();
|
||||
while (e) {
|
||||
const String &key = e->get();
|
||||
if (!data()->scene_get_packed_scene(key).is_valid()) {
|
||||
e = e->next();
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < (int)data()->scenes[*key].buildings.size();
|
||||
i++) {
|
||||
if (item_nodes.has(data()->scenes[*key].buildings[i]))
|
||||
for (i = 0; i < (int)data()->scene_get_item_count(key); i++) {
|
||||
if (item_nodes.has(data()->scene_get_item(key, i)))
|
||||
continue;
|
||||
Node *psc =
|
||||
data()->scenes[*key].packed_scene->instance();
|
||||
data()->scene_get_packed_scene(key)->instance();
|
||||
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);
|
||||
psp->set_global_transform(
|
||||
data()->get_building(
|
||||
data()->scenes[*key].buildings[i])
|
||||
data()->scene_get_item(key, i))
|
||||
.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())
|
||||
break;
|
||||
update_view();
|
||||
const String *key = data()->scenes.next(nullptr);
|
||||
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);
|
||||
}
|
||||
data()->scene_update();
|
||||
update_items();
|
||||
|
||||
} break;
|
||||
|
||||
Reference in New Issue
Block a user