From 3ca54f3ad493f4eb34b1f01d3dc9fc45b9815fb1 Mon Sep 17 00:00:00 2001 From: Jan Niklas Hasse Date: Tue, 17 May 2022 19:19:27 +0200 Subject: [PATCH 1/4] Use std::string_view in unordered_maps for Sprite and Texture, fix #27 --- CMakeLists.txt | 2 +- src/ImageDataWebP.cpp | 8 ++++---- src/ImageDataWebP.hpp | 2 +- src/jngl/sprite.cpp | 41 ++++++++++++++++++++--------------------- src/jngl/sprite.hpp | 15 ++++++++------- src/spriteimpl.cpp | 6 +++--- src/spriteimpl.hpp | 2 +- src/texture.cpp | 2 +- src/texture.hpp | 2 +- 9 files changed, 40 insertions(+), 40 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e9f4da609..27916f187 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(jngl ${SRC}) file(GLOB HEADERS src/*.hpp src/jngl/*.hpp) target_sources(jngl PRIVATE ${HEADERS}) -target_compile_features(jngl PUBLIC cxx_std_17) +target_compile_features(jngl PUBLIC cxx_std_20) set_target_properties(jngl PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/src/ diff --git a/src/ImageDataWebP.cpp b/src/ImageDataWebP.cpp index 649895982..26a02af3f 100644 --- a/src/ImageDataWebP.cpp +++ b/src/ImageDataWebP.cpp @@ -10,19 +10,19 @@ namespace jngl { -ImageDataWebP::ImageDataWebP(std::string filename, FILE* file, double scaleFactor) -: filename(std::move(filename)) { +ImageDataWebP::ImageDataWebP(std::string_view filename, FILE* file, double scaleFactor) +: filename(filename) { fseek(file, 0, SEEK_END); auto filesize = ftell(file); fseek(file, 0, SEEK_SET); std::vector buf(filesize); if (!fread(&buf[0], filesize, 1, file)) { - throw std::runtime_error(std::string("Couldn't open WebP file. (" + this->filename + ")")); + throw std::runtime_error(std::format("Couldn't open WebP file. ({})", filename)); } if (!WebPGetInfo(&buf[0], filesize, &imgWidth, &imgHeight)) { - throw std::runtime_error(std::string("Invalid WebP file. (" + this->filename + ")")); + throw std::runtime_error(std::format("Invalid WebP file. ({})", filename)); } WebPInitDecoderConfig(&config); diff --git a/src/ImageDataWebP.hpp b/src/ImageDataWebP.hpp index c58e65ac3..0a2fa64c8 100644 --- a/src/ImageDataWebP.hpp +++ b/src/ImageDataWebP.hpp @@ -11,7 +11,7 @@ namespace jngl { class ImageDataWebP : public ImageData { public: - ImageDataWebP(std::string filename, FILE*, double scaleFactor); + ImageDataWebP(std::string_view filename, FILE*, double scaleFactor); ~ImageDataWebP() override; ImageDataWebP(const ImageDataWebP&) = delete; ImageDataWebP& operator=(const ImageDataWebP&) = delete; diff --git a/src/jngl/sprite.cpp b/src/jngl/sprite.cpp index 09670342d..d9bc31c92 100644 --- a/src/jngl/sprite.cpp +++ b/src/jngl/sprite.cpp @@ -41,7 +41,7 @@ extern "C" { namespace jngl { -std::shared_ptr getTexture(const std::string& filename) { +std::shared_ptr getTexture(std::string_view filename) { auto it = textures.find(filename); if (it == textures.end()) { return nullptr; @@ -74,7 +74,7 @@ Sprite::Sprite(const unsigned char* const bytes, const size_t width, const size_ setCenter(0, 0); } -Sprite::Sprite(const std::string& filename, LoadType loadType) : texture(getTexture(filename)) { +Sprite::Sprite(std::string_view filename, LoadType loadType) : texture(getTexture(filename)) { if (texture) { width = texture->getPreciseWidth(); height = texture->getPreciseHeight(); @@ -87,7 +87,7 @@ Sprite::Sprite(const std::string& filename, LoadType loadType) : texture(getText jngl::debug(filename); jngl::debug("... "); } - auto fullFilename = pathPrefix + filename; + auto fullFilename = std::format("{}{}", pathPrefix, filename); const char* extensions[] = { #ifndef NOWEBP ".webp", @@ -100,7 +100,7 @@ Sprite::Sprite(const std::string& filename, LoadType loadType) : texture(getText #endif ".bmp" }; - std::function functions[] = { + std::function functions[] = { #ifndef NOWEBP &Sprite::LoadWebP, #endif @@ -113,7 +113,7 @@ Sprite::Sprite(const std::string& filename, LoadType loadType) : texture(getText &Sprite::LoadBMP }; const size_t size = sizeof(extensions) / sizeof(extensions[0]); - std::function loadFunction; + std::function loadFunction; for (size_t i = 0; i < size; ++i) { if (boost::algorithm::ends_with(fullFilename, extensions[i])) { loadFunction = functions[i]; @@ -231,7 +231,7 @@ const Shader& Sprite::vertexShader() { } #ifndef NOPNG -Finally Sprite::LoadPNG(const std::string& filename, FILE* const fp, const bool halfLoad) { +Finally Sprite::LoadPNG(std::string_view filename, FILE* const fp, const bool halfLoad) { const unsigned int PNG_BYTES_TO_CHECK = 4; png_byte buf[PNG_BYTES_TO_CHECK]; @@ -276,8 +276,7 @@ Finally Sprite::LoadPNG(const std::string& filename, FILE* const fp, const bool format = GL_RGBA; break; default: - throw std::runtime_error( - std::string("Unsupported number of channels. (" + filename + ")")); + throw std::runtime_error(std::format("Unsupported number of channels. ({})", filename)); } Finally freePng([&png_ptr, &info_ptr]() { @@ -299,20 +298,20 @@ void Sprite::cleanUpRowPointers(std::vector& buf) { } } -Finally Sprite::LoadBMP(const std::string& filename, FILE* const fp, const bool halfLoad) { +Finally Sprite::LoadBMP(std::string_view filename, FILE* const fp, const bool halfLoad) { fseek(fp, 10, SEEK_SET); BMPHeader header{}; if (!fread(&header, sizeof(header), 1, fp)) { - throw std::runtime_error(std::string("Error reading file. (" + filename + ")")); + throw std::runtime_error(std::format("Error reading file. ({})", filename)); } if (header.headerSize != 40) { - throw std::runtime_error(std::string("Unsupported header size. (" + filename + ")")); + throw std::runtime_error(std::format("Unsupported header size. ({})", filename)); } if (header.bpp != 24) { - throw std::runtime_error(std::string("Bpp not supported. (" + filename + ")")); + throw std::runtime_error(std::format("Bpp not supported. ({})", filename)); } if (header.compression != 0) { - throw std::runtime_error(std::string("Compression not supported. (" + filename + ")")); + throw std::runtime_error(std::format("Compression not supported. ({})", filename)); } if (header.dataSize == 0) { header.dataSize = header.width * header.height * 3; @@ -327,19 +326,19 @@ Finally Sprite::LoadBMP(const std::string& filename, FILE* const fp, const bool header.height = -header.height; for (int i = 0; i < header.height; ++i) { if (fseek(fp, header.dataOffset + i * header.width * 3, SEEK_SET) != 0) { - throw std::runtime_error(std::string("Error reading file. (" + filename + ")")); + throw std::runtime_error(std::format("Error reading file. ({})", filename)); } if (!fread(buf[i], header.width * 3, 1, fp)) { - throw std::runtime_error(std::string("Error reading data. (" + filename + ")")); + throw std::runtime_error(std::format("Error reading data. ({})", filename)); } } } else { // "bottom-up"-Bitmap for (int i = header.height - 1; i >= 0; --i) { if (fseek(fp, header.dataOffset + i * header.width * 3, SEEK_SET) != 0) { - throw std::runtime_error(std::string("Error reading file. (" + filename + ")")); + throw std::runtime_error(std::format("Error reading file. ({})", filename)); } if (!fread(buf[(header.height - 1) - i], header.width * 3, 1, fp)) { - throw std::runtime_error(std::string("Error reading data. (" + filename + ")")); + throw std::runtime_error(std::format("Error reading data. ({})", filename)); } } } @@ -347,7 +346,7 @@ Finally Sprite::LoadBMP(const std::string& filename, FILE* const fp, const bool return Finally(nullptr); } #ifndef NOJPEG -Finally Sprite::LoadJPG(const std::string& filename, FILE* file, const bool halfLoad) { +Finally Sprite::LoadJPG(std::string_view filename, FILE* file, const bool halfLoad) { jpeg_decompress_struct info{}; JpegErrorMgr err{}; info.err = jpeg_std_error(&err.pub); @@ -395,7 +394,7 @@ Finally Sprite::LoadJPG(const std::string& filename, FILE* file, const bool half } #endif #ifndef NOWEBP -Finally Sprite::LoadWebP(const std::string& filename, FILE* file, const bool halfLoad) { +Finally Sprite::LoadWebP(std::string_view filename, FILE* file, const bool halfLoad) { auto imageData = std::make_shared(filename, file, getScaleFactor()); width = static_cast(imageData->getImageWidth() * getScaleFactor()); height = static_cast(imageData->getImageHeight() * getScaleFactor()); @@ -406,7 +405,7 @@ Finally Sprite::LoadWebP(const std::string& filename, FILE* file, const bool hal } #endif -void Sprite::loadTexture(const int scaledWidth, const int scaledHeight, const std::string& filename, +void Sprite::loadTexture(const int scaledWidth, const int scaledHeight, std::string_view filename, const bool halfLoad, const unsigned int format, const unsigned char* const* const rowPointers, const unsigned char* const data) { @@ -414,7 +413,7 @@ void Sprite::loadTexture(const int scaledWidth, const int scaledHeight, const st if (halfLoad) { return; } - throw std::runtime_error(std::string("Window hasn't been created yet. (" + filename + ")")); + throw std::runtime_error(std::format("Window hasn't been created yet. ({})", filename)); } texture = std::make_shared(width, height, scaledWidth, scaledHeight, rowPointers, format, data); diff --git a/src/jngl/sprite.hpp b/src/jngl/sprite.hpp index dcd04c7fb..7648cf35c 100644 --- a/src/jngl/sprite.hpp +++ b/src/jngl/sprite.hpp @@ -9,6 +9,7 @@ #include "ShaderProgram.hpp" #include "Vec2.hpp" +#include #include namespace jngl { @@ -27,7 +28,7 @@ class Sprite : public Drawable { }; Sprite(const unsigned char* bytes, size_t width, size_t height); - explicit Sprite(const std::string& filename, LoadType loadType = LoadType::NORMAL); + explicit Sprite(std::string_view filename, LoadType loadType = LoadType::NORMAL); void step() override; void draw() const override; @@ -72,10 +73,10 @@ class Sprite : public Drawable { private: static void cleanUpRowPointers(std::vector& buf); - void loadTexture(int scaledWidth, int scaledHeight, const std::string& filename, bool halfLoad, + void loadTexture(int scaledWidth, int scaledHeight, std::string_view filename, bool halfLoad, unsigned int format, const unsigned char* const* rowPointers, const unsigned char* data = nullptr); - Finally LoadPNG(const std::string& filename, FILE* fp, bool halfLoad); + Finally LoadPNG(std::string_view filename, FILE* fp, bool halfLoad); struct BMPHeader { unsigned int dataOffset; unsigned int headerSize; @@ -86,18 +87,18 @@ class Sprite : public Drawable { unsigned int compression; unsigned int dataSize; }; - Finally LoadBMP(const std::string& filename, FILE* fp, bool halfLoad); + Finally LoadBMP(std::string_view filename, FILE* fp, bool halfLoad); #ifndef NOJPEG - Finally LoadJPG(const std::string& filename, FILE* file, bool halfLoad); + Finally LoadJPG(std::string_view filename, FILE* file, bool halfLoad); #endif #ifndef NOWEBP - Finally LoadWebP(const std::string& filename, FILE* file, bool halfLoad); + Finally LoadWebP(std::string_view filename, FILE* file, bool halfLoad); #endif std::shared_ptr texture; }; -void draw(const std::string& filename, double x, double y); +void draw(std::string_view filename, double x, double y); template void draw(const std::string& filename, Vect pos) { draw(filename, pos.x, pos.y); diff --git a/src/spriteimpl.cpp b/src/spriteimpl.cpp index e0078f0a1..d63789c7f 100644 --- a/src/spriteimpl.cpp +++ b/src/spriteimpl.cpp @@ -47,11 +47,11 @@ void setSpriteAlpha(unsigned char alpha) { setSpriteColor(spriteColorRed, spriteColorGreen, spriteColorBlue, alpha); } -std::unordered_map> sprites_; +std::unordered_map> sprites_; // halfLoad is used, if we only want to find out the width or height of an image. Load won't throw // an exception then -Sprite& GetSprite(const std::string& filename, const Sprite::LoadType loadType) { +Sprite& GetSprite(std::string_view filename, const Sprite::LoadType loadType) { auto it = sprites_.find(filename); if (it == sprites_.end()) { // texture hasn't been loaded yet? if (loadType != Sprite::LoadType::HALF) { @@ -63,7 +63,7 @@ Sprite& GetSprite(const std::string& filename, const Sprite::LoadType loadType) return *(it->second); } -void draw(const std::string& filename, double x, double y) { +void draw(std::string_view filename, double x, double y) { auto& s = GetSprite(filename); s.setPos(x, y); s.draw(); diff --git a/src/spriteimpl.hpp b/src/spriteimpl.hpp index 32d7be23b..a7b0cdec3 100644 --- a/src/spriteimpl.hpp +++ b/src/spriteimpl.hpp @@ -9,7 +9,7 @@ namespace jngl { Finally loadSprite(const std::string&); -Sprite& GetSprite(const std::string& filename, Sprite::LoadType loadType = Sprite::LoadType::NORMAL); +Sprite& GetSprite(std::string_view filename, Sprite::LoadType loadType = Sprite::LoadType::NORMAL); extern unsigned char spriteColorRed, spriteColorGreen, spriteColorBlue, spriteColorAlpha, colorRed, colorGreen, colorBlue, colorAlpha; diff --git a/src/texture.cpp b/src/texture.cpp index 97ac0b420..83bc9bff2 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -14,7 +14,7 @@ namespace jngl { -std::unordered_map> textures; +std::unordered_map> textures; ShaderProgram* Texture::textureShaderProgram = nullptr; Shader* Texture::textureVertexShader = nullptr; diff --git a/src/texture.hpp b/src/texture.hpp index f9c504fef..9580d2784 100644 --- a/src/texture.hpp +++ b/src/texture.hpp @@ -52,6 +52,6 @@ class Texture { std::vector vertexes; }; -extern std::unordered_map> textures; +extern std::unordered_map> textures; } // namespace jngl From bb8b58334ddfd5d811d950f653c999669abb5084 Mon Sep 17 00:00:00 2001 From: Jan Niklas Hasse Date: Tue, 17 May 2022 19:19:13 +0200 Subject: [PATCH 2/4] Add #include --- src/ImageDataWebP.cpp | 1 + src/jngl/sprite.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/ImageDataWebP.cpp b/src/ImageDataWebP.cpp index 26a02af3f..528652006 100644 --- a/src/ImageDataWebP.cpp +++ b/src/ImageDataWebP.cpp @@ -4,6 +4,7 @@ #include "ImageDataWebP.hpp" #include +#include #include #include #include diff --git a/src/jngl/sprite.cpp b/src/jngl/sprite.cpp index d9bc31c92..78566f77a 100644 --- a/src/jngl/sprite.cpp +++ b/src/jngl/sprite.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #ifndef NOJPEG From 72521441f7de7509db1a28dec65be28e6fbc28a1 Mon Sep 17 00:00:00 2001 From: Jan Niklas Hasse Date: Fri, 23 Feb 2024 18:06:15 +0100 Subject: [PATCH 3/4] Use std::format in PNG code --- src/jngl/sprite.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/jngl/sprite.cpp b/src/jngl/sprite.cpp index 15e4e5bf9..d92440489 100644 --- a/src/jngl/sprite.cpp +++ b/src/jngl/sprite.cpp @@ -283,23 +283,23 @@ Finally Sprite::LoadPNG(std::string_view filename, FILE* const fp, const bool ha // Read in some of the signature bytes if (fread(buf, 1, PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK || png_sig_cmp(buf, png_size_t(0), PNG_BYTES_TO_CHECK) != 0) { - throw std::runtime_error(std::string("Error reading signature bytes. (" + filename + ")")); + throw std::runtime_error(std::format("Error reading signature bytes. ({})", filename)); } png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); if (!png_ptr) { - throw std::runtime_error(std::string("libpng error while reading (" + filename + ")")); + throw std::runtime_error(std::format("libpng error while reading ({})", filename)); } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { - throw std::runtime_error(std::string("libpng error while reading (" + filename + ")")); + throw std::runtime_error(std::format("libpng error while reading ({})", filename)); } if (setjmp(png_jmpbuf(png_ptr))) { // Free all of the memory associated with the png_ptr and info_ptr png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); - throw std::runtime_error(std::string("Error reading file. (" + filename + ")")); + throw std::runtime_error(std::format("Error reading file. ({})", filename)); } png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); From f314e6393f3236304966c60eb2acc13599db1c12 Mon Sep 17 00:00:00 2001 From: Jan Niklas Hasse Date: Fri, 11 Oct 2024 23:37:47 +0200 Subject: [PATCH 4/4] Fix build after merge --- src/jngl/sprite.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jngl/sprite.cpp b/src/jngl/sprite.cpp index 01351000c..19d85614d 100644 --- a/src/jngl/sprite.cpp +++ b/src/jngl/sprite.cpp @@ -392,7 +392,7 @@ void Sprite::cleanUpRowPointers(std::vector& buf) { Finally Sprite::LoadBMP(std::string_view filename, FILE* const fp, const bool halfLoad) { if (fseek(fp, 10, SEEK_SET) != 0) { - throw std::runtime_error(std::string("Error seeking file. (" + filename + ")")); + throw std::runtime_error(std::format("Error seeking file. ({})", filename)); } BMPHeader header{}; if (!fread(&header, sizeof(header), 1, fp)) {