Separated module; generate grid size

This commit is contained in:
2024-10-30 17:31:24 +03:00
parent 6e1e864197
commit 245cb1e408
2 changed files with 693 additions and 642 deletions

View File

@@ -590,645 +590,3 @@ int BuildingLayoutGraph::get_layout_count() const
base_e.children([&count](flecs::entity e) { count++; }); base_e.children([&count](flecs::entity e) { count++; });
return count; return count;
} }
BuildingLayoutGraph::graph_module::graph_module(flecs::world ecs)
{
ecs.component<WorldEditor::components::buildings_layout_graph>();
ecs.component<WorldEditor::components::buildings_layout_base>();
ecs.system<WorldEditor::components::buildings_layout_floor>("FloorArea")
.kind(flecs::OnUpdate)
.without<WorldEditor::components::buildings_layout_area>()
.write<WorldEditor::components::buildings_layout_area>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_floor &f) {
flecs::entity floor_e = it.entity(count);
floor_e.set<
WorldEditor::components::buildings_layout_area>(
{ 0.0f });
});
ecs.system<WorldEditor::components::buildings_layout_unit>("UnitArea")
.kind(flecs::OnUpdate)
.without<WorldEditor::components::buildings_layout_area>()
.write<WorldEditor::components::buildings_layout_area>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_unit &f) {
flecs::entity floor_e = it.entity(count);
floor_e.set<
WorldEditor::components::buildings_layout_area>(
{ 0.0f });
});
ecs.system<WorldEditor::components::buildings_layout_zone>("ZoneArea")
.kind(flecs::OnUpdate)
.without<WorldEditor::components::buildings_layout_area>()
.write<WorldEditor::components::buildings_layout_area>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_zone &f) {
flecs::entity floor_e = it.entity(count);
floor_e.set<
WorldEditor::components::buildings_layout_area>(
{ 0.0f });
});
ecs.system<WorldEditor::components::buildings_layout_area,
const WorldEditor::components::buildings_layout_zone,
const WorldEditor::components::buildings_layout_floor_index>(
"MakeZoneAreas")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_area>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_area &area,
const WorldEditor::components::buildings_layout_zone &f,
const WorldEditor::components::
buildings_layout_floor_index &idx) {
flecs::entity zone_e = it.entity(count);
int index = idx.index;
float parea = 0.0f;
zone_e.children([index, &parea](flecs::entity ec) {
if (ec.has<WorldEditor::components::
buildings_layout_room>() &&
ec.has<WorldEditor::components::
buildings_layout_floor_index>() &&
ec.has<WorldEditor::components::
buildings_layout_area>()) {
if (ec.get<WorldEditor::components::
buildings_layout_floor_index>()
->index == index)
parea +=
ec.get<WorldEditor::components::
buildings_layout_area>()
->area;
}
});
area.area = parea;
print_line(String(zone_e.path()) +
" area: " + String::num(area.area));
});
ecs.system<WorldEditor::components::buildings_layout_area,
const WorldEditor::components::buildings_layout_unit,
const WorldEditor::components::buildings_layout_floor_index>(
"MakeUnitAreas")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_area>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_area &area,
const WorldEditor::components::buildings_layout_unit &f,
const WorldEditor::components::
buildings_layout_floor_index &idx) {
flecs::entity zone_e = it.entity(count);
int index = idx.index;
float parea = 0.0f;
zone_e.children([index, &parea](flecs::entity ec) {
if (ec.has<WorldEditor::components::
buildings_layout_zone>() &&
ec.has<WorldEditor::components::
buildings_layout_floor_index>() &&
ec.has<WorldEditor::components::
buildings_layout_area>()) {
if (ec.get<WorldEditor::components::
buildings_layout_floor_index>()
->index == index)
parea +=
ec.get<WorldEditor::components::
buildings_layout_area>()
->area;
}
});
area.area = parea;
print_line(String(zone_e.path()) +
" area: " + String::num(area.area));
});
ecs.system<WorldEditor::components::buildings_layout_area,
const WorldEditor::components::buildings_layout_floor,
const WorldEditor::components::buildings_layout_floor_index>(
"MakeFloorAreas")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_area>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_area &area,
const WorldEditor::components::buildings_layout_floor
&f,
const WorldEditor::components::
buildings_layout_floor_index &idx) {
flecs::entity floor_e = it.entity(count);
int index = idx.index;
float parea = 0.0f;
floor_e.children([index, &parea](flecs::entity ec) {
if (ec.has<WorldEditor::components::
buildings_layout_zone>() &&
ec.has<WorldEditor::components::
buildings_layout_floor_index>() &&
ec.has<WorldEditor::components::
buildings_layout_area>()) {
if (ec.get<WorldEditor::components::
buildings_layout_floor_index>()
->index == index)
parea +=
ec.get<WorldEditor::components::
buildings_layout_area>()
->area;
}
if (ec.has<WorldEditor::components::
buildings_layout_unit>() &&
ec.has<WorldEditor::components::
buildings_layout_floor_index>() &&
ec.has<WorldEditor::components::
buildings_layout_area>()) {
if (ec.get<WorldEditor::components::
buildings_layout_floor_index>()
->index == index)
parea +=
ec.get<WorldEditor::components::
buildings_layout_area>()
->area;
}
});
area.area = parea;
print_line(String(floor_e.path()) +
" area: " + String::num(area.area));
});
#if 0
ecs.system<WorldEditor::components::buildings_layout_area,
const WorldEditor::components::buildings_layout_floor,
const WorldEditor::components::buildings_layout_floor_index>(
"MakeAreas")
.kind(flecs::OnUpdate)
// .read<WorldEditor::components::buildings_layout_dirty>()
.with<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_area &area,
const WorldEditor::components::buildings_layout_floor
&f,
const WorldEditor::components::
buildings_layout_floor_index &idx) {
flecs::entity floor_e = it.entity(count);
flecs::world ecs_ = floor_e.world();
ecs_.system(ecs_.lookup("MakeZoneAreas")).run();
ecs_.system(ecs_.lookup("MakeUnitAreas")).run();
ecs_.system(ecs_.lookup("MakeFloorAreas")).run();
});
#endif
ecs.system<WorldEditor::components::buildings_layout_area,
const WorldEditor::components::buildings_layout_floor,
const WorldEditor::components::buildings_layout_floor_index>(
"MakeGridEntities")
.kind(flecs::OnUpdate)
// .read<WorldEditor::components::buildings_layout_dirty>()
.with<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_area &area,
const WorldEditor::components::buildings_layout_floor
&f,
const WorldEditor::components::
buildings_layout_floor_index &idx) {
#if 0
flecs::entity floor_e = it.entity(count);
List<flecs::entity> queue;
assert(false);
floor_e.children([&queue](flecs::entity ec) {
if (!ec.has<WorldEditor::components::
buildings_layout_floor>())
queue.push_back(ec);
});
while (!queue.empty()) {
flecs::entity e = queue.front()->get();
queue.pop_front();
}
#endif
});
#if 0
ecs.system<WorldEditor::components::buildings_layout_zone>(
"CreateZoneData")
.kind(flecs::OnUpdate)
.without<WorldEditor::components::buildings_layout_zone_data>()
.write<WorldEditor::components::buildings_layout_zone_data>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_zone
&p) {
flecs::entity e = it.entity(count);
e.set<WorldEditor::components::buildings_layout_zone_data>(
{ 0.0f, false });
e.add<WorldEditor::components::buildings_layout_dirty>();
String path(it.entity(count).path());
print_line("Create zone data: entity: " + path);
});
ecs.system<WorldEditor::components::buildings_layout_unit>(
"CreateUnitData")
.kind(flecs::OnUpdate)
.without<WorldEditor::components::buildings_layout_unit_data>()
.write<WorldEditor::components::buildings_layout_unit_data>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_unit
&p) {
flecs::entity e = it.entity(count);
e.set<WorldEditor::components::buildings_layout_unit_data>(
{ 0.0f });
e.add<WorldEditor::components::buildings_layout_dirty>();
String path(it.entity(count).path());
print_line("Create unit data: entity: " + path);
});
#if 0
ecs.system<WorldEditor::components::buildings_layout_floor>("CreateFloorIndex")
.kind(flecs::OnUpdate)
.without<WorldEditor::components::buildings_layout_floor_index>()
.write<WorldEditor::components::buildings_layout_floor_index>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_floor
&p) {
flecs::entity e = it.entity(count);
e.set<WorldEditor::components::buildings_layout_unit_data>(
{ 0.0f });
});
#endif
ecs.system<WorldEditor::components::buildings_layout_unit>(
"UpdateUnitData")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_unit_data>()
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_unit_data>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_unit
&p) {
flecs::entity e = it.entity(count);
float area = 0.0f;
e.children([&area](flecs::entity ec) {
if (ec.has<WorldEditor::components::
buildings_layout_zone_data>())
area += ec.get<WorldEditor::components::
buildings_layout_zone_data>()
->area;
});
WorldEditor::components::buildings_layout_unit_data
*udata = e.get_mut<
WorldEditor::components::
buildings_layout_unit_data>();
udata->area = area;
String path(it.entity(count).path());
print_line("Update unit data: entity: " + path +
" area: " + String::num(area));
e.remove<WorldEditor::components::
buildings_layout_dirty>();
BuildingLayoutGraph::get_singleton()
->get_layout_base()
.add<WorldEditor::components::
buildings_layout_dirty>();
});
ecs.system<WorldEditor::components::buildings_layout_zone>(
"UpdateZoneData")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_zone_data>()
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_zone_data>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_zone
&p) {
flecs::entity e = it.entity(count);
float area = 0.0f;
bool window = false;
e.children([&area, &window](flecs::entity ec) {
if (ec.has<WorldEditor::components::
buildings_layout_room_size>())
area += ec.get<WorldEditor::components::
buildings_layout_room_size>()
->area;
if (ec.has<WorldEditor::components::
buildings_layout_room>()) {
bool w =
ec.get<WorldEditor::components::
buildings_layout_room>()
->window;
if (w)
window = true;
}
});
WorldEditor::components::buildings_layout_zone_data
*zdata = e.get_mut<
WorldEditor::components::
buildings_layout_zone_data>();
zdata->area = area;
zdata->align_wall = window;
String path(it.entity(count).path());
print_line("Update zone data: entity: " + path +
" area: " + String::num(area));
e.remove<WorldEditor::components::
buildings_layout_dirty>();
flecs::entity parent_e = e.parent();
if (parent_e.has<WorldEditor::components::
buildings_layout_unit>())
parent_e.add<WorldEditor::components::
buildings_layout_dirty>();
BuildingLayoutGraph::get_singleton()
->get_layout_base()
.add<WorldEditor::components::
buildings_layout_dirty>();
});
ecs.system<WorldEditor::components::buildings_layout_floor>(
"PropogateFloorIndex")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_floor_index>()
.write<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_floor_data>()
.immediate()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_floor
&r) {
flecs::entity e = it.entity(count);
print_line("propogate: " + String(e.path()) + " " +
itos(r.index));
List<flecs::entity> queue;
float area = 0.0f;
/* e is a floor so skip it and add children instead*/
e.children([&area](flecs::entity ec) {
if (ec.has<WorldEditor::components::
buildings_layout_unit_data>())
area += ec.get<WorldEditor::components::
buildings_layout_unit_data>()
->area;
if (ec.has<WorldEditor::components::
buildings_layout_zone_data>())
area += ec.get<WorldEditor::components::
buildings_layout_zone_data>()
->area;
});
float size = Math::ceil(Math::sqrt(area) * 2.0f);
int grid_size = (int)Math::ceil(size / 2.0f);
e.set<WorldEditor::components::
buildings_layout_floor_data>(
{ area, grid_size });
e.children([&queue](flecs::entity ec) {
/* do not add children floors to the queue */
if (!ec.has<WorldEditor::components::
buildings_layout_floor>())
queue.push_back(ec);
});
while (!queue.empty()) {
flecs::entity qe = queue.front()->get();
queue.pop_front();
if (!qe.has<WorldEditor::components::
buildings_layout_floor>()) {
/* do not add children under another floor either */
qe.set<WorldEditor::components::
buildings_layout_floor_index>(
{ r.index });
qe.children([&queue](flecs::entity ec) {
queue.push_back(ec);
});
}
}
BuildingLayoutGraph::get_singleton()
->get_layout_base()
.add<WorldEditor::components::
buildings_layout_dirty>();
e.remove<WorldEditor::components::
buildings_layout_dirty>();
});
#if 0
ecs.system<WorldEditor::components::buildings_layout_graph>(
"CollectFloors")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_graph
&p) {
flecs::entity e = it.entity(count);
List<flecs::entity> queue;
queue.push_back(e);
while (!queue.empty()) {
flecs::entity em = queue.front()->get();
if (em.has<WorldEditor::components::buildings_layout_floor_data)
queue.pop_front();
em.children([&queue](flecs::entity ec) {
queue.push_back(ec);
});
}
e.remove<WorldEditor::components::
buildings_layout_dirty>();
});
ecs.system<WorldEditor::components::buildings_layout_base>(
"DestroyGrid")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_dirty>()
.immediate()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_base
&p) {
flecs::entity e = it.entity(count);
flecs::entity grid_base_e =
BuildingLayoutGraph::get_singleton()
->get_layout_grid_base();
grid_base_e.children([](flecs::entity ce) {
print_line("delete: " + String(ce.path()));
ce.destruct();
});
});
ecs.system<WorldEditor::components::buildings_layout_base>("CreateGrid")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_dirty>()
.immediate()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_base
&p) {
flecs::entity e = it.entity(count);
flecs::entity grid_base_e =
BuildingLayoutGraph::get_singleton()
->get_layout_grid_base();
e.children([&grid_base_e](flecs::entity ec) {
if (ec.has<WorldEditor::components::
buildings_layout_graph>()) {
print_line(String(grid_base_e.path()));
flecs::entity gc =
ec.world()
.entity(ec.name())
.child_of(grid_base_e);
gc.add<WorldEditor::components::
buildings_layout_grid>();
gc.add<WorldEditor::components::
buildings_layout_dirty>();
print_line("create: " +
String(gc.path()));
}
});
});
#endif
#if 0
ecs.system<WorldEditor::components::buildings_layout_grid>(
"PopulateGrid")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_dirty>()
.immediate()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_grid
&p) {
flecs::entity e = it.entity(count);
flecs::entity grid_layout_e =
BuildingLayoutGraph::get_singleton()
->get_layout_base();
flecs::entity layout_e
});
#endif
ecs.system<WorldEditor::components::buildings_layout_base>(
"UpdateGraph")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_base
&p) {
flecs::entity e = it.entity(count);
EditorEvent::get_singleton()->event.emit(
"update_layout_view", varray());
e.remove<WorldEditor::components::
buildings_layout_dirty>();
});
#endif
#if 0
ecs.observer<WorldEditor::components::buildings_layout_room>()
.event(flecs::OnSet)
.each([](flecs::entity e,
WorldEditor::components::buildings_layout_room &r) {
e.add<WorldEditor::components::buildings_layout_dirty>();
print_line("room set " + String(e.path()));
});
ecs.observer<WorldEditor::components::buildings_layout_zone>()
.event(flecs::OnSet)
.each([](flecs::entity e,
WorldEditor::components::buildings_layout_zone &r) {
e.add<WorldEditor::components::buildings_layout_zone>();
print_line("zone set " + String(e.path()));
});
ecs.observer<WorldEditor::components::buildings_layout_unit>()
.event(flecs::OnSet)
.each([](flecs::entity e,
WorldEditor::components::buildings_layout_unit &r) {
e.add<WorldEditor::components::buildings_layout_dirty>();
print_line("unit set " + String(e.path()));
});
#endif
ecs.system<const WorldEditor::components::buildings_layout_floor,
const WorldEditor::components::buildings_layout_floor_index,
const WorldEditor::components::buildings_layout_area>(
"FinishGraphUpdate")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_floor
&p,
const WorldEditor::components::
buildings_layout_floor_index &idx,
const WorldEditor::components::buildings_layout_area
&area) {
flecs::entity e = it.entity(count);
EditorEvent::get_singleton()->event.emit(
"update_layout_view", varray());
e.remove<WorldEditor::components::
buildings_layout_dirty>();
});
ecs.observer<const WorldEditor::components::buildings_layout_area>()
.event(flecs::OnSet)
.with<WorldEditor::components::buildings_layout_room>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::entity e,
const WorldEditor::components::buildings_layout_area
&r) {
/* if set for room make zone dirty */
flecs::entity parent_e = e.parent();
while (parent_e.is_valid()) {
print_line(String(parent_e.path()));
if (parent_e.has<
WorldEditor::components::
buildings_layout_floor>()) {
parent_e.add<
WorldEditor::components::
buildings_layout_dirty>();
break;
}
parent_e = parent_e.parent();
}
#if 0
if (parent_e.has<WorldEditor::components::
buildings_layout_zone>())
parent_e.add<
WorldEditor::components::
buildings_layout_dirty>();
parent_e.set<WorldEditor::components::
buildings_layout_area>(
{ 0.0f });
#endif
#if 0
flecs::world ecs_ = e.world();
ecs_.system(ecs_.lookup("MakeZoneAreas")).run();
ecs_.system(ecs_.lookup("MakeUnitAreas")).run();
ecs_.system(ecs_.lookup("MakeFloorAreas")).run();
#endif
print_line(String(e.path()) + ": set area");
});
/* Propagate floor index to children which are not floor */
ecs.observer<WorldEditor::components::buildings_layout_floor_index>()
.event(flecs::OnSet)
.with<WorldEditor::components::buildings_layout_floor>()
.each([](flecs::entity e,
const WorldEditor::components::
buildings_layout_floor_index &r) {
// e.add<WorldEditor::components::buildings_layout_dirty>();
if (e.has<WorldEditor::components::
buildings_layout_floor>()) {
List<flecs::entity> queue;
e.children([&queue](flecs::entity ec) {
queue.push_back(ec);
});
while (!queue.empty()) {
flecs::entity qe = queue.front()->get();
queue.pop_front();
if (!qe.has<WorldEditor::components::
buildings_layout_floor>()) {
qe.set<WorldEditor::components::
buildings_layout_floor_index>(
{ r.index });
print_line(String(qe.path()) +
" index set");
qe.children(
[&queue](flecs::entity
ec) {
queue.push_back(
ec);
});
}
}
}
EditorEvent::get_singleton()->event.emit(
"update_layout_view", varray());
print_line("floor set");
#if 0
List<flecs::entity> queue;
queue.push_back(e);
while (!queue.empty()) {
flecs::entity qe = queue.front()->get();
queue.pop_front();
if (!qe.has<WorldEditor::components::
buildings_layout_floor>()) {
qe.set<WorldEditor::components::
buildings_layout_floor_index>(
{ r.index });
}
}
BuildingLayoutGraph::get_singleton()
->get_layout_base()
.add<WorldEditor::components::
buildings_layout_dirty>();
#endif
});
}

