17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-11 00:35:16 +01:00

Merge branch 'master' into feat/renderers-cleanup

This commit is contained in:
2026-11-07 16:44:51 +01:00
177 changed files with 11657 additions and 833 deletions

View File

@@ -74,15 +74,28 @@ std::deque<std::string> ErrorStack;
// lock for log stacks
std::mutex logMutex;
namespace
{
// the log is written through the closing of the simulator, to the end: set once the closing has nothing more to tell
std::atomic<bool> &log_stopped()
{
static std::atomic<bool> stopped{false};
return stopped;
}
} // namespace
void StopLogService()
{
log_stopped() = true;
}
void LogService()
{
bool quitting{false};
while (!quitting)
// one more pass after the stop, so what came just before it gets written too
for (bool last{false}; false == last;)
{
// read before the stacks are drained, so everything logged before the quit order still gets written
quitting = Global.applicationQuitOrder;
last = log_stopped();
{
// --- Obsługa InfoStack ---
while (!InfoStack.empty())

View File

@@ -23,7 +23,9 @@ enum class logtype : unsigned int {
traction = 1 << 9,
powergrid = 1 << 10,
};
// writes the log until StopLogService(), and all of it that came before
void LogService();
void StopLogService();
void WriteLog( const char *str, logtype const Type = logtype::generic, bool isError = false );
void Error( const std::string &asMessage, bool box = false );
void Error( const char* &asMessage, bool box = false );

View File

@@ -266,6 +266,7 @@ std::string locale::label_cab_control(std::string const &Label)
{ "watercircuitslink_sw:", STRN("water circuits link") },
{ "fuelpump_sw:", STRN("fuel pump") },
{ "oilpump_sw:", STRN("oil pump") },
{ "oilfuelpump_sw:", STRN("oil and fuel pumps") },
{ "motorblowersfront_sw:", STRN("motor blowers A") },
{ "motorblowersrear_sw:", STRN("motor blowers B") },
{ "motorblowersalloff_sw:", STRN("all motor blowers") },

View File

@@ -350,8 +350,11 @@ void win1250_to_ascii(std::string &Input)
std::string win1250_to_utf8(const std::string &Input)
{
std::unordered_map<char, std::string> const charmap{{165, "Ą"}, {198, "Ć"}, {202, "Ę"}, {163, "Ł"}, {209, "Ń"}, {211, "Ó"}, {140, "Ś"}, {143, "Ź"}, {175, "Ż"},
{185, "ą"}, {230, "ć"}, {234, "ę"}, {179, "ł"}, {241, "ń"}, {243, "ó"}, {156, "ś"}, {159, "ź"}, {191, "ż"}};
// the utf-8 sequences written as bytes: the file has a byte order mark and the build doesn't give the compiler /utf-8, so letters
// written as letters would end up in the program in windows-1250, the same as the input
static std::unordered_map<char, std::string> const charmap{{'\xA5', "\xC4\x84"}, {'\xC6', "\xC4\x86"}, {'\xCA', "\xC4\x98"}, {'\xA3', "\xC5\x81"}, {'\xD1', "\xC5\x83"}, {'\xD3', "\xC3\x93"},
{'\x8C', "\xC5\x9A"}, {'\x8F', "\xC5\xB9"}, {'\xAF', "\xC5\xBB"}, {'\xB9', "\xC4\x85"}, {'\xE6', "\xC4\x87"}, {'\xEA', "\xC4\x99"},
{'\xB3', "\xC5\x82"}, {'\xF1', "\xC5\x84"}, {'\xF3', "\xC3\xB3"}, {'\x9C', "\xC5\x9B"}, {'\x9F', "\xC5\xBA"}, {'\xBF', "\xC5\xBC"}};
std::string output;
std::unordered_map<char, std::string>::const_iterator lookup;
for (auto &input : Input)
@@ -504,18 +507,24 @@ bool FileExists(std::string const &Filename)
return std::filesystem::exists(Filename);
}
std::string FileCased(std::string const &Filename)
std::string FileCased(std::filesystem::path const &Filename)
{
std::error_code error;
if (std::filesystem::exists(Filename, error))
return Filename;
std::filesystem::path const path{Filename};
auto const directory{path.has_parent_path() ? path.parent_path() : std::filesystem::path{"."}};
auto const wanted{ToLower(path.filename().string())};
return Filename.string();
#ifdef _WIN32
// the names there are found in any case already: no folder to go through for every file missing, nor names outside of the
// code page to throw on
return {};
#else
// only the name of the file itself, a folder named in another case isn't found
auto const directory{Filename.has_parent_path() ? Filename.parent_path() : std::filesystem::path{"."}};
auto const wanted{ToLower(Filename.filename().string())};
for (std::filesystem::directory_iterator entry{directory, error}, end; entry != end; entry.increment(error))
if (ToLower(entry->path().filename().string()) == wanted)
return path.has_parent_path() ? (directory / entry->path().filename()).string() : entry->path().filename().string();
return Filename.has_parent_path() ? (directory / entry->path().filename()).string() : entry->path().filename().string();
return {};
#endif
}
std::pair<std::string, std::string> FileExists(std::vector<std::string> const &Names, std::vector<std::string> const &Extensions)

View File

@@ -224,8 +224,8 @@ template <> bool extract_value(bool &Variable, std::string const &Key, std::stri
bool FileExists(std::string const &Filename);
// the file as it's named on the disk when only the case of its name differs, as in the sceneries made on Windows; empty when
// there's none
std::string FileCased(std::string const &Filename);
// there's none. the folders have to be named in their case; on Windows, finding the names in any case itself, the file given or none
std::string FileCased(std::filesystem::path const &Filename);
std::pair<std::string, std::string> FileExists(std::vector<std::string> const &Names, std::vector<std::string> const &Extensions);