proper command interface was implemented

This commit is contained in:
2024-11-03 06:23:10 +03:00
parent e3f37cdcdc
commit 50b2ae5363
7 changed files with 469 additions and 110 deletions

View File

@@ -369,12 +369,12 @@ void BuildingLayoutGraph::save_layouts()
buildings_layout_order>()
->index;
entry["order"] = order;
int command = -1;
if (e.has<WorldEditor::components::buildings_layout_command>())
command = e.get<WorldEditor::components::
buildings_layout_command>()
->command;
entry["command"] = command;
Array commands;
if (e.has<WorldEditor::components::buildings_layout_commands>())
commands = e.get<WorldEditor::components::
buildings_layout_commands>()
->to_array();
entry["commands"] = commands;
if (e.has<WorldEditor::components::buildings_layout_graph>()) {
entry["type"] = "layout";
/* remember it has floor component too */
@@ -470,7 +470,7 @@ void BuildingLayoutGraph::load_layouts()
String name = entry["name"];
String type = entry["type"];
int order = entry.get("order", 0);
int command = entry.get("command", -1);
Array commands = entry.get("commands", Array());
print_line("name: " + name + " type: " + type);
int parent = entry.get("parent", -1);
flecs::entity parent_e = base;
@@ -483,8 +483,10 @@ void BuildingLayoutGraph::load_layouts()
print_line(String(e.path()));
e.set<WorldEditor::components::buildings_layout_order>(
{ order });
e.set<WorldEditor::components::buildings_layout_command>(
{ command });
e.add<WorldEditor::components::buildings_layout_commands>();
e.get_mut<WorldEditor::components::buildings_layout_commands>()
->from_array(commands);
e.modified<WorldEditor::components::buildings_layout_commands>();
if (type == "layout") {
e.add<WorldEditor::components::buildings_layout_graph>();
if (entry.has("floor_index")) {
@@ -586,7 +588,12 @@ int BuildingLayoutGraph::get_layout_count() const
int BuildingLayoutGraph::get_children_count(flecs::entity base_e) const
{
ecs_iter_t it = ecs_children(base_e.world().c_ptr(), base_e.id());
int32_t cnt = ecs_iter_count(&it);
return (int)cnt;
#if 0
int count = 0;
base_e.children([&count](flecs::entity e) { count++; });
return count;
#endif
}

View File

@@ -245,43 +245,106 @@ void BuildingLayoutGraphUI::update_buttons(ColorRect *canvas)
args.size());
}
if (e.has<WorldEditor::components::
buildings_layout_command>()) {
buildings_layout_commands>()) {
std::vector<Variant> args = {
/* clang-format off */
"Commands...", "display_commands_button"
};
HashMap<String, Object *> save_data;
ui_field::ui_field_builder(canvas, box, "b#$",
args.data(),
args.size(),
&save_data);
assert(save_data.has(
"display_commands_button"));
Button *cmd_button = Object::cast_to<Button>(
save_data["display_commands_button"]);
cmd_button->connect(
"pressed", this, "show_command_editor",
varray(canvas, String(e.path())));
#if 0
int cmd,
cmd_count =
e.get<WorldEditor::components::
buildings_layout_commands>()
->commands.size();
for (cmd = 0; cmd < cmd_count; cmd++) {
std::vector<Variant> args = {
/* clang-format off */
"Command:",
"None", 3,
-1, "None",
1, "Arrach1",
2, "Attach2",
"command",
/* clang-format on */
};
HashMap<String, Object *> save_data;
ui_field::ui_field_builder(
canvas, box, "p{h{lo#$}}", args.data(),
args.size(), &save_data);
assert(!save_data.empty());
List<String> keys;
save_data.get_key_list(&keys);
print_line(keys.front()->get());
assert(save_data["command"]);
OptionButton *ob =
Object::cast_to<OptionButton>(
save_data["command"]);
int command =
e.get<WorldEditor::components::
buildings_layout_command>()
->command;
int selected = -1;
selected = ob->get_popup()->get_item_index(
command);
print_line("selected: " + itos(command) + " " +
itos(selected));
ob->select(selected);
ob->connect("item_selected", this,
"command_entered",
varray(save_data["command"],
String(e.path())));
"Delete"
/* clang-format on */
};
HashMap<String, Object *> save_data;
ui_field::ui_field_builder(
canvas, box, "p{h{lo#$b}}",
args.data(), args.size(),
&save_data);
assert(!save_data.empty());
List<String> keys;
save_data.get_key_list(&keys);
print_line(keys.front()->get());
assert(save_data["command"]);
OptionButton *ob =
Object::cast_to<OptionButton>(
save_data["command"]);
int command =
e.get<WorldEditor::components::
buildings_layout_commands>()
->commands[cmd]
.command;
int selected = -1;
selected =
ob->get_popup()->get_item_index(
command);
print_line(
"selected: " + itos(command) +
" " + itos(selected));
ob->set_meta("cmd", cmd);
ob->select(selected);
ob->connect("item_selected", this,
"command_entered",
varray(save_data["command"],
String(e.path())));
}
{
std::vector<Variant> args = {
/* clang-format off */
"Command:",
"None", 3,
-1, "None",
1, "Arrach1",
2, "Attach2",
"command",
"New"
/* clang-format on */
};
HashMap<String, Object *> save_data;
ui_field::ui_field_builder(
canvas, box, "p{h{lo#$b}}",
args.data(), args.size(),
&save_data);
assert(!save_data.empty());
List<String> keys;
save_data.get_key_list(&keys);
print_line(keys.front()->get());
assert(save_data["command"]);
OptionButton *ob =
Object::cast_to<OptionButton>(
save_data["command"]);
int selected = -1;
ob->select(selected);
ob->set_meta("cmd", -1);
ob->connect("item_selected", this,
"command_entered",
varray(save_data["command"],
String(e.path())));
}
#endif
}
button->get_popup()->connect(
"id_pressed", this, "menu_pressed",
@@ -377,6 +440,7 @@ void BuildingLayoutGraphUI::order_entered(float value, Control *item,
e.modified<WorldEditor::components::buildings_layout_order>();
print_line("data set order");
}
static PopupPanel *command_editor = nullptr;
void BuildingLayoutGraphUI::command_entered(int index, Control *item,
const String &path)
{
@@ -384,10 +448,115 @@ void BuildingLayoutGraphUI::command_entered(int index, Control *item,
flecs::world ecs = BaseData::get_singleton()->get();
flecs::entity e = ecs.lookup(path.ascii().ptr());
assert(e.is_valid());
e.get_mut<WorldEditor::components::buildings_layout_command>()->command =
index;
e.modified<WorldEditor::components::buildings_layout_command>();
int cmd = item->get_meta("cmd");
if (cmd >= 0) {
int command = index;
Vector<Variant> args;
WorldEditor::components::buildings_layout_commands *c = e.get_mut<
WorldEditor::components::buildings_layout_commands>();
c->commands.write[cmd].command = index;
c->commands.write[cmd].args = args;
} else {
int command = index;
Vector<Variant> args;
WorldEditor::components::buildings_layout_commands *c = e.get_mut<
WorldEditor::components::buildings_layout_commands>();
c->commands.push_back({ command, args });
}
e.modified<WorldEditor::components::buildings_layout_commands>();
print_line("data set command");
command_editor->hide();
command_editor->queue_delete();
command_editor = nullptr;
update_graph();
}
void BuildingLayoutGraphUI::show_command_editor(Control *item,
const String &path)
{
if (!command_editor) {
command_editor = memnew(PopupPanel);
item->add_child(command_editor);
} else {
command_editor->queue_delete();
command_editor = memnew(PopupPanel);
item->add_child(command_editor);
}
command_editor->set_anchor(Margin::MARGIN_LEFT, 0.2f);
command_editor->set_anchor(Margin::MARGIN_TOP, 0.2f);
command_editor->set_anchor(Margin::MARGIN_RIGHT, 0.8f);
command_editor->set_anchor(Margin::MARGIN_BOTTOM, 0.8f);
command_editor->set_custom_minimum_size(Vector2(400, 300));
flecs::world ecs = BaseData::get_singleton()->get();
flecs::entity e = ecs.lookup(path.ascii().ptr());
int cmd,
cmd_count =
e.get<WorldEditor::components::buildings_layout_commands>()
->commands.size();
VBoxContainer *vb = memnew(VBoxContainer);
command_editor->add_child(vb);
for (cmd = 0; cmd < cmd_count; cmd++) {
std::vector<Variant> args = {
/* clang-format off */
"Command:",
"None", 3,
-1, "None",
1, "Arrach1",
2, "Attach2",
"command",
"Delete"
/* clang-format on */
};
HashMap<String, Object *> save_data;
ui_field::ui_field_builder(item, vb, "p{h{lo#$b}}", args.data(),
args.size(), &save_data);
assert(!save_data.empty());
List<String> keys;
save_data.get_key_list(&keys);
print_line(keys.front()->get());
assert(save_data["command"]);
OptionButton *ob =
Object::cast_to<OptionButton>(save_data["command"]);
int command =
e.get<WorldEditor::components::buildings_layout_commands>()
->commands[cmd]
.command;
int selected = -1;
selected = ob->get_popup()->get_item_index(command);
print_line("selected: " + itos(command) + " " + itos(selected));
ob->set_meta("cmd", cmd);
ob->select(selected);
ob->connect("item_selected", this, "command_entered",
varray(save_data["command"], String(e.path())));
}
{
std::vector<Variant> args = {
/* clang-format off */
"Command:",
"None", 3,
-1, "None",
1, "Arrach1",
2, "Attach2",
"command",
"New"
/* clang-format on */
};
HashMap<String, Object *> save_data;
ui_field::ui_field_builder(item, vb, "p{h{lo#$b}}", args.data(),
args.size(), &save_data);
assert(!save_data.empty());
List<String> keys;
save_data.get_key_list(&keys);
print_line(keys.front()->get());
assert(save_data["command"]);
OptionButton *ob =
Object::cast_to<OptionButton>(save_data["command"]);
int selected = -1;
ob->select(selected);
ob->set_meta("cmd", -1);
ob->connect("item_selected", this, "command_entered",
varray(save_data["command"], String(e.path())));
}
command_editor->popup_centered();
}
void BuildingLayoutGraphUI::_bind_methods()
{
@@ -415,4 +584,6 @@ void BuildingLayoutGraphUI::_bind_methods()
"item"
"path"),
&BuildingLayoutGraphUI::command_entered);
ClassDB::bind_method(D_METHOD("show_command_editor", "item", "path"),
&BuildingLayoutGraphUI::show_command_editor);
}

