17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 16:49:21 +02:00

Merge the track layout editor into cpp20-modules, ported to modules

The editor branch was written against headers and the PCH, both of which this
branch has done away with, so its own files were ported rather than merged: the
five headers it added are now interface units and their .cpp files module
implementation units.

- editor/{puwg1992,polandmap,turnouts,orthophoto} become eu07.editor.* modules,
  application/planpanel becomes eu07.application.planpanel. The plan tool keeps
  to its own module rather than joining the eu07.simcore partitions: it stands on
  the editor's libraries and eu07.application.uilayer, not on the simulation core,
  so :editoruilayer can export import it without a cycle.
- glm arrives by import eu07.glm, never by include, as the rest of the tree does.
  maj0sted is header-only and glm-free, so its headers stay includes in the global
  module fragment - every unit that names those types includes them itself, since
  a global fragment is not visible across units.
- the one textual conflict was :editoruilayer's include block against this
  branch's imports; resolved this branch's way plus the planpanel import.

Builds with clang 22 (-DWITH_BETTER_RENDERER=OFF) and starts into the editor on
empty ground with -editor alone.
This commit is contained in:
maj00r
2026-09-13 12:36:21 +02:00
74 changed files with 13615 additions and 81 deletions

View File

@@ -269,77 +269,74 @@ void eu07_application::DiscordRPCService()
discord_rpc.startTimestamp = static_cast<int64_t>(now_c);
discord_rpc.largeImageText = "MaSzyna";
// run loop
while (!glfwWindowShouldClose(m_windows.front()) && !m_modestack.empty() && !Global.applicationQuitOrder)
// run until quit — do NOT require a non-empty mode stack: pop/push during scenery reload
// briefly empties the stack, and exiting here would Discord_Shutdown() mid-session (or race on top())
while (!Global.applicationQuitOrder && !m_windows.empty() && !glfwWindowShouldClose(m_windows.front()))
{
auto currentMode = m_modestack.top();
if (m_modestack.empty())
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue;
}
auto const currentMode = m_modestack.top();
if (currentMode == mode::launcher)
{
// in launcher mode
discord_rpc.state = Translations.lookup_c("In main menu");
discord_rpc.details = Translations.lookup_c("Browsing scenarios...");
discord_rpc.largeImageKey = "";
discord_rpc.largeImageText = "MaSzyna";
// RPC upload
Discord_UpdatePresence(&discord_rpc);
std::this_thread::sleep_for(std::chrono::milliseconds(5000)); // update RPC every 5 secs
continue;
}
else if (currentMode == mode::scenarioloader)
{
std::string rpcScnName = Global.SceneryFile;
if (rpcScnName[0] == '$')
if (!rpcScnName.empty() && rpcScnName.front() == '$')
rpcScnName.erase(0, 1);
rpcScnName.erase(rpcScnName.size() - 4, 4);
if (rpcScnName.find('_') != std::string::npos)
{
std::replace(rpcScnName.begin(), rpcScnName.end(), '_', ' ');
}
if (rpcScnName.size() >= 4)
rpcScnName.erase(rpcScnName.size() - 4, 4);
std::replace(rpcScnName.begin(), rpcScnName.end(), '_', ' ');
// realworld timestamp from datetime
static std::string state = Translations.lookup_s("Scenery: ") + rpcScnName;
static std::string state;
state = Translations.lookup_s("Scenery: ") + rpcScnName;
discord_rpc.state = state.c_str();
discord_rpc.details = Translations.lookup_c("Loading scenery...");
discord_rpc.largeImageKey = "logo";
discord_rpc.largeImageText = "MaSzyna";
// RPC upload
Discord_UpdatePresence(&discord_rpc);
std::this_thread::sleep_for(std::chrono::milliseconds(5000)); // update RPC every 5 secs
continue;
}
if (currentMode != mode::driver)
continue;
// Discord RPC updater
if (simulation::is_ready)
else if (currentMode == mode::editor)
{
discord_rpc.state = "Dłubie w edytorze";
discord_rpc.details = Global.SceneryFile.c_str();
discord_rpc.largeImageKey = "logo";
discord_rpc.largeImageText = "MaSzyna";
discord_rpc.smallImageKey = "";
discord_rpc.smallImageText = "";
Discord_UpdatePresence(&discord_rpc);
}
else if (currentMode == mode::driver && simulation::is_ready)
{
std::string PlayerVehicle;
if (simulation::Train != nullptr)
if (simulation::Train != nullptr && simulation::Train->Dynamic() != nullptr)
{
PlayerVehicle = simulation::Train->name();
// make to upper
for (auto &c : PlayerVehicle)
c = toupper(c);
c = static_cast<char>(toupper(static_cast<unsigned char>(c)));
PlayerVehicle = Translations.lookup_s("Driving: ") + PlayerVehicle;
discord_rpc.details = PlayerVehicle.c_str();
uint16_t playerTrainVelocity = simulation::Train->Dynamic()->GetVelocity();
auto const playerTrainVelocity = static_cast<uint16_t>(simulation::Train->Dynamic()->GetVelocity());
if (playerTrainVelocity > 1)
{
// ikonka ze jedziemy i nie spimy
discord_rpc.smallImageKey = "driving";
std::string smallText = Translations.lookup_s("Speed: ") + std::to_string(playerTrainVelocity) + " km/h";
static std::string smallText;
smallText = Translations.lookup_s("Speed: ") + std::to_string(playerTrainVelocity) + " km/h";
discord_rpc.smallImageText = smallText.c_str();
}
else
{
// krecimy postoj
discord_rpc.smallImageKey = "halt";
discord_rpc.smallImageText = Translations.lookup_c("Stopped");
}
@@ -347,7 +344,8 @@ void eu07_application::DiscordRPCService()
Discord_UpdatePresence(&discord_rpc);
}
std::this_thread::sleep_for(std::chrono::milliseconds(5000)); // update RPC every 5 secs
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
}
Discord_Shutdown();
@@ -1172,6 +1170,7 @@ int eu07_application::init_settings(int Argc, char *Argv[])
}
// process command line arguments
auto scenerywasasked = false;
for (int i = 1; i < Argc; ++i)
{
@@ -1182,6 +1181,7 @@ int eu07_application::init_settings(int Argc, char *Argv[])
if (i + 1 < Argc)
{
Global.SceneryFile = ToLower(Argv[++i]);
scenerywasasked = true;
}
}
else if (token == "-v")
@@ -1191,14 +1191,27 @@ int eu07_application::init_settings(int Argc, char *Argv[])
Global.local_start_vehicle = ToLower(Argv[++i]);
}
}
else if (token == "-editor")
{
Global.editor_startup = true;
}
else
{
std::cout << "usage: " << std::string(Argv[0]) << " [-s sceneryfilepath]"
<< " [-v vehiclename]" << std::endl;
<< " [-v vehiclename]"
<< " [-editor]" << std::endl;
return -1;
}
}
if (Global.editor_startup && false == scenerywasasked)
{
// the editor opens on empty ground unless a scenery was actually asked for. whatever the ini
// happens to name is the last thing that was driven, which has nothing to do with editing; an
// empty scenery still gives the region, the lighting and the clock, just nothing standing on it
Global.SceneryFile = "pusta.scn";
}
return 0;
}