Skip to content

Commit

Permalink
Logical groups implemented in the wiring editor #62
Browse files Browse the repository at this point in the history
  • Loading branch information
tatjam committed Aug 26, 2023
1 parent ce28611 commit f16b39a
Show file tree
Hide file tree
Showing 13 changed files with 347 additions and 244 deletions.
4 changes: 4 additions & 0 deletions res/.luadef/definitions/game_database.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ function game_database:add_plumbing_machine(path) end
---@param path string Path to the reaction .toml
function game_database:add_reaction(path) end

---@param local_id string ID to use for the group, not including the package, as it's automatically added
---@param display_str string String to display to the user. Displayed directly! It's not a locale string ID
function game_database:add_logical_group(local_id, display_str) end

---@param locale table Table containing the locale
function game_database:load_locale(locale) end

Expand Down
4 changes: 3 additions & 1 deletion res/core/locale.lua
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ local locale =
{"gman_move_down", "Move Group Down", "Bajar Grupo"},
{"gman_move_all", "Move all parts to...", "Mover las partes a..."},
-- Symmetry
{"radial_piece_name", "Radial Symmetry - Piece", "Simetria Radial - Pieza"}
{"radial_piece_name", "Radial Symmetry - Piece", "Simetria Radial - Pieza"},
-- Logical groups
{"lg_control", "Control Orders", "Ordenes de Control"}

}

Expand Down
8 changes: 5 additions & 3 deletions res/core/package.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ local logger = require("logger")
local glm = require("glm")

function load(database)
-- The first locale is the default if selected one is not available
database:load_locale(dofile("locale.lua"))

database:add_part_category("categories/command.toml")
database:add_part_category("categories/engines.toml")
database:add_part_category("categories/all.toml")
Expand All @@ -20,13 +23,12 @@ function load(database)
database:add_reaction("materials/reactions/hydrogen_combustion.toml")
database:add_reaction("materials/reactions/methane_combustion.toml")

-- The first locale is the default if selected one is not available
database:load_locale(dofile("locale.lua"))

database:add_editor_script("scenes/editor/editor.lua")
database:add_editor_script("scenes/editor/symmetry_debug.lua")

database:add_symmetry_mode("scenes/editor/symmetry/radial_piece.toml")

database:add_logical_group("control", database:get_string("core:lg_control"))

end

5 changes: 5 additions & 0 deletions src/game/database/GameDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,8 @@ void GameDatabase::add_symmetry_mode(const std::string &path, const std::string
symmetry_modes.push_back(sane_path);
}

void GameDatabase::add_logical_group(const std::string &id, const std::string &display_string)
{
logical_groups.emplace_back(id, display_string);
}

5 changes: 5 additions & 0 deletions src/game/database/GameDatabase.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ class GameDatabase
std::vector<std::string> symmetry_modes;
std::vector<std::string> reactions;
std::vector<std::string> materials;

// id and localized name (ready to display to user)
std::vector<std::pair<std::string, std::string>> logical_groups;

std::unordered_map<std::string, std::string> current_locale;

std::vector<std::string> editor_scripts;
Expand All @@ -43,6 +47,7 @@ class GameDatabase
void add_symmetry_mode(const std::string& path, const std::string& pkg);
void add_material(const std::string& path, const std::string& pkg);
void add_reaction(const std::string& path, const std::string& pkg);
void add_logical_group(const std::string& id, const std::string& display_string);

void finish_loading();

Expand Down
1 change: 1 addition & 0 deletions src/game/scenes/editor/gui/EditorGUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ int EditorGUI::get_panel_width()
part_list.init(sc, vg);
trashcan.init(sc, vg);
plumbing.init(sc, vg);
wiring.init(sc, vg);
modify_tools.init(sc, vg);

create_toolset();
Expand Down
26 changes: 26 additions & 0 deletions src/game/scenes/editor/gui/WiringPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,35 @@ void WiringPanel::init(EditorScene *sc, NVGcontext *vg)
this->vg = vg;
this->edgui = &sc->gui;

group_dropdown = std::make_shared<GUIDropDown>();
update_logical_groups();
group_dropdown->item = 0;
scene->vehicle_int.wire_interface.editing = scene->vehicle->veh->logical_groups[group_dropdown->options[0].first];