View File

@@ -165,6 +165,7 @@ public:
const String &path);
void order_entered(float value, Control *item, const String &path);
void command_entered(int index, Control *item, const String &path);
void show_command_editor(Control *item, const String &path);
Vector<Vector2> buttons;
#define DEPTH_MUL 160
#define Y_MUL 220

View File

@@ -6,6 +6,65 @@
#define MIN_ROOM_SIZE 16 /* 4 * 4 tiles */
struct state {
Rect2i main_rect;
Rect2i last_rect;
bool first;
int count;
List<Rect2i> rectangles;
List<bool> windows;
struct room_data {
float area;
bool wall;
};
List<struct room_data> rooms;
Vector2i get_new_position(int way)
{
Vector2i ret;
if (way == 0) {
ret.x = last_rect.position.x + last_rect.size.x;
ret.y = last_rect.position.y;
} else {
ret.x = last_rect.position.x;
ret.y = last_rect.position.y + last_rect.size.y;
}
return ret;
}
Vector2i get_new_size(int way, float area)
{
Vector2i ret;
if (way == 0) {
ret.y = last_rect.size.y;
ret.x = area / last_rect.size.y;
} else {
ret.x = last_rect.size.x;
ret.y = area / last_rect.size.x;
}
return ret;
}
void add_rect(const Rect2i &rect, bool window)
{
rectangles.push_back(rect);
windows.push_back(window);
}
void pack_room(float area, bool wall)
{
rooms.push_back({ area, wall });
}
void next()
{
last_rect = main_rect;
}
void dump()
{
List<Rect2i>::Element *e = rectangles.front();
while (e) {
print_line(e->get().operator String());
e = e->next();
}
}
};
BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
{
ecs.module<BuildingLayoutGraph::graph_module>();
@@ -279,6 +338,94 @@ BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
print_line("grid size: " +
itos((int)Math::ceil(grid_size)));
});
ecs.system<WorldEditor::components::buildings_layout_zone>(
"AssembleZones")
.kind(0)
.each([module_name](
flecs::iter &it, size_t count,
WorldEditor::components::buildings_layout_zone &f) {
flecs::entity zone_e = it.entity(count);
flecs::query<const WorldEditor::components::
buildings_layout_order,
const WorldEditor::components::
buildings_layout_room,
const WorldEditor::components::
buildings_layout_area,
const WorldEditor::components::
buildings_layout_commands>
q = zone_e.world()
.query_builder<
const WorldEditor::components::
buildings_layout_order,
const WorldEditor::components::
buildings_layout_room,
const WorldEditor::components::
buildings_layout_area,
const WorldEditor::components::
buildings_layout_commands>()
.with(flecs::ChildOf, zone_e)
.order_by<
WorldEditor::components::
buildings_layout_order>(
[](flecs::entity_t e1,
const WorldEditor::components::
buildings_layout_order
*d1,
flecs::entity_t e2,
const WorldEditor::components::
buildings_layout_order
*d2) {
return (d1->index >
d2->index) -
(d1->index <
d2->index);
})
.build();
int c = 0;
struct state state;
state.first = true;
state.count = 0;
q.each([&c, &state](
flecs::entity e,
const WorldEditor::components::
buildings_layout_order &order,
const WorldEditor::components::
buildings_layout_room &r,
const WorldEditor::components::
buildings_layout_area &area,
const WorldEditor::components::
buildings_layout_commands &cmd) {
int i, j;
String output = String(e.path()) + "\n";
output +=
"\torder: " + itos(order.index) + "\n";
output += "\troom_type: " + itos(r.room_type) +
"\n";
output += "\twindow: " + itos(r.window) + "\n";
output += "\tarea: " + String::num(area.area) +
"\n";
output += "\tcommands: " +
itos(cmd.commands.size()) + "\n";
for (i = 0; i < cmd.commands.size(); i++) {
output +=
"\t\t" +
itos(cmd.commands[i].command) +
"\n";
for (j = 0;
j < cmd.commands[i].args.size();
j++)
output +=
"\t\t\t" +
(cmd.commands[i].args[j].
operator String()) +
"\n";
}
print_line(output);
state.pack_room(area.area, r.window);
c++;
});
state.dump();
});
ecs.system<WorldEditor::components::buildings_layout_floor>(
"FloorCompleteArea")
.kind(0)
@@ -289,9 +436,11 @@ BuildingLayoutGraph::graph_module::graph_module(flecs::world &ecs)
flecs::entity floor_e = it.entity(count);
flecs::world w = floor_e.world();
std::vector<String> systems = {
"RoomArea", "ZoneArea", "UnitArea",
"FloorArea", "ZoneAreaSum", "UnitAreaSum",
"FloorAreaSum", "CreateFloorData"
"RoomArea", "ZoneArea",
"UnitArea", "FloorArea",
"ZoneAreaSum", "UnitAreaSum",
"FloorAreaSum", "CreateFloorData",
"AssembleZones"
};
int i;
for (i = 0; i < (int)systems.size(); i++) {
@@ -1017,6 +1166,7 @@ void BuildingLayoutGraph::create_zone(const String &base_path, int zone_type)
{ 0, 0, 0 });
int count = get_children_count(new_e.parent());
new_e.set<WorldEditor::components::buildings_layout_order>({ count });
new_e.add<WorldEditor::components::buildings_layout_commands>();
}
void BuildingLayoutGraph::create_unit(const String &base_path)
@@ -1027,6 +1177,7 @@ void BuildingLayoutGraph::create_unit(const String &base_path)
{ 0, 0, 0 });
int count = get_children_count(new_e.parent());
new_e.set<WorldEditor::components::buildings_layout_order>({ count });
new_e.add<WorldEditor::components::buildings_layout_commands>();
}
void BuildingLayoutGraph::create_floor(const String &base_path)
@@ -1057,7 +1208,7 @@ void BuildingLayoutGraph::create_room(const String &base_path, int id)
assert(new_e.has<WorldEditor::components::buildings_layout_graph_node>());
int count = get_children_count(new_e.parent());
new_e.set<WorldEditor::components::buildings_layout_order>({ count });
new_e.set<WorldEditor::components::buildings_layout_command>({ -1 });
new_e.add<WorldEditor::components::buildings_layout_commands>();
}
void BuildingLayoutGraph::create_new_layout(const String &layout_name)

View File

@@ -104,8 +104,37 @@ public:
struct buildings_layout_order {
int index;
};
struct buildings_layout_command {
int command;
struct buildings_layout_commands {
struct command {
int command;
Vector<Variant> args;
};
Vector<struct command> commands;
void from_array(const Array &data)
{
int i;
commands.clear();
for (i = 0; i < data.size(); i++) {
Array entry = data[i];
int command = entry[0];
Vector<Variant> args = entry[1];
commands.push_back({ command, args });
}
}
Array to_array() const
{
int i;
Array ret;
ret.resize(commands.size());
for (i = 0; i < commands.size(); i++) {
Array entry;
entry.resize(2);
entry[0] = commands[i].command;
entry[1] = commands[i].args;
ret[i] = entry;
}
return ret;
}
};
};
};