mirror of
https://github.com/alterware/iw4-validator.git
synced 2025-04-19 08:32:53 +00:00
feature(map_rotation): better error handling (#4)
This commit is contained in:
parent
bc1d808391
commit
5066b64bb3
17
.github/workflows/build.yml
vendored
17
.github/workflows/build.yml
vendored
@ -14,14 +14,13 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-win:
|
||||
build-windows:
|
||||
name: Build Windows
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
configuration:
|
||||
- Debug
|
||||
- Release
|
||||
arch:
|
||||
- x64
|
||||
@ -68,14 +67,11 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
configuration:
|
||||
- Debug
|
||||
- Release
|
||||
arch:
|
||||
- x64
|
||||
- arm64
|
||||
include:
|
||||
- configuration: Debug
|
||||
config: debug
|
||||
- configuration: Release
|
||||
config: release
|
||||
steps:
|
||||
@ -90,7 +86,7 @@ jobs:
|
||||
if: matrix.arch == 'arm64'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install crossbuild-essential-arm64
|
||||
sudo apt-get install crossbuild-essential-arm64 -y
|
||||
|
||||
- name: Install Premake5
|
||||
uses: abel0b/setup-premake@v2.2
|
||||
@ -103,7 +99,12 @@ jobs:
|
||||
- name: Set up problem matching
|
||||
uses: ammaraskar/gcc-problem-matcher@master
|
||||
|
||||
- name: Set up environment variables
|
||||
- name: Set up CC environment variable
|
||||
if: matrix.arch == 'arm64'
|
||||
run: |
|
||||
echo "CC=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up CXX environment variable
|
||||
if: matrix.arch == 'arm64'
|
||||
run: |
|
||||
echo "CXX=aarch64-linux-gnu-g++" >> $GITHUB_ENV
|
||||
@ -122,7 +123,7 @@ jobs:
|
||||
|
||||
deploy:
|
||||
name: Deploy artifacts
|
||||
needs: [build-linux, build-win]
|
||||
needs: [build-linux, build-windows]
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' && (github.ref == 'refs/heads/master')
|
||||
steps:
|
||||
|
@ -42,10 +42,15 @@ editandcontinue "Off"
|
||||
warnings "Extra"
|
||||
characterset "ASCII"
|
||||
|
||||
if os.istarget("linux") or os.istarget("darwin") then
|
||||
filter {"system:linux", "system:macosx"}
|
||||
buildoptions "-pthread"
|
||||
linkoptions "-pthread"
|
||||
end
|
||||
filter {}
|
||||
|
||||
filter {"system:macosx", "platforms:arm64"}
|
||||
buildoptions "-arch arm64"
|
||||
linkoptions "-arch arm64"
|
||||
filter {}
|
||||
|
||||
if os.getenv("CI") then
|
||||
defines "CI"
|
||||
|
@ -8,22 +8,41 @@ using namespace std::literals;
|
||||
|
||||
namespace map_rotation
|
||||
{
|
||||
namespace
|
||||
{
|
||||
bool is_valid_key(const std::string& key)
|
||||
{
|
||||
static std::array<const char*, 3> keys =
|
||||
{
|
||||
"map",
|
||||
"gametype",
|
||||
"exec",
|
||||
};
|
||||
|
||||
return std::ranges::find(keys, key) != std::end(keys);
|
||||
}
|
||||
}
|
||||
|
||||
rotation_data::rotation_data()
|
||||
: index_(0)
|
||||
{
|
||||
}
|
||||
|
||||
void rotation_data::randomize()
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
|
||||
std::ranges::shuffle(this->rotation_entries_, gen);
|
||||
}
|
||||
|
||||
void rotation_data::add_entry(const std::string& key, const std::string& value)
|
||||
{
|
||||
this->rotation_entries_.emplace_back(std::make_pair(key, value));
|
||||
this->rotation_entries_.emplace_back(key, value);
|
||||
}
|
||||
|
||||
std::size_t rotation_data::get_entries_size() const noexcept
|
||||
{
|
||||
return this->rotation_entries_.size();
|
||||
}
|
||||
|
||||
rotation_data::rotation_entry& rotation_data::get_next_entry()
|
||||
{
|
||||
const auto index = this->index_;
|
||||
++this->index_ %= this->rotation_entries_.size();
|
||||
return this->rotation_entries_.at(index);
|
||||
}
|
||||
|
||||
bool rotation_data::contains(const std::string& key, const std::string& value) const
|
||||
@ -39,18 +58,6 @@ namespace map_rotation
|
||||
return this->rotation_entries_.empty();
|
||||
}
|
||||
|
||||
std::size_t rotation_data::get_entries_size() const noexcept
|
||||
{
|
||||
return this->rotation_entries_.size();
|
||||
}
|
||||
|
||||
rotation_data::rotation_entry& rotation_data::get_next_entry()
|
||||
{
|
||||
const auto index = this->index_;
|
||||
++this->index_ %= this->rotation_entries_.size();
|
||||
return this->rotation_entries_.at(index);
|
||||
}
|
||||
|
||||
void rotation_data::parse(const std::string& data)
|
||||
{
|
||||
const auto tokens = utils::string::split(data, ' ');
|
||||
@ -59,13 +66,13 @@ namespace map_rotation
|
||||
const auto& key = tokens[i];
|
||||
const auto& value = tokens[i + 1];
|
||||
|
||||
if (key == "map"s || key == "gametype"s)
|
||||
if (is_valid_key(key))
|
||||
{
|
||||
this->add_entry(key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw map_rotation_parse_error();
|
||||
throw map_rotation_parse_error(utils::string::va("Invalid key '%s'", key.data()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,33 @@
|
||||
|
||||
namespace map_rotation
|
||||
{
|
||||
struct map_rotation_parse_error : public std::exception
|
||||
#define DEFAULT_ERROR_MSG "Map Rotation Parse Error"
|
||||
|
||||
class map_rotation_parse_error : public std::runtime_error
|
||||
{
|
||||
[[nodiscard]] const char* what() const noexcept override { return "Map Rotation Parse Error"; }
|
||||
static std::string fmt(const std::string& message)
|
||||
{
|
||||
std::string error = DEFAULT_ERROR_MSG;
|
||||
|
||||
if (!message.empty())
|
||||
{
|
||||
error.append(": ");
|
||||
error.append(message);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
public:
|
||||
map_rotation_parse_error(const std::string& message)
|
||||
: std::runtime_error(fmt(message))
|
||||
{
|
||||
}
|
||||
|
||||
map_rotation_parse_error()
|
||||
: std::runtime_error(DEFAULT_ERROR_MSG)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class rotation_data
|
||||
@ -14,14 +38,14 @@ namespace map_rotation
|
||||
|
||||
rotation_data();
|
||||
|
||||
void randomize();
|
||||
|
||||
void add_entry(const std::string& key, const std::string& value);
|
||||
|
||||
[[nodiscard]] std::size_t get_entries_size() const noexcept;
|
||||
|
||||
[[nodiscard]] rotation_entry& get_next_entry();
|
||||
|
||||
[[nodiscard]] bool contains(const std::string& key, const std::string& value) const;
|
||||
[[nodiscard]] bool empty() const noexcept;
|
||||
[[nodiscard]] std::size_t get_entries_size() const noexcept;
|
||||
[[nodiscard]] rotation_entry& get_next_entry();
|
||||
|
||||
void parse(const std::string& data);
|
||||
|
||||
|
@ -50,7 +50,7 @@ namespace
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
console::error(utils::string::va("%s: '%s' contains invalid data!", ex.what(), filename.data()));
|
||||
console::error(utils::string::va("%s. '%s' contains invalid data!\n", ex.what(), filename.data()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <cstring>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
Loading…
x
Reference in New Issue
Block a user