// Group selector
panel.divide_v(0.05);
panel.child_pixels = 32;
panel.pixels_for_child_1 = false;

panel.child_0->layout = std::make_shared<GUISingleLayout>();
panel.child_0->layout->add_widget(group_dropdown);

}

void WiringPanel::add_gui(int width, int panel_width, int height, GUIScreen *screen)
{
screen->add_canvas(&panel, glm::ivec2(0, 0), glm::ivec2(panel_width, height));
}

void WiringPanel::update_logical_groups()
{
for(auto& p : scene->vehicle->veh->logical_groups)
{
group_dropdown->options.emplace_back(p.first, p.second->display_str);
}
// Last option to allow the user to create logical groups
group_dropdown->options.emplace_back("manage", "Manager user logical groups");
group_dropdown->update_options();
}
10 changes: 7 additions & 3 deletions src/game/scenes/editor/gui/WiringPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
#include "EditorPanel.h"
#include <gui/GUICanvas.h>
#include <gui/layouts/GUISingleLayout.h>
#include <gui/widgets/GUIImageButton.h>
#include <gui/widgets/GUIDropDown.h>
#include <assets/AssetManager.h>
#include <assets/Image.h>


class EditorVehicleInterface;
class EditorGUI;

Expand All @@ -16,12 +17,15 @@ class WiringPanel : EditorPanel

AssetHandle<Image> trash_image;


GUICanvas panel;
GUISingleLayout* trash_area_layout;
GUIImageButton trash_button;
std::shared_ptr<GUIDropDown> group_dropdown;


EditorGUI* edgui;

void update_logical_groups();