View File

@@ -0,0 +1,693 @@
#include <cassert>
#include "base_data.h"
#include "world_editor.h"
#include "editor_event.h"
#include "building_layout_graph.h"
BuildingLayoutGraph::graph_module::graph_module(flecs::world ecs)
{
ecs.component<WorldEditor::components::buildings_layout_graph>();
ecs.component<WorldEditor::components::buildings_layout_base>();
ecs.system<WorldEditor::components::buildings_layout_floor>("FloorArea")
.kind(flecs::OnUpdate)
.without<WorldEditor::components::buildings_layout_area>()
.write<WorldEditor::components::buildings_layout_area>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_floor &f) {
flecs::entity floor_e = it.entity(count);
floor_e.set<
WorldEditor::components::buildings_layout_area>(
{ 0.0f });
});
ecs.system<WorldEditor::components::buildings_layout_unit>("UnitArea")
.kind(flecs::OnUpdate)
.without<WorldEditor::components::buildings_layout_area>()
.write<WorldEditor::components::buildings_layout_area>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_unit &f) {
flecs::entity floor_e = it.entity(count);
floor_e.set<
WorldEditor::components::buildings_layout_area>(
{ 0.0f });
});
ecs.system<WorldEditor::components::buildings_layout_zone>("ZoneArea")
.kind(flecs::OnUpdate)
.without<WorldEditor::components::buildings_layout_area>()
.write<WorldEditor::components::buildings_layout_area>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_zone &f) {
flecs::entity floor_e = it.entity(count);
floor_e.set<
WorldEditor::components::buildings_layout_area>(
{ 0.0f });
});
ecs.system<WorldEditor::components::buildings_layout_area,
const WorldEditor::components::buildings_layout_zone,
const WorldEditor::components::buildings_layout_floor_index>(
"MakeZoneAreas")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_area>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_area &area,
const WorldEditor::components::buildings_layout_zone &f,
const WorldEditor::components::
buildings_layout_floor_index &idx) {
flecs::entity zone_e = it.entity(count);
int index = idx.index;
float parea = 0.0f;
zone_e.children([index, &parea](flecs::entity ec) {
if (ec.has<WorldEditor::components::
buildings_layout_room>() &&
ec.has<WorldEditor::components::
buildings_layout_floor_index>() &&
ec.has<WorldEditor::components::
buildings_layout_area>()) {
if (ec.get<WorldEditor::components::
buildings_layout_floor_index>()
->index == index)
parea +=
ec.get<WorldEditor::components::
buildings_layout_area>()
->area;
}
});
area.area = parea;
print_line(String(zone_e.path()) +
" area: " + String::num(area.area));
});
ecs.system<WorldEditor::components::buildings_layout_area,
const WorldEditor::components::buildings_layout_unit,
const WorldEditor::components::buildings_layout_floor_index>(
"MakeUnitAreas")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_area>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_area &area,
const WorldEditor::components::buildings_layout_unit &f,
const WorldEditor::components::
buildings_layout_floor_index &idx) {
flecs::entity zone_e = it.entity(count);
int index = idx.index;
float parea = 0.0f;
zone_e.children([index, &parea](flecs::entity ec) {
if (ec.has<WorldEditor::components::
buildings_layout_zone>() &&
ec.has<WorldEditor::components::
buildings_layout_floor_index>() &&
ec.has<WorldEditor::components::
buildings_layout_area>()) {
if (ec.get<WorldEditor::components::
buildings_layout_floor_index>()
->index == index)
parea +=
ec.get<WorldEditor::components::
buildings_layout_area>()
->area;
}
});
area.area = parea;
print_line(String(zone_e.path()) +
" area: " + String::num(area.area));
});
ecs.system<WorldEditor::components::buildings_layout_area,
const WorldEditor::components::buildings_layout_floor,
const WorldEditor::components::buildings_layout_floor_index>(
"MakeFloorAreas")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_area>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_area &area,
const WorldEditor::components::buildings_layout_floor
&f,
const WorldEditor::components::
buildings_layout_floor_index &idx) {
flecs::entity floor_e = it.entity(count);
int index = idx.index;
float parea = 0.0f;
floor_e.children([index, &parea](flecs::entity ec) {
if (ec.has<WorldEditor::components::
buildings_layout_zone>() &&
ec.has<WorldEditor::components::
buildings_layout_floor_index>() &&
ec.has<WorldEditor::components::
buildings_layout_area>()) {
if (ec.get<WorldEditor::components::
buildings_layout_floor_index>()
->index == index)
parea +=
ec.get<WorldEditor::components::
buildings_layout_area>()
->area;
}
if (ec.has<WorldEditor::components::
buildings_layout_unit>() &&
ec.has<WorldEditor::components::
buildings_layout_floor_index>() &&
ec.has<WorldEditor::components::
buildings_layout_area>()) {
if (ec.get<WorldEditor::components::
buildings_layout_floor_index>()
->index == index)
parea +=
ec.get<WorldEditor::components::
buildings_layout_area>()
->area;
}
});
area.area = parea;
print_line(String(floor_e.path()) +
" area: " + String::num(area.area));
});
#if 0
ecs.system<WorldEditor::components::buildings_layout_area,
const WorldEditor::components::buildings_layout_floor,
const WorldEditor::components::buildings_layout_floor_index>(
"MakeAreas")
.kind(flecs::OnUpdate)
// .read<WorldEditor::components::buildings_layout_dirty>()
.with<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_area &area,
const WorldEditor::components::buildings_layout_floor
&f,
const WorldEditor::components::
buildings_layout_floor_index &idx) {
flecs::entity floor_e = it.entity(count);
flecs::world ecs_ = floor_e.world();
ecs_.system(ecs_.lookup("MakeZoneAreas")).run();
ecs_.system(ecs_.lookup("MakeUnitAreas")).run();
ecs_.system(ecs_.lookup("MakeFloorAreas")).run();
});
#endif
ecs.system<WorldEditor::components::buildings_layout_area,
const WorldEditor::components::buildings_layout_floor,
const WorldEditor::components::buildings_layout_floor_index>(
"MakeGridEntities")
.kind(flecs::OnUpdate)
// .read<WorldEditor::components::buildings_layout_dirty>()
.with<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_area &area,
const WorldEditor::components::buildings_layout_floor
&f,
const WorldEditor::components::
buildings_layout_floor_index &idx) {
#if 0
flecs::entity floor_e = it.entity(count);
List<flecs::entity> queue;
assert(false);
floor_e.children([&queue](flecs::entity ec) {
if (!ec.has<WorldEditor::components::
buildings_layout_floor>())
queue.push_back(ec);
});
while (!queue.empty()) {
flecs::entity e = queue.front()->get();
queue.pop_front();
}
#endif
});
#if 0
ecs.system<WorldEditor::components::buildings_layout_zone>(
"CreateZoneData")
.kind(flecs::OnUpdate)
.without<WorldEditor::components::buildings_layout_zone_data>()
.write<WorldEditor::components::buildings_layout_zone_data>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_zone
&p) {
flecs::entity e = it.entity(count);
e.set<WorldEditor::components::buildings_layout_zone_data>(
{ 0.0f, false });
e.add<WorldEditor::components::buildings_layout_dirty>();
String path(it.entity(count).path());
print_line("Create zone data: entity: " + path);
});
ecs.system<WorldEditor::components::buildings_layout_unit>(
"CreateUnitData")
.kind(flecs::OnUpdate)
.without<WorldEditor::components::buildings_layout_unit_data>()
.write<WorldEditor::components::buildings_layout_unit_data>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_unit
&p) {
flecs::entity e = it.entity(count);
e.set<WorldEditor::components::buildings_layout_unit_data>(
{ 0.0f });
e.add<WorldEditor::components::buildings_layout_dirty>();
String path(it.entity(count).path());
print_line("Create unit data: entity: " + path);
});
#if 0
ecs.system<WorldEditor::components::buildings_layout_floor>("CreateFloorIndex")
.kind(flecs::OnUpdate)
.without<WorldEditor::components::buildings_layout_floor_index>()
.write<WorldEditor::components::buildings_layout_floor_index>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_floor
&p) {
flecs::entity e = it.entity(count);
e.set<WorldEditor::components::buildings_layout_unit_data>(
{ 0.0f });
});
#endif
ecs.system<WorldEditor::components::buildings_layout_unit>(
"UpdateUnitData")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_unit_data>()
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_unit_data>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_unit
&p) {
flecs::entity e = it.entity(count);
float area = 0.0f;
e.children([&area](flecs::entity ec) {
if (ec.has<WorldEditor::components::
buildings_layout_zone_data>())
area += ec.get<WorldEditor::components::
buildings_layout_zone_data>()
->area;
});
WorldEditor::components::buildings_layout_unit_data
*udata = e.get_mut<
WorldEditor::components::
buildings_layout_unit_data>();
udata->area = area;
String path(it.entity(count).path());
print_line("Update unit data: entity: " + path +
" area: " + String::num(area));
e.remove<WorldEditor::components::
buildings_layout_dirty>();
BuildingLayoutGraph::get_singleton()
->get_layout_base()
.add<WorldEditor::components::
buildings_layout_dirty>();
});
ecs.system<WorldEditor::components::buildings_layout_zone>(
"UpdateZoneData")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_zone_data>()
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_zone_data>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_zone
&p) {
flecs::entity e = it.entity(count);
float area = 0.0f;
bool window = false;
e.children([&area, &window](flecs::entity ec) {
if (ec.has<WorldEditor::components::
buildings_layout_room_size>())
area += ec.get<WorldEditor::components::
buildings_layout_room_size>()
->area;
if (ec.has<WorldEditor::components::
buildings_layout_room>()) {
bool w =
ec.get<WorldEditor::components::
buildings_layout_room>()
->window;
if (w)
window = true;
}
});
WorldEditor::components::buildings_layout_zone_data
*zdata = e.get_mut<
WorldEditor::components::
buildings_layout_zone_data>();
zdata->area = area;
zdata->align_wall = window;
String path(it.entity(count).path());
print_line("Update zone data: entity: " + path +
" area: " + String::num(area));
e.remove<WorldEditor::components::
buildings_layout_dirty>();
flecs::entity parent_e = e.parent();
if (parent_e.has<WorldEditor::components::
buildings_layout_unit>())
parent_e.add<WorldEditor::components::
buildings_layout_dirty>();
BuildingLayoutGraph::get_singleton()
->get_layout_base()
.add<WorldEditor::components::
buildings_layout_dirty>();
});
ecs.system<WorldEditor::components::buildings_layout_floor>(
"PropogateFloorIndex")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_floor_index>()
.write<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_floor_data>()
.immediate()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_floor
&r) {
flecs::entity e = it.entity(count);
print_line("propogate: " + String(e.path()) + " " +
itos(r.index));
List<flecs::entity> queue;
float area = 0.0f;
/* e is a floor so skip it and add children instead*/
e.children([&area](flecs::entity ec) {
if (ec.has<WorldEditor::components::
buildings_layout_unit_data>())
area += ec.get<WorldEditor::components::
buildings_layout_unit_data>()
->area;
if (ec.has<WorldEditor::components::
buildings_layout_zone_data>())
area += ec.get<WorldEditor::components::
buildings_layout_zone_data>()
->area;
});
float size = Math::ceil(Math::sqrt(area) * 2.0f);
int grid_size = (int)Math::ceil(size / 2.0f);
e.set<WorldEditor::components::
buildings_layout_floor_data>(
{ area, grid_size });
e.children([&queue](flecs::entity ec) {
/* do not add children floors to the queue */
if (!ec.has<WorldEditor::components::
buildings_layout_floor>())
queue.push_back(ec);
});
while (!queue.empty()) {
flecs::entity qe = queue.front()->get();
queue.pop_front();
if (!qe.has<WorldEditor::components::
buildings_layout_floor>()) {
/* do not add children under another floor either */
qe.set<WorldEditor::components::
buildings_layout_floor_index>(
{ r.index });
qe.children([&queue](flecs::entity ec) {
queue.push_back(ec);
});
}
}
BuildingLayoutGraph::get_singleton()
->get_layout_base()
.add<WorldEditor::components::
buildings_layout_dirty>();
e.remove<WorldEditor::components::
buildings_layout_dirty>();
});
#if 0
ecs.system<WorldEditor::components::buildings_layout_graph>(
"CollectFloors")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_graph
&p) {
flecs::entity e = it.entity(count);
List<flecs::entity> queue;
queue.push_back(e);
while (!queue.empty()) {
flecs::entity em = queue.front()->get();
if (em.has<WorldEditor::components::buildings_layout_floor_data)
queue.pop_front();
em.children([&queue](flecs::entity ec) {
queue.push_back(ec);
});
}
e.remove<WorldEditor::components::
buildings_layout_dirty>();
});
ecs.system<WorldEditor::components::buildings_layout_base>(
"DestroyGrid")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_dirty>()
.immediate()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_base
&p) {
flecs::entity e = it.entity(count);
flecs::entity grid_base_e =
BuildingLayoutGraph::get_singleton()
->get_layout_grid_base();
grid_base_e.children([](flecs::entity ce) {
print_line("delete: " + String(ce.path()));
ce.destruct();
});
});
ecs.system<WorldEditor::components::buildings_layout_base>("CreateGrid")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_dirty>()
.immediate()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_base
&p) {
flecs::entity e = it.entity(count);
flecs::entity grid_base_e =
BuildingLayoutGraph::get_singleton()
->get_layout_grid_base();
e.children([&grid_base_e](flecs::entity ec) {
if (ec.has<WorldEditor::components::
buildings_layout_graph>()) {
print_line(String(grid_base_e.path()));
flecs::entity gc =
ec.world()
.entity(ec.name())
.child_of(grid_base_e);
gc.add<WorldEditor::components::
buildings_layout_grid>();
gc.add<WorldEditor::components::
buildings_layout_dirty>();
print_line("create: " +
String(gc.path()));
}
});
});
#endif
#if 0
ecs.system<WorldEditor::components::buildings_layout_grid>(
"PopulateGrid")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_dirty>()
.immediate()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_grid
&p) {
flecs::entity e = it.entity(count);
flecs::entity grid_layout_e =
BuildingLayoutGraph::get_singleton()
->get_layout_base();
flecs::entity layout_e
});
#endif
ecs.system<WorldEditor::components::buildings_layout_base>(
"UpdateGraph")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_base
&p) {
flecs::entity e = it.entity(count);
EditorEvent::get_singleton()->event.emit(
"update_layout_view", varray());
e.remove<WorldEditor::components::
buildings_layout_dirty>();
});
#endif
#if 0
ecs.observer<WorldEditor::components::buildings_layout_room>()
.event(flecs::OnSet)
.each([](flecs::entity e,
WorldEditor::components::buildings_layout_room &r) {
e.add<WorldEditor::components::buildings_layout_dirty>();
print_line("room set " + String(e.path()));
});
ecs.observer<WorldEditor::components::buildings_layout_zone>()
.event(flecs::OnSet)
.each([](flecs::entity e,
WorldEditor::components::buildings_layout_zone &r) {
e.add<WorldEditor::components::buildings_layout_zone>();
print_line("zone set " + String(e.path()));
});
ecs.observer<WorldEditor::components::buildings_layout_unit>()
.event(flecs::OnSet)
.each([](flecs::entity e,
WorldEditor::components::buildings_layout_unit &r) {
e.add<WorldEditor::components::buildings_layout_dirty>();
print_line("unit set " + String(e.path()));
});
#endif
ecs.system<const WorldEditor::components::buildings_layout_floor,
const WorldEditor::components::buildings_layout_floor_index,
const WorldEditor::components::buildings_layout_area>(
"CreateFloorData")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_floor_data>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_floor
&p,
const WorldEditor::components::
buildings_layout_floor_index &idx,
const WorldEditor::components::buildings_layout_area
&area) {
flecs::entity e = it.entity(count);
float grid_size = Math::ceil(
Math::ceil(Math::sqrt(area.area)) / 4.0f);
e.set<WorldEditor::components::
buildings_layout_floor_data>(
{ (int)Math::ceil(grid_size) });
print_line("grid size: " +
itos((int)Math::ceil(grid_size)));
assert(false);
});
ecs.system<const WorldEditor::components::buildings_layout_floor,
const WorldEditor::components::buildings_layout_floor_index,
const WorldEditor::components::buildings_layout_area>(
"CreateGridEntity")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_grid>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_floor
&p,
const WorldEditor::components::
buildings_layout_floor_index &idx,
const WorldEditor::components::buildings_layout_area
&area) {
flecs::entity e = it.entity(count);
flecs::entity grid_e = e.lookup("grid");
if (!grid_e.is_valid())
grid_e = e.world().entity("grid").child_of(e);
grid_e.add<
WorldEditor::components::buildings_layout_grid>();
/* create grid here */
});
ecs.system<const WorldEditor::components::buildings_layout_floor,
const WorldEditor::components::buildings_layout_floor_index,
const WorldEditor::components::buildings_layout_area>(
"FinishGraphUpdate")
.kind(flecs::OnUpdate)
.with<WorldEditor::components::buildings_layout_dirty>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::iter &it, size_t count,
const WorldEditor::components::buildings_layout_floor
&p,
const WorldEditor::components::
buildings_layout_floor_index &idx,
const WorldEditor::components::buildings_layout_area
&area) {
flecs::entity e = it.entity(count);
EditorEvent::get_singleton()->event.emit(
"update_layout_view", varray());
e.remove<WorldEditor::components::
buildings_layout_dirty>();
});
ecs.observer<const WorldEditor::components::buildings_layout_area>()
.event(flecs::OnSet)
.with<WorldEditor::components::buildings_layout_room>()
.write<WorldEditor::components::buildings_layout_dirty>()
.each([](flecs::entity e,
const WorldEditor::components::buildings_layout_area
&r) {
/* if set for room make zone dirty */
flecs::entity parent_e = e.parent();
while (parent_e.is_valid()) {
print_line(String(parent_e.path()));
if (parent_e.has<
WorldEditor::components::
buildings_layout_floor>()) {
parent_e.add<
WorldEditor::components::
buildings_layout_dirty>();
break;
}
parent_e = parent_e.parent();
}
#if 0
if (parent_e.has<WorldEditor::components::
buildings_layout_zone>())
parent_e.add<
WorldEditor::components::
buildings_layout_dirty>();
parent_e.set<WorldEditor::components::
buildings_layout_area>(
{ 0.0f });
#endif
#if 0
flecs::world ecs_ = e.world();
ecs_.system(ecs_.lookup("MakeZoneAreas")).run();
ecs_.system(ecs_.lookup("MakeUnitAreas")).run();
ecs_.system(ecs_.lookup("MakeFloorAreas")).run();
#endif
print_line(String(e.path()) + ": set area");
});
/* Propagate floor index to children which are not floor */
ecs.observer<WorldEditor::components::buildings_layout_floor_index>()
.event(flecs::OnSet)
.with<WorldEditor::components::buildings_layout_floor>()
.each([](flecs::entity e,
const WorldEditor::components::
buildings_layout_floor_index &r) {
// e.add<WorldEditor::components::buildings_layout_dirty>();
if (e.has<WorldEditor::components::
buildings_layout_floor>()) {
List<flecs::entity> queue;
e.children([&queue](flecs::entity ec) {
queue.push_back(ec);
});
while (!queue.empty()) {
flecs::entity qe = queue.front()->get();
queue.pop_front();
if (!qe.has<WorldEditor::components::
buildings_layout_floor>()) {
qe.set<WorldEditor::components::
buildings_layout_floor_index>(
{ r.index });
print_line(String(qe.path()) +
" index set");
qe.children(
[&queue](flecs::entity
ec) {
queue.push_back(
ec);
});
}
}
}
EditorEvent::get_singleton()->event.emit(
"update_layout_view", varray());
print_line("floor set");
#if 0
List<flecs::entity> queue;
queue.push_back(e);
while (!queue.empty()) {
flecs::entity qe = queue.front()->get();
queue.pop_front();
if (!qe.has<WorldEditor::components::
buildings_layout_floor>()) {
qe.set<WorldEditor::components::
buildings_layout_floor_index>(
{ r.index });
}
}
BuildingLayoutGraph::get_singleton()
->get_layout_base()
.add<WorldEditor::components::
buildings_layout_dirty>();
#endif
});
}