Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions ext/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@ if(pcg-cpp_ADDED) # pcg-cpp does not include cmake
target_include_directories(pcg-cpp SYSTEM INTERFACE ${pcg-cpp_SOURCE_DIR}/include/)
endif()

CPMAddPackage(
NAME optional
GITHUB_REPOSITORY TartanLlama/optional
GIT_TAG v1.1.0
OPTIONS
"OPTIONAL_BUILD_TESTS OFF"
"OPTIONAL_BUILD_PACKAGES OFF"
) # defines: tl::optional

CPMAddPackage(
NAME asio
VERSION 1.32.0
Expand Down Expand Up @@ -266,6 +275,7 @@ set(SHARED_EXTERNAL_LIBS
asio
alpaca
magic_enum
tl::optional
)

if(WIN32)
Expand Down
5 changes: 4 additions & 1 deletion scripts/globals/roe.lua
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,10 @@ xi.roe.initialize = function()
RoeParseRecords(xi.roe.records)

-- Load timetable for timed records
if xi.settings.main.ENABLE_ROE and xi.settings.main.ENABLE_ROE_TIMED > 0 then
if
xi.settings.main.ENABLE_ROE == 1 and
xi.settings.main.ENABLE_ROE_TIMED == 1
then
RoeParseTimed(timedSchedule)
end
end
Expand Down
4 changes: 2 additions & 2 deletions src/common/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ void Application::tryRestoreQuickEditMode() const
void Application::prepareLogging()
{
auto logFile = fmt::format("log/{}-server.log", serverName_);
bool appendDate = false;
auto appendDate = logging::AppendDate::No;

//
// Regular setup
Expand All @@ -217,7 +217,7 @@ void Application::prepareLogging()

if (args_->get<bool>("--append-date"))
{
appendDate = true;
appendDate = logging::AppendDate::Yes;
}

logging::InitializeLog(serverName_, logFile, appendDate);
Expand Down
2 changes: 1 addition & 1 deletion src/common/logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ const std::vector<std::string> logNames = {
"trace",
};

void logging::InitializeLog(const std::string& serverName, const std::string& logFile, bool appendDate)
void logging::InitializeLog(const std::string& serverName, const std::string& logFile, AppendDate appendDate)
{
ServerName = serverName;

Expand Down
13 changes: 8 additions & 5 deletions src/common/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "cbasetypes.h"
#include "macros.h"
#include "tracy.h"
#include "xi.h"

#include <string>
#include <string_view>
Expand All @@ -49,7 +50,9 @@ T get(std::string);
namespace logging
{

void InitializeLog(const std::string& serverName, const std::string& logFile, bool appendDate);
using AppendDate = xi::Flag<struct AppendDateTag>;

void InitializeLog(const std::string& serverName, const std::string& logFile, AppendDate appendDate);
void ShutDown();

void SetPattern(const std::string& str);
Expand All @@ -61,10 +64,8 @@ void tapWarningOrError();

} // namespace logging

// clang-format off

template <typename T>
std::string asStringFromUntrustedSource(const T* ptr)
auto asStringFromUntrustedSource(const T* ptr) -> std::string
{
if (!ptr)
{
Expand All @@ -78,7 +79,7 @@ std::string asStringFromUntrustedSource(const T* ptr)
}

template <typename T>
std::string asStringFromUntrustedSource(const T* ptr, size_t max_size)
auto asStringFromUntrustedSource(const T* ptr, size_t max_size) -> std::string
{
if (!ptr)
{
Expand All @@ -90,6 +91,8 @@ std::string asStringFromUntrustedSource(const T* ptr, size_t max_size)
return std::string(str, len);
}

// clang-format off

// Helper for allowing `enum` and `enum class` types to be formatted
// as their underlying numeric type.
#define DECLARE_FORMAT_AS_UNDERLYING(type) \
Expand Down
16 changes: 8 additions & 8 deletions src/common/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,15 @@ void init()

if (innerValObj.is<bool>())
{
settingsMap[key] = innerValObj.as<bool>();
settingsMap.insert_or_assign(key, innerValObj.as<bool>());
}
else if (innerValObj.is<double>())
{
settingsMap[key] = innerValObj.as<double>();
settingsMap.insert_or_assign(key, innerValObj.as<double>());
}
else if (innerValObj.is<std::string>())
{
settingsMap[key] = innerValObj.as<std::string>();
settingsMap.insert_or_assign(key, innerValObj.as<std::string>());
}
}
}
Expand Down Expand Up @@ -173,15 +173,15 @@ void init()

if (innerValObj.is<bool>())
{
settingsMap[key] = innerValObj.as<bool>();
settingsMap.insert_or_assign(key, innerValObj.as<bool>());
}
else if (innerValObj.is<double>())
{
settingsMap[key] = innerValObj.as<double>();
settingsMap.insert_or_assign(key, innerValObj.as<double>());
}
else if (innerValObj.is<std::string>())
{
settingsMap[key] = innerValObj.as<std::string>();
settingsMap.insert_or_assign(key, innerValObj.as<std::string>());
}

// Apply any environment variables over the default/user settings.
Expand All @@ -200,11 +200,11 @@ void init()
// Therefor we need to check if the value is a number.
if (isNumber(value))
{
settingsMap[key] = std::stod(value);
settingsMap.insert_or_assign(key, std::stod(value));
}
else
{
settingsMap[key] = value;
settingsMap.insert_or_assign(key, value);
}
}
}
Expand Down
144 changes: 71 additions & 73 deletions src/common/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
namespace settings
{

using SettingsVariant = std::variant<bool, double, std::string>;
using SettingsVariant = xi::Variant<bool, double, std::string>;
extern std::unordered_map<std::string, SettingsVariant> settingsMap;

void init();
Expand Down Expand Up @@ -63,82 +63,80 @@ T get(std::string name)
auto& variant = (*maybeResult).second;

// arg = type held inside the variant
std::visit(
xi::overload{
[&](const bool& arg)
variant.visit(xi::overload{
[&](const bool& arg)
{
if constexpr (std::is_same_v<T, bool>)
{
if constexpr (std::is_same_v<T, bool>)
{
out = arg;
}
else if constexpr (std::is_floating_point_v<T>)
{
out = static_cast<double>(arg);
}
else if constexpr (std::is_integral_v<T> && std::is_signed_v<T>)
{
out = static_cast<int>(arg);
}
else if constexpr (std::is_integral_v<T> && std::is_unsigned_v<T>)
{
out = static_cast<unsigned int>(arg);
}
else if constexpr (std::is_same_v<T, std::string>)
{
out = std::string(arg ? "true" : "false");
}
},
[&](const double& arg)
out = arg;
}
else if constexpr (std::is_floating_point_v<T>)
{
if constexpr (std::is_same_v<T, bool>)
{
out = static_cast<bool>(arg);
}
else if constexpr (std::is_floating_point_v<T>)
{
out = arg;
}
else if constexpr (std::is_integral_v<T> && std::is_signed_v<T>)
{
out = static_cast<int>(arg);
}
else if constexpr (std::is_integral_v<T> && std::is_unsigned_v<T>)
{
out = static_cast<unsigned int>(arg);
}
else if constexpr (std::is_same_v<T, std::string>)
{
out = fmt::format("{}", arg);
}
},
[&](const std::string& arg)
out = static_cast<double>(arg);
}
else if constexpr (std::is_integral_v<T> && std::is_signed_v<T>)
{
bool isTruthy = !arg.empty() && arg != "false" && arg != "0";
std::ignore = isTruthy;

if constexpr (std::is_same_v<T, bool>)
{
out = isTruthy;
}
else if constexpr (std::is_floating_point_v<T>)
{
out = static_cast<double>(isTruthy);
}
else if constexpr (std::is_integral_v<T> && std::is_signed_v<T>)
{
out = static_cast<int>(isTruthy);
}
else if constexpr (std::is_integral_v<T> && std::is_unsigned_v<T>)
{
out = static_cast<unsigned int>(isTruthy);
}
else if constexpr (std::is_same_v<T, std::string>)
{
out = arg;
}
},
out = static_cast<int>(arg);
}
else if constexpr (std::is_integral_v<T> && std::is_unsigned_v<T>)
{
out = static_cast<unsigned int>(arg);
}
else if constexpr (std::is_same_v<T, std::string>)
{
out = std::string(arg ? "true" : "false");
}
},
[&](const double& arg)
{
if constexpr (std::is_same_v<T, bool>)
{
out = static_cast<bool>(arg);
}
else if constexpr (std::is_floating_point_v<T>)
{
out = arg;
}
else if constexpr (std::is_integral_v<T> && std::is_signed_v<T>)
{
out = static_cast<int>(arg);
}
else if constexpr (std::is_integral_v<T> && std::is_unsigned_v<T>)
{
out = static_cast<unsigned int>(arg);
}
else if constexpr (std::is_same_v<T, std::string>)
{
out = fmt::format("{}", arg);
}
},
[&](const std::string& arg)
{
bool isTruthy = !arg.empty() && arg != "false" && arg != "0";
std::ignore = isTruthy;

if constexpr (std::is_same_v<T, bool>)
{
out = isTruthy;
}
else if constexpr (std::is_floating_point_v<T>)
{
out = static_cast<double>(isTruthy);
}
else if constexpr (std::is_integral_v<T> && std::is_signed_v<T>)
{
out = static_cast<int>(isTruthy);
}
else if constexpr (std::is_integral_v<T> && std::is_unsigned_v<T>)
{
out = static_cast<unsigned int>(isTruthy);
}
else if constexpr (std::is_same_v<T, std::string>)
{
out = arg;
}
},
variant);
});
return out;
}

Expand Down
73 changes: 73 additions & 0 deletions src/common/types/flag.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
===========================================================================

Copyright (c) 2025 LandSandBoat Dev Teams

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/

===========================================================================
*/

#pragma once

namespace xi
{

//
// Flag<Tag>
//
// A strongly typed boolean flag.
//

template <typename Tag>
class Flag
{
public:
constexpr explicit Flag(bool value) noexcept;

constexpr operator bool() const noexcept;

constexpr bool operator==(const Flag& other) const noexcept = default;
constexpr bool operator!=(const Flag& other) const noexcept = default;

static const Flag Yes;
static const Flag No;

private:
bool value_ = false;
};

//
// Implementation
//

template <typename Tag>
constexpr Flag<Tag>::Flag(bool value) noexcept
: value_(value)
{
}

template <typename Tag>
constexpr Flag<Tag>::operator bool() const noexcept
{
return value_;
}

template <typename Tag>
constexpr Flag<Tag> Flag<Tag>::Yes{ true };

template <typename Tag>
constexpr Flag<Tag> Flag<Tag>::No{ false };

} // namespace xi
Loading
Loading