public:
void init(EditorScene* sc, NVGcontext* vg) override;
void add_gui(int width, int panel_width, int height, GUIScreen* screen) override;
Expand Down
3 changes: 2 additions & 1 deletion src/game/scenes/editor/interfaces/WireInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ class WireInterface : public BaseInterface
{
private:

LogicalGroup* editing;

EditorVehicle* edveh;
EditorScene* scene;
Expand All @@ -35,6 +34,8 @@ class WireInterface : public BaseInterface

public:

LogicalGroup* editing;

bool show_hidden;

virtual void update(double dt) override;
Expand Down
7 changes: 7 additions & 0 deletions src/lua/libs/LuaGameDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ void LuaGameDatabase::load_to(sol::table& table)
std::string pkg = view["__pkg"];
self->add_reaction(path, pkg);
},
"add_logical_group", [](GameDatabase* self, const std::string& local_id, const std::string& display, sol::this_environment st)
{
sol::environment view = st;
std::string pkg = view["__pkg"];
std::string id = pkg + ":" + local_id;
self->add_logical_group(id, display);
},
"load_locale", [](GameDatabase* self, const sol::table& table, sol::this_environment st)
{
sol::environment view = st;
Expand Down
143 changes: 88 additions & 55 deletions src/universe/vehicle/VehicleLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,80 +245,108 @@ void VehicleLoader::copy_pieces(const cpptoml::table& root)
void VehicleLoader::obtain_logical_groups(const cpptoml::table& root)
{
auto groups = root.get_table_array_qualified("logical_group");
if(!groups)
if(groups)
{
return;
}

for(auto& g : *groups)
{
auto connections = root.get_table_array_qualified("connection");
if (!connections)
for(auto& g : *groups)
{
return;
}
auto connections = g->get_table_array_qualified("connection");
if (!connections)
{
continue;
}

LogicalGroup* gr = new LogicalGroup();
auto id = g->get_qualified_as<std::string>("id");
logger->check(!id->empty(), "Logical group has no ID!");
LogicalGroup* gr = new LogicalGroup();
auto id = g->get_qualified_as<std::string>("id");
logger->check(!id->empty(), "Logical group has no ID!");

auto existing = n_vehicle->logical_groups.find(*id);
logger->check(existing == n_vehicle->logical_groups.end(), "Duplicated ID for logical group");
auto existing = n_vehicle->logical_groups.find(*id);
logger->check(existing == n_vehicle->logical_groups.end(), "Duplicated ID for logical group");

for (auto conn_toml : *connections)
{
int from = *conn_toml->get_as<int>("from");
int to = *conn_toml->get_as<int>("to");
std::string fmachine = *conn_toml->get_as<std::string>("fmachine");
std::string tmachine = *conn_toml->get_as<std::string>("tmachine");

Part *fromp = parts_by_id[from];
Part *top = parts_by_id[to];
Machine *fromm = fromp->get_machine(fmachine);
Machine *tom = top->get_machine(tmachine);

// Check if it already exists bidirectionally to emit a warning
// TODO: Move this code to a function as it may be reused
auto from_it = gr->connections.equal_range(fromm);
bool found_from_to = false;
for (auto from_subit = from_it.first; from_subit != from_it.second; from_subit++)
for (auto conn_toml : *connections)
{
if (from_subit->second == tom)
int from = *conn_toml->get_as<int>("from");
int to = *conn_toml->get_as<int>("to");
std::string fmachine = *conn_toml->get_as<std::string>("fmachine");
std::string tmachine = *conn_toml->get_as<std::string>("tmachine");

Part *fromp = parts_by_id[from];
Part *top = parts_by_id[to];
Machine *fromm = fromp->get_machine(fmachine);
Machine *tom = top->get_machine(tmachine);

// Check if it already exists bidirectionally to emit a warning
// TODO: Move this code to a function as it may be reused
auto from_it = gr->connections.equal_range(fromm);
bool found_from_to = false;
for (auto from_subit = from_it.first; from_subit != from_it.second; from_subit++)
{
found_from_to = true;
break;
if (from_subit->second == tom)
{
found_from_to = true;
break;
}
}
}

auto to_it = gr->connections.equal_range(tom);
bool found_to_from = false;
for (auto to_subit = to_it.first; to_subit != to_it.second; to_subit++)
{
if (to_subit->second == fromm)
auto to_it = gr->connections.equal_range(tom);
bool found_to_from = false;
for (auto to_subit = to_it.first; to_subit != to_it.second; to_subit++)
{
found_to_from = true;
break;
if (to_subit->second == fromm)
{
found_to_from = true;
break;
}
}
}

if (!found_from_to)
{
gr->connections.insert(std::make_pair(fromm, tom));
}
if (!found_from_to)
{
gr->connections.insert(std::make_pair(fromm, tom));
}

if (!found_to_from)
{
gr->connections.insert(std::make_pair(tom, fromm));
}

if (!found_to_from)
if (found_from_to || found_to_from)
{
logger->warn("Found a duplicate wire (from: {} fmachine: {} -> to: {} tmachine: {}), it was ignored",
from, fmachine, to, tmachine);
}
}
// Search for the logical group display string in the game database, if not present use ID directly
gr->display_str = *id;
for(const auto& p : osp->game_database->logical_groups)
{
gr->connections.insert(std::make_pair(tom, fromm));
if(p.first == *id)
{
gr->display_str = p.second;
break;
}
}
// Insert the logical group
n_vehicle->logical_groups[*id] = gr;
}
}

if (found_from_to || found_to_from)
// Load empty logical groups from game database
for(const auto& p : osp->game_database->logical_groups)
{
bool found = false;
for(const auto& lg : n_vehicle->logical_groups)
{
if(lg.first == p.first)
{
logger->warn("Found a duplicate wire (from: {} fmachine: {} -> to: {} tmachine: {}), it was ignored",
from, fmachine, to, tmachine);
found = true;
break;
}
}
// Insert the logical group
n_vehicle->logical_groups[*id] = gr;
if(!found)
{
LogicalGroup* gr = new LogicalGroup();
gr->display_str = p.second;
n_vehicle->logical_groups[p.first] = gr;
}
}
}

Expand Down Expand Up @@ -528,6 +556,11 @@ void VehicleSaver::write_logical_groups(cpptoml::table &target, const Vehicle &w

for(auto lg : what.logical_groups)
{
if(lg.second->connections.empty())
{
continue;
}

auto tb = cpptoml::make_table();

auto conn_array = cpptoml::make_table_array();
Expand Down
1 change: 1 addition & 0 deletions src/universe/vehicle/connections/LogicalGroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class Machine;
class LogicalGroup
{
public:
std::string display_str;

// Bidirectional wires, so if A is connected to B then B is connected to A
std::unordered_multimap<Machine*, Machine*> connections;
Expand Down
Loading

0 comments on commit f16b39a

Please sign in to comment.