Skip to content

Commit a8b2cf2

Browse files
committed
Bump to v3.1.1
1 parent 45b43e0 commit a8b2cf2

50 files changed

Lines changed: 977 additions & 779 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.clang-tidy

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ Checks: '*,
88
-llvm*,
99
-zircon*,
1010
-*use-trailing-return-type,
11-
-*signed-bitwise,
11+
-*signed-bitwise,
1212
-*magic-numbers,
13-
-*vararg,
13+
-*vararg,
1414
-*uppercase-literal-suffix,
15-
-*type-union-access'
15+
-*type-union-access,
16+
-*readability-identifier-length'
1617
WarningsAsErrors: ''
1718
HeaderFilterRegex: ''
18-
AnalyzeTemporaryDtors: false
1919
FormatStyle: llvm

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,8 @@ CMakeSettings.json
2929
CMakeUserPresets.json
3030
compile_commands.json
3131

32+
# ctest
33+
Testing
34+
3235
# Git
3336
*.stackdump
157 KB
Loading

external/abcg/abcgApplication.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ abcg::Application::Application([[maybe_unused]] int argc, char **argv) {
5656
argv_str.substr(0, argv_str.find_last_of('/'));
5757
#endif
5858

59-
abcg::Application::m_assetsPath = abcg::Application::m_basePath + "/assets/";
59+
abcg::Application::m_assetsPath = abcg::Application::m_basePath / "assets/";
6060
}
6161

