Replace tl::expected with std::expected

Now that the project targets C++23, use the standard library's
std::expected instead of the vendored tl::expected polyfill:

- tl::expected -> std::expected, tl::unexpected/tl::make_unexpected -> std::unexpected
- .map()/.map_error() -> .transform()/.transform_error()
- #include <expected.hpp> -> #include <expected>, grouped with std headers
- Remove 3rdParty/tl/expected.hpp (the tl target remains for function_ref.hpp)

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Gleb Mazovetskiy
2026-07-22 00:00:04 +02:00
committed by Anders Jenbo
co-authored by Claude Fable 5
parent c4fed8aeb6
commit 63e85d9b1b
98 changed files with 678 additions and 3161 deletions
-2444
View File
File diff suppressed because it is too large Load Diff
+2 -3
View File
@@ -8,6 +8,7 @@
#include <cstdio>
#include <cstring>
#include <ctime>
#include <expected>
#ifdef USE_SDL3
#include <SDL3/SDL_error.h>
@@ -19,8 +20,6 @@
#include "utils/sdl_compat.h"
#endif
#include <expected.hpp>
#define DEVILUTIONX_SCREENSHOT_FORMAT_PCX 0
#define DEVILUTIONX_SCREENSHOT_FORMAT_PNG 1
@@ -102,7 +101,7 @@ void CaptureScreen()
system_palette = origSystemPalette;
SystemPaletteUpdated();
const tl::expected<void, std::string> result =
const std::expected<void, std::string> result =
#if DEVILUTIONX_SCREENSHOT_FORMAT == DEVILUTIONX_SCREENSHOT_FORMAT_PCX
WriteSurfaceToFilePcx(GlobalBackBuffer(), outStream);
#elif DEVILUTIONX_SCREENSHOT_FORMAT == DEVILUTIONX_SCREENSHOT_FORMAT_PNG
+2 -3
View File
@@ -2,6 +2,7 @@
#include <cstddef>
#include <cstdint>
#include <expected>
#include <optional>
#include <string>
#include <string_view>
@@ -18,8 +19,6 @@
#endif
#endif
#include <expected.hpp>
#include "DiabloUI/text_input.hpp"
#include "DiabloUI/ui_flags.hpp"
#include "engine/displacement.hpp"
@@ -94,7 +93,7 @@ void AddInfoBoxString(std::string &&str, bool floatingBox = false);
void DrawPanelBox(const Surface &out, SDL_Rect srcRect, Point targetPosition);
Point GetPanelPosition(UiPanels panel, Point offset = { 0, 0 });
tl::expected<void, std::string> InitMainPanel();
std::expected<void, std::string> InitMainPanel();
void DrawMainPanel(const Surface &out);
/**
+1 -1
View File
@@ -353,7 +353,7 @@ void DrawPanelBox(const Surface &out, SDL_Rect srcRect, Point targetPosition)
out.BlitFrom(*BottomBuffer, srcRect, targetPosition);
}
tl::expected<void, std::string> InitMainPanel()
std::expected<void, std::string> InitMainPanel()
{
if (!HeadlessMode) {
BottomBuffer.emplace(GetMainPanel().size.width, (GetMainPanel().size.height + PanelPaddingHeight) * (IsChatAvailable() ? 2 : 1));
+12 -12
View File
@@ -3,10 +3,10 @@
#include <bitset>
#include <cstddef>
#include <cstdint>
#include <expected>
#include <limits>
#include <memory>
#include <expected.hpp>
#include <fmt/format.h>
#include "engine/assets.hpp"
@@ -14,27 +14,27 @@
#include "utils/language.h"
namespace devilution {
tl::expected<DataFile, DataFile::Error> DataFile::load(std::string_view path)
std::expected<DataFile, DataFile::Error> DataFile::load(std::string_view path)
{
AssetRef ref = FindAsset(path);
if (!ref.ok())
return tl::unexpected { Error::NotFound };
return std::unexpected { Error::NotFound };
const size_t size = ref.size();
// TODO: It should be possible to stream the data file contents instead of copying the whole thing into memory
std::unique_ptr<char[]> data { new char[size] };
{
AssetHandle handle = OpenIntegralAsset(std::move(ref));
if (!handle.ok())
return tl::unexpected { Error::OpenFailed };
return std::unexpected { Error::OpenFailed };
if (size > 0 && !handle.read(data.get(), size))
return tl::unexpected { Error::BadRead };
return std::unexpected { Error::BadRead };
}
return DataFile { std::move(data), size };
}
DataFile DataFile::loadOrDie(std::string_view path)
{
tl::expected<DataFile, DataFile::Error> dataFileResult = DataFile::load(path);
std::expected<DataFile, DataFile::Error> dataFileResult = DataFile::load(path);
if (!dataFileResult.has_value()) {
DataFile::reportFatalError(dataFileResult.error(), path);
}
@@ -92,7 +92,7 @@ void DataFile::reportFatalFieldError(DataFileField::Error code, std::string_view
}
}
tl::expected<void, DataFile::Error> DataFile::parseHeader(ColumnDefinition *begin, ColumnDefinition *end, tl::function_ref<tl::expected<uint8_t, ColumnDefinition::Error>(std::string_view)> mapper)
std::expected<void, DataFile::Error> DataFile::parseHeader(ColumnDefinition *begin, ColumnDefinition *end, tl::function_ref<std::expected<uint8_t, ColumnDefinition::Error>(std::string_view)> mapper)
{
std::bitset<std::numeric_limits<uint8_t>::max()> seenColumns;
unsigned lastColumn = 0;
@@ -129,23 +129,23 @@ tl::expected<void, DataFile::Error> DataFile::parseHeader(ColumnDefinition *begi
// Incrementing the iterator causes it to read to the end of the record in case we broke early (maybe there were extra columns)
++firstRecord;
if (firstRecord == this->end()) {
return tl::unexpected { Error::NoContent };
return std::unexpected { Error::NoContent };
}
body_ = firstRecord.data();
if (begin != end) {
return tl::unexpected { Error::NotEnoughColumns };
return std::unexpected { Error::NotEnoughColumns };
}
return {};
}
tl::expected<void, DataFile::Error> DataFile::skipHeader()
std::expected<void, DataFile::Error> DataFile::skipHeader()
{
RecordIterator it { data(), data() + size(), false };
++it;
if (it == this->end()) {
return tl::unexpected { Error::NoContent };
return std::unexpected { Error::NoContent };
}
body_ = it.data();
return {};
@@ -153,7 +153,7 @@ tl::expected<void, DataFile::Error> DataFile::skipHeader()
void DataFile::skipHeaderOrDie(std::string_view path)
{
if (tl::expected<void, DataFile::Error> result = skipHeader(); !result.has_value()) {
if (std::expected<void, DataFile::Error> result = skipHeader(); !result.has_value()) {
DataFile::reportFatalError(result.error(), path);
}
}
+5 -5
View File
@@ -1,11 +1,11 @@
#pragma once
#include <cstddef>
#include <expected>
#include <limits>
#include <memory>
#include <string_view>
#include <expected.hpp>
#include <function_ref.hpp>
#include "iterators.hpp"
@@ -74,7 +74,7 @@ public:
* @return an object containing an owned pointer to an in-memory copy of the file
* or an error code describing the reason for failure.
*/
static tl::expected<DataFile, Error> load(std::string_view path);
static std::expected<DataFile, Error> load(std::string_view path);
static DataFile loadOrDie(std::string_view path);
@@ -95,7 +95,7 @@ public:
* @param mapper Function that maps from a string_view to a unique numeric identifier for the column
* @return If the file ends after the header or not enough columns were defined this function returns an error code describing the failure.
*/
[[nodiscard]] tl::expected<void, DataFile::Error> parseHeader(ColumnDefinition *begin, ColumnDefinition *end, tl::function_ref<tl::expected<uint8_t, ColumnDefinition::Error>(std::string_view)> mapper);
[[nodiscard]] std::expected<void, DataFile::Error> parseHeader(ColumnDefinition *begin, ColumnDefinition *end, tl::function_ref<std::expected<uint8_t, ColumnDefinition::Error>(std::string_view)> mapper);
/**
* @brief Templated version of parseHeader(uint8_t) to allow using directly with enum definitions of columns
@@ -106,12 +106,12 @@ public:
* @return A void success result or an error code as described above
*/
template <typename T>
[[nodiscard]] tl::expected<void, DataFile::Error> parseHeader(ColumnDefinition *begin, ColumnDefinition *end, std::function<tl::expected<T, ColumnDefinition::Error>(std::string_view)> typedMapper)
[[nodiscard]] std::expected<void, DataFile::Error> parseHeader(ColumnDefinition *begin, ColumnDefinition *end, std::function<std::expected<T, ColumnDefinition::Error>(std::string_view)> typedMapper)
{
return parseHeader(begin, end, [typedMapper](std::string_view label) { return typedMapper(label).transform([](T value) { return static_cast<uint8_t>(value); }); });
}
[[nodiscard]] tl::expected<void, DataFile::Error> skipHeader();
[[nodiscard]] std::expected<void, DataFile::Error> skipHeader();
void skipHeaderOrDie(std::string_view path);
+30 -31
View File
@@ -1,11 +1,10 @@
#pragma once
#include <charconv>
#include <expected>
#include <optional>
#include <ostream>
#include <expected.hpp>
#include "parser.hpp"
#include "utils/parse_int.hpp"
#include "utils/str_cat.hpp"
@@ -26,29 +25,29 @@ public:
InvalidValue
};
static tl::expected<void, Error> mapError(std::errc ec)
static std::expected<void, Error> mapError(std::errc ec)
{
if (ec == std::errc())
return {};
switch (ec) {
case std::errc::result_out_of_range:
return tl::unexpected { Error::OutOfRange };
return std::unexpected { Error::OutOfRange };
case std::errc::invalid_argument:
return tl::unexpected { Error::NotANumber };
return std::unexpected { Error::NotANumber };
default:
return tl::unexpected { Error::InvalidValue };
return std::unexpected { Error::InvalidValue };
}
}
static tl::expected<void, Error> mapError(ParseIntError ec)
static std::expected<void, Error> mapError(ParseIntError ec)
{
switch (ec) {
case ParseIntError::OutOfRange:
return tl::unexpected { Error::OutOfRange };
return std::unexpected { Error::OutOfRange };
case ParseIntError::ParseError:
return tl::unexpected { Error::NotANumber };
return std::unexpected { Error::NotANumber };
default:
return tl::unexpected { Error::InvalidValue };
return std::unexpected { Error::InvalidValue };
}
}
@@ -95,7 +94,7 @@ public:
* @return an error code corresponding to the from_chars result if parsing failed
*/
template <typename T>
[[nodiscard]] tl::expected<void, Error> parseInt(T &destination)
[[nodiscard]] std::expected<void, Error> parseInt(T &destination)
{
std::from_chars_result result {};
if (state_->status == GetFieldResult::Status::ReadyToRead) {
@@ -114,7 +113,7 @@ public:
return mapError(result.ec);
}
[[nodiscard]] tl::expected<void, Error> parseBool(bool &destination)
[[nodiscard]] std::expected<void, Error> parseBool(bool &destination)
{
const std::string_view str = value();
if (str == "true") {
@@ -125,16 +124,16 @@ public:
destination = false;
return {};
}
return tl::make_unexpected(DataFileField::Error::InvalidValue);
return std::unexpected(DataFileField::Error::InvalidValue);
}
template <typename T>
[[nodiscard]] tl::expected<void, Error> parseIntArray(T *destination, size_t n)
[[nodiscard]] std::expected<void, Error> parseIntArray(T *destination, size_t n)
{
size_t i = 0;
for (const std::string_view part : SplitByChar(value(), ',')) {
if (i == n)
return tl::make_unexpected(Error::InvalidValue);
return std::unexpected(Error::InvalidValue);
const std::from_chars_result result
= std::from_chars(part.data(), part.data() + part.size(), destination[i]);
if (result.ec != std::errc())
@@ -142,41 +141,41 @@ public:
++i;
}
if (i != n)
return tl::make_unexpected(Error::InvalidValue);
return std::unexpected(Error::InvalidValue);
return {};
}
template <typename T, size_t N>
[[nodiscard]] tl::expected<void, Error> parseIntArray(T (&destination)[N])
[[nodiscard]] std::expected<void, Error> parseIntArray(T (&destination)[N])
{
return parseIntArray<T>(destination, N);
}
template <typename T, size_t N>
[[nodiscard]] tl::expected<void, Error> parseIntArray(std::array<T, N> &destination)
[[nodiscard]] std::expected<void, Error> parseIntArray(std::array<T, N> &destination)
{
return parseIntArray<T>(destination.data(), N);
}
template <typename T, typename ParseFn>
[[nodiscard]] tl::expected<void, std::string> parseEnumArray(T *destination, size_t n, std::optional<T> fillMissing, ParseFn &&parseFn)
[[nodiscard]] std::expected<void, std::string> parseEnumArray(T *destination, size_t n, std::optional<T> fillMissing, ParseFn &&parseFn)
{
size_t i = 0;
const std::string_view str = value();
if (!str.empty()) {
for (const std::string_view part : SplitByChar(str, ',')) {
if (i == n)
return tl::make_unexpected(StrCat("Too many values, max: ", n));
return std::unexpected(StrCat("Too many values, max: ", n));
auto result = parseFn(part);
if (!result.has_value()) {
return tl::make_unexpected(std::move(result).error());
return std::unexpected(std::move(result).error());
}
destination[i++] = *result;
}
}
if (i != n) {
if (!fillMissing.has_value()) {
return tl::make_unexpected(StrCat("Too few values, expected ", n, " got ", i));
return std::unexpected(StrCat("Too few values, expected ", n, " got ", i));
}
while (i < n) {
destination[i++] = *fillMissing;
@@ -186,19 +185,19 @@ public:
}
template <typename T, size_t N, typename ParseFn>
[[nodiscard]] tl::expected<void, std::string> parseEnumArray(T (&destination)[N], std::optional<T> fillMissing, ParseFn &&parseFn)
[[nodiscard]] std::expected<void, std::string> parseEnumArray(T (&destination)[N], std::optional<T> fillMissing, ParseFn &&parseFn)
{
return parseEnumArray<T, ParseFn>(destination, N, std::move(fillMissing), std::forward<ParseFn>(parseFn));
}
template <typename T, size_t N, typename ParseFn>
[[nodiscard]] tl::expected<void, std::string> parseIntArray(std::array<T, N> &destination, std::optional<T> fillMissing, ParseFn &&parseFn)
[[nodiscard]] std::expected<void, std::string> parseIntArray(std::array<T, N> &destination, std::optional<T> fillMissing, ParseFn &&parseFn)
{
return parseEnumArray<T, ParseFn>(destination.data(), N, std::move(fillMissing), std::forward<ParseFn>(parseFn));
}
template <typename T, typename ParseFn>
[[nodiscard]] tl::expected<void, std::string> parseEnumList(T &destination, ParseFn &&parseFn)
[[nodiscard]] std::expected<void, std::string> parseEnumList(T &destination, ParseFn &&parseFn)
{
destination = {};
const std::string_view str = value();
@@ -207,17 +206,17 @@ public:
for (const std::string_view part : SplitByChar(str, ',')) {
auto result = parseFn(part);
if (!result.has_value())
return tl::make_unexpected(std::move(result).error());
return std::unexpected(std::move(result).error());
destination |= result.value();
}
return {};
}
template <typename T>
[[nodiscard]] tl::expected<T, Error> asInt()
[[nodiscard]] std::expected<T, Error> asInt()
{
T value = 0;
return parseInt(value).map([value]() { return value; });
return parseInt(value).transform([value]() { return value; });
}
/**
@@ -231,7 +230,7 @@ public:
* @return an error code equivalent to what you'd get from from_chars if parsing failed
*/
template <typename T>
[[nodiscard]] tl::expected<void, Error> parseFixed6(T &destination)
[[nodiscard]] std::expected<void, Error> parseFixed6(T &destination)
{
ParseIntResult<T> parseResult;
if (state_->status == GetFieldResult::Status::ReadyToRead) {
@@ -255,10 +254,10 @@ public:
}
template <typename T>
[[nodiscard]] tl::expected<T, Error> asFixed6()
[[nodiscard]] std::expected<T, Error> asFixed6()
{
T value = 0;
return parseFixed6(value).map([value]() { return value; });
return parseFixed6(value).transform([value]() { return value; });
}
/**
+4 -4
View File
@@ -1,10 +1,10 @@
#pragma once
#include <array>
#include <expected>
#include <string_view>
#include <type_traits>
#include <expected.hpp>
#include <function_ref.hpp>
#include "data/file.hpp"
@@ -86,7 +86,7 @@ public:
void read(std::string_view name, T &out, F &&parseFn)
{
DataFileField field = nextField();
tl::expected<T, std::string> result = parseFn(field.value());
std::expected<T, std::string> result = parseFn(field.value());
failOnError(result, name, field, DataFileField::Error::InvalidValue);
out = *std::move(result);
}
@@ -116,7 +116,7 @@ public:
private:
template <typename T>
void failOnError(const tl::expected<T, DataFileField::Error> &result, std::string_view name, const DataFileField &field)
void failOnError(const std::expected<T, DataFileField::Error> &result, std::string_view name, const DataFileField &field)
{
if (!result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename_, name, field);
@@ -124,7 +124,7 @@ private:
}
template <typename T>
void failOnError(const tl::expected<T, std::string> &result, std::string_view name, const DataFileField &field, DataFileField::Error error)
void failOnError(const std::expected<T, std::string> &result, std::string_view name, const DataFileField &field, DataFileField::Error error)
{
if (!result.has_value()) {
DataFile::reportFatalFieldError(error, filename_, name, field, result.error());
+9 -9
View File
@@ -1,10 +1,10 @@
#pragma once
#include <array>
#include <expected>
#include <string_view>
#include <type_traits>
#include <expected.hpp>
#include <function_ref.hpp>
#include "data/file.hpp"
@@ -25,7 +25,7 @@ public:
void readValue(std::string_view expectedKey, T &outValue, F &&readFn)
{
DataFileField valueField = getValueField(expectedKey);
if (const tl::expected<void, devilution::DataFileField::Error> result = readFn(valueField, outValue);
if (const std::expected<void, devilution::DataFileField::Error> result = readFn(valueField, outValue);
!result.has_value()) {
DataFile::reportFatalFieldError(result.error(), filename_, "Value", valueField);
}
@@ -35,10 +35,10 @@ public:
template <typename T, typename F>
void read(std::string_view expectedKey, T &outValue, F &&parseFn)
{
readValue(expectedKey, outValue, [&parseFn](DataFileField &valueField, T &outValue) -> tl::expected<void, devilution::DataFileField::Error> {
readValue(expectedKey, outValue, [&parseFn](DataFileField &valueField, T &outValue) -> std::expected<void, devilution::DataFileField::Error> {
const auto result = parseFn(valueField.value());
if (!result.has_value()) {
return tl::make_unexpected(devilution::DataFileField::Error::InvalidValue);
return std::unexpected(devilution::DataFileField::Error::InvalidValue);
}
outValue = result.value();
@@ -49,10 +49,10 @@ public:
template <typename T, typename F>
void readEnumList(std::string_view expectedKey, T &outValue, F &&parseFn)
{
readValue(expectedKey, outValue, [&parseFn](DataFileField &valueField, T &outValue) -> tl::expected<void, devilution::DataFileField::Error> {
readValue(expectedKey, outValue, [&parseFn](DataFileField &valueField, T &outValue) -> std::expected<void, devilution::DataFileField::Error> {
const auto result = valueField.parseEnumList(outValue, std::forward<F>(parseFn));
if (!result.has_value()) {
return tl::make_unexpected(devilution::DataFileField::Error::InvalidValue);
return std::unexpected(devilution::DataFileField::Error::InvalidValue);
}
return {};
@@ -81,15 +81,15 @@ public:
{
readValue(expectedKey, outValue, [](DataFileField &valueField, std::string &outValue) {
outValue = valueField.value();
return tl::expected<void, devilution::DataFileField::Error> {};
return std::expected<void, devilution::DataFileField::Error> {};
});
}
void readChar(std::string_view expectedKey, char &outValue)
{
readValue(expectedKey, outValue, [](DataFileField &valueField, char &outValue) -> tl::expected<void, devilution::DataFileField::Error> {
readValue(expectedKey, outValue, [](DataFileField &valueField, char &outValue) -> std::expected<void, devilution::DataFileField::Error> {
if (valueField.value().size() != 1) {
return tl::make_unexpected(devilution::DataFileField::Error::InvalidValue);
return std::unexpected(devilution::DataFileField::Error::InvalidValue);
}
outValue = valueField.value().at(0);
+9 -9
View File
@@ -1360,12 +1360,12 @@ void DiabloDeinit()
SDL_Quit();
}
tl::expected<void, std::string> LoadLvlGFX()
std::expected<void, std::string> LoadLvlGFX()
{
assert(pDungeonCels == nullptr);
constexpr int SpecialCelWidth = 64;
const auto loadAll = [](const char *cel, const char *til, const char *special) -> tl::expected<void, std::string> {
const auto loadAll = [](const char *cel, const char *til, const char *special) -> std::expected<void, std::string> {
ASSIGN_OR_RETURN(pDungeonCels, LoadFileInMemWithStatus(cel));
ASSIGN_OR_RETURN(pMegaTiles, LoadFileInMemWithStatus<MegaTile>(til));
ASSIGN_OR_RETURN(pSpecialCels, LoadCelWithStatus(special, SpecialCelWidth));
@@ -1420,11 +1420,11 @@ tl::expected<void, std::string> LoadLvlGFX()
"nlevels\\l5data\\l5.til",
"nlevels\\l5data\\l5s");
default:
return tl::make_unexpected("LoadLvlGFX");
return std::unexpected("LoadLvlGFX");
}
}
tl::expected<void, std::string> LoadAllGFX()
std::expected<void, std::string> LoadAllGFX()
{
IncProgress();
#if !defined(USE_SDL1) && !defined(__vita__)
@@ -3136,7 +3136,7 @@ void LoadGameLevelStash()
gbIsHellfireSaveGame = isHellfireSaveGame;
}
tl::expected<void, std::string> LoadGameLevelDungeon(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
std::expected<void, std::string> LoadGameLevelDungeon(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
{
if (firstflag || lvldir == ENTRY_LOAD || !myPlayer._pLvlVisited[currlevel] || gbIsMultiplayer) {
HoldThemeRooms();
@@ -3232,7 +3232,7 @@ void LoadGameLevelSetVisited()
}
}
tl::expected<void, std::string> LoadGameLevelTown(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
std::expected<void, std::string> LoadGameLevelTown(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
{
for (int i = 0; i < MAXDUNX; i++) { // NOLINT(modernize-loop-convert)
for (int j = 0; j < MAXDUNY; j++) {
@@ -3261,7 +3261,7 @@ tl::expected<void, std::string> LoadGameLevelTown(bool firstflag, lvl_entry lvld
return {};
}
tl::expected<void, std::string> LoadGameLevelSetLevel(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
std::expected<void, std::string> LoadGameLevelSetLevel(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
{
LoadSetMap();
IncProgress();
@@ -3313,7 +3313,7 @@ tl::expected<void, std::string> LoadGameLevelSetLevel(bool firstflag, lvl_entry
return {};
}
tl::expected<void, std::string> LoadGameLevelStandardLevel(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
std::expected<void, std::string> LoadGameLevelStandardLevel(bool firstflag, lvl_entry lvldir, const Player &myPlayer)
{
CreateLevel(lvldir);
@@ -3396,7 +3396,7 @@ void LoadGameLevelCalculateCursor()
CheckCursMove();
}
tl::expected<void, std::string> LoadGameLevel(bool firstflag, lvl_entry lvldir)
std::expected<void, std::string> LoadGameLevel(bool firstflag, lvl_entry lvldir)
{
const _music_id neededTrack = GetLevelMusic(leveltype);
+1 -1
View File
@@ -106,7 +106,7 @@ void diablo_focus_pause();
void diablo_focus_unpause();
bool PressEscKey();
void DisableInputEventHandler(const SDL_Event &event, uint16_t modState);
tl::expected<void, std::string> LoadGameLevel(bool firstflag, lvl_entry lvldir);
std::expected<void, std::string> LoadGameLevel(bool firstflag, lvl_entry lvldir);
bool IsDiabloAlive(bool playSFX);
void PrintScreen(SDL_Keycode vkey);
+39 -40
View File
@@ -3,6 +3,7 @@
#include <algorithm>
#include <cstdint>
#include <cstring>
#include <expected>
#include <memory>
#ifdef USE_SDL3
@@ -11,8 +12,6 @@
#include <SDL.h>
#endif
#include <expected.hpp>
#include "player.h"
namespace devilution {
@@ -20,7 +19,7 @@ namespace net {
void base::process_network_packets()
{
tl::expected<void, PacketError> result = poll();
std::expected<void, PacketError> result = poll();
if (!result.has_value()) {
LogVerbose("Error polling network: {}", result.error().what());
}
@@ -61,7 +60,7 @@ void base::DisconnectNet(plr_t plr)
{
}
tl::expected<void, PacketError> base::SendEchoRequest(plr_t player)
std::expected<void, PacketError> base::SendEchoRequest(plr_t player)
{
if (plr_self == PLR_BROADCAST)
return {};
@@ -69,29 +68,29 @@ tl::expected<void, PacketError> base::SendEchoRequest(plr_t player)
return {};
const timestamp_t now = SDL_GetTicks();
tl::expected<std::unique_ptr<packet>, PacketError> pkt
std::expected<std::unique_ptr<packet>, PacketError> pkt
= pktfty->make_packet<PT_ECHO_REQUEST>(plr_self, player, now);
if (!pkt.has_value()) {
return tl::make_unexpected(pkt.error());
return std::unexpected(pkt.error());
}
return send(**pkt);
}
tl::expected<void, PacketError> base::HandleAccept(packet &pkt)
std::expected<void, PacketError> base::HandleAccept(packet &pkt)
{
if (plr_self != PLR_BROADCAST) {
return {}; // already have player id
}
if (pkt.Cookie() == cookie_self) {
tl::expected<plr_t, PacketError> newPlayerPkt = pkt.NewPlayer();
std::expected<plr_t, PacketError> newPlayerPkt = pkt.NewPlayer();
if (!newPlayerPkt.has_value())
return tl::make_unexpected(newPlayerPkt.error());
return std::unexpected(newPlayerPkt.error());
plr_self = *std::move(newPlayerPkt);
Connect(plr_self);
}
tl::expected<const buffer_t *, PacketError> infoPkt = pkt.Info();
std::expected<const buffer_t *, PacketError> infoPkt = pkt.Info();
if (!infoPkt.has_value())
return tl::make_unexpected(infoPkt.error());
return std::unexpected(infoPkt.error());
const buffer_t &info = **infoPkt;
if (game_init_info != info) {
if (info.size() != sizeof(GameData)) {
@@ -109,14 +108,14 @@ tl::expected<void, PacketError> base::HandleAccept(packet &pkt)
return {};
}
tl::expected<void, PacketError> base::HandleConnect(packet &pkt)
std::expected<void, PacketError> base::HandleConnect(packet &pkt)
{
return pkt.NewPlayer().transform([this](plr_t &&newPlayer) {
Connect(newPlayer);
});
}
tl::expected<void, PacketError> base::HandleTurn(packet &pkt)
std::expected<void, PacketError> base::HandleTurn(packet &pkt)
{
const plr_t src = pkt.Source();
PlayerState &playerState = playerStateTable_[src];
@@ -127,17 +126,17 @@ tl::expected<void, PacketError> base::HandleTurn(packet &pkt)
});
}
tl::expected<void, PacketError> base::HandleDisconnect(packet &pkt)
std::expected<void, PacketError> base::HandleDisconnect(packet &pkt)
{
tl::expected<plr_t, PacketError> newPlayer = pkt.NewPlayer();
std::expected<plr_t, PacketError> newPlayer = pkt.NewPlayer();
if (!newPlayer.has_value())
return tl::make_unexpected(newPlayer.error());
return std::unexpected(newPlayer.error());
if (*newPlayer == plr_self)
return tl::make_unexpected("We were dropped by the owner?");
return std::unexpected("We were dropped by the owner?");
if (IsConnected(*newPlayer)) {
tl::expected<leaveinfo_t, PacketError> leaveinfo = pkt.LeaveInfo();
std::expected<leaveinfo_t, PacketError> leaveinfo = pkt.LeaveInfo();
if (!leaveinfo.has_value())
return tl::make_unexpected(leaveinfo.error());
return std::unexpected(leaveinfo.error());
_SNETEVENT ev;
ev.eventid = EVENT_TYPE_PLAYER_LEAVE_GAME;
ev.playerid = *newPlayer;
@@ -153,7 +152,7 @@ tl::expected<void, PacketError> base::HandleDisconnect(packet &pkt)
return {};
}
tl::expected<void, PacketError> base::HandleEchoRequest(packet &pkt)
std::expected<void, PacketError> base::HandleEchoRequest(packet &pkt)
{
// If we have already left the game,
// there is no need to respond to echoes
@@ -168,7 +167,7 @@ tl::expected<void, PacketError> base::HandleEchoRequest(packet &pkt)
});
}
tl::expected<void, PacketError> base::HandleEchoReply(packet &pkt)
std::expected<void, PacketError> base::HandleEchoReply(packet &pkt)
{
const uint32_t now = SDL_GetTicks();
plr_t src = pkt.Source();
@@ -189,7 +188,7 @@ void base::ClearMsg(plr_t plr)
message_queue.end());
}
tl::expected<void, PacketError> base::Connect(plr_t player)
std::expected<void, PacketError> base::Connect(plr_t player)
{
PlayerState &playerState = playerStateTable_[player];
const bool wasConnected = playerState.isConnected;
@@ -206,10 +205,10 @@ bool base::IsConnected(plr_t player) const
return playerState.isConnected;
}
tl::expected<void, PacketError> base::RecvLocal(packet &pkt)
std::expected<void, PacketError> base::RecvLocal(packet &pkt)
{
if (pkt.Source() < MAX_PLRS) {
if (tl::expected<void, PacketError> result = Connect(pkt.Source());
if (std::expected<void, PacketError> result = Connect(pkt.Source());
!result.has_value()) {
return result;
}
@@ -271,13 +270,13 @@ bool base::SNetSendMessage(uint8_t playerId, void *data, size_t size)
else
dest = playerId;
if (dest != plr_self) {
tl::expected<std::unique_ptr<packet>, PacketError> pkt
std::expected<std::unique_ptr<packet>, PacketError> pkt
= pktfty->make_packet<PT_MESSAGE>(plr_self, dest, message);
if (!pkt.has_value()) {
LogError("make_packet: {}", pkt.error().what());
return false;
}
tl::expected<void, PacketError> result = send(**pkt);
std::expected<void, PacketError> result = send(**pkt);
if (!result.has_value()) {
LogError("send: {}", result.error().what());
return false;
@@ -384,23 +383,23 @@ bool base::SNetSendTurn(char *data, size_t size)
return true;
}
tl::expected<void, PacketError> base::SendTurnIfReady(turn_t turn)
std::expected<void, PacketError> base::SendTurnIfReady(turn_t turn)
{
if (awaitingSequenceNumber_)
awaitingSequenceNumber_ = !IsGameHost();
if (!awaitingSequenceNumber_) {
tl::expected<std::unique_ptr<packet>, PacketError> pkt
std::expected<std::unique_ptr<packet>, PacketError> pkt
= pktfty->make_packet<PT_TURN>(plr_self, PLR_BROADCAST, turn);
if (!pkt.has_value()) {
return tl::make_unexpected(pkt.error());
return std::unexpected(pkt.error());
}
return send(**pkt);
}
return {};
}
tl::expected<void, PacketError> base::SendFirstTurnIfReady(plr_t player)
std::expected<void, PacketError> base::SendFirstTurnIfReady(plr_t player)
{
if (awaitingSequenceNumber_)
return {};
@@ -411,12 +410,12 @@ tl::expected<void, PacketError> base::SendFirstTurnIfReady(plr_t player)
return {};
for (const turn_t turn : turnQueue) {
tl::expected<std::unique_ptr<packet>, PacketError> pkt
std::expected<std::unique_ptr<packet>, PacketError> pkt
= pktfty->make_packet<PT_TURN>(plr_self, player, turn);
if (!pkt.has_value()) {
return tl::make_unexpected(pkt.error());
return std::unexpected(pkt.error());
}
tl::expected<void, PacketError> result = send(**pkt);
std::expected<void, PacketError> result = send(**pkt);
if (!result.has_value()) {
return result;
}
@@ -424,7 +423,7 @@ tl::expected<void, PacketError> base::SendFirstTurnIfReady(plr_t player)
return {};
}
tl::expected<void, PacketError> base::MakeReady(seq_t sequenceNumber)
std::expected<void, PacketError> base::MakeReady(seq_t sequenceNumber)
{
if (!awaitingSequenceNumber_)
return {};
@@ -438,7 +437,7 @@ tl::expected<void, PacketError> base::MakeReady(seq_t sequenceNumber)
for (turn_t &turn : turnQueue) {
turn.SequenceNumber = next_turn;
next_turn++;
if (tl::expected<void, PacketError> result = SendTurnIfReady(turn);
if (std::expected<void, PacketError> result = SendTurnIfReady(turn);
!result.has_value()) {
return result;
}
@@ -482,14 +481,14 @@ bool base::SNetRegisterEventHandler(event_type evtype, SEVTHANDLER func)
bool base::SNetLeaveGame(net::leaveinfo_t type)
{
tl::expected<std::unique_ptr<packet>, PacketError> pkt
std::expected<std::unique_ptr<packet>, PacketError> pkt
= pktfty->make_packet<PT_DISCONNECT>(
plr_self, PLR_BROADCAST, plr_self, type);
if (!pkt.has_value()) {
LogError("make_packet: {}", pkt.error().what());
return false;
}
tl::expected<void, PacketError> result = send(**pkt);
std::expected<void, PacketError> result = send(**pkt);
if (!result.has_value()) {
LogError("send: {}", result.error().what());
return false;
@@ -501,7 +500,7 @@ bool base::SNetLeaveGame(net::leaveinfo_t type)
bool base::SNetDropPlayer(int playerid, net::leaveinfo_t flags)
{
const auto plr = static_cast<plr_t>(playerid);
tl::expected<std::unique_ptr<packet>, PacketError> pkt
std::expected<std::unique_ptr<packet>, PacketError> pkt
= pktfty->make_packet<PT_DISCONNECT>(
plr_self,
PLR_BROADCAST,
@@ -514,12 +513,12 @@ bool base::SNetDropPlayer(int playerid, net::leaveinfo_t flags)
// Disconnect at the network layer first so we
// don't send players their own disconnect packet
DisconnectNet(plr);
tl::expected<void, PacketError> sendResult = send(**pkt);
std::expected<void, PacketError> sendResult = send(**pkt);
if (!sendResult.has_value()) {
LogError("send: {}", sendResult.error().what());
return false;
}
tl::expected<void, PacketError> receiveResult = RecvLocal(**pkt);
std::expected<void, PacketError> receiveResult = RecvLocal(**pkt);
if (!receiveResult.has_value()) {
LogError("SNetDropPlayer: {}", receiveResult.error().what());
return false;
+14 -14
View File
@@ -30,8 +30,8 @@ public:
bool SNetGetOwnerTurnsWaiting(uint32_t *turns) override;
bool SNetGetTurnsInTransit(uint32_t *turns) override;
virtual tl::expected<void, PacketError> poll() = 0;
virtual tl::expected<void, PacketError> send(packet &pkt) = 0;
virtual std::expected<void, PacketError> poll() = 0;
virtual std::expected<void, PacketError> send(packet &pkt) = 0;
virtual void DisconnectNet(plr_t plr);
void process_network_packets() override;
@@ -81,10 +81,10 @@ protected:
std::unique_ptr<packet_factory> pktfty;
tl::expected<void, PacketError> Connect(plr_t player);
tl::expected<void, PacketError> RecvLocal(packet &pkt);
std::expected<void, PacketError> Connect(plr_t player);
std::expected<void, PacketError> RecvLocal(packet &pkt);
void RunEventHandler(_SNETEVENT &ev);
tl::expected<void, PacketError> SendEchoRequest(plr_t player);
std::expected<void, PacketError> SendEchoRequest(plr_t player);
[[nodiscard]] bool IsConnected(plr_t player) const;
virtual bool IsGameHost() = 0;
@@ -96,17 +96,17 @@ private:
plr_t GetOwner();
bool AllTurnsArrived();
tl::expected<void, PacketError> MakeReady(seq_t sequenceNumber);
tl::expected<void, PacketError> SendTurnIfReady(turn_t turn);
tl::expected<void, PacketError> SendFirstTurnIfReady(plr_t player);
std::expected<void, PacketError> MakeReady(seq_t sequenceNumber);
std::expected<void, PacketError> SendTurnIfReady(turn_t turn);
std::expected<void, PacketError> SendFirstTurnIfReady(plr_t player);
void ClearMsg(plr_t plr);
tl::expected<void, PacketError> HandleAccept(packet &pkt);
tl::expected<void, PacketError> HandleConnect(packet &pkt);
tl::expected<void, PacketError> HandleTurn(packet &pkt);
tl::expected<void, PacketError> HandleDisconnect(packet &pkt);
tl::expected<void, PacketError> HandleEchoRequest(packet &pkt);
tl::expected<void, PacketError> HandleEchoReply(packet &pkt);
std::expected<void, PacketError> HandleAccept(packet &pkt);
std::expected<void, PacketError> HandleConnect(packet &pkt);
std::expected<void, PacketError> HandleTurn(packet &pkt);
std::expected<void, PacketError> HandleDisconnect(packet &pkt);
std::expected<void, PacketError> HandleEchoRequest(packet &pkt);
std::expected<void, PacketError> HandleEchoReply(packet &pkt);
};
} // namespace net
+60 -60
View File
@@ -27,8 +27,8 @@ class base_protocol : public base {
public:
int create(std::string_view addrstr) override;
int join(std::string_view addrstr) override;
tl::expected<void, PacketError> poll() override;
tl::expected<void, PacketError> send(packet &pkt) override;
std::expected<void, PacketError> poll() override;
std::expected<void, PacketError> send(packet &pkt) override;
void DisconnectNet(plr_t plr) override;
bool SNetLeaveGame(net::leaveinfo_t type) override;
@@ -66,18 +66,18 @@ private:
bool isGameHost_;
plr_t get_master();
tl::expected<void, PacketError> InitiateHandshake(plr_t player);
tl::expected<void, PacketError> SendTo(plr_t player, packet &pkt);
std::expected<void, PacketError> InitiateHandshake(plr_t player);
std::expected<void, PacketError> SendTo(plr_t player, packet &pkt);
void DrainSendQueue(plr_t player);
void recv();
tl::expected<void, PacketError> handle_join_request(packet &pkt, endpoint_t sender);
tl::expected<void, PacketError> recv_decrypted(packet &pkt, endpoint_t sender);
tl::expected<void, PacketError> recv_ingame(packet &pkt, endpoint_t sender);
std::expected<void, PacketError> handle_join_request(packet &pkt, endpoint_t sender);
std::expected<void, PacketError> recv_decrypted(packet &pkt, endpoint_t sender);
std::expected<void, PacketError> recv_ingame(packet &pkt, endpoint_t sender);
bool is_recognized(endpoint_t sender);
tl::expected<void, PacketError> wait_network();
tl::expected<void, PacketError> wait_firstpeer();
tl::expected<void, PacketError> wait_join();
std::expected<void, PacketError> wait_network();
std::expected<void, PacketError> wait_firstpeer();
std::expected<void, PacketError> wait_join();
};
template <class P>
@@ -91,18 +91,18 @@ plr_t base_protocol<P>::get_master()
}
template <class P>
tl::expected<void, PacketError> base_protocol<P>::wait_network()
std::expected<void, PacketError> base_protocol<P>::wait_network()
{
// wait for ZeroTier for 5 seconds
for (auto i = 0; i < 500; ++i) {
tl::expected<bool, PacketError> status = proto.network_online();
std::expected<bool, PacketError> status = proto.network_online();
if (!status.has_value())
return tl::make_unexpected(std::move(status).error());
return std::unexpected(std::move(status).error());
if (*status)
return {};
SDL_Delay(10);
}
return tl::make_unexpected("Timeout waiting for ZeroTier network initialization");
return std::unexpected("Timeout waiting for ZeroTier network initialization");
}
template <class P>
@@ -114,7 +114,7 @@ void base_protocol<P>::DisconnectNet(plr_t plr)
}
template <class P>
tl::expected<void, PacketError> base_protocol<P>::wait_firstpeer()
std::expected<void, PacketError> base_protocol<P>::wait_firstpeer()
{
firstpeer = {};
// wait for peer for 5 seconds
@@ -129,21 +129,21 @@ tl::expected<void, PacketError> base_protocol<P>::wait_firstpeer()
SDL_Delay(10);
}
if (!firstpeer)
return tl::make_unexpected("Timeout waiting for response from game host");
return std::unexpected("Timeout waiting for response from game host");
return {};
}
template <class P>
bool base_protocol<P>::send_info_request()
{
tl::expected<bool, PacketError> status = proto.peers_ready();
std::expected<bool, PacketError> status = proto.peers_ready();
if (!status.has_value()) {
LogError("peers_ready: {}", status.error().what());
return false;
}
if (!*status)
return false;
tl::expected<std::unique_ptr<packet>, PacketError> pkt
std::expected<std::unique_ptr<packet>, PacketError> pkt
= pktfty->make_packet<PT_INFO_REQUEST>(PLR_BROADCAST, PLR_MASTER);
if (!pkt.has_value()) {
LogError("make_packet: {}", pkt.error().what());
@@ -154,15 +154,15 @@ bool base_protocol<P>::send_info_request()
}
template <class P>
tl::expected<void, PacketError> base_protocol<P>::wait_join()
std::expected<void, PacketError> base_protocol<P>::wait_join()
{
cookie_self = packet_out::GenerateCookie();
tl::expected<std::unique_ptr<packet>, PacketError> pkt
std::expected<std::unique_ptr<packet>, PacketError> pkt
= pktfty->make_packet<PT_JOIN_REQUEST>(PLR_BROADCAST, PLR_MASTER, cookie_self, game_init_info);
if (!pkt.has_value()) {
return tl::make_unexpected(pkt.error());
return std::unexpected(pkt.error());
}
tl::expected<void, PacketError> result = proto.send(firstpeer, (*pkt)->Data());
std::expected<void, PacketError> result = proto.send(firstpeer, (*pkt)->Data());
if (!result.has_value()) {
return result;
}
@@ -172,7 +172,7 @@ tl::expected<void, PacketError> base_protocol<P>::wait_join()
return {}; // join successful
SDL_Delay(10);
}
return tl::make_unexpected("Timeout waiting to join game");
return std::unexpected("Timeout waiting to join game");
}
template <class P>
@@ -181,14 +181,14 @@ int base_protocol<P>::create(std::string_view addrstr)
gamename = addrstr;
isGameHost_ = true;
tl::expected<void, PacketError> isReady = wait_network();
std::expected<void, PacketError> isReady = wait_network();
if (!isReady.has_value()) {
const std::string_view message = isReady.error().what();
SDL_SetError("%.*s", static_cast<int>(message.size()), message.data());
return -1;
}
plr_self = 0;
if (tl::expected<void, PacketError> result = Connect(plr_self);
if (std::expected<void, PacketError> result = Connect(plr_self);
!result.has_value()) {
const std::string_view message = result.error().what();
SDL_SetError("%.*s", static_cast<int>(message.size()), message.data());
@@ -203,19 +203,19 @@ int base_protocol<P>::join(std::string_view addrstr)
gamename = addrstr;
isGameHost_ = false;
tl::expected<void, PacketError> isReady = wait_network();
std::expected<void, PacketError> isReady = wait_network();
if (!isReady.has_value()) {
const std::string_view message = isReady.error().what();
SDL_SetError("%.*s", static_cast<int>(message.size()), message.data());
return -1;
}
tl::expected<void, PacketError> isPeerReady = wait_firstpeer();
std::expected<void, PacketError> isPeerReady = wait_firstpeer();
if (!isPeerReady.has_value()) {
const std::string_view message = isPeerReady.error().what();
SDL_SetError("%.*s", static_cast<int>(message.size()), message.data());
return -1;
}
tl::expected<void, PacketError> isJoined = wait_join();
std::expected<void, PacketError> isJoined = wait_join();
if (!isJoined.has_value()) {
const std::string_view message = isJoined.error().what();
SDL_SetError("%.*s", static_cast<int>(message.size()), message.data());
@@ -231,14 +231,14 @@ bool base_protocol<P>::IsGameHost()
}
template <class P>
tl::expected<void, PacketError> base_protocol<P>::poll()
std::expected<void, PacketError> base_protocol<P>::poll()
{
recv();
return {};
}
template <class P>
tl::expected<void, PacketError> base_protocol<P>::InitiateHandshake(plr_t player)
std::expected<void, PacketError> base_protocol<P>::InitiateHandshake(plr_t player)
{
Peer &peer = peers[player];
@@ -253,26 +253,26 @@ tl::expected<void, PacketError> base_protocol<P>::InitiateHandshake(plr_t player
}
template <class P>
tl::expected<void, PacketError> base_protocol<P>::send(packet &pkt)
std::expected<void, PacketError> base_protocol<P>::send(packet &pkt)
{
plr_t destination = pkt.Destination();
if (destination == PLR_BROADCAST) {
for (plr_t player = 0; player < Players.size(); player++) {
tl::expected<void, PacketError> result = SendTo(player, pkt);
std::expected<void, PacketError> result = SendTo(player, pkt);
if (!result.has_value())
LogError("Failed to send packet {} to player {}: {}", static_cast<uint8_t>(pkt.Type()), player, result.error().what());
}
return {};
}
if (destination >= MAX_PLRS)
return tl::make_unexpected("Invalid player ID");
return std::unexpected("Invalid player ID");
if (destination == plr_self)
return {};
return SendTo(destination, pkt);
}
template <class P>
tl::expected<void, PacketError> base_protocol<P>::SendTo(plr_t player, packet &pkt)
std::expected<void, PacketError> base_protocol<P>::SendTo(plr_t player, packet &pkt)
{
Peer &peer = peers[player];
if (!peer.endpoint)
@@ -294,7 +294,7 @@ void base_protocol<P>::recv()
buffer_t pkt_buf;
endpoint_t sender;
while (proto.recv(sender, pkt_buf)) { // read until kernel buffer is empty?
tl::expected<void, PacketError> result
std::expected<void, PacketError> result
= pktfty->make_packet(pkt_buf)
.and_then([&](std::unique_ptr<packet> &&pkt) {
return recv_decrypted(*pkt, sender);
@@ -316,7 +316,7 @@ void base_protocol<P>::recv()
}
template <class P>
tl::expected<void, PacketError> base_protocol<P>::handle_join_request(packet &inPkt, endpoint_t sender)
std::expected<void, PacketError> base_protocol<P>::handle_join_request(packet &inPkt, endpoint_t sender)
{
plr_t i;
for (i = 0; i < Players.size(); ++i) {
@@ -324,7 +324,7 @@ tl::expected<void, PacketError> base_protocol<P>::handle_join_request(packet &in
if (i != plr_self && !peer.endpoint) {
peer.endpoint = sender;
peer.sendQueue = std::make_unique<std::deque<packet>>();
if (tl::expected<void, PacketError> result = Connect(i);
if (std::expected<void, PacketError> result = Connect(i);
!result.has_value()) {
return result;
}
@@ -340,7 +340,7 @@ tl::expected<void, PacketError> base_protocol<P>::handle_join_request(packet &in
for (plr_t j = 0; j < Players.size(); ++j) {
endpoint_t peer = peers[j].endpoint;
if ((j != plr_self) && (j != i) && peer) {
tl::expected<void, PacketError> result
std::expected<void, PacketError> result
= pktfty->make_packet<PT_CONNECT>(PLR_MASTER, PLR_BROADCAST, i, senderinfo)
.and_then([&](std::unique_ptr<packet> &&pkt) { return proto.send(peer, pkt->Data()); })
.and_then([&]() { return pktfty->make_packet<PT_CONNECT>(PLR_MASTER, PLR_BROADCAST, j, peer.serialize()); })
@@ -352,14 +352,14 @@ tl::expected<void, PacketError> base_protocol<P>::handle_join_request(packet &in
// PT_JOIN_ACCEPT must be sent after all PT_CONNECT packets so the new player does
// not resume game logic until after having been notified of all existing players
tl::expected<cookie_t, PacketError> cookie = inPkt.Cookie();
std::expected<cookie_t, PacketError> cookie = inPkt.Cookie();
if (!cookie.has_value())
return tl::make_unexpected(cookie.error());
tl::expected<std::unique_ptr<packet>, PacketError> pkt
return std::unexpected(cookie.error());
std::expected<std::unique_ptr<packet>, PacketError> pkt
= pktfty->make_packet<PT_JOIN_ACCEPT>(plr_self, PLR_BROADCAST, *cookie, i, game_init_info);
if (!pkt.has_value())
return tl::make_unexpected(pkt.error());
tl::expected<void, PacketError> result = proto.send(sender, (*pkt)->Data());
return std::unexpected(pkt.error());
std::expected<void, PacketError> result = proto.send(sender, (*pkt)->Data());
if (!result.has_value())
return result;
DrainSendQueue(i);
@@ -367,13 +367,13 @@ tl::expected<void, PacketError> base_protocol<P>::handle_join_request(packet &in
}
template <class P>
tl::expected<void, PacketError> base_protocol<P>::recv_decrypted(packet &pkt, endpoint_t sender)
std::expected<void, PacketError> base_protocol<P>::recv_decrypted(packet &pkt, endpoint_t sender)
{
if (pkt.Source() == PLR_BROADCAST && pkt.Destination() == PLR_MASTER && pkt.Type() == PT_INFO_REPLY) {
size_t neededSize = sizeof(GameData) + (PlayerNameLength * MAX_PLRS);
const tl::expected<const buffer_t *, PacketError> pktInfo = pkt.Info();
const std::expected<const buffer_t *, PacketError> pktInfo = pkt.Info();
if (!pktInfo.has_value())
return tl::make_unexpected(pktInfo.error());
return std::unexpected(pktInfo.error());
const buffer_t &infoBuffer = **pktInfo;
if (infoBuffer.size() < neededSize)
return {};
@@ -406,11 +406,11 @@ tl::expected<void, PacketError> base_protocol<P>::recv_decrypted(packet &pkt, en
}
template <class P>
tl::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpoint_t sender)
std::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpoint_t sender)
{
if (pkt.Source() == PLR_BROADCAST && pkt.Destination() == PLR_MASTER) {
if (pkt.Type() == PT_JOIN_REQUEST) {
if (tl::expected<void, PacketError> result = handle_join_request(pkt, sender);
if (std::expected<void, PacketError> result = handle_join_request(pkt, sender);
!result.has_value()) {
return result;
}
@@ -427,10 +427,10 @@ tl::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpo
}
}
std::memcpy(buf.data() + game_init_info.size() + (PlayerNameLength * MAX_PLRS), &gamename[0], gamename.size());
tl::expected<std::unique_ptr<packet>, PacketError> reply
std::expected<std::unique_ptr<packet>, PacketError> reply
= pktfty->make_packet<PT_INFO_REPLY>(PLR_BROADCAST, PLR_MASTER, buf);
if (!reply.has_value()) {
return tl::make_unexpected(reply.error());
return std::unexpected(reply.error());
}
proto.send_oob(sender, (*reply)->Data());
}
@@ -444,19 +444,19 @@ tl::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpo
}
// addrinfo packets
tl::expected<plr_t, PacketError> newPlayer = pkt.NewPlayer();
std::expected<plr_t, PacketError> newPlayer = pkt.NewPlayer();
if (!newPlayer.has_value())
return tl::make_unexpected(newPlayer.error());
return std::unexpected(newPlayer.error());
Peer &peer = peers[*newPlayer];
tl::expected<const buffer_t *, PacketError> pktInfo = pkt.Info();
std::expected<const buffer_t *, PacketError> pktInfo = pkt.Info();
if (!pktInfo.has_value())
return tl::make_unexpected(pktInfo.error());
if (tl::expected<void, PacketError> result = peer.endpoint.unserialize(**pktInfo);
return std::unexpected(pktInfo.error());
if (std::expected<void, PacketError> result = peer.endpoint.unserialize(**pktInfo);
!result.has_value()) {
return result;
}
peer.sendQueue = std::make_unique<std::deque<packet>>();
if (tl::expected<void, PacketError> result = Connect(*newPlayer);
if (std::expected<void, PacketError> result = Connect(*newPlayer);
!result.has_value()) {
return result;
}
@@ -473,7 +473,7 @@ tl::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpo
if (sender == firstpeer && pkt.Type() == PT_JOIN_ACCEPT) {
plr_t src = pkt.Source();
peers[src].endpoint = sender;
if (tl::expected<void, PacketError> result = Connect(src);
if (std::expected<void, PacketError> result = Connect(src);
!result.has_value()) {
return result;
}
@@ -486,7 +486,7 @@ tl::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpo
return {}; // packet not for us, drop
bool wasBroadcast = plr_self == PLR_BROADCAST;
if (tl::expected<void, PacketError> result = RecvLocal(pkt);
if (std::expected<void, PacketError> result = RecvLocal(pkt);
!result.has_value()) {
return result;
}
@@ -495,7 +495,7 @@ tl::expected<void, PacketError> base_protocol<P>::recv_ingame(packet &pkt, endpo
if (wasBroadcast) {
// Send a handshake to everyone just after PT_JOIN_ACCEPT
for (plr_t player = 0; player < Players.size(); player++) {
if (tl::expected<void, PacketError> result = InitiateHandshake(player);
if (std::expected<void, PacketError> result = InitiateHandshake(player);
!result.has_value()) {
return result;
}
@@ -517,7 +517,7 @@ void base_protocol<P>::DrainSendQueue(plr_t player)
std::deque<packet> &sendQueue = *srcPeer.sendQueue;
while (!sendQueue.empty()) {
packet &pkt = sendQueue.front();
tl::expected<void, PacketError> result = proto.send(srcPeer.endpoint, pkt.Data());
std::expected<void, PacketError> result = proto.send(srcPeer.endpoint, pkt.Data());
if (!result.has_value())
LogError("DrainSendQueue failed to send packet: {}", result.error().what());
sendQueue.pop_front();
+11 -11
View File
@@ -25,10 +25,10 @@ framesize_t frame_queue::Size() const
return current_size;
}
tl::expected<buffer_t, PacketError> frame_queue::Read(framesize_t s)
std::expected<buffer_t, PacketError> frame_queue::Read(framesize_t s)
{
if (current_size < s)
return tl::make_unexpected(FrameQueueError());
return std::unexpected(FrameQueueError());
buffer_t ret;
while (s > 0 && s >= buffer_deque.front().size()) {
const auto bufferSize = static_cast<framesize_t>(buffer_deque.front().size());
@@ -56,17 +56,17 @@ void frame_queue::Write(buffer_t buf)
buffer_deque.push_back(std::move(buf));
}
tl::expected<bool, PacketError> frame_queue::PacketReady()
std::expected<bool, PacketError> frame_queue::PacketReady()
{
if (nextsize == 0) {
if (Size() < sizeof(framesize_t))
return false;
tl::expected<buffer_t, PacketError> szbuf = Read(sizeof(framesize_t));
std::expected<buffer_t, PacketError> szbuf = Read(sizeof(framesize_t));
if (!szbuf.has_value())
return tl::make_unexpected(szbuf.error());
return std::unexpected(szbuf.error());
nextsize = LoadLE32(szbuf->data());
if (nextsize == 0)
return tl::make_unexpected(FrameQueueError());
return std::unexpected(FrameQueueError());
}
return Size() >= (nextsize & frame_size_mask);
}
@@ -77,22 +77,22 @@ uint16_t frame_queue::ReadPacketFlags()
return static_cast<uint16_t>(nextsize >> 16);
}
tl::expected<buffer_t, PacketError> frame_queue::ReadPacket()
std::expected<buffer_t, PacketError> frame_queue::ReadPacket()
{
const framesize_t packetSize = nextsize & frame_size_mask;
if (nextsize == 0 || Size() < packetSize)
return tl::make_unexpected(FrameQueueError());
tl::expected<buffer_t, PacketError> ret = Read(packetSize);
return std::unexpected(FrameQueueError());
std::expected<buffer_t, PacketError> ret = Read(packetSize);
nextsize = 0;
return ret;
}
tl::expected<buffer_t, PacketError> frame_queue::MakeFrame(buffer_t packetbuf, uint16_t flags)
std::expected<buffer_t, PacketError> frame_queue::MakeFrame(buffer_t packetbuf, uint16_t flags)
{
buffer_t ret;
const auto size = static_cast<framesize_t>(packetbuf.size());
if (size > max_frame_size)
return tl::make_unexpected("Buffer exceeds maximum frame size");
return std::unexpected("Buffer exceeds maximum frame size");
static_assert(sizeof(size) == 4, "framesize_t is not 4 bytes");
unsigned char sizeBuf[4];
WriteLE32(sizeBuf, size | (static_cast<framesize_t>(flags) << 16));
+5 -6
View File
@@ -3,10 +3,9 @@
#include <cstdint>
#include <deque>
#include <exception>
#include <expected>
#include <vector>
#include <expected.hpp>
#include "dvlnet/packet.h"
namespace devilution {
@@ -26,15 +25,15 @@ private:
framesize_t nextsize = 0;
framesize_t Size() const;
tl::expected<buffer_t, PacketError> Read(framesize_t s);
std::expected<buffer_t, PacketError> Read(framesize_t s);
public:
tl::expected<bool, PacketError> PacketReady();
std::expected<bool, PacketError> PacketReady();
uint16_t ReadPacketFlags();
tl::expected<buffer_t, PacketError> ReadPacket();
std::expected<buffer_t, PacketError> ReadPacket();
void Write(buffer_t buf);
static tl::expected<buffer_t, PacketError> MakeFrame(buffer_t packetbuf, uint16_t flags = 0);
static std::expected<buffer_t, PacketError> MakeFrame(buffer_t packetbuf, uint16_t flags = 0);
};
} // namespace net
+17 -18
View File
@@ -2,6 +2,7 @@
#include <cassert>
#include <cstdint>
#include <expected>
#ifdef PACKET_ENCRYPTION
#include <sodium.h>
@@ -10,8 +11,6 @@
#include <random>
#endif
#include <expected.hpp>
#include "utils/algorithm/container.hpp"
#include "utils/str_cat.hpp"
@@ -113,11 +112,11 @@ PacketError PacketTypeError(std::initializer_list<packet_type> expectedTypes, st
namespace {
tl::expected<void, PacketError> CheckPacketTypeOneOf(std::initializer_list<packet_type> expectedTypes, std::uint8_t actualType)
std::expected<void, PacketError> CheckPacketTypeOneOf(std::initializer_list<packet_type> expectedTypes, std::uint8_t actualType)
{
if (c_none_of(expectedTypes,
[actualType](uint8_t type) { return type == actualType; })) {
return tl::make_unexpected(PacketTypeError(expectedTypes, actualType));
return std::unexpected(PacketTypeError(expectedTypes, actualType));
}
return {};
}
@@ -150,60 +149,60 @@ plr_t packet::Destination() const
return m_dest;
}
tl::expected<const buffer_t *, PacketError> packet::Message()
std::expected<const buffer_t *, PacketError> packet::Message()
{
assert(have_decrypted);
return CheckPacketTypeOneOf({ PT_MESSAGE }, m_type)
.transform([this]() { return &m_message; });
}
tl::expected<turn_t, PacketError> packet::Turn()
std::expected<turn_t, PacketError> packet::Turn()
{
assert(have_decrypted);
return CheckPacketTypeOneOf({ PT_TURN }, m_type)
.transform([this]() { return m_turn; });
}
tl::expected<cookie_t, PacketError> packet::Cookie()
std::expected<cookie_t, PacketError> packet::Cookie()
{
assert(have_decrypted);
return CheckPacketTypeOneOf({ PT_JOIN_REQUEST, PT_JOIN_ACCEPT }, m_type)
.transform([this]() { return m_cookie; });
}
tl::expected<plr_t, PacketError> packet::NewPlayer()
std::expected<plr_t, PacketError> packet::NewPlayer()
{
assert(have_decrypted);
return CheckPacketTypeOneOf({ PT_JOIN_ACCEPT, PT_CONNECT, PT_DISCONNECT }, m_type)
.transform([this]() { return m_newplr; });
}
tl::expected<timestamp_t, PacketError> packet::Time()
std::expected<timestamp_t, PacketError> packet::Time()
{
assert(have_decrypted);
return CheckPacketTypeOneOf({ PT_ECHO_REQUEST, PT_ECHO_REPLY }, m_type)
.transform([this]() { return m_time; });
}
tl::expected<const buffer_t *, PacketError> packet::Info()
std::expected<const buffer_t *, PacketError> packet::Info()
{
assert(have_decrypted);
return CheckPacketTypeOneOf({ PT_JOIN_REQUEST, PT_JOIN_ACCEPT, PT_CONNECT, PT_INFO_REPLY }, m_type)
.transform([this]() { return &m_info; });
}
tl::expected<leaveinfo_t, PacketError> packet::LeaveInfo()
std::expected<leaveinfo_t, PacketError> packet::LeaveInfo()
{
assert(have_decrypted);
return CheckPacketTypeOneOf({ PT_DISCONNECT }, m_type)
.transform([this]() { return m_leaveinfo; });
}
tl::expected<void, PacketError> packet_in::Create(buffer_t buf)
std::expected<void, PacketError> packet_in::Create(buffer_t buf)
{
assert(!have_encrypted && !have_decrypted);
if (buf.size() < sizeof(packet_type) + 2 * sizeof(plr_t))
return tl::make_unexpected(PacketError());
return std::unexpected(PacketError());
decrypted_buffer = std::move(buf);
have_decrypted = true;
@@ -217,7 +216,7 @@ tl::expected<void, PacketError> packet_in::Create(buffer_t buf)
}
#ifdef PACKET_ENCRYPTION
tl::expected<void, PacketError> packet_in::Decrypt(buffer_t buf)
std::expected<void, PacketError> packet_in::Decrypt(buffer_t buf)
{
assert(!have_encrypted && !have_decrypted);
encrypted_buffer = std::move(buf);
@@ -226,7 +225,7 @@ tl::expected<void, PacketError> packet_in::Decrypt(buffer_t buf)
if (encrypted_buffer.size() < crypto_secretbox_NONCEBYTES
+ crypto_secretbox_MACBYTES
+ sizeof(packet_type) + 2 * sizeof(plr_t))
return tl::make_unexpected(PacketError());
return std::unexpected(PacketError());
auto pktlen = (encrypted_buffer.size()
- crypto_secretbox_NONCEBYTES
- crypto_secretbox_MACBYTES);
@@ -240,7 +239,7 @@ tl::expected<void, PacketError> packet_in::Decrypt(buffer_t buf)
if (status != 0) {
auto code = PacketError::ErrorCode::DecryptionFailed;
std::string_view message = "Failed to decrypt packet data";
return tl::make_unexpected(PacketError(code, message));
return std::unexpected(PacketError(code, message));
}
have_decrypted = true;
@@ -249,7 +248,7 @@ tl::expected<void, PacketError> packet_in::Decrypt(buffer_t buf)
#endif
#ifdef PACKET_ENCRYPTION
tl::expected<void, PacketError> packet_out::Encrypt()
std::expected<void, PacketError> packet_out::Encrypt()
{
assert(have_decrypted);
@@ -271,7 +270,7 @@ tl::expected<void, PacketError> packet_out::Encrypt()
if (status != 0) {
auto code = PacketError::ErrorCode::EncryptionFailed;
std::string_view message = "Failed to encrypt packet data";
return tl::make_unexpected(PacketError(code, message));
return std::unexpected(PacketError(code, message));
}
have_encrypted = true;
+37 -38
View File
@@ -3,12 +3,11 @@
#include <array>
#include <cstdint>
#include <cstring>
#include <expected>
#include <memory>
#include <string>
#include <type_traits>
#include <expected.hpp>
#ifdef PACKET_ENCRYPTION
#include <sodium.h>
#endif
@@ -175,30 +174,30 @@ public:
packet_type Type();
plr_t Source() const;
plr_t Destination() const;
tl::expected<const buffer_t *, PacketError> Message();
tl::expected<turn_t, PacketError> Turn();
tl::expected<cookie_t, PacketError> Cookie();
tl::expected<plr_t, PacketError> NewPlayer();
tl::expected<timestamp_t, PacketError> Time();
tl::expected<const buffer_t *, PacketError> Info();
tl::expected<leaveinfo_t, PacketError> LeaveInfo();
std::expected<const buffer_t *, PacketError> Message();
std::expected<turn_t, PacketError> Turn();
std::expected<cookie_t, PacketError> Cookie();
std::expected<plr_t, PacketError> NewPlayer();
std::expected<timestamp_t, PacketError> Time();
std::expected<const buffer_t *, PacketError> Info();
std::expected<leaveinfo_t, PacketError> LeaveInfo();
};
template <class P>
class packet_proc : public packet {
public:
using packet::packet;
tl::expected<void, PacketError> process_data();
std::expected<void, PacketError> process_data();
};
class packet_in : public packet_proc<packet_in> {
public:
using packet_proc<packet_in>::packet_proc;
tl::expected<void, PacketError> Create(buffer_t buf);
tl::expected<void, PacketError> process_element(buffer_t &x);
std::expected<void, PacketError> Create(buffer_t buf);
std::expected<void, PacketError> process_element(buffer_t &x);
template <class T>
tl::expected<void, PacketError> process_element(T &x);
tl::expected<void, PacketError> Decrypt(buffer_t buf);
std::expected<void, PacketError> process_element(T &x);
std::expected<void, PacketError> Decrypt(buffer_t buf);
};
class packet_out : public packet_proc<packet_out> {
@@ -208,19 +207,19 @@ public:
template <packet_type t, typename... Args>
void create(Args... args);
tl::expected<void, PacketError> process_element(buffer_t &x);
std::expected<void, PacketError> process_element(buffer_t &x);
template <class T>
tl::expected<void, PacketError> process_element(const T &x);
std::expected<void, PacketError> process_element(const T &x);
static cookie_t GenerateCookie();
tl::expected<void, PacketError> Encrypt();
std::expected<void, PacketError> Encrypt();
};
template <class P>
tl::expected<void, PacketError> packet_proc<P>::process_data()
std::expected<void, PacketError> packet_proc<P>::process_data()
{
P &self = static_cast<P &>(*this);
{
tl::expected<void, PacketError> result
std::expected<void, PacketError> result
= self.process_element(m_type)
.and_then([&]() {
return self.process_element(m_src);
@@ -258,10 +257,10 @@ tl::expected<void, PacketError> packet_proc<P>::process_data()
case PT_ECHO_REPLY:
return self.process_element(m_time);
}
return tl::make_unexpected(PacketTypeError(m_type));
return std::unexpected(PacketTypeError(m_type));
}
inline tl::expected<void, PacketError> packet_in::process_element(buffer_t &x)
inline std::expected<void, PacketError> packet_in::process_element(buffer_t &x)
{
x.insert(x.begin(), decrypted_buffer.begin(), decrypted_buffer.end());
decrypted_buffer.resize(0);
@@ -269,12 +268,12 @@ inline tl::expected<void, PacketError> packet_in::process_element(buffer_t &x)
}
template <class T>
tl::expected<void, PacketError> packet_in::process_element(T &x)
std::expected<void, PacketError> packet_in::process_element(T &x)
{
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Unsupported T");
static_assert(sizeof(T) == 4 || sizeof(T) == 2 || sizeof(T) == 1, "Unsupported T");
if (decrypted_buffer.size() < sizeof(T)) {
return tl::make_unexpected(PacketError());
return std::unexpected(PacketError());
}
if (sizeof(T) == 4) {
x = static_cast<T>(LoadLE32(decrypted_buffer.data()));
@@ -427,14 +426,14 @@ inline void packet_out::create<PT_ECHO_REPLY>(plr_t s, plr_t d, timestamp_t t)
m_time = t;
}
inline tl::expected<void, PacketError> packet_out::process_element(buffer_t &x)
inline std::expected<void, PacketError> packet_out::process_element(buffer_t &x)
{
decrypted_buffer.insert(decrypted_buffer.end(), x.begin(), x.end());
return {};
}
template <class T>
tl::expected<void, PacketError> packet_out::process_element(const T &x)
std::expected<void, PacketError> packet_out::process_element(const T &x)
{
static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "Unsupported T");
static_assert(sizeof(T) == 4 || sizeof(T) == 2 || sizeof(T) == 1, "Unsupported T");
@@ -469,43 +468,43 @@ public:
packet_factory();
packet_factory(std::string pw);
tl::expected<std::unique_ptr<packet>, PacketError> make_packet(buffer_t buf);
std::expected<std::unique_ptr<packet>, PacketError> make_packet(buffer_t buf);
template <packet_type t, typename... Args>
tl::expected<std::unique_ptr<packet>, PacketError> make_packet(Args... args);
std::expected<std::unique_ptr<packet>, PacketError> make_packet(Args... args);
};
inline tl::expected<std::unique_ptr<packet>, PacketError> packet_factory::make_packet(buffer_t buf)
inline std::expected<std::unique_ptr<packet>, PacketError> packet_factory::make_packet(buffer_t buf)
{
auto ret = std::make_unique<packet_in>(key);
#ifndef PACKET_ENCRYPTION
tl::expected<void, PacketError> isCreated = ret->Create(std::move(buf));
std::expected<void, PacketError> isCreated = ret->Create(std::move(buf));
#else
tl::expected<void, PacketError> isCreated = !secure
std::expected<void, PacketError> isCreated = !secure
? ret->Create(std::move(buf))
: ret->Decrypt(std::move(buf));
#endif
if (!isCreated.has_value()) {
return tl::make_unexpected(isCreated.error());
return std::unexpected(isCreated.error());
}
if (const tl::expected<void, PacketError> result = ret->process_data(); !result.has_value()) {
return tl::make_unexpected(result.error());
if (const std::expected<void, PacketError> result = ret->process_data(); !result.has_value()) {
return std::unexpected(result.error());
}
return ret;
}
template <packet_type t, typename... Args>
tl::expected<std::unique_ptr<packet>, PacketError> packet_factory::make_packet(Args... args)
std::expected<std::unique_ptr<packet>, PacketError> packet_factory::make_packet(Args... args)
{
auto ret = std::make_unique<packet_out>(key);
ret->create<t>(args...);
if (const tl::expected<void, PacketError> result = ret->process_data(); !result.has_value()) {
return tl::make_unexpected(result.error());
if (const std::expected<void, PacketError> result = ret->process_data(); !result.has_value()) {
return std::unexpected(result.error());
}
#ifdef PACKET_ENCRYPTION
if (secure) {
tl::expected<void, PacketError> isEncrypted = ret->Encrypt();
std::expected<void, PacketError> isEncrypted = ret->Encrypt();
if (!isEncrypted.has_value()) {
return tl::make_unexpected(isEncrypted.error());
return std::unexpected(isEncrypted.error());
}
}
#endif
+14 -14
View File
@@ -92,7 +92,7 @@ void protocol_zt::set_reuseaddr(int fd)
lwip_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes));
}
tl::expected<bool, PacketError> protocol_zt::network_online()
std::expected<bool, PacketError> protocol_zt::network_online()
{
if (!zerotier_network_ready())
return false;
@@ -110,7 +110,7 @@ tl::expected<bool, PacketError> protocol_zt::network_online()
if (ret < 0) {
std::string_view format = "Error binding to ZeroTier UDP socket: {}";
PacketError error = ProtocolError(format, strerror(errno));
return tl::make_unexpected(std::move(error));
return std::unexpected(std::move(error));
}
set_nonblock(fd_udp);
}
@@ -121,13 +121,13 @@ tl::expected<bool, PacketError> protocol_zt::network_online()
if (r1 < 0) {
std::string_view format = "Error binding to ZeroTier TCP socket: {}";
PacketError error = ProtocolError(format, strerror(errno));
return tl::make_unexpected(std::move(error));
return std::unexpected(std::move(error));
}
auto r2 = lwip_listen(fd_tcp, 10);
if (r2 < 0) {
std::string_view format = "Error listening on ZeroTier TCP socket: {}";
PacketError error = ProtocolError(format, strerror(errno));
return tl::make_unexpected(std::move(error));
return std::unexpected(std::move(error));
}
set_nonblock(fd_tcp);
set_nodelay(fd_tcp);
@@ -135,17 +135,17 @@ tl::expected<bool, PacketError> protocol_zt::network_online()
return true;
}
tl::expected<bool, PacketError> protocol_zt::peers_ready()
std::expected<bool, PacketError> protocol_zt::peers_ready()
{
return network_online()
.map([&](bool isOnline) { return isOnline && zerotier_peers_ready(); });
.transform([&](bool isOnline) { return isOnline && zerotier_peers_ready(); });
}
tl::expected<void, PacketError> protocol_zt::send(const endpoint &peer, const buffer_t &data)
std::expected<void, PacketError> protocol_zt::send(const endpoint &peer, const buffer_t &data)
{
tl::expected<buffer_t, PacketError> frame = frame_queue::MakeFrame(data);
std::expected<buffer_t, PacketError> frame = frame_queue::MakeFrame(data);
if (!frame.has_value())
return tl::make_unexpected(frame.error());
return std::unexpected(frame.error());
peer_list[peer].send_queue.push_back(*frame);
return {};
}
@@ -168,7 +168,7 @@ bool protocol_zt::send_oob_mc(const buffer_t &data) const
return send_oob(mc, data);
}
tl::expected<bool, PacketError> protocol_zt::send_queued_peer(const endpoint &peer)
std::expected<bool, PacketError> protocol_zt::send_queued_peer(const endpoint &peer)
{
peer_state &state = peer_list[peer];
if (state.fd == -1) {
@@ -200,7 +200,7 @@ tl::expected<bool, PacketError> protocol_zt::send_queued_peer(const endpoint &pe
} else {
std::string_view format = "Impossible number of bytes sent: {} available, {} sent";
PacketError error = ProtocolError(format, len, decltype(len)(r));
return tl::make_unexpected(std::move(error));
return std::unexpected(std::move(error));
}
}
return true;
@@ -223,7 +223,7 @@ bool protocol_zt::recv_peer(const endpoint &peer)
bool protocol_zt::send_queued_all()
{
for (const auto &[endpoint, _] : peer_list) {
tl::expected<bool, PacketError> result = send_queued_peer(endpoint);
std::expected<bool, PacketError> result = send_queued_peer(endpoint);
if (!result.has_value()) {
LogError("send_queued_peer: {}", result.error().what());
continue;
@@ -302,14 +302,14 @@ bool protocol_zt::recv(endpoint &peer, buffer_t &data)
}
for (auto &p : peer_list) {
tl::expected<bool, PacketError> ready = p.second.recv_queue.PacketReady();
std::expected<bool, PacketError> ready = p.second.recv_queue.PacketReady();
if (!ready.has_value()) {
LogError("PacketReady: {}", ready.error().what());
continue;
}
if (!*ready)
continue;
tl::expected<buffer_t, PacketError> packet = p.second.recv_queue.ReadPacket();
std::expected<buffer_t, PacketError> packet = p.second.recv_queue.ReadPacket();
if (!packet.has_value()) {
LogError("Failed reading packet data from peer: {}", packet.error().what());
continue;
+6 -6
View File
@@ -57,12 +57,12 @@ public:
return buffer_t(addr.begin(), addr.end());
}
tl::expected<void, PacketError> unserialize(const buffer_t &buf)
std::expected<void, PacketError> unserialize(const buffer_t &buf)
{
if (buf.size() != 16) {
std::string_view format = "Endpoint deserialization expected 16 bytes, got {}";
PacketError error = ProtocolError(format, buf.size());
return tl::make_unexpected(std::move(error));
return std::unexpected(std::move(error));
}
std::copy(buf.begin(), buf.end(), addr.begin());
return {};
@@ -83,13 +83,13 @@ public:
protocol_zt();
~protocol_zt();
void disconnect(const endpoint &peer);
tl::expected<void, PacketError> send(const endpoint &peer, const buffer_t &data);
std::expected<void, PacketError> send(const endpoint &peer, const buffer_t &data);
bool send_oob(const endpoint &peer, const buffer_t &data) const;
bool send_oob_mc(const buffer_t &data) const;
bool recv(endpoint &peer, buffer_t &data);
bool get_disconnected(endpoint &peer);
tl::expected<bool, PacketError> network_online();
tl::expected<bool, PacketError> peers_ready();
std::expected<bool, PacketError> network_online();
std::expected<bool, PacketError> peers_ready();
bool is_peer_connected(endpoint &peer);
std::optional<bool> is_peer_relayed(const endpoint &peer) const;
std::optional<int> get_latency_to(const endpoint &peer) const;
@@ -119,7 +119,7 @@ private:
static void set_nodelay(int fd);
static void set_reuseaddr(int fd);
tl::expected<bool, PacketError> send_queued_peer(const endpoint &peer);
std::expected<bool, PacketError> send_queued_peer(const endpoint &peer);
bool recv_peer(const endpoint &peer);
bool send_queued_all();
bool recv_from_peers();
+13 -13
View File
@@ -1,6 +1,7 @@
#include "dvlnet/tcp_client.h"
#include <exception>
#include <expected>
#include <functional>
#include <memory>
#include <stdexcept>
@@ -14,7 +15,6 @@
#endif
#include <asio/connect.hpp>
#include <expected.hpp>
#include <fmt/format.h>
#include "options.h"
@@ -89,7 +89,7 @@ int tcp_client::join(std::string_view addrstr)
StartReceive();
{
cookie_self = packet_out::GenerateCookie();
tl::expected<std::unique_ptr<packet>, PacketError> pkt
std::expected<std::unique_ptr<packet>, PacketError> pkt
= pktfty->make_packet<PT_JOIN_REQUEST>(
PLR_BROADCAST, PLR_MASTER, cookie_self, game_init_info);
if (!pkt.has_value()) {
@@ -97,14 +97,14 @@ int tcp_client::join(std::string_view addrstr)
SDL_SetError("make_packet: %.*s", static_cast<int>(message.size()), message.data());
return -1;
}
tl::expected<void, PacketError> sendResult = send(**pkt);
std::expected<void, PacketError> sendResult = send(**pkt);
if (!sendResult.has_value()) {
const std::string_view message = sendResult.error().what();
SDL_SetError("send: %.*s", static_cast<int>(message.size()), message.data());
return -1;
}
for (auto i = 0; i < NoSleep; ++i) {
tl::expected<void, PacketError> pollResult = poll();
std::expected<void, PacketError> pollResult = poll();
if (!pollResult.has_value()) {
const std::string_view message = pollResult.error().what();
SDL_SetError("%.*s", static_cast<int>(message.size()), message.data());
@@ -129,17 +129,17 @@ bool tcp_client::IsGameHost()
return local_server != nullptr;
}
tl::expected<void, PacketError> tcp_client::poll()
std::expected<void, PacketError> tcp_client::poll()
{
while (ioc.poll_one() > 0) {
if (IsGameHost()) {
tl::expected<void, PacketError> serverResult = local_server->CheckIoHandlerError();
std::expected<void, PacketError> serverResult = local_server->CheckIoHandlerError();
if (!serverResult.has_value())
return serverResult;
}
if (ioHandlerResult == std::nullopt)
continue;
tl::expected<void, PacketError> packetError = tl::make_unexpected(*ioHandlerResult);
std::expected<void, PacketError> packetError = std::unexpected(*ioHandlerResult);
ioHandlerResult = std::nullopt;
return packetError;
}
@@ -162,7 +162,7 @@ void tcp_client::HandleReceive(const asio::error_code &error, size_t bytesRead)
recv_queue.Write(std::move(recv_buffer));
recv_buffer.resize(frame_queue::max_frame_size);
while (true) {
tl::expected<bool, PacketError> ready = recv_queue.PacketReady();
std::expected<bool, PacketError> ready = recv_queue.PacketReady();
if (!ready.has_value()) {
RaiseIoHandlerError(ready.error());
return;
@@ -173,7 +173,7 @@ void tcp_client::HandleReceive(const asio::error_code &error, size_t bytesRead)
HandleTcpErrorCode();
return;
}
tl::expected<void, PacketError> result
std::expected<void, PacketError> result
= recv_queue.ReadPacket()
.and_then([this](buffer_t &&pktData) { return pktfty->make_packet(pktData); })
.and_then([this](std::unique_ptr<packet> &&pkt) { return RecvLocal(*pkt); });
@@ -200,7 +200,7 @@ void tcp_client::HandleSend(const asio::error_code &error, size_t /*bytesSent*/)
void tcp_client::HandleTcpErrorCode()
{
tl::expected<buffer_t, PacketError> packet = recv_queue.ReadPacket();
std::expected<buffer_t, PacketError> packet = recv_queue.ReadPacket();
if (!packet.has_value()) {
RaiseIoHandlerError(packet.error());
return;
@@ -219,11 +219,11 @@ void tcp_client::HandleTcpErrorCode()
RaiseIoHandlerError(fmt::format("Unknown error code received from server: {:#04x}", pktData[0]));
}
tl::expected<void, PacketError> tcp_client::send(packet &pkt)
std::expected<void, PacketError> tcp_client::send(packet &pkt)
{
tl::expected<buffer_t, PacketError> frame = frame_queue::MakeFrame(pkt.Data());
std::expected<buffer_t, PacketError> frame = frame_queue::MakeFrame(pkt.Data());
if (!frame.has_value())
return tl::make_unexpected(frame.error());
return std::unexpected(frame.error());
std::unique_ptr<buffer_t> framePtr = std::make_unique<buffer_t>(*frame);
const asio::mutable_buffer buf = asio::buffer(*framePtr);
asio::async_write(sock, buf, [this, frame = std::move(framePtr)](const asio::error_code &error, size_t bytesSent) {
+2 -2
View File
@@ -30,8 +30,8 @@ public:
int create(std::string_view addrstr) override;
int join(std::string_view addrstr) override;
tl::expected<void, PacketError> poll() override;
tl::expected<void, PacketError> send(packet &pkt) override;
std::expected<void, PacketError> poll() override;
std::expected<void, PacketError> send(packet &pkt) override;
void DisconnectNet(plr_t plr) override;
bool SNetLeaveGame(net::leaveinfo_t type) override;
+24 -25
View File
@@ -1,12 +1,11 @@
#include "dvlnet/tcp_server.h"
#include <chrono>
#include <expected>
#include <functional>
#include <memory>
#include <utility>
#include <expected.hpp>
#include "dvlnet/base.h"
#include "player.h"
#include "utils/log.hpp"
@@ -78,7 +77,7 @@ void tcp_server::HandleReceive(const scc &con, const asio::error_code &ec,
con->recv_queue.Write(std::move(con->recv_buffer));
con->recv_buffer.resize(frame_queue::max_frame_size);
while (true) {
tl::expected<bool, PacketError> ready = con->recv_queue.PacketReady();
std::expected<bool, PacketError> ready = con->recv_queue.PacketReady();
if (!ready.has_value()) {
Log("PacketReady: {}", ready.error().what());
DropConnection(con);
@@ -86,13 +85,13 @@ void tcp_server::HandleReceive(const scc &con, const asio::error_code &ec,
}
if (!*ready)
break;
tl::expected<buffer_t, PacketError> pktData = con->recv_queue.ReadPacket();
std::expected<buffer_t, PacketError> pktData = con->recv_queue.ReadPacket();
if (!pktData.has_value()) {
Log("ReadPacket: {}", pktData.error().what());
DropConnection(con);
return;
}
tl::expected<std::unique_ptr<packet>, PacketError> pkt = pktfty.make_packet(*pktData);
std::expected<std::unique_ptr<packet>, PacketError> pkt = pktfty.make_packet(*pktData);
if (!pkt.has_value()) {
Log("make_packet: {}", pkt.error().what());
if (pkt.error().code() == PacketError::ErrorCode::DecryptionFailed)
@@ -101,7 +100,7 @@ void tcp_server::HandleReceive(const scc &con, const asio::error_code &ec,
return;
}
if (con->plr == PLR_BROADCAST) {
tl::expected<void, PacketError> result = HandleReceiveNewPlayer(con, **pkt);
std::expected<void, PacketError> result = HandleReceiveNewPlayer(con, **pkt);
if (!result.has_value()) {
Log("HandleReceiveNewPlayer: {}", result.error().what());
DropConnection(con);
@@ -109,7 +108,7 @@ void tcp_server::HandleReceive(const scc &con, const asio::error_code &ec,
}
} else {
con->timeout = timeout_active;
tl::expected<void, PacketError> result = HandleReceivePacket(**pkt);
std::expected<void, PacketError> result = HandleReceivePacket(**pkt);
if (!result.has_value()) {
Log("Network error: {}", result.error().what());
DropConnection(con);
@@ -120,22 +119,22 @@ void tcp_server::HandleReceive(const scc &con, const asio::error_code &ec,
StartReceive(con);
}
tl::expected<void, PacketError> tcp_server::HandleReceiveNewPlayer(const scc &con, packet &inPkt)
std::expected<void, PacketError> tcp_server::HandleReceiveNewPlayer(const scc &con, packet &inPkt)
{
auto newplr = NextFree();
if (newplr == PLR_BROADCAST)
return tl::make_unexpected(ServerError());
return std::unexpected(ServerError());
if (Empty()) {
tl::expected<const buffer_t *, PacketError> pktInfo = inPkt.Info();
std::expected<const buffer_t *, PacketError> pktInfo = inPkt.Info();
if (!pktInfo.has_value())
return tl::make_unexpected(pktInfo.error());
return std::unexpected(pktInfo.error());
game_init_info = **pktInfo;
}
for (plr_t player = 0; player < Players.size(); player++) {
if (connections[player]) {
tl::expected<void, PacketError> result
std::expected<void, PacketError> result
= pktfty.make_packet<PT_CONNECT>(PLR_MASTER, PLR_BROADCAST, newplr)
.and_then([&](std::unique_ptr<packet> &&pkt) { return StartSend(connections[player], *pkt); })
.and_then([&]() { return pktfty.make_packet<PT_CONNECT>(PLR_MASTER, PLR_BROADCAST, player); })
@@ -145,7 +144,7 @@ tl::expected<void, PacketError> tcp_server::HandleReceiveNewPlayer(const scc &co
}
}
tl::expected<void, PacketError> result
std::expected<void, PacketError> result
= inPkt.Cookie()
.and_then([&](cookie_t &&cookie) { return pktfty.make_packet<PT_JOIN_ACCEPT>(PLR_MASTER, PLR_BROADCAST, cookie, newplr, game_init_info); })
.and_then([&](std::unique_ptr<packet> &&pkt) { return StartSend(con, *pkt); });
@@ -157,47 +156,47 @@ tl::expected<void, PacketError> tcp_server::HandleReceiveNewPlayer(const scc &co
return {};
}
tl::expected<void, PacketError> tcp_server::HandleReceivePacket(packet &pkt)
std::expected<void, PacketError> tcp_server::HandleReceivePacket(packet &pkt)
{
return SendPacket(pkt);
}
tl::expected<void, PacketError> tcp_server::SendPacket(packet &pkt)
std::expected<void, PacketError> tcp_server::SendPacket(packet &pkt)
{
if (pkt.Destination() == PLR_BROADCAST) {
for (size_t i = 0; i < Players.size(); ++i) {
if (i == pkt.Source() || !connections[i])
continue;
tl::expected<void, PacketError> result = StartSend(connections[i], pkt);
std::expected<void, PacketError> result = StartSend(connections[i], pkt);
if (!result.has_value())
LogError("Failed to send packet {} to player {}: {}", static_cast<uint8_t>(pkt.Type()), i, result.error().what());
}
return {};
}
if (pkt.Destination() >= MAX_PLRS)
return tl::make_unexpected(ServerError());
return std::unexpected(ServerError());
if (pkt.Destination() == pkt.Source() || !connections[pkt.Destination()])
return {};
return StartSend(connections[pkt.Destination()], pkt);
}
tl::expected<void, PacketError> tcp_server::StartSend(const scc &con, packet &pkt)
std::expected<void, PacketError> tcp_server::StartSend(const scc &con, packet &pkt)
{
return StartSend(con, pkt.Data(), 0);
}
tl::expected<void, PacketError> tcp_server::StartSend(const scc &con, PacketError::ErrorCode errorCode)
std::expected<void, PacketError> tcp_server::StartSend(const scc &con, PacketError::ErrorCode errorCode)
{
buffer_t pktData;
pktData.push_back(static_cast<unsigned char>(errorCode));
return StartSend(con, pktData, TcpErrorCodeFlags);
}
tl::expected<void, PacketError> tcp_server::StartSend(const scc &con, buffer_t pktData, uint16_t flags)
std::expected<void, PacketError> tcp_server::StartSend(const scc &con, buffer_t pktData, uint16_t flags)
{
tl::expected<buffer_t, PacketError> frame = frame_queue::MakeFrame(pktData, flags);
std::expected<buffer_t, PacketError> frame = frame_queue::MakeFrame(pktData, flags);
if (!frame.has_value())
return tl::make_unexpected(frame.error());
return std::unexpected(frame.error());
std::unique_ptr<buffer_t> framePtr = std::make_unique<buffer_t>(*frame);
const asio::mutable_buffer buf = asio::buffer(*framePtr);
asio::async_write(con->socket, buf,
@@ -279,7 +278,7 @@ void tcp_server::DropConnection(const scc &con)
}
connections[plr] = nullptr;
tl::expected<std::unique_ptr<packet>, PacketError> pkt
std::expected<std::unique_ptr<packet>, PacketError> pkt
= pktfty.make_packet<PT_DISCONNECT>(PLR_MASTER, PLR_BROADCAST,
plr, leaveinfo_t::LEAVE_DROP);
if (pkt.has_value()) {
@@ -294,11 +293,11 @@ void tcp_server::RaiseIoHandlerError(const PacketError &error)
ioHandlerResult.emplace(error);
}
tl::expected<void, PacketError> tcp_server::CheckIoHandlerError()
std::expected<void, PacketError> tcp_server::CheckIoHandlerError()
{
if (ioHandlerResult == std::nullopt)
return {};
tl::expected<void, PacketError> packetError = tl::make_unexpected(*ioHandlerResult);
std::expected<void, PacketError> packetError = std::unexpected(*ioHandlerResult);
ioHandlerResult = std::nullopt;
return packetError;
}
+8 -9
View File
@@ -1,6 +1,7 @@
#pragma once
#include <array>
#include <expected>
#include <memory>
#include <string>
@@ -13,8 +14,6 @@
// the 3DS SDK.
#include <fmt/core.h>
#include <expected.hpp>
#include <asio/ts/buffer.hpp>
#include <asio/ts/internet.hpp>
#include <asio/ts/io_context.hpp>
@@ -40,7 +39,7 @@ public:
tcp_server(asio::io_context &ioc, const std::string &bindaddr,
unsigned short port, packet_factory &pktfty);
std::string LocalhostSelf();
tl::expected<void, PacketError> CheckIoHandlerError();
std::expected<void, PacketError> CheckIoHandlerError();
void DisconnectNet(plr_t plr);
void Close();
virtual ~tcp_server();
@@ -80,12 +79,12 @@ private:
void HandleAccept(const scc &con, const asio::error_code &ec);
void StartReceive(const scc &con);
void HandleReceive(const scc &con, const asio::error_code &ec, size_t bytesRead);
tl::expected<void, PacketError> HandleReceiveNewPlayer(const scc &con, packet &pkt);
tl::expected<void, PacketError> HandleReceivePacket(packet &pkt);
tl::expected<void, PacketError> SendPacket(packet &pkt);
tl::expected<void, PacketError> StartSend(const scc &con, packet &pkt);
tl::expected<void, PacketError> StartSend(const scc &con, PacketError::ErrorCode errorCode);
tl::expected<void, PacketError> StartSend(const scc &con, buffer_t pktData, uint16_t flags);
std::expected<void, PacketError> HandleReceiveNewPlayer(const scc &con, packet &pkt);
std::expected<void, PacketError> HandleReceivePacket(packet &pkt);
std::expected<void, PacketError> SendPacket(packet &pkt);
std::expected<void, PacketError> StartSend(const scc &con, packet &pkt);
std::expected<void, PacketError> StartSend(const scc &con, PacketError::ErrorCode errorCode);
std::expected<void, PacketError> StartSend(const scc &con, buffer_t pktData, uint16_t flags);
void HandleSend(const scc &con, const asio::error_code &ec, size_t bytesSent);
void StartTimeout(const scc &con);
void HandleTimeout(const scc &con, const asio::error_code &ec);
+7 -7
View File
@@ -6,9 +6,9 @@
#include "effects.h"
#include <cstdint>
#include <expected>
#include <string_view>
#include <expected.hpp>
#include <magic_enum/magic_enum.hpp>
#include "data/file.hpp"
@@ -126,7 +126,7 @@ SfxID RndSFX(SfxID psfx)
}
}
tl::expected<sfx_flag, std::string> ParseSfxFlag(std::string_view value)
std::expected<sfx_flag, std::string> ParseSfxFlag(std::string_view value)
{
if (value == "Stream") return sfx_STREAM;
if (value == "Misc") return sfx_MISC;
@@ -135,7 +135,7 @@ tl::expected<sfx_flag, std::string> ParseSfxFlag(std::string_view value)
if (value == "Rogue") return sfx_ROGUE;
if (value == "Warrior") return sfx_WARRIOR;
if (value == "Sorcerer") return sfx_SORCERER;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
void LoadEffectsData()
@@ -329,22 +329,22 @@ int GetSFXLength(SfxID nSFX)
return sfx.pSnd->DSB.GetLength();
}
tl::expected<HeroSpeech, std::string> ParseHeroSpeech(std::string_view value)
std::expected<HeroSpeech, std::string> ParseHeroSpeech(std::string_view value)
{
const std::optional<HeroSpeech> enumValueOpt = magic_enum::enum_cast<HeroSpeech>(value);
if (enumValueOpt.has_value()) {
return enumValueOpt.value();
}
return tl::make_unexpected("Unknown enum value.");
return std::unexpected("Unknown enum value.");
}
tl::expected<SfxID, std::string> ParseSfxId(std::string_view value)
std::expected<SfxID, std::string> ParseSfxId(std::string_view value)
{
const std::optional<SfxID> enumValueOpt = magic_enum::enum_cast<SfxID>(value);
if (enumValueOpt.has_value()) {
return enumValueOpt.value();
}
return tl::make_unexpected("Unknown enum value.");
return std::unexpected("Unknown enum value.");
}
} // namespace devilution
+3 -4
View File
@@ -6,11 +6,10 @@
#pragma once
#include <cstdint>
#include <expected>
#include <memory>
#include <string>
#include <expected.hpp>
#include "engine/sound.h"
#include "sound_effect_enums.h"
@@ -37,7 +36,7 @@ void ui_sound_init();
void effects_play_sound(SfxID);
int GetSFXLength(SfxID nSFX);
tl::expected<HeroSpeech, std::string> ParseHeroSpeech(std::string_view value);
tl::expected<SfxID, std::string> ParseSfxId(std::string_view value);
std::expected<HeroSpeech, std::string> ParseHeroSpeech(std::string_view value);
std::expected<SfxID, std::string> ParseSfxId(std::string_view value);
} // namespace devilution
+5 -5
View File
@@ -1,7 +1,7 @@
// Stubbed implementations of effects for the NOSOUND mode.
#include "effects.h"
#include <expected.hpp>
#include <expected>
#include <magic_enum/magic_enum.hpp>
#include "engine/random.hpp"
@@ -50,22 +50,22 @@ void ui_sound_init() { }
void effects_play_sound(SfxID id) { }
int GetSFXLength(SfxID nSFX) { return 0; }
tl::expected<HeroSpeech, std::string> ParseHeroSpeech(std::string_view value)
std::expected<HeroSpeech, std::string> ParseHeroSpeech(std::string_view value)
{
const std::optional<HeroSpeech> enumValueOpt = magic_enum::enum_cast<HeroSpeech>(value);
if (enumValueOpt.has_value()) {
return enumValueOpt.value();
}
return tl::make_unexpected("Unknown enum value.");
return std::unexpected("Unknown enum value.");
}
tl::expected<SfxID, std::string> ParseSfxId(std::string_view value)
std::expected<SfxID, std::string> ParseSfxId(std::string_view value)
{
const std::optional<SfxID> enumValueOpt = magic_enum::enum_cast<SfxID>(value);
if (enumValueOpt.has_value()) {
return enumValueOpt.value();
}
return tl::make_unexpected("Unknown enum value.");
return std::unexpected("Unknown enum value.");
}
} // namespace devilution
+20 -19
View File
@@ -4,6 +4,7 @@
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <expected>
#include <functional>
#include <memory>
#include <string_view>
@@ -311,11 +312,11 @@ SDL_IOStream *OpenAssetAsSdlRwOps(std::string_view filename, bool threadsafe)
#endif
}
tl::expected<AssetData, std::string> LoadAsset(std::string_view path)
std::expected<AssetData, std::string> LoadAsset(std::string_view path)
{
AssetRef ref = FindAsset(path);
if (!ref.ok()) {
return tl::make_unexpected(StrCat("Asset not found: ", path));
return std::unexpected(StrCat("Asset not found: ", path));
}
const size_t size = ref.size();
@@ -323,21 +324,21 @@ tl::expected<AssetData, std::string> LoadAsset(std::string_view path)
AssetHandle handle = OpenAsset(std::move(ref));
if (!handle.ok()) {
return tl::make_unexpected(StrCat("Failed to open asset: ", path, "\n", handle.error()));
return std::unexpected(StrCat("Failed to open asset: ", path, "\n", handle.error()));
}
if (size > 0 && !handle.read(data.get(), size)) {
return tl::make_unexpected(StrCat("Read failed: ", path, "\n", handle.error()));
return std::unexpected(StrCat("Read failed: ", path, "\n", handle.error()));
}
return AssetData { std::move(data), size };
}
tl::expected<AssetData, std::string> LoadIntegralAsset(std::string_view path)
std::expected<AssetData, std::string> LoadIntegralAsset(std::string_view path)
{
AssetRef ref = FindAsset(path);
if (!ref.ok()) {
return tl::make_unexpected(StrCat("Asset not found: ", path));
return std::unexpected(StrCat("Asset not found: ", path));
}
const size_t size = ref.size();
@@ -345,11 +346,11 @@ tl::expected<AssetData, std::string> LoadIntegralAsset(std::string_view path)
AssetHandle handle = OpenIntegralAsset(std::move(ref));
if (!handle.ok()) {
return tl::make_unexpected(StrCat("Failed to open asset: ", path, "\n", handle.error()));
return std::unexpected(StrCat("Failed to open asset: ", path, "\n", handle.error()));
}
if (size > 0 && !handle.read(data.get(), size)) {
return tl::make_unexpected(StrCat("Read failed: ", path, "\n", handle.error()));
return std::unexpected(StrCat("Read failed: ", path, "\n", handle.error()));
}
return AssetData { std::move(data), size };
@@ -415,7 +416,7 @@ bool LoadMPQ(std::span<const std::string> paths, std::string_view mpqName, int p
mpqAbsPath = StrCat(path, mpqName, ext);
if (!FileExists(mpqAbsPath))
continue;
tl::expected<MpqArchive, std::string> archive = MpqArchive::Open(mpqAbsPath.c_str());
std::expected<MpqArchive, std::string> archive = MpqArchive::Open(mpqAbsPath.c_str());
if (!archive.has_value()) {
foundButFailed = true;
LogError("Error {}: {}", archive.error(), mpqAbsPath);
@@ -607,22 +608,22 @@ void UnloadModArchives()
#ifndef UNPACKED_MPQS
namespace {
tl::expected<ModManifest, int32_t> ReadPackedModManifestFrom(MpqArchive &archive)
std::expected<ModManifest, int32_t> ReadPackedModManifestFrom(MpqArchive &archive)
{
constexpr std::string_view ManifestName = "manifest.ini";
if (!archive.HasFile(ManifestName))
return tl::make_unexpected(0);
return std::unexpected(0);
size_t fileSize = 0;
int32_t error = 0;
std::unique_ptr<std::byte[]> data = archive.ReadFile(ManifestName, fileSize, error);
if (data == nullptr)
return tl::make_unexpected(error);
return std::unexpected(error);
return ParseModManifest(std::string_view(reinterpret_cast<const char *>(data.get()), fileSize));
}
tl::expected<ModManifest, int32_t> ReadPackedModManifest(std::span<const std::string> paths, std::string_view modname)
std::expected<ModManifest, int32_t> ReadPackedModManifest(std::span<const std::string> paths, std::string_view modname)
{
const std::string mpqName = StrCat("mods" DIRECTORY_SEPARATOR_STR, modname);
std::string mpqAbsPath;
@@ -630,12 +631,12 @@ tl::expected<ModManifest, int32_t> ReadPackedModManifest(std::span<const std::st
mpqAbsPath = StrCat(path, mpqName, ".mpq");
if (!FileExists(mpqAbsPath))
continue;
tl::expected<MpqArchive, std::string> archive = MpqArchive::Open(mpqAbsPath.c_str());
std::expected<MpqArchive, std::string> archive = MpqArchive::Open(mpqAbsPath.c_str());
if (!archive.has_value())
return tl::make_unexpected(0);
return std::unexpected(0);
return ReadPackedModManifestFrom(*archive);
}
return tl::make_unexpected(0);
return std::unexpected(0);
}
// Reads the mod's `manifest.ini` from its own archive (registered at `priority`) and
@@ -647,7 +648,7 @@ void ReadLoadedModManifest(ModIdentifier &mod, int priority)
if (it == MpqArchives.end())
return;
MpqArchive &archive = it->second;
tl::expected<ModManifest, int32_t> manifest = ReadPackedModManifestFrom(archive);
std::expected<ModManifest, int32_t> manifest = ReadPackedModManifestFrom(archive);
if (manifest.has_value())
mod.manifest = std::move(*manifest);
else if (manifest.error() != 0)
@@ -659,7 +660,7 @@ void ReadLoadedModManifest(ModIdentifier &mod, int priority)
// the mod has no packed archive, no manifest, or an unreadable one.
std::vector<std::string> ReadPackedModRequiredMods(std::span<const std::string> paths, std::string_view modname)
{
tl::expected<ModManifest, int32_t> manifest = ReadPackedModManifest(paths, modname);
std::expected<ModManifest, int32_t> manifest = ReadPackedModManifest(paths, modname);
if (!manifest.has_value())
return {};
return std::move(manifest->requiredMods);
@@ -693,7 +694,7 @@ ModManifest ReadModManifestByName(std::string_view name)
#ifndef UNPACKED_MPQS
// Packed mod archive.
tl::expected<ModManifest, int32_t> manifest = ReadPackedModManifest(searchPaths, name);
std::expected<ModManifest, int32_t> manifest = ReadPackedModManifest(searchPaths, name);
if (manifest.has_value())
return std::move(*manifest);
#endif
+3 -4
View File
@@ -3,6 +3,7 @@
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <expected>
#include <functional>
#include <map>
#include <span>
@@ -17,8 +18,6 @@
#include <SDL.h>
#endif
#include <expected.hpp>
#include <fmt/format.h>
#include "appfat.h"
@@ -298,8 +297,8 @@ struct AssetData {
}
};
tl::expected<AssetData, std::string> LoadAsset(std::string_view path);
tl::expected<AssetData, std::string> LoadIntegralAsset(std::string_view path);
std::expected<AssetData, std::string> LoadAsset(std::string_view path);
std::expected<AssetData, std::string> LoadIntegralAsset(std::string_view path);
#ifdef UNPACKED_MPQS
using MpqArchiveT = std::string;
+3 -4
View File
@@ -2,6 +2,7 @@
#include <cstddef>
#include <cstdint>
#include <expected>
#include <memory>
#include <string>
@@ -9,8 +10,6 @@
#include <iostream>
#endif
#include <expected.hpp>
#include "appfat.h"
#include "mpq/mpq_common.hpp"
#include "utils/status_macros.hpp"
@@ -25,7 +24,7 @@
namespace devilution {
tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadCelListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths)
std::expected<OwnedClxSpriteListOrSheet, std::string> LoadCelListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths)
{
char path[MaxMpqPathSize];
*BufCopy(path, pszName, DEVILUTIONX_CEL_EXT) = '\0';
@@ -43,7 +42,7 @@ tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadCelListOrSheetWithStatu
OwnedClxSpriteListOrSheet LoadCelListOrSheet(const char *pszName, PointerOrValue<uint16_t> widthOrWidths)
{
tl::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCelListOrSheetWithStatus(pszName, widthOrWidths);
std::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCelListOrSheetWithStatus(pszName, widthOrWidths);
if (DVL_PREDICT_FALSE(!result.has_value())) app_fatal(result.error());
return std::move(result).value();
}
+6 -7
View File
@@ -1,10 +1,9 @@
#pragma once
#include <cstdint>
#include <expected>
#include <string>
#include <expected.hpp>
#include "engine/clx_sprite.hpp"
#include "utils/pointer_value_union.hpp"
#include "utils/status_macros.hpp"
@@ -17,7 +16,7 @@
namespace devilution {
tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadCelListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths);
std::expected<OwnedClxSpriteListOrSheet, std::string> LoadCelListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths);
OwnedClxSpriteListOrSheet LoadCelListOrSheet(const char *pszName, PointerOrValue<uint16_t> widthOrWidths);
@@ -28,13 +27,13 @@ inline OwnedClxSpriteList LoadCel(const char *pszName, uint16_t width)
inline OptionalOwnedClxSpriteList LoadOptionalCel(const char *pszName, uint16_t width)
{
tl::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCelListOrSheetWithStatus(pszName, PointerOrValue<uint16_t> { width });
std::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCelListOrSheetWithStatus(pszName, PointerOrValue<uint16_t> { width });
if (!result.has_value())
return std::nullopt;
return (*std::move(result)).list();
}
inline tl::expected<OwnedClxSpriteList, std::string> LoadCelWithStatus(const char *pszName, uint16_t width)
inline std::expected<OwnedClxSpriteList, std::string> LoadCelWithStatus(const char *pszName, uint16_t width)
{
ASSIGN_OR_RETURN(OwnedClxSpriteListOrSheet result, LoadCelListOrSheetWithStatus(pszName, PointerOrValue<uint16_t> { width }));
return std::move(result).list();
@@ -47,13 +46,13 @@ inline OwnedClxSpriteList LoadCel(const char *pszName, const uint16_t *widths)
inline OptionalOwnedClxSpriteList LoadOptionalCel(const char *pszName, const uint16_t *widths)
{
tl::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCelListOrSheetWithStatus(pszName, PointerOrValue<uint16_t> { widths });
std::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCelListOrSheetWithStatus(pszName, PointerOrValue<uint16_t> { widths });
if (!result.has_value())
return std::nullopt;
return (*std::move(result)).list();
}
inline tl::expected<OwnedClxSpriteList, std::string> LoadCelWithStatus(const char *pszName, const uint16_t *widths)
inline std::expected<OwnedClxSpriteList, std::string> LoadCelWithStatus(const char *pszName, const uint16_t *widths)
{
ASSIGN_OR_RETURN(OwnedClxSpriteListOrSheet result, LoadCelListOrSheetWithStatus(pszName, PointerOrValue<uint16_t> { widths }));
return std::move(result).list();
+3 -4
View File
@@ -1,11 +1,10 @@
#include "engine/load_cl2.hpp"
#include <cstdint>
#include <expected>
#include <memory>
#include <utility>
#include <expected.hpp>
#include "mpq/mpq_common.hpp"
#include "utils/status_macros.hpp"
#include "utils/str_cat.hpp"
@@ -19,7 +18,7 @@
namespace devilution {
tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadCl2ListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths)
std::expected<OwnedClxSpriteListOrSheet, std::string> LoadCl2ListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths)
{
char path[MaxMpqPathSize];
*BufCopy(path, pszName, DEVILUTIONX_CL2_EXT) = '\0';
@@ -34,7 +33,7 @@ tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadCl2ListOrSheetWithStatu
OwnedClxSpriteListOrSheet LoadCl2ListOrSheet(const char *pszName, PointerOrValue<uint16_t> widthOrWidths)
{
tl::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCl2ListOrSheetWithStatus(pszName, widthOrWidths);
std::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadCl2ListOrSheetWithStatus(pszName, widthOrWidths);
if (!result.has_value()) app_fatal(result.error());
return std::move(result).value();
}
+4 -4
View File
@@ -3,9 +3,9 @@
#include <array>
#include <cstdint>
#include <cstring>
#include <expected>
#include <string>
#include <expected.hpp>
#include <function_ref.hpp>
#include "appfat.h"
@@ -29,11 +29,11 @@
namespace devilution {
tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadCl2ListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths);
std::expected<OwnedClxSpriteListOrSheet, std::string> LoadCl2ListOrSheetWithStatus(const char *pszName, PointerOrValue<uint16_t> widthOrWidths);
OwnedClxSpriteListOrSheet LoadCl2ListOrSheet(const char *pszName, PointerOrValue<uint16_t> widthOrWidths);
template <size_t MaxCount>
tl::expected<OwnedClxSpriteSheet, std::string> LoadMultipleCl2Sheet(tl::function_ref<const char *(size_t)> filenames, size_t count, uint16_t width)
std::expected<OwnedClxSpriteSheet, std::string> LoadMultipleCl2Sheet(tl::function_ref<const char *(size_t)> filenames, size_t count, uint16_t width)
{
StaticVector<std::array<char, MaxMpqPathSize>, MaxCount> paths;
StaticVector<AssetRef, MaxCount> files;
@@ -76,7 +76,7 @@ tl::expected<OwnedClxSpriteSheet, std::string> LoadMultipleCl2Sheet(tl::function
#endif
}
inline tl::expected<OwnedClxSpriteList, std::string> LoadCl2WithStatus(const char *pszName, uint16_t width)
inline std::expected<OwnedClxSpriteList, std::string> LoadCl2WithStatus(const char *pszName, uint16_t width)
{
ASSIGN_OR_RETURN(OwnedClxSpriteListOrSheet result, LoadCl2ListOrSheetWithStatus(pszName, PointerOrValue<uint16_t> { width }));
return std::move(result).list();
+5 -6
View File
@@ -2,8 +2,7 @@
#include <cstddef>
#include <cstdint>
#include <expected.hpp>
#include <expected>
#include "appfat.h"
#include "engine/assets.hpp"
@@ -26,17 +25,17 @@ OptionalOwnedClxSpriteListOrSheet LoadOptionalClxListOrSheet(const char *path)
return OwnedClxSpriteListOrSheet::FromBuffer(std::move(data), size);
}
tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadClxListOrSheetWithStatus(const char *path)
std::expected<OwnedClxSpriteListOrSheet, std::string> LoadClxListOrSheetWithStatus(const char *path)
{
size_t size;
tl::expected<std::unique_ptr<uint8_t[]>, std::string> data = LoadFileInMemWithStatus<uint8_t>(path, &size);
if (!data.has_value()) return tl::make_unexpected(std::move(data).error());
std::expected<std::unique_ptr<uint8_t[]>, std::string> data = LoadFileInMemWithStatus<uint8_t>(path, &size);
if (!data.has_value()) return std::unexpected(std::move(data).error());
return OwnedClxSpriteListOrSheet::FromBuffer(std::move(data).value(), size);
}
OwnedClxSpriteListOrSheet LoadClxListOrSheet(const char *path)
{
tl::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadClxListOrSheetWithStatus(path);
std::expected<OwnedClxSpriteListOrSheet, std::string> result = LoadClxListOrSheetWithStatus(path);
if (!result.has_value()) app_fatal(result.error());
return std::move(result).value();
}
+3 -4
View File
@@ -1,9 +1,8 @@
#pragma once
#include <expected>
#include <string>
#include <expected.hpp>
#include "clx_sprite.hpp"
#include "utils/status_macros.hpp"
@@ -11,14 +10,14 @@ namespace devilution {
OwnedClxSpriteListOrSheet LoadClxListOrSheet(const char *path);
tl::expected<OwnedClxSpriteListOrSheet, std::string> LoadClxListOrSheetWithStatus(const char *path);
std::expected<OwnedClxSpriteListOrSheet, std::string> LoadClxListOrSheetWithStatus(const char *path);
inline OwnedClxSpriteList LoadClx(const char *path)
{
return LoadClxListOrSheet(path).list();
}
inline tl::expected<OwnedClxSpriteList, std::string> LoadClxWithStatus(const char *path)
inline std::expected<OwnedClxSpriteList, std::string> LoadClxWithStatus(const char *path)
{
ASSIGN_OR_RETURN(OwnedClxSpriteListOrSheet result, LoadClxListOrSheetWithStatus(path));
return std::move(result).list();
+20 -21
View File
@@ -4,10 +4,9 @@
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <expected>
#include <memory>
#include <expected.hpp>
#include "appfat.h"
#include "engine/assets.hpp"
#include "mpq/mpq_common.hpp"
@@ -17,35 +16,35 @@
namespace devilution {
template <typename T>
tl::expected<void, std::string> LoadFileInMemWithStatus(const char *path, T *data)
std::expected<void, std::string> LoadFileInMemWithStatus(const char *path, T *data)
{
size_t size;
AssetHandle handle = OpenAsset(path, size);
if (!handle.ok()) {
return tl::make_unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
return std::unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
}
if ((size % sizeof(T)) != 0) {
return tl::make_unexpected(StrCat("File size does not align with type\n", path));
return std::unexpected(StrCat("File size does not align with type\n", path));
}
if (!handle.read(data, size)) {
return tl::make_unexpected("handle.read failed");
return std::unexpected("handle.read failed");
}
return {};
}
template <typename T>
tl::expected<void, std::string> LoadIntegralFileInMemWithStatus(const char *path, T *data)
std::expected<void, std::string> LoadIntegralFileInMemWithStatus(const char *path, T *data)
{
size_t size;
AssetHandle handle = OpenIntegralAsset(path, size);
if (!handle.ok()) {
return tl::make_unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
return std::unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
}
if ((size % sizeof(T)) != 0) {
return tl::make_unexpected(StrCat("File size does not align with type\n", path));
return std::unexpected(StrCat("File size does not align with type\n", path));
}
if (!handle.read(data, size)) {
return tl::make_unexpected("handle.read failed");
return std::unexpected("handle.read failed");
}
return {};
}
@@ -53,19 +52,19 @@ tl::expected<void, std::string> LoadIntegralFileInMemWithStatus(const char *path
template <typename T>
void LoadFileInMem(const char *path, T *data)
{
const tl::expected<void, std::string> result = LoadFileInMemWithStatus<T>(path, data);
const std::expected<void, std::string> result = LoadFileInMemWithStatus<T>(path, data);
if (!result.has_value()) app_fatal(result.error());
}
template <typename T>
tl::expected<void, std::string> LoadFileInMemWithStatus(const char *path, T *data, std::size_t count)
std::expected<void, std::string> LoadFileInMemWithStatus(const char *path, T *data, std::size_t count)
{
AssetHandle handle = OpenAsset(path);
if (!handle.ok()) {
return tl::make_unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
return std::unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
}
if (!handle.read(data, count * sizeof(T))) {
return tl::make_unexpected("handle.read failed");
return std::unexpected("handle.read failed");
}
return {};
}
@@ -73,7 +72,7 @@ tl::expected<void, std::string> LoadFileInMemWithStatus(const char *path, T *dat
template <typename T>
void LoadFileInMem(const char *path, T *data, std::size_t count)
{
tl::expected<void, std::string> result = LoadFileInMemWithStatus<T>(path, data, count);
std::expected<void, std::string> result = LoadFileInMemWithStatus<T>(path, data, count);
if (!result.has_value()) app_fatal(result.error());
}
@@ -85,7 +84,7 @@ bool LoadOptionalFileInMem(const char *path, T *data, std::size_t count)
}
template <typename T, std::size_t N>
tl::expected<void, std::string> LoadFileInMemWithStatus(const char *path, std::array<T, N> &data)
std::expected<void, std::string> LoadFileInMemWithStatus(const char *path, std::array<T, N> &data)
{
return LoadFileInMemWithStatus(path, data.data(), N);
}
@@ -97,15 +96,15 @@ void LoadFileInMem(const char *path, std::array<T, N> &data)
}
template <typename T = std::byte>
tl::expected<std::unique_ptr<T[]>, std::string> LoadFileInMemWithStatus(const char *path, std::size_t *numRead = nullptr)
std::expected<std::unique_ptr<T[]>, std::string> LoadFileInMemWithStatus(const char *path, std::size_t *numRead = nullptr)
{
size_t size;
AssetHandle handle = OpenAsset(path, size);
if (!handle.ok()) {
return tl::make_unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
return std::unexpected(FailedToOpenFileErrorMessage(path, handle.error()));
}
if ((size % sizeof(T)) != 0) {
return tl::make_unexpected(StrCat("File size does not align with type\n", path));
return std::unexpected(StrCat("File size does not align with type\n", path));
}
if (numRead != nullptr)
@@ -113,7 +112,7 @@ tl::expected<std::unique_ptr<T[]>, std::string> LoadFileInMemWithStatus(const ch
std::unique_ptr<T[]> buf { new T[size / sizeof(T)] };
if (!handle.read(buf.get(), size)) {
return tl::make_unexpected("handle.read failed");
return std::unexpected("handle.read failed");
}
return { std::move(buf) };
}
@@ -127,7 +126,7 @@ tl::expected<std::unique_ptr<T[]>, std::string> LoadFileInMemWithStatus(const ch
template <typename T = std::byte>
std::unique_ptr<T[]> LoadFileInMem(const char *path, std::size_t *numRead = nullptr)
{
tl::expected<std::unique_ptr<T[]>, std::string> result = LoadFileInMemWithStatus<T>(path, numRead);
std::expected<std::unique_ptr<T[]>, std::string> result = LoadFileInMemWithStatus<T>(path, numRead);
if (!result.has_value()) app_fatal(result.error());
return std::move(result).value();
}
+9 -9
View File
@@ -8,6 +8,7 @@
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <expected>
#include <list>
#include <memory>
#include <mutex>
@@ -23,7 +24,6 @@
#include <Aulib/Stream.h>
#include <SDL.h>
#endif
#include <expected.hpp>
#include "appfat.h"
#include "engine/assets.hpp"
@@ -64,7 +64,7 @@ std::string GetMp3Path(const char *path)
return mp3Path;
}
tl::expected<void, std::string> LoadAudioFile(const char *path, bool stream, SoundSample &result)
std::expected<void, std::string> LoadAudioFile(const char *path, bool stream, SoundSample &result)
{
bool isMp3 = true;
std::string foundPath = GetMp3Path(path);
@@ -75,7 +75,7 @@ tl::expected<void, std::string> LoadAudioFile(const char *path, bool stream, Sou
isMp3 = false;
}
if (!ref.ok()) {
return tl::make_unexpected(StrCat("Audio file not found\n", path, "\n", SDL_GetError(), "\n" __FILE__ ":", __LINE__));
return std::unexpected(StrCat("Audio file not found\n", path, "\n", SDL_GetError(), "\n" __FILE__ ":", __LINE__));
}
#ifdef STREAM_ALL_AUDIO_MIN_FILE_SIZE
@@ -92,7 +92,7 @@ tl::expected<void, std::string> LoadAudioFile(const char *path, bool stream, Sou
if (stream) {
if (result.SetChunkStream(foundPath, isMp3, /*logErrors=*/true) != 0) {
return tl::make_unexpected(StrCat("Failed to load audio file\n", foundPath, "\n", SDL_GetError(), "\n" __FILE__ ":", __LINE__));
return std::unexpected(StrCat("Failed to load audio file\n", foundPath, "\n", SDL_GetError(), "\n" __FILE__ ":", __LINE__));
}
} else {
#if !defined(STREAM_ALL_AUDIO_MIN_FILE_SIZE) || STREAM_ALL_AUDIO_MIN_FILE_SIZE == 0
@@ -100,15 +100,15 @@ tl::expected<void, std::string> LoadAudioFile(const char *path, bool stream, Sou
#endif
AssetHandle handle = OpenAsset(std::move(ref));
if (!handle.ok()) {
return tl::make_unexpected(StrCat("Failed to load audio file\n", foundPath, "\n", SDL_GetError(), "\n" __FILE__ ":", __LINE__));
return std::unexpected(StrCat("Failed to load audio file\n", foundPath, "\n", SDL_GetError(), "\n" __FILE__ ":", __LINE__));
}
auto waveFile = MakeArraySharedPtr<std::uint8_t>(size);
if (!handle.read(waveFile.get(), size)) {
return tl::make_unexpected(StrCat("Failed to read file\n", foundPath, ": ", SDL_GetError(), __FILE__ ":", __LINE__));
return std::unexpected(StrCat("Failed to read file\n", foundPath, ": ", SDL_GetError(), __FILE__ ":", __LINE__));
}
const int error = result.SetChunk(waveFile, size, isMp3);
if (error != 0) {
return tl::make_unexpected(SDL_GetError());
return std::unexpected(SDL_GetError());
}
}
return {};
@@ -224,7 +224,7 @@ void snd_play_snd(TSnd *pSnd, int lVolume, int lPan, int userVolume)
pSnd->start_tc = tc;
}
tl::expected<std::unique_ptr<TSnd>, std::string> SoundFileLoadWithStatus(const char *path, bool stream)
std::expected<std::unique_ptr<TSnd>, std::string> SoundFileLoadWithStatus(const char *path, bool stream)
{
auto snd = std::make_unique<TSnd>();
snd->start_tc = SDL_GetTicks() - 80 - 1;
@@ -236,7 +236,7 @@ tl::expected<std::unique_ptr<TSnd>, std::string> SoundFileLoadWithStatus(const c
std::unique_ptr<TSnd> sound_file_load(const char *path, bool stream)
{
tl::expected<std::unique_ptr<TSnd>, std::string> result = SoundFileLoadWithStatus(path, stream);
std::expected<std::unique_ptr<TSnd>, std::string> result = SoundFileLoadWithStatus(path, stream);
if (!result.has_value()) app_fatal(result.error());
return std::move(result).value();
}
+2 -3
View File
@@ -6,12 +6,11 @@
#pragma once
#include <cstdint>
#include <expected>
#include <memory>
#include <optional>
#include <string>
#include <expected.hpp>
#include "levels/gendung.h"
#include "utils/attributes.h"
@@ -69,7 +68,7 @@ extern _music_id sgnMusicTrack;
void ClearDuplicateSounds();
void snd_play_snd(TSnd *pSnd, int lVolume, int lPan, int userVolume);
std::unique_ptr<TSnd> sound_file_load(const char *path, bool stream = false);
tl::expected<std::unique_ptr<TSnd>, std::string> SoundFileLoadWithStatus(const char *path, bool stream = false);
std::expected<std::unique_ptr<TSnd>, std::string> SoundFileLoadWithStatus(const char *path, bool stream = false);
void snd_init();
void snd_deinit();
_music_id GetLevelMusic(dungeon_type dungeonType);
+1 -1
View File
@@ -11,7 +11,7 @@ _music_id sgnMusicTrack = NUM_MUSIC;
void ClearDuplicateSounds() { }
void snd_play_snd(TSnd *pSnd, int lVolume, int lPan, int userVolume) { }
std::unique_ptr<TSnd> sound_file_load(const char *path, bool stream) { return nullptr; }
tl::expected<std::unique_ptr<TSnd>, std::string> SoundFileLoadWithStatus(const char *path, bool stream) { return nullptr; }
std::expected<std::unique_ptr<TSnd>, std::string> SoundFileLoadWithStatus(const char *path, bool stream) { return nullptr; }
TSnd::~TSnd() { }
void snd_init() { }
void snd_deinit() { }
+1 -1
View File
@@ -309,7 +309,7 @@ void gamemenu_load_game(bool /*bActivate*/)
DeactivateVirtualGamepad();
FreeVirtualGamepadTextures();
#endif
if (tl::expected<void, std::string> result = LoadGame(false); !result.has_value()) {
if (std::expected<void, std::string> result = LoadGame(false); !result.has_value()) {
app_fatal(result.error());
}
#if !defined(USE_SDL1) && !defined(__vita__)
+3 -4
View File
@@ -5,6 +5,7 @@
*/
#include <cstdint>
#include <expected>
#include <optional>
#include <string>
#include <utility>
@@ -20,8 +21,6 @@
#include <SDL.h>
#endif
#include <expected.hpp>
#include "control/control.hpp"
#include "controls/input.h"
#include "engine/clx_sprite.hpp"
@@ -317,7 +316,7 @@ void DoLoad(interface_mode uMsg)
IncProgress();
Player &myPlayer = *MyPlayer;
tl::expected<void, std::string> loadResult;
std::expected<void, std::string> loadResult;
switch (uMsg) {
case WM_DIABLOADGAME:
IncProgress(2);
@@ -464,7 +463,7 @@ void DoLoad(interface_mode uMsg)
if (loadResult.has_value()) IncProgress();
break;
default:
loadResult = tl::make_unexpected<std::string>("Unknown progress mode");
loadResult = std::unexpected<std::string>("Unknown progress mode");
break;
}
+7 -7
View File
@@ -2,6 +2,7 @@
#include <cstddef>
#include <cstdint>
#include <expected>
#include <memory>
#include <stack>
#include <string>
@@ -9,7 +10,6 @@
#include <vector>
#include <ankerl/unordered_dense.h>
#include <expected.hpp>
#include <magic_enum/magic_enum.hpp>
#include "engine/clx_sprite.hpp"
@@ -439,7 +439,7 @@ void CreateDungeon(uint32_t rseed, lvl_entry entry)
Make_SetPC(SetPiece);
}
tl::expected<void, std::string> LoadLevelSOLData()
std::expected<void, std::string> LoadLevelSOLData()
{
switch (leveltype) {
case DTYPE_TOWN:
@@ -501,7 +501,7 @@ tl::expected<void, std::string> LoadLevelSOLData()
SOLData[142] = TileProperties::None; // Tile is incorrectly marked as being solid
break;
default:
return tl::make_unexpected("LoadLevelSOLData");
return std::unexpected("LoadLevelSOLData");
}
return {};
}
@@ -833,7 +833,7 @@ void FloodTransparencyValues(uint8_t floorID)
}
}
tl::expected<dungeon_type, std::string> ParseDungeonType(std::string_view value)
std::expected<dungeon_type, std::string> ParseDungeonType(std::string_view value)
{
if (value.empty()) return DTYPE_NONE;
if (value == "DTYPE_TOWN") return DTYPE_TOWN;
@@ -843,16 +843,16 @@ tl::expected<dungeon_type, std::string> ParseDungeonType(std::string_view value)
if (value == "DTYPE_HELL") return DTYPE_HELL;
if (value == "DTYPE_NEST") return DTYPE_NEST;
if (value == "DTYPE_CRYPT") return DTYPE_CRYPT;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<_setlevels, std::string> ParseSetLevel(std::string_view value)
std::expected<_setlevels, std::string> ParseSetLevel(std::string_view value)
{
const std::optional<_setlevels> enumValueOpt = magic_enum::enum_cast<_setlevels>(value);
if (enumValueOpt.has_value()) {
return enumValueOpt.value();
}
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
} // namespace devilution
+4 -5
View File
@@ -7,13 +7,12 @@
#include <cstddef>
#include <cstdint>
#include <expected>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <expected.hpp>
#include "engine/clx_sprite.hpp"
#include "engine/point.hpp"
#include "engine/rectangle.hpp"
@@ -58,8 +57,8 @@ inline bool IsArenaLevel(_setlevels setLevel)
}
}
tl::expected<dungeon_type, std::string> ParseDungeonType(std::string_view value);
tl::expected<_setlevels, std::string> ParseSetLevel(std::string_view value);
std::expected<dungeon_type, std::string> ParseDungeonType(std::string_view value);
std::expected<_setlevels, std::string> ParseSetLevel(std::string_view value);
enum class DungeonFlag : uint8_t {
// clang-format off
@@ -298,7 +297,7 @@ struct Miniset {
return HasAnyOf(SOLData[dPiece[coords.x][coords.y]], property);
}
tl::expected<void, std::string> LoadLevelSOLData();
std::expected<void, std::string> LoadLevelSOLData();
void SetDungeonMicros(std::unique_ptr<std::byte[]> &dungeonCels, uint_fast8_t &microTileLen);
void DRLG_InitTrans();
void DRLG_MRectTrans(WorldTilePosition origin, WorldTilePosition extent);
+2 -3
View File
@@ -8,11 +8,10 @@
#include <algorithm>
#include <cstdint>
#include <cstring>
#include <expected>
#include <numeric>
#include <string>
#include <expected.hpp>
#include "automap.h"
#include "engine/displacement.hpp"
#include "engine/lighting_defs.hpp"
@@ -221,7 +220,7 @@ void DoVision(Point position, uint8_t radius, MapExplorationType doAutomap, bool
DoVision(position, radius, markVisibleFn, markTransparentFn, passesLightFn, inBoundsFn);
}
tl::expected<void, std::string> LoadTrns()
std::expected<void, std::string> LoadTrns()
{
RETURN_IF_ERROR(LoadFileInMemWithStatus("plrgfx\\infra.trn", InfravisionTable));
RETURN_IF_ERROR(LoadFileInMemWithStatus("plrgfx\\stone.trn", StoneTable));
+2 -3
View File
@@ -7,8 +7,7 @@
#include <array>
#include <cstdint>
#include <expected.hpp>
#include <expected>
#include "automap.h"
#include "engine/displacement.hpp"
@@ -57,7 +56,7 @@ void DoUnLight(Point position, uint8_t radius);
void DoLighting(Point position, uint8_t radius, DisplacementOf<int8_t> offset);
void DoUnVision(Point position, uint8_t radius);
void DoVision(Point position, uint8_t radius, MapExplorationType doAutomap, bool visible);
tl::expected<void, std::string> LoadTrns();
std::expected<void, std::string> LoadTrns();
void MakeLightTable();
#ifdef _DEBUG
void ToggleLighting();
+9 -9
View File
@@ -9,11 +9,11 @@
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <expected>
#include <numeric>
#include <string>
#include <ankerl/unordered_dense.h>
#include <expected.hpp>
#include "automap.h"
#include "codec.h"
@@ -2004,7 +2004,7 @@ void SaveLevel(SaveWriter &saveWriter, LevelConversionData *levelConversionData)
myPlayer._pSLvlVisited[setlvlnum] = true;
}
tl::expected<void, std::string> LoadLevel(LevelConversionData *levelConversionData)
std::expected<void, std::string> LoadLevel(LevelConversionData *levelConversionData)
{
char szName[MaxMpqPathSize];
std::optional<SaveReader> archive = OpenSaveArchive(gSaveNumber);
@@ -2013,7 +2013,7 @@ tl::expected<void, std::string> LoadLevel(LevelConversionData *levelConversionDa
GetPermLevelNames(szName);
LoadHelper file(std::move(archive), szName);
if (!file.IsValid())
return tl::make_unexpected(std::string(_("Unable to open save file archive")));
return std::unexpected(std::string(_("Unable to open save file archive")));
if (leveltype != DTYPE_TOWN) {
for (int j = 0; j < MAXDUNY; j++) {
@@ -2125,7 +2125,7 @@ bool IsStashSizeValid(size_t stashSize, uint32_t pages, uint32_t itemCount)
} // namespace
tl::expected<void, std::string> ConvertLevels(SaveWriter &saveWriter)
std::expected<void, std::string> ConvertLevels(SaveWriter &saveWriter)
{
// Backup current level state
const bool tmpSetlevel = setlevel;
@@ -2464,17 +2464,17 @@ void RemoveEmptyInventory(Player &player)
}
}
tl::expected<void, std::string> LoadGame(bool firstflag)
std::expected<void, std::string> LoadGame(bool firstflag)
{
FreeGameMem();
LoadHelper file(OpenSaveArchive(gSaveNumber), "game");
if (!file.IsValid()) {
return tl::make_unexpected(std::string(_("Unable to open save file archive")));
return std::unexpected(std::string(_("Unable to open save file archive")));
}
if (!IsHeaderValid(file.NextLE<uint32_t>())) {
return tl::make_unexpected(std::string(_("Invalid save file")));
return std::unexpected(std::string(_("Invalid save file")));
}
if (gbIsHellfireSaveGame) {
@@ -2506,7 +2506,7 @@ tl::expected<void, std::string> LoadGame(bool firstflag)
const int tmpNobjects = file.NextBE<int32_t>();
if (!gbIsHellfire && IsAnyOf(leveltype, DTYPE_NEST, DTYPE_CRYPT)) {
return tl::make_unexpected(std::string(_("Player is on a Hellfire only level")));
return std::unexpected(std::string(_("Player is on a Hellfire only level")));
}
for (uint8_t i = 0; i < giNumberOfLevels; i++) {
@@ -2938,7 +2938,7 @@ void SaveLevel(SaveWriter &saveWriter)
SaveLevel(saveWriter, nullptr);
}
tl::expected<void, std::string> LoadLevel()
std::expected<void, std::string> LoadLevel()
{
return LoadLevel(nullptr);
}
+4 -5
View File
@@ -6,8 +6,7 @@
#pragma once
#include <cstdint>
#include <expected.hpp>
#include <expected>
#include "pfile.h"
#include "player.h"
@@ -36,14 +35,14 @@ void RemoveEmptyInventory(Player &player);
* @brief Load game state
* @param firstflag Can be set to false if we are simply reloading the current game
*/
tl::expected<void, std::string> LoadGame(bool firstflag);
std::expected<void, std::string> LoadGame(bool firstflag);
void SaveHotkeys(SaveWriter &saveWriter, const Player &player);
void SaveHeroItems(SaveWriter &saveWriter, Player &player);
void SaveGameData(SaveWriter &saveWriter);
void SaveGame();
void SaveLevel(SaveWriter &saveWriter);
tl::expected<void, std::string> LoadLevel();
tl::expected<void, std::string> ConvertLevels(SaveWriter &saveWriter);
std::expected<void, std::string> LoadLevel();
std::expected<void, std::string> ConvertLevels(SaveWriter &saveWriter);
void LoadStash();
void SaveStash(SaveWriter &stashWriter);
+1 -1
View File
@@ -42,7 +42,7 @@ struct ValueInfo {
sol::protected_function LoadLuaFunctionSignatureGetter(sol::state &lua)
{
tl::expected<AssetData, std::string> src = LoadAsset("lua_internal\\get_lua_function_signature.lua");
std::expected<AssetData, std::string> src = LoadAsset("lua_internal\\get_lua_function_signature.lua");
if (!src.has_value()) {
app_fatal(src.error());
}
+2 -2
View File
@@ -1,13 +1,13 @@
#include "lua/lua_global.hpp"
#include <algorithm>
#include <expected>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
#include <ankerl/unordered_dense.h>
#include <expected.hpp>
#include <function_ref.hpp>
#include <sol/bytecode.hpp>
#include <sol/debug.hpp>
@@ -113,7 +113,7 @@ sol::object LuaLoadScriptFromAssets(std::string_view packageName)
return luaState.sol.load(iter->second.as_string_view(), path, sol::load_mode::binary);
}
tl::expected<AssetData, std::string> assetData = LoadIntegralAsset(path);
std::expected<AssetData, std::string> assetData = LoadIntegralAsset(path);
if (!assetData.has_value()) {
sol::stack::push(luaState.sol.lua_state(), assetData.error());
return sol::stack_object(luaState.sol.lua_state(), -1);
+1 -1
View File
@@ -1,8 +1,8 @@
#pragma once
#include <expected>
#include <string_view>
#include <expected.hpp>
#include <function_ref.hpp>
#include <sol/forward.hpp>
+2 -2
View File
@@ -59,7 +59,7 @@ std::string DebugCmdSpawnUniqueMonster(std::string name, std::optional<unsigned>
if (!found) {
if (LevelMonsterTypeCount == MaxLvlMTypes)
LevelMonsterTypeCount--; // we are running out of monster types, so override last used monster type
tl::expected<size_t, std::string> idResult = AddMonsterType(uniqueIndex, PLACE_SCATTER);
std::expected<size_t, std::string> idResult = AddMonsterType(uniqueIndex, PLACE_SCATTER);
if (!idResult.has_value()) return std::move(idResult).error();
id = idResult.value();
CMonster &monsterType = LevelMonsterTypes[id];
@@ -134,7 +134,7 @@ std::string DebugCmdSpawnMonster(std::string name, std::optional<unsigned> count
if (!found) {
if (LevelMonsterTypeCount == MaxLvlMTypes)
LevelMonsterTypeCount--; // we are running out of monster types, so override last used monster type
tl::expected<size_t, std::string> idResult = AddMonsterType(static_cast<_monster_id>(mtype), PLACE_SCATTER);
std::expected<size_t, std::string> idResult = AddMonsterType(static_cast<_monster_id>(mtype), PLACE_SCATTER);
if (!idResult.has_value()) return std::move(idResult).error();
id = idResult.value();
CMonster &monsterType = LevelMonsterTypes[id];
+4 -4
View File
@@ -2,11 +2,11 @@
#include "lua/repl.hpp"
#include <cstddef>
#include <expected>
#include <optional>
#include <string>
#include <string_view>
#include <expected.hpp>
#include <sol/sol.hpp>
#include <sol/utility/to_string.hpp>
@@ -87,14 +87,14 @@ sol::environment &GetLuaReplEnvironment()
return *replEnv;
}
tl::expected<std::string, std::string> RunLuaReplLine(std::string_view code)
std::expected<std::string, std::string> RunLuaReplLine(std::string_view code)
{
const sol::protected_function_result result = TryRunLuaAsExpressionThenStatement(code);
if (!result.valid()) {
if (result.get_type() == sol::type::string) {
return tl::make_unexpected(result.get<std::string>());
return std::unexpected(result.get<std::string>());
}
return tl::make_unexpected("Unknown Lua error");
return std::unexpected("Unknown Lua error");
}
if (result.get_type() == sol::type::none) {
return std::string {};
+2 -2
View File
@@ -1,15 +1,15 @@
#pragma once
#ifdef _DEBUG
#include <expected>
#include <string>
#include <string_view>
#include <expected.hpp>
#include <sol/forward.hpp>
namespace devilution {
tl::expected<std::string, std::string> RunLuaReplLine(std::string_view code);
std::expected<std::string, std::string> RunLuaReplLine(std::string_view code);
sol::environment &GetLuaReplEnvironment();
+2 -1
View File
@@ -4,6 +4,7 @@
#include <array>
#include <cstdint>
#include <cstdio>
#include <expected>
#include <span>
#include <string>
#include <string_view>
@@ -95,7 +96,7 @@ bool HexToModHash(std::string_view hex, std::array<uint8_t, 32> &out)
ModManifest ParseModManifest(std::string_view manifestIni)
{
ModManifest manifest;
tl::expected<Ini, std::string> ini = Ini::parse(manifestIni);
std::expected<Ini, std::string> ini = Ini::parse(manifestIni);
if (!ini.has_value()) {
LogError("Failed to parse mod manifest: {}", ini.error());
return manifest;
+15 -15
View File
@@ -14,6 +14,7 @@
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <expected>
#include <iterator>
#include <limits>
#include <memory>
@@ -30,7 +31,6 @@
#include <SDL.h>
#endif
#include <expected.hpp>
#include <fmt/core.h>
#include <fmt/format.h>
@@ -462,7 +462,7 @@ Point GetUniqueMonstPosition(UniqueMonsterType uniqindex)
return position;
}
tl::expected<void, std::string> PlaceUniqueMonst(UniqueMonsterType uniqindex, size_t minionType, int bosspacksize)
std::expected<void, std::string> PlaceUniqueMonst(UniqueMonsterType uniqindex, size_t minionType, int bosspacksize)
{
const auto &uniqueMonsterData = UniqueMonstersData[static_cast<size_t>(uniqindex)];
const size_t typeIndex = GetMonsterTypeIndex(uniqueMonsterData.mtype);
@@ -503,7 +503,7 @@ void ClrAllMonsters()
}
}
tl::expected<void, std::string> PlaceUniqueMonsters()
std::expected<void, std::string> PlaceUniqueMonsters()
{
for (size_t u = 0; u < UniqueMonstersData.size(); ++u) {
if (UniqueMonstersData[u].mlevel != currlevel)
@@ -530,7 +530,7 @@ tl::expected<void, std::string> PlaceUniqueMonsters()
return {};
}
tl::expected<void, std::string> PlaceQuestMonsters()
std::expected<void, std::string> PlaceQuestMonsters()
{
if (!setlevel) {
if (Quests[Q_BUTCHER].IsAvailable()) {
@@ -612,7 +612,7 @@ tl::expected<void, std::string> PlaceQuestMonsters()
return {};
}
tl::expected<void, std::string> LoadDiabMonsts()
std::expected<void, std::string> LoadDiabMonsts()
{
{
ASSIGN_OR_RETURN(auto dunData, LoadFileInMemWithStatus<uint16_t>("levels\\l4data\\diab1.dun"));
@@ -3288,7 +3288,7 @@ bool PosOkMovingMissile(Point position)
} // namespace
tl::expected<size_t, std::string> AddMonsterType(_monster_id type, placeflag placeflag)
std::expected<size_t, std::string> AddMonsterType(_monster_id type, placeflag placeflag)
{
const size_t typeIndex = GetMonsterTypeIndex(type);
CMonster &monsterType = LevelMonsterTypes[typeIndex];
@@ -3316,7 +3316,7 @@ tl::expected<size_t, std::string> AddMonsterType(_monster_id type, placeflag pla
return typeIndex;
}
tl::expected<void, std::string> InitTRNForUniqueMonster(Monster &monster)
std::expected<void, std::string> InitTRNForUniqueMonster(Monster &monster)
{
char filestr[64];
*BufCopy(filestr, R"(monsters\monsters\)", UniqueMonstersData[static_cast<size_t>(monster.uniqueType)].mTrnName, ".trn") = '\0';
@@ -3324,7 +3324,7 @@ tl::expected<void, std::string> InitTRNForUniqueMonster(Monster &monster)
return {};
}
tl::expected<void, std::string> PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, size_t minionType, int bosspacksize, const UniqueMonsterData &uniqueMonsterData)
std::expected<void, std::string> PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, size_t minionType, int bosspacksize, const UniqueMonsterData &uniqueMonsterData)
{
monster.uniqueType = monsterType;
monster.maxHitPoints = uniqueMonsterData.mmaxhp << 6;
@@ -3431,7 +3431,7 @@ void InitLevelMonsters()
uniquetrans = 0;
}
tl::expected<void, std::string> GetLevelMTypes()
std::expected<void, std::string> GetLevelMTypes()
{
RETURN_IF_ERROR(AddMonsterType(MT_GOLEM, PLACE_SPECIAL));
if (currlevel == 16) {
@@ -3517,7 +3517,7 @@ tl::expected<void, std::string> GetLevelMTypes()
return {};
}
tl::expected<void, std::string> InitMonsterSND(CMonster &monsterType)
std::expected<void, std::string> InitMonsterSND(CMonster &monsterType)
{
if (!gbSndInited)
return {};
@@ -3546,7 +3546,7 @@ tl::expected<void, std::string> InitMonsterSND(CMonster &monsterType)
return {};
}
tl::expected<void, std::string> InitMonsterGFX(CMonster &monsterType, MonsterSpritesData &&spritesData)
std::expected<void, std::string> InitMonsterGFX(CMonster &monsterType, MonsterSpritesData &&spritesData)
{
if (HeadlessMode)
return {};
@@ -3620,7 +3620,7 @@ tl::expected<void, std::string> InitMonsterGFX(CMonster &monsterType, MonsterSpr
return {};
}
tl::expected<void, std::string> InitAllMonsterGFX()
std::expected<void, std::string> InitAllMonsterGFX()
{
if (HeadlessMode)
return {};
@@ -3685,7 +3685,7 @@ void InitGolems()
}
}
tl::expected<void, std::string> InitMonsters()
std::expected<void, std::string> InitMonsters()
{
if (!gbIsSpawn && !setlevel && currlevel == 16)
LoadDiabMonsts();
@@ -3748,7 +3748,7 @@ tl::expected<void, std::string> InitMonsters()
return InitAllMonsterGFX();
}
tl::expected<void, std::string> SetMapMonsters(const uint16_t *dunData, Point startPosition)
std::expected<void, std::string> SetMapMonsters(const uint16_t *dunData, Point startPosition)
{
RETURN_IF_ERROR(AddMonsterType(MT_GOLEM, PLACE_SPECIAL));
if (setlevel)
@@ -4392,7 +4392,7 @@ bool LineClearMovingMissile(Point startPoint, Point endPoint)
return LineClear(PosOkMovingMissile, startPoint, endPoint);
}
tl::expected<void, std::string> SyncMonsterAnim(Monster &monster)
std::expected<void, std::string> SyncMonsterAnim(Monster &monster)
{
#ifdef _DEBUG
// fix for saves with debug monsters having type originally not on the level
+11 -11
View File
@@ -7,12 +7,12 @@
#include <cstddef>
#include <cstdint>
#include <expected>
#include <array>
#include <functional>
#include <string>
#include <expected.hpp>
#include <function_ref.hpp>
#include "engine/actor_position.hpp"
@@ -496,21 +496,21 @@ extern size_t ActiveMonsterCount;
extern int MonsterKillCounts[NUM_MAX_MTYPES];
extern bool sgbSaveSoundOn;
tl::expected<void, std::string> PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, size_t miniontype, int bosspacksize, const UniqueMonsterData &uniqueMonsterData);
std::expected<void, std::string> PrepareUniqueMonst(Monster &monster, UniqueMonsterType monsterType, size_t miniontype, int bosspacksize, const UniqueMonsterData &uniqueMonsterData);
void InitLevelMonsters();
tl::expected<void, std::string> GetLevelMTypes();
tl::expected<size_t, std::string> AddMonsterType(_monster_id type, placeflag placeflag);
inline tl::expected<size_t, std::string> AddMonsterType(UniqueMonsterType uniqueType, placeflag placeflag)
std::expected<void, std::string> GetLevelMTypes();
std::expected<size_t, std::string> AddMonsterType(_monster_id type, placeflag placeflag);
inline std::expected<size_t, std::string> AddMonsterType(UniqueMonsterType uniqueType, placeflag placeflag)
{
return AddMonsterType(UniqueMonstersData[static_cast<size_t>(uniqueType)].mtype, placeflag);
}
tl::expected<void, std::string> InitMonsterSND(CMonster &monsterType);
tl::expected<void, std::string> InitMonsterGFX(CMonster &monsterType, MonsterSpritesData &&spritesData = {});
tl::expected<void, std::string> InitAllMonsterGFX();
std::expected<void, std::string> InitMonsterSND(CMonster &monsterType);
std::expected<void, std::string> InitMonsterGFX(CMonster &monsterType, MonsterSpritesData &&spritesData = {});
std::expected<void, std::string> InitAllMonsterGFX();
void WeakenNaKrul();
void InitGolems();
tl::expected<void, std::string> InitMonsters();
tl::expected<void, std::string> SetMapMonsters(const uint16_t *dunData, Point startPosition);
std::expected<void, std::string> InitMonsters();
std::expected<void, std::string> SetMapMonsters(const uint16_t *dunData, Point startPosition);
Monster *AddMonster(Point position, Direction dir, size_t typeIndex, bool inMap);
/**
* @brief Spawns a new monsters (dynamically/not on level load).
@@ -555,7 +555,7 @@ bool LineClearMissile(Point startPoint, Point endPoint);
* @brief Checks for same missile obstructions as CheckMissileCol() for missiles that move along a path between two points
*/
bool LineClearMovingMissile(Point startPoint, Point endPoint);
tl::expected<void, std::string> SyncMonsterAnim(Monster &monster);
std::expected<void, std::string> SyncMonsterAnim(Monster &monster);
void M_FallenFear(Point position);
void PrintMonstHistory(int mt);
void PrintUniqueHistory();
+4 -4
View File
@@ -67,22 +67,22 @@ MpqArchive::~MpqArchive()
mpqfs_close(archive_);
}
tl::expected<MpqArchive, std::string> MpqArchive::Open(const char *path)
std::expected<MpqArchive, std::string> MpqArchive::Open(const char *path)
{
mpqfs_archive_t *handle = nullptr;
const mpqfs_error_code code = mpqfs_open(path, &handle);
if (code != MPQFS_OK) {
return tl::make_unexpected(FormatMpqfsError(code));
return std::unexpected(FormatMpqfsError(code));
}
return MpqArchive(path, handle);
}
tl::expected<MpqArchive, std::string> MpqArchive::Clone()
std::expected<MpqArchive, std::string> MpqArchive::Clone()
{
mpqfs_archive_t *clone = nullptr;
const mpqfs_error_code code = mpqfs_clone(archive_, &clone);
if (code != MPQFS_OK) {
return tl::make_unexpected(FormatMpqfsError(code));
return std::unexpected(FormatMpqfsError(code));
}
return MpqArchive(path_, clone);
}
+3 -4
View File
@@ -2,12 +2,11 @@
#include <cstddef>
#include <cstdint>
#include <expected>
#include <memory>
#include <string>
#include <string_view>
#include <expected.hpp>
// Forward-declare so that we can avoid exposing mpqfs.h to all consumers.
struct mpqfs_archive;
typedef struct mpqfs_archive mpqfs_archive_t;
@@ -16,8 +15,8 @@ namespace devilution {
class MpqArchive {
public:
static tl::expected<MpqArchive, std::string> Open(const char *path);
tl::expected<MpqArchive, std::string> Clone();
static std::expected<MpqArchive, std::string> Open(const char *path);
std::expected<MpqArchive, std::string> Clone();
MpqArchive(MpqArchive &&other) noexcept;
MpqArchive &operator=(MpqArchive &&other) noexcept;
+3 -3
View File
@@ -7,11 +7,11 @@
#include <cmath>
#include <cstdint>
#include <ctime>
#include <expected>
#include <string>
#include <algorithm>
#include <expected.hpp>
#include <fmt/core.h>
#include <fmt/format.h>
@@ -3681,7 +3681,7 @@ bool IsItemBlockingObjectAtPosition(Point position)
return false;
}
tl::expected<void, std::string> LoadLevelObjects(uint16_t filesWidths[65])
std::expected<void, std::string> LoadLevelObjects(uint16_t filesWidths[65])
{
if (HeadlessMode)
return {};
@@ -3706,7 +3706,7 @@ tl::expected<void, std::string> LoadLevelObjects(uint16_t filesWidths[65])
return {};
}
tl::expected<void, std::string> InitObjectGFX()
std::expected<void, std::string> InitObjectGFX()
{
uint16_t filesWidths[65] = {};
+2 -3
View File
@@ -7,10 +7,9 @@
#include <cmath>
#include <cstdint>
#include <expected>
#include <string>
#include <expected.hpp>
#include "cursor.h"
#include "engine/clx_sprite.hpp"
#include "engine/point.hpp"
@@ -329,7 +328,7 @@ inline Object &ObjectAtPosition(Point position)
*/
bool IsItemBlockingObjectAtPosition(Point position);
tl::expected<void, std::string> InitObjectGFX();
std::expected<void, std::string> InitObjectGFX();
void FreeObjectGFX();
void AddL1Objs(int x1, int y1, int x2, int y2);
void AddL2Objs(int x1, int y1, int x2, int y2);
+2 -2
View File
@@ -10,6 +10,7 @@
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <expected>
#include <functional>
#include <iterator>
#include <optional>
@@ -26,7 +27,6 @@
#include <SDL_version.h>
#endif
#include <expected.hpp>
#include <fmt/format.h>
#include <function_ref.hpp>
@@ -157,7 +157,7 @@ void LoadIni()
}
std::fclose(file);
}
tl::expected<Ini, std::string> result = Ini::parse(std::string_view(buffer.data(), buffer.size()));
std::expected<Ini, std::string> result = Ini::parse(std::string_view(buffer.data(), buffer.size()));
if (!result.has_value()) app_fatal(result.error());
ini.emplace(std::move(result).value());
}
+2 -2
View File
@@ -1,11 +1,11 @@
#include "panels/charpanel.hpp"
#include <cstdint>
#include <expected>
#include <algorithm>
#include <string>
#include <expected.hpp>
#include <fmt/format.h>
#include <function_ref.hpp>
@@ -270,7 +270,7 @@ void DrawStatButtons(const Surface &out)
} // namespace
tl::expected<void, std::string> LoadCharPanel()
std::expected<void, std::string> LoadCharPanel()
{
ASSIGN_OR_RETURN(OptionalOwnedClxSpriteList background, LoadClxWithStatus("data\\charbg.clx"));
const OwnedSurface out((*background)[0].width(), (*background)[0].height());
+2 -3
View File
@@ -1,9 +1,8 @@
#pragma once
#include <expected>
#include <string>
#include <expected.hpp>
#include "engine/clx_sprite.hpp"
#include "engine/surface.hpp"
@@ -12,7 +11,7 @@ namespace devilution {
extern OptionalOwnedClxSpriteList pChrButtons;
void DrawChr(const Surface &);
tl::expected<void, std::string> LoadCharPanel();
std::expected<void, std::string> LoadCharPanel();
void FreeCharPanel();
} // namespace devilution
+2 -2
View File
@@ -53,7 +53,7 @@ constexpr std::string_view HelpText =
" Up/Down to fill the input from history,"
" Shift+Up/Down to fill the input from output history,"
" Ctrl+L to clear history, Esc to close.";
std::optional<tl::expected<AssetData, std::string>> ConsolePrelude;
std::optional<std::expected<AssetData, std::string>> ConsolePrelude;
bool IsConsoleVisible;
char ConsoleInputBuffer[4096];
@@ -639,7 +639,7 @@ void InitConsole()
void RunInConsole(std::string_view code)
{
AddConsoleLine(ConsoleLine { .type = ConsoleLine::Input, .text = StrCat(Prompt, code) });
tl::expected<std::string, std::string> result = RunLuaReplLine(code);
std::expected<std::string, std::string> result = RunLuaReplLine(code);
if (result.has_value()) {
if (!result->empty()) {
+2 -3
View File
@@ -1,11 +1,10 @@
#include "panels/mainpanel.hpp"
#include <cstdint>
#include <expected>
#include <optional>
#include <string>
#include <expected.hpp>
#include "control/control.hpp"
#include "engine/clx_sprite.hpp"
#include "engine/load_clx.hpp"
@@ -70,7 +69,7 @@ void RenderMainButton(const Surface &out, int buttonId, std::string_view text, i
} // namespace
tl::expected<void, std::string> LoadMainPanel()
std::expected<void, std::string> LoadMainPanel()
{
std::optional<OwnedSurface> out;
constexpr uint16_t NumButtonSprites = 6;
+2 -3
View File
@@ -1,9 +1,8 @@
#pragma once
#include <expected>
#include <string>
#include <expected.hpp>
#include "engine/clx_sprite.hpp"
namespace devilution {
@@ -11,7 +10,7 @@ namespace devilution {
extern OptionalOwnedClxSpriteList PanelButtonDown;
extern OptionalOwnedClxSpriteList TalkButton;
tl::expected<void, std::string> LoadMainPanel();
std::expected<void, std::string> LoadMainPanel();
void FreeMainPanel();
} // namespace devilution
+2 -2
View File
@@ -1,6 +1,6 @@
#include "panels/partypanel.hpp"
#include <expected.hpp>
#include <expected>
#include <optional>
#include "automap.h"
@@ -135,7 +135,7 @@ bool PartySidePanelOpen = true;
bool InspectingFromPartyPanel;
int PortraitIdUnderCursor = -1;
tl::expected<void, std::string> LoadPartyPanel()
std::expected<void, std::string> LoadPartyPanel()
{
ASSIGN_OR_RETURN(OwnedClxSpriteList frame, LoadCelWithStatus("data\\textslid", FrameSpriteSize));
ASSIGN_OR_RETURN(PlayerTags, LoadClxWithStatus("data\\monstertags.clx"));
+2 -3
View File
@@ -1,9 +1,8 @@
#pragma once
#include <expected>
#include <string>
#include <expected.hpp>
#include "engine/clx_sprite.hpp"
#include "engine/surface.hpp"
@@ -13,7 +12,7 @@ extern bool PartySidePanelOpen;
extern bool InspectingFromPartyPanel;
extern int PortraitIdUnderCursor;
tl::expected<void, std::string> LoadPartyPanel();
std::expected<void, std::string> LoadPartyPanel();
void FreePartyPanel();
void DrawPartyMemberInfoPanel(const Surface &out);
bool DidRightClickPartyPortrait();
+2 -2
View File
@@ -1,10 +1,10 @@
#include "panels/spell_book.hpp"
#include <cstdint>
#include <expected>
#include <optional>
#include <string>
#include <expected.hpp>
#include <fmt/format.h>
#include "control/control.hpp"
@@ -119,7 +119,7 @@ StringOrView GetSpellPowerText(SpellID spell, int spellLevel)
} // namespace
tl::expected<void, std::string> InitSpellBook()
std::expected<void, std::string> InitSpellBook()
{
ASSIGN_OR_RETURN(spellBookBackground, LoadCelWithStatus("data\\spellbk", static_cast<uint16_t>(SidePanelSize.width)));
ASSIGN_OR_RETURN(spellBookButtons, LoadCelWithStatus("data\\spellbkb", SpellBookButtonWidth()));
+2 -3
View File
@@ -1,15 +1,14 @@
#pragma once
#include <expected>
#include <string>
#include <expected.hpp>
#include "engine/clx_sprite.hpp"
#include "engine/surface.hpp"
namespace devilution {
tl::expected<void, std::string> InitSpellBook();
std::expected<void, std::string> InitSpellBook();
void FreeSpellBook();
void CheckSBook();
void DrawSpellBook(const Surface &out);
+2 -2
View File
@@ -84,7 +84,7 @@ const SpellIcon SpellITbl[] = {
} // namespace
tl::expected<void, std::string> LoadLargeSpellIcons()
std::expected<void, std::string> LoadLargeSpellIcons()
{
#ifdef UNPACKED_MPQS
LargeSpellIcons = LoadOptionalClx("data\\spelicon_fg.clx");
@@ -111,7 +111,7 @@ void FreeLargeSpellIcons()
LargeSpellIcons = std::nullopt;
}
tl::expected<void, std::string> LoadSmallSpellIcons()
std::expected<void, std::string> LoadSmallSpellIcons()
{
#ifdef UNPACKED_MPQS
ASSIGN_OR_RETURN(SmallSpellIcons, LoadClxWithStatus("data\\spelli2_fg.clx"));
+3 -4
View File
@@ -1,10 +1,9 @@
#pragma once
#include <cstdint>
#include <expected>
#include <string>
#include <expected.hpp>
#include "engine/clx_sprite.hpp"
#include "engine/point.hpp"
#include "engine/surface.hpp"
@@ -109,10 +108,10 @@ void DrawSmallSpellIconBorder(const Surface &out, Point position);
*/
void SetSpellTrans(SpellType t);
tl::expected<void, std::string> LoadLargeSpellIcons();
std::expected<void, std::string> LoadLargeSpellIcons();
void FreeLargeSpellIcons();
tl::expected<void, std::string> LoadSmallSpellIcons();
std::expected<void, std::string> LoadSmallSpellIcons();
void FreeSmallSpellIcons();
} // namespace devilution
+3 -3
View File
@@ -7,12 +7,12 @@
#include <cstddef>
#include <cstdint>
#include <expected>
#include <optional>
#include <string>
#include <string_view>
#include <ankerl/unordered_dense.h>
#include <expected.hpp>
#ifdef USE_SDL3
#include <SDL3/SDL_iostream.h>
@@ -265,7 +265,7 @@ std::optional<SaveReader> CreateSaveReader(std::string &&path)
return std::nullopt;
return SaveReader(std::move(path));
#else
tl::expected<MpqArchive, std::string> opened = MpqArchive::Open(path.c_str());
std::expected<MpqArchive, std::string> opened = MpqArchive::Open(path.c_str());
if (!opened.has_value()) return std::nullopt;
return std::move(*opened);
#endif
@@ -809,7 +809,7 @@ void pfile_save_level()
SaveLevel(saveWriter);
}
tl::expected<void, std::string> pfile_convert_levels()
std::expected<void, std::string> pfile_convert_levels()
{
SaveWriter saveWriter = GetSaveWriter(gSaveNumber);
return ConvertLevels(saveWriter);
+2 -3
View File
@@ -6,10 +6,9 @@
#pragma once
#include <cstdint>
#include <expected>
#include <string>
#include <expected.hpp>
#include "DiabloUI/diabloui.h"
#include "player.h"
@@ -125,7 +124,7 @@ bool pfile_ui_save_create(_uiheroinfo *heroinfo);
bool pfile_delete_save(_uiheroinfo *heroInfo);
void pfile_read_player_from_save(uint32_t saveNum, Player &player);
void pfile_save_level();
tl::expected<void, std::string> pfile_convert_levels();
std::expected<void, std::string> pfile_convert_levels();
void pfile_remove_temp_files();
std::unique_ptr<std::byte[]> pfile_read(const char *pszName, size_t *pdwLen);
void pfile_update(bool forceSave);
+1 -1
View File
@@ -8,7 +8,7 @@ namespace {
bool AreExtraFontsOutOfDateForMpqPath(const char *mpqPath)
{
tl::expected<MpqArchive, std::string> archive = MpqArchive::Open(mpqPath);
std::expected<MpqArchive, std::string> archive = MpqArchive::Open(mpqPath);
return archive.has_value() && AreExtraFontsOutOfDate(*archive);
}
+25 -25
View File
@@ -41,18 +41,18 @@ std::vector<PLStruct> ItemPrefixes;
/** Contains the data related to each item suffix. */
std::vector<PLStruct> ItemSuffixes;
tl::expected<_item_indexes, std::string> ParseItemId(std::string_view value)
std::expected<_item_indexes, std::string> ParseItemId(std::string_view value)
{
const std::optional<_item_indexes> enumValueOpt = magic_enum::enum_cast<_item_indexes>(value);
if (enumValueOpt.has_value()) {
return enumValueOpt.value();
}
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
namespace {
tl::expected<item_class, std::string> ParseItemClass(std::string_view value)
std::expected<item_class, std::string> ParseItemClass(std::string_view value)
{
if (value == "None") return ICLASS_NONE;
if (value == "Weapon") return ICLASS_WEAPON;
@@ -60,10 +60,10 @@ tl::expected<item_class, std::string> ParseItemClass(std::string_view value)
if (value == "Misc") return ICLASS_MISC;
if (value == "Gold") return ICLASS_GOLD;
if (value == "Quest") return ICLASS_QUEST;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<item_equip_type, std::string> ParseItemEquipType(std::string_view value)
std::expected<item_equip_type, std::string> ParseItemEquipType(std::string_view value)
{
if (value == "None") return ILOC_NONE;
if (value == "One-handed") return ILOC_ONEHAND;
@@ -74,10 +74,10 @@ tl::expected<item_equip_type, std::string> ParseItemEquipType(std::string_view v
if (value == "Amulet") return ILOC_AMULET;
if (value == "Unequippable") return ILOC_UNEQUIPABLE;
if (value == "Belt") return ILOC_BELT;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<item_cursor_graphic, std::string> ParseItemCursorGraphic(std::string_view value)
std::expected<item_cursor_graphic, std::string> ParseItemCursorGraphic(std::string_view value)
{
if (value == "POTION_OF_FULL_MANA") return ICURS_POTION_OF_FULL_MANA;
if (value == "SCROLL_OF") return ICURS_SCROLL_OF;
@@ -253,11 +253,11 @@ tl::expected<item_cursor_graphic, std::string> ParseItemCursorGraphic(std::strin
// also support providing the item cursor icon frame number directly
return ParseInt<uint8_t>(value)
.map([](auto numericalValue) { return static_cast<item_cursor_graphic>(numericalValue); })
.map_error([](auto) { return std::string("Unknown enum value"); });
.transform([](auto numericalValue) { return static_cast<item_cursor_graphic>(numericalValue); })
.transform_error([](auto) { return std::string("Unknown enum value"); });
}
tl::expected<ItemType, std::string> ParseItemType(std::string_view value)
std::expected<ItemType, std::string> ParseItemType(std::string_view value)
{
if (value == "Misc") return ItemType::Misc;
if (value == "Sword") return ItemType::Sword;
@@ -274,10 +274,10 @@ tl::expected<ItemType, std::string> ParseItemType(std::string_view value)
if (value == "Ring") return ItemType::Ring;
if (value == "Amulet") return ItemType::Amulet;
if (value == "None") return ItemType::None;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<unique_base_item, std::string> ParseUniqueBaseItem(std::string_view value)
std::expected<unique_base_item, std::string> ParseUniqueBaseItem(std::string_view value)
{
if (value == "NONE") return UITYPE_NONE;
if (value == "SHORTBOW") return UITYPE_SHORTBOW;
@@ -354,10 +354,10 @@ tl::expected<unique_base_item, std::string> ParseUniqueBaseItem(std::string_view
return static_cast<unique_base_item>(findIt->second);
}
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<unique_base_item, std::string> ParseOrAddUniqueBaseItem(std::string_view value)
std::expected<unique_base_item, std::string> ParseOrAddUniqueBaseItem(std::string_view value)
{
const auto parseResult = ParseUniqueBaseItem(value);
if (parseResult.has_value()) {
@@ -367,7 +367,7 @@ tl::expected<unique_base_item, std::string> ParseOrAddUniqueBaseItem(std::string
const size_t newUniqueBaseItemIndex = static_cast<size_t>(NUM_DEFAULT_UITYPES) + AdditionalUniqueBaseItemStringsToIndices.size();
if (newUniqueBaseItemIndex >= static_cast<size_t>(NUM_MAX_UITYPES)) {
return tl::make_unexpected(fmt::format("Could not define new unique base item \"{}\", since the maximum number of {} has already been reached.", value, static_cast<size_t>(NUM_MAX_UITYPES)));
return std::unexpected(fmt::format("Could not define new unique base item \"{}\", since the maximum number of {} has already been reached.", value, static_cast<size_t>(NUM_MAX_UITYPES)));
}
const auto newUniqueBaseItem = static_cast<unique_base_item>(newUniqueBaseItemIndex);
@@ -375,7 +375,7 @@ tl::expected<unique_base_item, std::string> ParseOrAddUniqueBaseItem(std::string
return newUniqueBaseItem;
}
tl::expected<ItemSpecialEffect, std::string> ParseItemSpecialEffect(std::string_view value)
std::expected<ItemSpecialEffect, std::string> ParseItemSpecialEffect(std::string_view value)
{
if (value == "RandomStealLife") return ItemSpecialEffect::RandomStealLife;
if (value == "RandomArrowVelocity") return ItemSpecialEffect::RandomArrowVelocity;
@@ -403,10 +403,10 @@ tl::expected<ItemSpecialEffect, std::string> ParseItemSpecialEffect(std::string_
if (value == "HalfTrapDamage") return ItemSpecialEffect::HalfTrapDamage;
if (value == "TripleDemonDamage") return ItemSpecialEffect::TripleDemonDamage;
if (value == "ZeroResistance") return ItemSpecialEffect::ZeroResistance;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<item_misc_id, std::string> ParseItemMiscId(std::string_view value)
std::expected<item_misc_id, std::string> ParseItemMiscId(std::string_view value)
{
if (value == "NONE") return IMISC_NONE;
if (value == "USEFIRST") return IMISC_USEFIRST;
@@ -454,10 +454,10 @@ tl::expected<item_misc_id, std::string> ParseItemMiscId(std::string_view value)
if (value == "AURIC") return IMISC_AURIC;
if (value == "NOTE") return IMISC_NOTE;
if (value == "ARENAPOT") return IMISC_ARENAPOT;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<item_effect_type, std::string> ParseItemEffectType(std::string_view value)
std::expected<item_effect_type, std::string> ParseItemEffectType(std::string_view value)
{
if (value == "TOHIT") return IPL_TOHIT;
if (value == "TOHIT_CURSE") return IPL_TOHIT_CURSE;
@@ -539,10 +539,10 @@ tl::expected<item_effect_type, std::string> ParseItemEffectType(std::string_view
if (value == "ACUNDEAD") return IPL_ACUNDEAD;
if (value == "MANATOLIFE") return IPL_MANATOLIFE;
if (value == "LIFETOMANA") return IPL_LIFETOMANA;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<AffixItemType, std::string> ParseAffixItemType(std::string_view value)
std::expected<AffixItemType, std::string> ParseAffixItemType(std::string_view value)
{
if (value == "Misc") return AffixItemType::Misc;
if (value == "Bow") return AffixItemType::Bow;
@@ -550,15 +550,15 @@ tl::expected<AffixItemType, std::string> ParseAffixItemType(std::string_view val
if (value == "Weapon") return AffixItemType::Weapon;
if (value == "Shield") return AffixItemType::Shield;
if (value == "Armor") return AffixItemType::Armor;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<goodorevil, std::string> ParseAffixAlignment(std::string_view value)
std::expected<goodorevil, std::string> ParseAffixAlignment(std::string_view value)
{
if (value == "Any") return GOE_ANY;
if (value == "Evil") return GOE_EVIL;
if (value == "Good") return GOE_GOOD;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
} // namespace
+2 -2
View File
@@ -6,11 +6,11 @@
#pragma once
#include <cstdint>
#include <expected>
#include <string_view>
#include <vector>
#include <ankerl/unordered_dense.h>
#include <expected.hpp>
#include <magic_enum/magic_enum.hpp>
#include "tables/objdat.h"
@@ -656,7 +656,7 @@ extern std::vector<PLStruct> ItemSuffixes;
extern DVL_API_FOR_TEST std::vector<UniqueItem> UniqueItems;
extern ankerl::unordered_dense::map<int32_t, int32_t> UniqueItemMappingIdsToIndices;
tl::expected<_item_indexes, std::string> ParseItemId(std::string_view value);
std::expected<_item_indexes, std::string> ParseItemId(std::string_view value);
void LoadItemDatFromFile(DataFile &dataFile, std::string_view filename, int32_t baseMappingId);
void LoadUniqueItemDatFromFile(DataFile &dataFile, std::string_view filename, int32_t baseMappingId);
void LoadItemData();
+19 -20
View File
@@ -9,14 +9,13 @@
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <expected>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include <vector>
#include <expected.hpp>
#include "data/file.hpp"
#include "data/iterators.hpp"
#include "data/record_reader.hpp"
@@ -57,15 +56,15 @@ size_t ToIndex(std::vector<std::array<uint8_t, 16>> &all, const std::array<uint8
return all.size() - 1;
}
tl::expected<MissileGraphicsFlags, std::string> ParseMissileGraphicsFlag(std::string_view value)
std::expected<MissileGraphicsFlags, std::string> ParseMissileGraphicsFlag(std::string_view value)
{
if (value.empty()) return MissileGraphicsFlags::None;
if (value == "MonsterOwned") return MissileGraphicsFlags::MonsterOwned;
if (value == "NotAnimated") return MissileGraphicsFlags::NotAnimated;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<MissileGraphicID, std::string> ParseMissileGraphicID(std::string_view value)
std::expected<MissileGraphicID, std::string> ParseMissileGraphicID(std::string_view value)
{
if (value.empty()) return MissileGraphicID::None;
if (value == "Arrow") return MissileGraphicID::Arrow;
@@ -127,7 +126,7 @@ tl::expected<MissileGraphicID, std::string> ParseMissileGraphicID(std::string_vi
if (value == "BlueFlare2") return MissileGraphicID::BlueFlare2;
if (value == "OrangeFlareExplosion") return MissileGraphicID::OrangeFlareExplosion;
if (value == "BlueFlareExplosion2") return MissileGraphicID::BlueFlareExplosion2;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
void LoadMissileSpriteData()
@@ -166,7 +165,7 @@ void LoadMissileSpriteData()
MissileAnimLengths.shrink_to_fit();
}
tl::expected<MissileDataFlags, std::string> ParseMissileDataFlag(std::string_view value)
std::expected<MissileDataFlags, std::string> ParseMissileDataFlag(std::string_view value)
{
if (value == "Physical") return MissileDataFlags::Physical;
if (value == "Fire") return MissileDataFlags::Fire;
@@ -175,11 +174,11 @@ tl::expected<MissileDataFlags, std::string> ParseMissileDataFlag(std::string_vie
if (value == "Acid") return MissileDataFlags::Acid;
if (value == "Arrow") return MissileDataFlags::Arrow;
if (value == "Invisible") return MissileDataFlags::Invisible;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
tl::expected<MissileData::AddFn, std::string> ParseMissileAddFn(std::string_view value)
std::expected<MissileData::AddFn, std::string> ParseMissileAddFn(std::string_view value)
{
if (value.empty()) return nullptr;
if (value == "AddOpenNest") return AddOpenNest;
@@ -255,11 +254,11 @@ tl::expected<MissileData::AddFn, std::string> ParseMissileAddFn(std::string_view
if (value == "AddBoneSpirit") return AddBoneSpirit;
if (value == "AddRedPortal") return AddRedPortal;
if (value == "AddDiabloApocalypse") return AddDiabloApocalypse;
return tl::make_unexpected("Unknown MissileData::AddFn name");
return std::unexpected("Unknown MissileData::AddFn name");
}
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
tl::expected<MissileData::ProcessFn, std::string> ParseMissileProcessFn(std::string_view value)
std::expected<MissileData::ProcessFn, std::string> ParseMissileProcessFn(std::string_view value)
{
if (value.empty()) return nullptr;
if (value == "ProcessElementalArrow") return ProcessElementalArrow;
@@ -307,12 +306,12 @@ tl::expected<MissileData::ProcessFn, std::string> ParseMissileProcessFn(std::str
if (value == "ProcessBoneSpirit") return ProcessBoneSpirit;
if (value == "ProcessResurrectBeam") return ProcessResurrectBeam;
if (value == "ProcessRedPortal") return ProcessRedPortal;
return tl::make_unexpected("Unknown MissileData::ProcessFn name");
return std::unexpected("Unknown MissileData::ProcessFn name");
}
// A temporary solution for parsing SfxID until we have a more general one.
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
tl::expected<SfxID, std::string> ParseCastSound(std::string_view value)
std::expected<SfxID, std::string> ParseCastSound(std::string_view value)
{
if (value.empty()) return SfxID::None;
if (value == "BigExplosion") return SfxID::BigExplosion;
@@ -345,11 +344,11 @@ tl::expected<SfxID, std::string> ParseCastSound(std::string_view value)
if (value == "SpellStoneCurse") return SfxID::SpellStoneCurse;
if (value == "SpellTeleport") return SfxID::SpellTeleport;
if (value == "SpellTrapDisarm") return SfxID::SpellTrapDisarm;
return tl::make_unexpected("Unknown enum value (only a few are supported for now)");
return std::unexpected("Unknown enum value (only a few are supported for now)");
}
// A temporary solution for parsing SfxID until we have a more general one.
tl::expected<SfxID, std::string> ParseHitSound(std::string_view value)
std::expected<SfxID, std::string> ParseHitSound(std::string_view value)
{
if (value.empty()) return SfxID::None;
if (value == "BigExplosion") return SfxID::BigExplosion;
@@ -358,15 +357,15 @@ tl::expected<SfxID, std::string> ParseHitSound(std::string_view value)
if (value == "SpellFireHit") return SfxID::SpellFireHit;
if (value == "SpellLightningHit") return SfxID::SpellLightningHit;
if (value == "SpellResurrect") return SfxID::SpellResurrect;
return tl::make_unexpected("Unknown enum value (only a few are supported for now)");
return std::unexpected("Unknown enum value (only a few are supported for now)");
}
tl::expected<MissileMovementDistribution, std::string> ParseMissileMovementDistribution(std::string_view value)
std::expected<MissileMovementDistribution, std::string> ParseMissileMovementDistribution(std::string_view value)
{
if (value.empty()) return MissileMovementDistribution::Disabled;
if (value == "Blockable") return MissileMovementDistribution::Blockable;
if (value == "Unblockable") return MissileMovementDistribution::Unblockable;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
void LoadMisdat()
@@ -408,7 +407,7 @@ uint8_t MissileFileData::animLen(uint8_t dir) const
return MissileAnimLengths[animLenIdx][dir];
}
tl::expected<void, std::string> MissileFileData::LoadGFX()
std::expected<void, std::string> MissileFileData::LoadGFX()
{
if (sprites)
return {};
@@ -451,7 +450,7 @@ const MissileData &GetMissileData(MissileID missileId)
return MissilesData[static_cast<std::underlying_type_t<MissileID>>(missileId)];
}
tl::expected<void, std::string> InitMissileGFX()
std::expected<void, std::string> InitMissileGFX()
{
if (HeadlessMode)
return {};
+3 -4
View File
@@ -7,11 +7,10 @@
#include <cstddef>
#include <cstdint>
#include <expected>
#include <string>
#include <type_traits>
#include <expected.hpp>
#include "effects.h"
#include "engine/clx_sprite.hpp"
#include "tables/spelldat.h"
@@ -220,7 +219,7 @@ struct MissileFileData {
[[nodiscard]] uint8_t animDelay(uint8_t dir) const;
[[nodiscard]] uint8_t animLen(uint8_t dir) const;
tl::expected<void, std::string> LoadGFX();
std::expected<void, std::string> LoadGFX();
void FreeGFX()
{
@@ -246,7 +245,7 @@ MissileFileData &GetMissileSpriteData(MissileGraphicID graphicId);
void LoadMissileData();
tl::expected<void, std::string> InitMissileGFX();
std::expected<void, std::string> InitMissileGFX();
void FreeMissileGFX();
} // namespace devilution
+19 -19
View File
@@ -8,13 +8,13 @@
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <expected>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
#include <ankerl/unordered_dense.h>
#include <expected.hpp>
#include <fmt/core.h>
#include <fmt/format.h>
#include <magic_enum/magic_enum.hpp>
@@ -223,7 +223,7 @@ namespace {
/** Contains the mapping between monster ID strings and indices, used for parsing additional monster data. */
ankerl::unordered_dense::map<std::string, int16_t> AdditionalMonsterIdStringsToIndices;
tl::expected<_monster_id, std::string> ParseMonsterId(std::string_view value)
std::expected<_monster_id, std::string> ParseMonsterId(std::string_view value)
{
const std::optional<_monster_id> enumValueOpt = magic_enum::enum_cast<_monster_id>(value);
if (enumValueOpt.has_value()) {
@@ -233,27 +233,27 @@ tl::expected<_monster_id, std::string> ParseMonsterId(std::string_view value)
if (findIt != AdditionalMonsterIdStringsToIndices.end()) {
return static_cast<_monster_id>(findIt->second);
}
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<MonsterAvailability, std::string> ParseMonsterAvailability(std::string_view value)
std::expected<MonsterAvailability, std::string> ParseMonsterAvailability(std::string_view value)
{
if (value == "Always") return MonsterAvailability::Always;
if (value == "Never") return MonsterAvailability::Never;
if (value == "Retail") return MonsterAvailability::Retail;
return tl::make_unexpected("Expected one of: Always, Never, or Retail");
return std::unexpected("Expected one of: Always, Never, or Retail");
}
tl::expected<MonsterAIID, std::string> ParseAiId(std::string_view value)
std::expected<MonsterAIID, std::string> ParseAiId(std::string_view value)
{
const std::optional<MonsterAIID> enumValueOpt = magic_enum::enum_cast<MonsterAIID>(value);
if (enumValueOpt.has_value()) {
return enumValueOpt.value();
}
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<monster_flag, std::string> ParseMonsterFlag(std::string_view value)
std::expected<monster_flag, std::string> ParseMonsterFlag(std::string_view value)
{
if (value == "HIDDEN") return MFLAG_HIDDEN;
if (value == "LOCK_ANIMATION") return MFLAG_LOCK_ANIMATION;
@@ -267,37 +267,37 @@ tl::expected<monster_flag, std::string> ParseMonsterFlag(std::string_view value)
if (value == "NO_ENEMY") return MFLAG_NO_ENEMY;
if (value == "BERSERK") return MFLAG_BERSERK;
if (value == "NOLIFESTEAL") return MFLAG_NOLIFESTEAL;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<MonsterClass, std::string> ParseMonsterClass(std::string_view value)
std::expected<MonsterClass, std::string> ParseMonsterClass(std::string_view value)
{
const std::optional<MonsterClass> enumValueOpt = magic_enum::enum_cast<MonsterClass>(value);
if (enumValueOpt.has_value()) {
return enumValueOpt.value();
}
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<monster_resistance, std::string> ParseMonsterResistance(std::string_view value)
std::expected<monster_resistance, std::string> ParseMonsterResistance(std::string_view value)
{
const std::optional<monster_resistance> enumValueOpt = magic_enum::enum_cast<monster_resistance>(value);
if (enumValueOpt.has_value()) {
return enumValueOpt.value();
}
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<SelectionRegion, std::string> ParseSelectionRegion(std::string_view value)
std::expected<SelectionRegion, std::string> ParseSelectionRegion(std::string_view value)
{
if (value.empty()) return SelectionRegion::None;
if (value == "Bottom") return SelectionRegion::Bottom;
if (value == "Middle") return SelectionRegion::Middle;
if (value == "Top") return SelectionRegion::Top;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<uint16_t, std::string> ParseMonsterTreasure(std::string_view value)
std::expected<uint16_t, std::string> ParseMonsterTreasure(std::string_view value)
{
// TODO: Replace this hack with proper parsing.
@@ -305,16 +305,16 @@ tl::expected<uint16_t, std::string> ParseMonsterTreasure(std::string_view value)
if (value == "None") return T_NODROP;
if (value == "Uniq(SKCROWN)") return Uniq(UITEM_SKCROWN);
if (value == "Uniq(CLEAVER)") return Uniq(UITEM_CLEAVER);
return tl::make_unexpected("Invalid value. NOTE: Parser is incomplete");
return std::unexpected("Invalid value. NOTE: Parser is incomplete");
}
tl::expected<UniqueMonsterPack, std::string> ParseUniqueMonsterPack(std::string_view value)
std::expected<UniqueMonsterPack, std::string> ParseUniqueMonsterPack(std::string_view value)
{
const std::optional<UniqueMonsterPack> enumValueOpt = magic_enum::enum_cast<UniqueMonsterPack>(value);
if (enumValueOpt.has_value()) {
return enumValueOpt.value();
}
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
} // namespace
+9 -9
View File
@@ -5,12 +5,12 @@
*/
#include "tables/objdat.h"
#include <expected>
#include <string>
#include <string_view>
#include <vector>
#include <ankerl/unordered_dense.h>
#include <expected.hpp>
#include "cursor.h"
#include "data/file.hpp"
@@ -178,7 +178,7 @@ std::vector<std::string> ObjMasterLoadList;
namespace {
tl::expected<theme_id, std::string> ParseTheme(std::string_view value)
std::expected<theme_id, std::string> ParseTheme(std::string_view value)
{
if (value.empty()) return THEME_NONE;
if (value == "THEME_BARREL") return THEME_BARREL;
@@ -198,10 +198,10 @@ tl::expected<theme_id, std::string> ParseTheme(std::string_view value)
if (value == "THEME_TEARFOUNTAIN") return THEME_TEARFOUNTAIN;
if (value == "THEME_BRNCROSS") return THEME_BRNCROSS;
if (value == "THEME_WEAPONRACK") return THEME_WEAPONRACK;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<quest_id, std::string> ParseQuest(std::string_view value)
std::expected<quest_id, std::string> ParseQuest(std::string_view value)
{
if (value.empty()) return Q_INVALID;
if (value == "Q_ROCK") return Q_ROCK;
@@ -228,10 +228,10 @@ tl::expected<quest_id, std::string> ParseQuest(std::string_view value)
if (value == "Q_NAKRUL") return Q_NAKRUL;
if (value == "Q_CORNSTN") return Q_CORNSTN;
if (value == "Q_JERSEY") return Q_JERSEY;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<ObjectDataFlags, std::string> ParseObjectDataFlags(std::string_view value)
std::expected<ObjectDataFlags, std::string> ParseObjectDataFlags(std::string_view value)
{
if (value.empty()) return ObjectDataFlags::None;
if (value == "Animated") return ObjectDataFlags::Animated;
@@ -240,16 +240,16 @@ tl::expected<ObjectDataFlags, std::string> ParseObjectDataFlags(std::string_view
if (value == "Light") return ObjectDataFlags::Light;
if (value == "Trap") return ObjectDataFlags::Trap;
if (value == "Breakable") return ObjectDataFlags::Breakable;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<SelectionRegion, std::string> ParseSelectionRegion(std::string_view value)
std::expected<SelectionRegion, std::string> ParseSelectionRegion(std::string_view value)
{
if (value.empty()) return SelectionRegion::None;
if (value == "Bottom") return SelectionRegion::Bottom;
if (value == "Middle") return SelectionRegion::Middle;
if (value == "Top") return SelectionRegion::Top;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
} // namespace
+10 -10
View File
@@ -11,9 +11,9 @@
#include <bitset>
#include <charconv>
#include <cstdint>
#include <expected>
#include <vector>
#include <expected.hpp>
#include <fmt/format.h>
#include <magic_enum/magic_enum_utility.hpp>
@@ -74,7 +74,7 @@ enum class ExperienceColumn {
LAST = Experience
};
tl::expected<ExperienceColumn, ColumnDefinition::Error> mapExperienceColumnFromName(std::string_view name)
std::expected<ExperienceColumn, ColumnDefinition::Error> mapExperienceColumnFromName(std::string_view name)
{
if (name == "Level") {
return ExperienceColumn::Level;
@@ -82,7 +82,7 @@ tl::expected<ExperienceColumn, ColumnDefinition::Error> mapExperienceColumnFromN
if (name == "Experience") {
return ExperienceColumn::Experience;
}
return tl::unexpected { ColumnDefinition::Error::UnknownColumn };
return std::unexpected { ColumnDefinition::Error::UnknownColumn };
}
void ReloadExperienceData()
@@ -156,19 +156,19 @@ void ReloadExperienceData()
}
}
tl::expected<PlayerClassFlag, std::string> ParsePlayerClassFlag(std::string_view value)
std::expected<PlayerClassFlag, std::string> ParsePlayerClassFlag(std::string_view value)
{
const std::optional<PlayerClassFlag> enumValueOpt = magic_enum::enum_cast<PlayerClassFlag>(value);
if (enumValueOpt.has_value()) {
return enumValueOpt.value();
}
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
void LoadClassData(std::string_view classPath, ClassAttributes &attributes, PlayerCombatData &combat)
{
const std::string filename = StrCat("txtdata\\classes\\", classPath, "\\attributes.tsv");
tl::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
std::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
DataFile &dataFile = dataFileResult.value();
dataFile.skipHeaderOrDie(filename);
@@ -200,7 +200,7 @@ void LoadClassData(std::string_view classPath, ClassAttributes &attributes, Play
void LoadClassStartingLoadoutData(std::string_view classPath, PlayerStartingLoadoutData &startingLoadoutData)
{
const std::string filename = StrCat("txtdata\\classes\\", classPath, "\\starting_loadout.tsv");
tl::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
std::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
DataFile &dataFile = dataFileResult.value();
dataFile.skipHeaderOrDie(filename);
@@ -218,7 +218,7 @@ void LoadClassStartingLoadoutData(std::string_view classPath, PlayerStartingLoad
void LoadClassSpriteData(std::string_view classPath, PlayerSpriteData &spriteData)
{
const std::string filename = StrCat("txtdata\\classes\\", classPath, "\\sprites.tsv");
tl::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
std::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
DataFile &dataFile = dataFileResult.value();
dataFile.skipHeaderOrDie(filename);
@@ -242,7 +242,7 @@ void LoadClassSpriteData(std::string_view classPath, PlayerSpriteData &spriteDat
void LoadClassAnimData(std::string_view classPath, PlayerAnimData &animData)
{
const std::string filename = StrCat("txtdata\\classes\\", classPath, "\\animations.tsv");
tl::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
std::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
DataFile &dataFile = dataFileResult.value();
dataFile.skipHeaderOrDie(filename);
@@ -280,7 +280,7 @@ void LoadClassAnimData(std::string_view classPath, PlayerAnimData &animData)
void LoadClassSounds(std::string_view classPath, ankerl::unordered_dense::map<HeroSpeech, SfxID> &sounds)
{
const std::string filename = StrCat("txtdata\\classes\\", classPath, "\\sounds.tsv");
tl::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
std::expected<DataFile, DataFile::Error> dataFileResult = DataFile::loadOrDie(filename);
DataFile &dataFile = dataFileResult.value();
dataFile.skipHeaderOrDie(filename);
+9 -10
View File
@@ -5,11 +5,10 @@
*/
#include "tables/spelldat.h"
#include <expected>
#include <optional>
#include <string_view>
#include <expected.hpp>
#include "data/file.hpp"
#include "data/iterators.hpp"
#include "data/record_reader.hpp"
@@ -33,26 +32,26 @@ void AddNullSpell()
}
// A temporary solution for parsing soundID until we have a more general one.
tl::expected<SfxID, std::string> ParseSpellSoundId(std::string_view value)
std::expected<SfxID, std::string> ParseSpellSoundId(std::string_view value)
{
if (value == "CastFire") return SfxID::CastFire;
if (value == "CastHealing") return SfxID::CastHealing;
if (value == "CastLightning") return SfxID::CastLightning;
if (value == "CastSkill") return SfxID::CastSkill;
return tl::make_unexpected("Unknown enum value (only a few are supported for now)");
return std::unexpected("Unknown enum value (only a few are supported for now)");
}
tl::expected<SpellDataFlags, std::string> ParseSpellDataFlag(std::string_view value)
std::expected<SpellDataFlags, std::string> ParseSpellDataFlag(std::string_view value)
{
if (value == "Fire") return SpellDataFlags::Fire;
if (value == "Lightning") return SpellDataFlags::Lightning;
if (value == "Magic") return SpellDataFlags::Magic;
if (value == "Targeted") return SpellDataFlags::Targeted;
if (value == "AllowedInTown") return SpellDataFlags::AllowedInTown;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
tl::expected<MissileID, std::string> ParseMissileId(std::string_view value)
std::expected<MissileID, std::string> ParseMissileId(std::string_view value)
{
if (value == "Arrow") return MissileID::Arrow;
if (value == "Firebolt") return MissileID::Firebolt;
@@ -162,7 +161,7 @@ tl::expected<MissileID, std::string> ParseMissileId(std::string_view value)
if (value == "BlueExplosion") return MissileID::BlueExplosion;
if (value == "BlueExplosion2") return MissileID::BlueExplosion2;
if (value == "OrangeExplosion") return MissileID::OrangeExplosion;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
} // namespace
@@ -170,7 +169,7 @@ tl::expected<MissileID, std::string> ParseMissileId(std::string_view value)
/** Data related to each spell ID. */
std::vector<SpellData> SpellsData;
tl::expected<SpellID, std::string> ParseSpellId(std::string_view value)
std::expected<SpellID, std::string> ParseSpellId(std::string_view value)
{
if (value == "Null") return SpellID::Null;
if (value == "Firebolt") return SpellID::Firebolt;
@@ -224,7 +223,7 @@ tl::expected<SpellID, std::string> ParseSpellId(std::string_view value)
if (value == "RuneOfNova") return SpellID::RuneOfNova;
if (value == "RuneOfImmolation") return SpellID::RuneOfImmolation;
if (value == "RuneOfStone") return SpellID::RuneOfStone;
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
void LoadSpellData()
+2 -3
View File
@@ -6,13 +6,12 @@
#pragma once
#include <cstdint>
#include <expected>
#include <string>
#include <string_view>
#include <type_traits>
#include <vector>
#include <expected.hpp>
#include "sound_effect_enums.h"
#include "utils/enum_traits.h"
@@ -88,7 +87,7 @@ enum class SpellID : int8_t {
Invalid = -1,
};
tl::expected<SpellID, std::string> ParseSpellId(std::string_view value);
std::expected<SpellID, std::string> ParseSpellId(std::string_view value);
enum class MagicType : uint8_t {
Fire,
+2 -2
View File
@@ -25,7 +25,7 @@ std::vector<Speech> Speeches;
/** Contains the mapping between text ID strings and indices, used for parsing additional text data. */
ankerl::unordered_dense::map<std::string, int16_t> AdditionalTextIdStringsToIndices;
tl::expected<_speech_id, std::string> ParseSpeechId(std::string_view value)
std::expected<_speech_id, std::string> ParseSpeechId(std::string_view value)
{
if (value.empty()) {
return TEXT_NONE;
@@ -41,7 +41,7 @@ tl::expected<_speech_id, std::string> ParseSpeechId(std::string_view value)
return static_cast<_speech_id>(findIt->second);
}
return tl::make_unexpected("Invalid value.");
return std::unexpected("Invalid value.");
}
namespace {
+2 -2
View File
@@ -6,9 +6,9 @@
#pragma once
#include <cstdint>
#include <expected>
#include <string>
#include <expected.hpp>
#include <magic_enum/magic_enum.hpp>
#include "sound_effect_enums.h"
@@ -435,7 +435,7 @@ struct Speech {
extern std::vector<Speech> Speeches;
tl::expected<_speech_id, std::string> ParseSpeechId(std::string_view value);
std::expected<_speech_id, std::string> ParseSpeechId(std::string_view value);
void LoadTextData();
+3 -3
View File
@@ -6,12 +6,12 @@
#include "tables/townerdat.hpp"
#include <charconv>
#include <expected>
#include <optional>
#include <string_view>
#include <unordered_map>
#include <vector>
#include <expected.hpp>
#include <magic_enum/magic_enum.hpp>
#include "data/file.hpp"
@@ -31,13 +31,13 @@ namespace {
* @return The parsed enum value, or an error message
*/
template <typename EnumT>
tl::expected<EnumT, std::string> ParseEnum(std::string_view value)
std::expected<EnumT, std::string> ParseEnum(std::string_view value)
{
const auto enumValueOpt = magic_enum::enum_cast<EnumT>(value);
if (enumValueOpt.has_value()) {
return enumValueOpt.value();
}
return tl::make_unexpected("Unknown enum value");
return std::unexpected("Unknown enum value");
}
/**
+6 -6
View File
@@ -6,6 +6,7 @@
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <expected>
#include <span>
#include <string>
#include <string_view>
@@ -15,7 +16,6 @@
#include <vector>
#include <ankerl/unordered_dense.h>
#include <expected.hpp>
#include <fmt/core.h>
#include <fmt/format.h>
@@ -122,7 +122,7 @@ void Ini::Values::append(const Ini::Value &value)
std::get<std::vector<Value>>(rep_).push_back(value);
}
tl::expected<Ini, std::string> Ini::parse(std::string_view buffer)
std::expected<Ini, std::string> Ini::parse(std::string_view buffer)
{
Ini::FileData fileData;
ankerl::unordered_dense::map<std::string, ValuesData, StringViewHash, StringViewEquals> *sectionEntries = nullptr;
@@ -160,10 +160,10 @@ tl::expected<Ini, std::string> Ini::parse(std::string_view buffer)
++keyEnd;
}
if (keyEnd == lineEnd) {
return tl::make_unexpected(fmt::format("line {}: unclosed section name {}", lineNum, std::string_view(keyBegin, keyEnd - keyBegin)));
return std::unexpected(fmt::format("line {}: unclosed section name {}", lineNum, std::string_view(keyBegin, keyEnd - keyBegin)));
}
if (const char *after = SkipTrailingWhitespace(keyEnd + 1, lineEnd); after != lineEnd) {
return tl::make_unexpected(fmt::format("line {}: content after section [{}]: {}", lineNum, std::string_view(keyBegin, keyEnd - keyBegin), std::string_view(after, lineEnd - after)));
return std::unexpected(fmt::format("line {}: content after section [{}]: {}", lineNum, std::string_view(keyBegin, keyEnd - keyBegin), std::string_view(after, lineEnd - after)));
}
const std::string_view sectionName = std::string_view(keyBegin, keyEnd - keyBegin);
auto it = fileData.sections.find(sectionName);
@@ -180,10 +180,10 @@ tl::expected<Ini, std::string> Ini::parse(std::string_view buffer)
continue;
}
if (sectionEntries == nullptr) return tl::unexpected(fmt::format("line {}: key not in any section", lineNum));
if (sectionEntries == nullptr) return std::unexpected(fmt::format("line {}: key not in any section", lineNum));
const char *eqPos = static_cast<const char *>(memchr(keyBegin, '=', lineEnd - keyBegin));
if (eqPos == nullptr) {
return tl::make_unexpected(fmt::format("line {}: key {} has no value", lineNum, std::string_view(keyBegin, lineEnd - keyBegin)));
return std::unexpected(fmt::format("line {}: key {} has no value", lineNum, std::string_view(keyBegin, lineEnd - keyBegin)));
}
const char *keyEnd = SkipTrailingWhitespace(keyBegin, eqPos);
const std::string_view key = std::string_view(keyBegin, keyEnd - keyBegin);
+2 -2
View File
@@ -2,6 +2,7 @@
#include <cstddef>
#include <cstdint>
#include <expected>
#include <optional>
#include <span>
#include <string>
@@ -11,7 +12,6 @@
#include <vector>
#include <ankerl/unordered_dense.h>
#include <expected.hpp>
#include "utils/string_view_hash.hpp"
@@ -51,7 +51,7 @@ public:
friend class Ini;
};
static tl::expected<Ini, std::string> parse(std::string_view buffer);
static std::expected<Ini, std::string> parse(std::string_view buffer);
[[nodiscard]] std::string serialize() const;
/** @return all the keys associated with this section in the ini */
+8 -9
View File
@@ -2,11 +2,10 @@
#include <charconv>
#include <cstdint>
#include <expected>
#include <string_view>
#include <system_error>
#include <expected.hpp>
namespace devilution {
enum class ParseIntError {
@@ -15,7 +14,7 @@ enum class ParseIntError {
};
template <typename IntT>
using ParseIntResult = tl::expected<IntT, ParseIntError>;
using ParseIntResult = std::expected<IntT, ParseIntError>;
template <typename IntT>
ParseIntResult<IntT> ParseInt(
@@ -28,11 +27,11 @@ ParseIntResult<IntT> ParseInt(
*endOfParse = result.ptr;
}
if (result.ec == std::errc::invalid_argument)
return tl::unexpected(ParseIntError::ParseError);
return std::unexpected(ParseIntError::ParseError);
if (result.ec == std::errc::result_out_of_range || value < min || value > max)
return tl::unexpected(ParseIntError::OutOfRange);
return std::unexpected(ParseIntError::OutOfRange);
if (result.ec != std::errc())
return tl::unexpected(ParseIntError::ParseError);
return std::unexpected(ParseIntError::ParseError);
return value;
}
@@ -53,7 +52,7 @@ ParseIntResult<IntT> ParseFixed6(std::string_view str, const char **endOfParse =
}
if (str.empty()) {
return tl::unexpected { ParseIntError::ParseError };
return std::unexpected { ParseIntError::ParseError };
}
constexpr IntT minIntegerValue = std::numeric_limits<IntT>::min() >> 6;
@@ -82,7 +81,7 @@ ParseIntResult<IntT> ParseFixed6(std::string_view str, const char **endOfParse =
if (!haveDigits) {
// early return in case we got a string like "-.abc", don't want to set the end pointer in this case
return tl::unexpected { ParseIntError::ParseError };
return std::unexpected { ParseIntError::ParseError };
}
if (endOfParse != nullptr) {
@@ -100,7 +99,7 @@ ParseIntResult<IntT> ParseFixed6(std::string_view str, const char **endOfParse =
// rounding could give us a value of 64 for the fraction part (e.g. 0.993 rounds to 1.0) so we need to ensure this doesn't overflow
if (fractionPart >= 64 && (integerPart >= maxIntegerValue || (std::is_signed_v<IntT> && integerPart <= minIntegerValue))) {
return tl::unexpected { ParseIntError::OutOfRange };
return std::unexpected { ParseIntError::OutOfRange };
} else {
IntT fixedValue = integerPart << 6;
if (isNegative) {
+2 -2
View File
@@ -4,7 +4,7 @@
#define RETURN_IF_ERROR(expr) \
if (auto result = expr; DVL_PREDICT_FALSE(!result.has_value())) { \
return tl::make_unexpected(std::move(result).error()); \
return std::unexpected(std::move(result).error()); \
}
#define STATUS_MACROS_CONCAT_NAME_INNER(x, y) x##y
@@ -13,7 +13,7 @@
#define ASSIGN_OR_RETURN_IMPL(result, lhs, rhs) \
auto result = rhs; /* NOLINT(bugprone-macro-parentheses): assignment */ \
if (DVL_PREDICT_FALSE(!result.has_value())) { /* NOLINT(bugprone-macro-parentheses): assignment */ \
return tl::make_unexpected(std::move(result).error()); \
return std::unexpected(std::move(result).error()); \
} \
lhs = std::move(result).value(); /* NOLINT(bugprone-macro-parentheses): assignment */
+9 -10
View File
@@ -4,6 +4,7 @@
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <expected>
#include <string>
#ifdef USE_SDL3
@@ -13,8 +14,6 @@
#include <SDL.h>
#endif
#include <expected.hpp>
#include "engine/surface.hpp"
#include "utils/endian_swap.hpp"
#include "utils/pcx.hpp"
@@ -23,13 +22,13 @@
namespace devilution {
namespace {
tl::expected<void, std::string> CheckedFWrite(const void *ptr, size_t size, SDL_IOStream *out)
std::expected<void, std::string> CheckedFWrite(const void *ptr, size_t size, SDL_IOStream *out)
{
if (SDL_WriteIO(out, ptr, size) != size) {
const char *errorMessage = SDL_GetError();
if (errorMessage == nullptr)
errorMessage = "";
tl::expected<void, std::string> result = tl::make_unexpected(std::string("write failed with: ").append(errorMessage));
std::expected<void, std::string> result = std::unexpected(std::string("write failed with: ").append(errorMessage));
SDL_ClearError();
return result;
}
@@ -43,7 +42,7 @@ tl::expected<void, std::string> CheckedFWrite(const void *ptr, size_t size, SDL_
* @param out File stream to write to
* @return True on success
*/
tl::expected<void, std::string> WritePcxHeader(int16_t width, int16_t height, SDL_IOStream *out)
std::expected<void, std::string> WritePcxHeader(int16_t width, int16_t height, SDL_IOStream *out)
{
PCXHeader buffer;
@@ -68,7 +67,7 @@ tl::expected<void, std::string> WritePcxHeader(int16_t width, int16_t height, SD
* @param out File stream for the PCX file.
* @return True if successful, else false
*/
tl::expected<void, std::string> WritePcxPalette(SDL_Color *palette, SDL_IOStream *out)
std::expected<void, std::string> WritePcxPalette(SDL_Color *palette, SDL_IOStream *out)
{
uint8_t pcxPalette[1 + 256 * 3];
@@ -131,7 +130,7 @@ uint8_t *WritePcxLine(uint8_t *src, uint8_t *dst, int width)
* @param out File stream for the PCX file.
* @return True if successful, else false
*/
tl::expected<void, std::string> WritePcxPixels(const Surface &buf, SDL_IOStream *out)
std::expected<void, std::string> WritePcxPixels(const Surface &buf, SDL_IOStream *out)
{
const int width = buf.w();
const std::unique_ptr<uint8_t[]> pBuffer { new uint8_t[static_cast<size_t>(2 * width)] };
@@ -139,7 +138,7 @@ tl::expected<void, std::string> WritePcxPixels(const Surface &buf, SDL_IOStream
for (int height = buf.h(); height > 0; height--) {
const uint8_t *pBufferEnd = WritePcxLine(pixels, pBuffer.get(), width);
pixels += buf.pitch();
tl::expected<void, std::string> result = CheckedFWrite(pBuffer.get(), pBufferEnd - pBuffer.get(), out);
std::expected<void, std::string> result = CheckedFWrite(pBuffer.get(), pBufferEnd - pBuffer.get(), out);
if (!result.has_value()) return result;
}
return {};
@@ -147,10 +146,10 @@ tl::expected<void, std::string> WritePcxPixels(const Surface &buf, SDL_IOStream
} // namespace
tl::expected<void, std::string>
std::expected<void, std::string>
WriteSurfaceToFilePcx(const Surface &buf, SDL_IOStream *outStream)
{
tl::expected<void, std::string> result = WritePcxHeader(buf.w(), buf.h(), outStream);
std::expected<void, std::string> result = WritePcxHeader(buf.w(), buf.h(), outStream);
if (!result.has_value()) return result;
result = WritePcxPixels(buf, outStream);
if (!result.has_value()) return result;
+2 -3
View File
@@ -1,3 +1,4 @@
#include <expected>
#include <string>
#ifdef USE_SDL3
@@ -8,13 +9,11 @@
#include "utils/sdl_compat.h"
#endif
#include <expected.hpp>
#include "engine/surface.hpp"
namespace devilution {
tl::expected<void, std::string>
std::expected<void, std::string>
WriteSurfaceToFilePcx(const Surface &buf, SDL_IOStream *outStream);
} // namespace devilution
+3 -4
View File
@@ -1,5 +1,6 @@
#include "utils/surface_to_png.hpp"
#include <expected>
#include <string>
#ifdef USE_SDL3
@@ -12,8 +13,6 @@
#include "utils/sdl_compat.h"
#endif
#include <expected.hpp>
#include "engine/surface.hpp"
namespace devilution {
@@ -22,7 +21,7 @@ namespace devilution {
extern "C" int IMG_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst);
#endif
tl::expected<void, std::string>
std::expected<void, std::string>
WriteSurfaceToFilePng(const Surface &buf, SDL_IOStream *dst)
{
#ifdef USE_SDL3
@@ -31,7 +30,7 @@ WriteSurfaceToFilePng(const Surface &buf, SDL_IOStream *dst)
const bool ok = IMG_SavePNG_RW(buf.surface, dst, /*freedst=*/1) == 0;
#endif
if (!ok) {
tl::expected<void, std::string> result = tl::make_unexpected(std::string(SDL_GetError()));
std::expected<void, std::string> result = std::unexpected(std::string(SDL_GetError()));
SDL_ClearError();
return result;
}
+2 -3
View File
@@ -1,4 +1,5 @@
#include <cstdio>
#include <expected>
#include <string>
#ifdef USE_SDL3
@@ -8,8 +9,6 @@
#include <SDL.h>
#endif
#include <expected.hpp>
#include "engine/surface.hpp"
namespace devilution {
@@ -19,7 +18,7 @@ namespace devilution {
*
* Takes ownership of `dst` and closes it when done.
*/
tl::expected<void, std::string>
std::expected<void, std::string>
WriteSurfaceToFilePng(const Surface &buf,
#ifdef USE_SDL3
SDL_IOStream *
+2 -2
View File
@@ -200,7 +200,7 @@ TEST(DataFileTest, ParseInt)
}
DataFile &dataFile = result.value();
auto unused = dataFile.parseHeader(nullptr, nullptr, [](std::string_view) -> tl::expected<uint8_t, ColumnDefinition::Error> { return tl::unexpected { ColumnDefinition::Error::UnknownColumn }; });
auto unused = dataFile.parseHeader(nullptr, nullptr, [](std::string_view) -> std::expected<uint8_t, ColumnDefinition::Error> { return std::unexpected { ColumnDefinition::Error::UnknownColumn }; });
EXPECT_TRUE(unused.has_value()) << "Should be able to parse and discard the header from the sample.tsv file";
@@ -334,7 +334,7 @@ TEST(DataFileTest, ParseHeaderThenIterateOverRecords)
{ "1", "", "3" },
};
auto parseHeaderResult = dataFile.parseHeader(nullptr, nullptr, [](std::string_view) -> tl::expected<uint8_t, ColumnDefinition::Error> { return tl::unexpected { ColumnDefinition::Error::UnknownColumn }; });
auto parseHeaderResult = dataFile.parseHeader(nullptr, nullptr, [](std::string_view) -> std::expected<uint8_t, ColumnDefinition::Error> { return std::unexpected { ColumnDefinition::Error::UnknownColumn }; });
EXPECT_TRUE(parseHeaderResult.has_value()) << "Expected to be able to parse and discard the header record";
unsigned row = 0;
+1 -1
View File
@@ -32,7 +32,7 @@ std::string ReplaceNewlines(std::string_view s)
TEST(IniTest, BasicTest)
{
tl::expected<Ini, std::string> result = Ini::parse(R"(
std::expected<Ini, std::string> result = Ini::parse(R"(
; Section A comment
[sectionA]
key1 = value1
+2 -2
View File
@@ -3,6 +3,7 @@
#include <cstddef>
#include <cstdint>
#include <expected>
#include <iostream>
#include <string>
#include <string_view>
@@ -15,7 +16,6 @@
#include <SDL.h>
#endif
#include <expected.hpp>
#include <function_ref.hpp>
#include "engine/load_file.hpp"
@@ -397,7 +397,7 @@ TEST_P(TextRenderIntegrationTest, RenderAndCompareTest)
SDL_IOStream *actual = SDL_IOFromFile(actualPath.c_str(), "wb");
ASSERT_NE(actual, nullptr) << SDL_GetError();
const tl::expected<void, std::string> result = WriteSurfaceToFilePng(out, actual);
const std::expected<void, std::string> result = WriteSurfaceToFilePng(out, actual);
ASSERT_TRUE(result.has_value()) << result.error();
// We compare pixels rather than PNG file contents because different