Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use std::string_view in unordered_maps for Sprite and Texture, fix #27 #77

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/ImageDataWebP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,26 @@
#include "ImageDataWebP.hpp"

#include <cmath>
#include <format>
#include <future>
#include <thread>
#include <vector>

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<uint8_t> 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);
Expand Down
2 changes: 1 addition & 1 deletion src/ImageDataWebP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
48 changes: 24 additions & 24 deletions src/jngl/sprite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#if __cplusplus < 202002L
#include <boost/algorithm/string/predicate.hpp>
#endif
#include <format>
#include <sstream>
#include <thread>
#ifndef NOWEBP
Expand All @@ -35,7 +36,7 @@

namespace jngl {

std::shared_ptr<Texture> getTexture(const std::string& filename) {
std::shared_ptr<Texture> getTexture(std::string_view filename) {
auto it = textures.find(filename);
if (it == textures.end()) {
return nullptr;
Expand Down Expand Up @@ -63,7 +64,7 @@ Sprite::Sprite(const ImageData& imageData, double scale, std::optional<std::stri
}
}

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();
Expand All @@ -76,7 +77,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",
Expand All @@ -86,7 +87,7 @@ Sprite::Sprite(const std::string& filename, LoadType loadType) : texture(getText
#endif
".bmp"
};
std::function<Finally(Sprite*, std::string, FILE*, bool)> functions[] = {
std::function<Finally(Sprite*, std::string_view, FILE*, bool)> functions[] = {
#ifndef NOWEBP
&Sprite::LoadWebP,
#endif
Expand All @@ -96,7 +97,7 @@ Sprite::Sprite(const std::string& filename, LoadType loadType) : texture(getText
&Sprite::LoadBMP
};
const size_t size = sizeof(extensions) / sizeof(extensions[0]);
std::function<Finally(Sprite*, std::string, FILE*, bool)> loadFunction;
std::function<Finally(Sprite*, std::string_view, FILE*, bool)> loadFunction;
for (size_t i = 0; i < size; ++i) {
#if __cplusplus < 202002L
if (boost::algorithm::ends_with(fullFilename, extensions[i])) {
Expand Down Expand Up @@ -277,30 +278,30 @@ 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];

// 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);
Expand All @@ -322,8 +323,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]() {
Expand All @@ -345,20 +345,20 @@ void Sprite::cleanUpRowPointers(std::vector<unsigned char*>& 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;
Expand All @@ -373,19 +373,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));
}
}
}
Expand All @@ -395,7 +395,7 @@ Finally Sprite::LoadBMP(const std::string& filename, FILE* const fp, const bool
return Finally(nullptr);
}
#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<ImageDataWebP>(filename, file, getScaleFactor());
width = static_cast<float>(imageData->getImageWidth() * getScaleFactor());
height = static_cast<float>(imageData->getImageHeight() * getScaleFactor());
Expand All @@ -406,15 +406,15 @@ 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) {
if (!pWindow) {
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<Texture>(width, height, scaledWidth, scaledHeight, rowPointers,
format, data);
Expand Down
13 changes: 7 additions & 6 deletions src/jngl/sprite.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "Vec2.hpp"

#include <future>
#include <string_view>
#include <optional>
#include <vector>

Expand Down Expand Up @@ -51,7 +52,7 @@ class Sprite : public Drawable {
std::optional<std::string_view> filename = std::nullopt);

/// \deprecated Use Loader instead
explicit Sprite(const std::string& filename, LoadType loadType = LoadType::NORMAL);
explicit Sprite(std::string_view filename, LoadType loadType = LoadType::NORMAL);

/// Does nothing
void step() override;
Expand Down Expand Up @@ -160,10 +161,10 @@ class Sprite : public Drawable {

private:
static void cleanUpRowPointers(std::vector<unsigned char*>& 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;
Expand All @@ -174,15 +175,15 @@ 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 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> texture;
};

void draw(const std::string& filename, double x, double y);
void draw(std::string_view filename, double x, double y);

template <class Vect> void draw(const std::string& filename, Vect pos) {
draw(filename, pos.x, pos.y);
Expand Down
6 changes: 3 additions & 3 deletions src/spriteimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ void setSpriteAlpha(unsigned char alpha) {
gSpriteColor.setAlpha(Alpha::u8(alpha));
}

std::unordered_map<std::string, std::shared_ptr<Sprite>> sprites_;
std::unordered_map<std::string_view, std::shared_ptr<Sprite>> 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) {
Expand All @@ -59,7 +59,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();
Expand Down
2 changes: 1 addition & 1 deletion src/spriteimpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 Rgba gSpriteColor;
extern Rgba gShapeColor;
Expand Down
2 changes: 1 addition & 1 deletion src/texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

namespace jngl {

std::unordered_map<std::string, std::shared_ptr<Texture>> textures;
std::unordered_map<std::string_view, std::shared_ptr<Texture>> textures;

ShaderProgram* Texture::textureShaderProgram = nullptr;
Shader* Texture::textureVertexShader = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion src/texture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@ class Texture {
std::vector<GLfloat> vertexes;
};

extern std::unordered_map<std::string, std::shared_ptr<Texture>> textures;
extern std::unordered_map<std::string_view, std::shared_ptr<Texture>> textures;

} // namespace jngl
Loading