6262
/**
@@ -77,8 +77,7 @@ void abcg::Application::run(Window &window) {
7777
SDL_SetHint(SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR, "1");
7878
SDL_SetHint(SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR, "1");
7979

80-
if (Uint32 const subsystemMask{SDL_INIT_VIDEO};
81-
!SDL_Init(subsystemMask)) {
80+
if (Uint32 const subsystemMask{SDL_INIT_VIDEO}; !SDL_Init(subsystemMask)) {
8281
throw abcg::SDLError("SDL_Init failed");
8382
}
8483

@@ -114,7 +113,7 @@ void abcg::Application::run(Window &window) {
114113
*
115114
* @sa abcg::Application::getBasePath
116115
*/
117-
std::string const &abcg::Application::getAssetsPath() noexcept {
116+
std::filesystem::path const &abcg::Application::getAssetsPath() noexcept {
118117
return m_assetsPath;
119118
}
120119

@@ -130,16 +129,17 @@ std::string const &abcg::Application::getAssetsPath() noexcept {
130129
*
131130
* @remark The returned path does not end with a slash.
132131
*/
133-
std::string const &abcg::Application::getBasePath() noexcept {
132+
std::filesystem::path const &abcg::Application::getBasePath() noexcept {
134133
return m_basePath;
135134
}
136135

137136
void abcg::Application::mainLoopIterator([[maybe_unused]] bool &done) const {
138137
SDL_Event event{};
139-
while (SDL_PollEvent(&event) != 0) {
138+
while (static_cast<int>(SDL_PollEvent(&event)) != 0) {
140139
#if !defined(__EMSCRIPTEN__)
141-
if (event.type == SDL_EVENT_QUIT)
140+
if (event.type == SDL_EVENT_QUIT) {
142141
done = true;
142+
}
143143
#endif
144144
m_window->templateHandleEvent(event, done);
145145
}

external/abcg/abcgApplication.hpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
#ifndef ABCG_APPLICATION_HPP_
1212
#define ABCG_APPLICATION_HPP_
1313

14-
#include <string>
14+
#include <filesystem>
1515

1616
#define ABCG_VERSION_MAJOR 3
1717
#define ABCG_VERSION_MINOR 1
18-
#define ABCG_VERSION_PATCH 1
18+
#define ABCG_VERSION_PATCH 3
1919

2020
/**
2121
* @brief Root namespace.
@@ -40,8 +40,8 @@ class abcg::Application {
4040

4141
void run(Window &window);
4242

43-
static std::string const &getAssetsPath() noexcept;
44-
static std::string const &getBasePath() noexcept;
43+
static std::filesystem::path const &getAssetsPath() noexcept;
44+
static std::filesystem::path const &getBasePath() noexcept;
4545

4646
private:
4747
void mainLoopIterator(bool &done) const;
@@ -52,11 +52,8 @@ class abcg::Application {
5252
friend void mainLoopCallback(void *userData);
5353
#endif
5454

55-
// NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables)
56-
// See https://bugs.llvm.org/show_bug.cgi?id=48040
57-
static inline std::string m_assetsPath;
58-
static inline std::string m_basePath;
59-
// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
55+
static inline std::filesystem::path m_assetsPath;
56+
static inline std::filesystem::path m_basePath;
6057
};
6158

6259
#endif

external/abcg/abcgException.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ abcg::RuntimeError::RuntimeError(std::string_view what,
4646
std::string
4747
abcg::RuntimeError::prettyPrint(std::string_view what,
4848
source_location const &sourceLocation) {
49-
return toRedString(what.data()) + " in " + sourceLocation.file_name() + ":" +
49+
return toRedString(what) + " in " + sourceLocation.file_name() + ":" +
5050
std::to_string(sourceLocation.line()) + ", " +
5151
toYellowString(sourceLocation.function_name()) + "\n";
5252
}
@@ -66,7 +66,7 @@ abcg::SDLError::SDLError(std::string_view what,
6666

6767
std::string abcg::SDLError::prettyPrint(std::string_view what,
6868
source_location const &sourceLocation) {
69-
return toRedString(what.data()) + " (" + SDL_GetError() + ") in " +
69+
return toRedString(what) + " (" + SDL_GetError() + ") in " +
7070
sourceLocation.file_name() + ":" +
7171
std::to_string(sourceLocation.line()) + ", " +
7272
toYellowString(sourceLocation.function_name()) + "\n";
@@ -76,14 +76,14 @@ abcg::RuntimeError::RuntimeError(std::string_view what)
7676
: Exception(prettyPrint(what)) {}
7777

7878
std::string abcg::RuntimeError::prettyPrint(std::string_view what) {
79-
return toRedString(what.data()) + "\n";
79+
return toRedString(what) + "\n";
8080
}
8181

8282
abcg::SDLError::SDLError(std::string_view what)
8383
: Exception(prettyPrint(what)) {}
8484

8585
std::string abcg::SDLError::prettyPrint(std::string_view what) {
86-
return toRedString(what.data()) + " (" + SDL_GetError() + ")\n";
86+
return toRedString(what) + " (" + SDL_GetError() + ")\n";
8787
}
8888

8989
#endif

external/abcg/abcgException.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ using source_location = std::source_location;
3131
#endif
3232
#endif
3333

34+
#include <stdexcept>
3435
#include <string>
3536

3637
namespace abcg {
@@ -51,7 +52,7 @@ class abcg::Exception : public std::exception {
5152
[[nodiscard]] char const *what() const noexcept override;
5253

5354
private:
54-
std::string m_what{};
55+
std::string m_what;
5556
};
5657

5758
/**

external/abcg/abcgImage.cpp

Lines changed: 89 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12,80 +12,126 @@
1212

1313
#include <cppitertools/itertools.hpp>
1414
#include <fmt/format.h>
15+
#include <gsl/gsl>
1516
#define STB_IMAGE_IMPLEMENTATION
1617
#include <stb_image.h>
1718

19+
#include <span>
20+
1821
#include "abcgException.hpp"
1922

2023
/**
21-
* @brief Loads an image from disk using stb_image.
24+
* @brief Constructs a new abcg::Image.
2225
*
2326
* Loads the file at the given path and decodes it into raw pixel data.
2427
* Optionally forces a specific number of channels.
2528
*
2629
* @param path Filesystem path to the image file.
2730
*
28-
* @param forceChannels Number of channels to force (e.g., 3 or 4). Pass 0
29-
* to preserve the file's original channels (default).
31+
* @param layout Channel layout. Use abcg::Image::ChannelLayout::FromFile
32+
* to preserve the file's original layout (default).
3033
*
3134
* @throw abcg::RuntimeError If the file cannot be opened or decoded.
35+
*/
36+
abcg::Image::Image(std::filesystem::path const &path, ChannelLayout layout) {
37+
loadImage(path, layout);
38+
}
39+
40+
/**
41+
* @brief Returns the dimensions (width, height, channel count) of the image.
42+
*
43+
* @returns Image dimensions.
44+
*/
45+
abcg::Image::Dimensions const &abcg::Image::dimensions() const noexcept {
46+
return m_dimensions;
47+
}
48+
49+
/**
50+
* @brief Returns a mutable span of the image data.
51+
*
52+
* @returns Image data in row-major order and interleaved (size = width *
53+
* height * channels).
54+
*/
55+
std::span<std::uint8_t> abcg::Image::data() noexcept { return m_data; }
56+
57+
/**
58+
* @brief Returns a view (immutable span) of the image data.
3259
*
33-
* @return A fully populated Image structure containing width, height, channel
34-
* count, and pixel data.
60+
* @returns Image data in row-major order and interleaved (size = width *
61+
* height * channels).
3562
*/
36-
abcg::Image abcg::loadImage(std::string_view path, int forceChannels) {
37-
int w{}, h{}, c{};
38-
auto *pixels{stbi_load(path.data(), &w, &h, &c, forceChannels)};
39-
if (!pixels) {
63+
std::span<std::uint8_t const> abcg::Image::data() const noexcept {
64+
return m_data;
65+
}
66+
67+
void abcg::Image::loadImage(std::filesystem::path const &path,
68+
ChannelLayout layout) {
69+
using StbiDeleter = decltype(&stbi_image_free);
70+
using StbiPtr = std::unique_ptr<stbi_uc, StbiDeleter>;
71+
72+
auto const requestedChannels{static_cast<int>(layout)};
73+
74+
int width{};
75+
int height{};
76+
int channels{};
77+
StbiPtr rawPixels{
78+
stbi_load(path.c_str(), &width, &height, &channels, requestedChannels),
79+
stbi_image_free};
80+
if (!rawPixels) {
4081
throw abcg::RuntimeError(
41-
fmt::format("Failed to load texture file {}", path));
82+
fmt::format("Failed to load image file {}", path.string()));
4283
}
4384

44-
Image img{};
45-
img.width = w;
46-
img.height = h;
47-
img.channels = (forceChannels != 0 ? forceChannels : c);
48-
img.data.assign(pixels, pixels + (w * h * img.channels));
49-
stbi_image_free(pixels);
85+
auto const actualChannels{
86+
(layout != ChannelLayout::FromFile ? requestedChannels : channels)};
87+
m_dimensions = Dimensions{.width = gsl::narrow<size_t>(width),
88+
.height = gsl::narrow<size_t>(height),
89+
.channels = gsl::narrow<size_t>(actualChannels)};
5090

51-
return img;
91+
auto const sizeInBytes{m_dimensions.width * m_dimensions.height *
92+
m_dimensions.channels};
93+
std::span<stbi_uc const> const pixels{rawPixels.get(), sizeInBytes};
94+
95+
m_data.assign(pixels.begin(), pixels.end());
5296
}
5397

5498
/**
55-
* @brief Flips an image horizontally.
56-
*
57-
* Flips the image horizontally by swapping pixels across the vertical axis.
58-
* This mirrors each scanline left-to-right in-place.
99+
* @brief Flips the image vertically.
59100
*
60-
* @param img Image data loaded with abcg::loadImage.
101+
* Flips the image vertically by swapping entire scanlines.
102+
* This mirrors the image top-to-bottom in-place.
61103
*/
62-
void abcg::flipHorizontally(Image &img) {
63-
auto const rowStride{img.width * img.channels};
64-
for (auto const y : iter::range(img.height)) {
65-
auto *row{img.data.data() + y * rowStride};
66-
for (auto const x : iter::range(img.width / 2)) {
67-
auto *left{row + x * img.channels};
68-
auto *right{row + (img.width - 1 - x) * img.channels};
69-
for (auto const c : iter::range(img.channels)) {
70-
std::swap(left[c], right[c]);
71-
}
72-
}
104+
void abcg::Image::flipVertically() noexcept {
105+
auto const &[width, height, channels]{m_dimensions};
106+
auto const rowStride{width * channels};
107+
auto const halfHeight{height / 2};
108+
auto const img{std::span{m_data}};
109+
for (auto const y : iter::range(halfHeight)) {
110+
auto const top{img.subspan(y * rowStride, rowStride)};
111+
auto const bottom{img.subspan((height - 1 - y) * rowStride, rowStride)};
112+
std::ranges::swap_ranges(top, bottom);
73113
}
74114
}
75115

76116
/**
77-
* @brief Flips an image vertically.
117+
* @brief Flips the image horizontally.
78118
*
79-
* Flips the image vertically by swapping entire scanlines.
80-
* This mirrors the image top-to-bottom in-place.
119+
* Flips the image horizontally by swapping pixels across the vertical axis.
120+
* This mirrors each scanline left-to-right in-place.
81121
*
82122
* @param img Image data loaded with abcg::loadImage.
83123
*/
84-
void abcg::flipVertically(Image &img) {
85-
auto const rowStride{img.width * img.channels};
86-
for (auto const y : iter::range(img.height / 2)) {
87-
auto *top{img.data.data() + y * rowStride};
88-
auto *bottom{img.data.data() + (img.height - 1 - y) * rowStride};
89-
std::swap_ranges(top, top + rowStride, bottom);
124+
void abcg::Image::flipHorizontally() noexcept {
125+
auto const &[width, height, channels]{m_dimensions};
126+
auto const rowStride{width * channels};
127+
auto const halfWidth{width / 2};
128+
auto const img{std::span{m_data}};
129+
for (auto const y : iter::range(height)) {
130+
auto const row{img.subspan(y * rowStride, rowStride)};
131+
for (auto const x : iter::range(halfWidth)) {
132+
auto const left{row.subspan(x * channels, channels)};
133+
auto const right{row.subspan((width - 1 - x) * channels, channels)};
134+
std::ranges::swap_ranges(left, right);
135+
}
90136
}
91-
}
137+
}

0 commit comments

Comments
 (0)