Skip to content

Commit

Permalink
Use std::string_view in unordered_maps for Sprite and Texture, fix #27
Browse files Browse the repository at this point in the history
  • Loading branch information
jhasse committed May 17, 2022
1 parent b2bf07e commit b0fd5a4
Show file tree
Hide file tree
Showing 9 changed files with 39 additions and 38 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand Down
8 changes: 4 additions & 4 deletions src/ImageDataWebP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<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
38 changes: 19 additions & 19 deletions src/jngl/sprite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ extern "C" {

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 @@ -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();
Expand All @@ -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",
Expand All @@ -100,7 +100,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 @@ -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<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 (boost::algorithm::ends_with(fullFilename, extensions[i])) {
loadFunction = functions[i];
Expand Down Expand Up @@ -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];

Expand Down Expand Up @@ -299,20 +299,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 @@ -327,27 +327,27 @@ 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));
}
}
}
loadTexture(header.width, header.height, filename, halfLoad, GL_BGR, &buf[0]);
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);
Expand Down Expand Up @@ -395,7 +395,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<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
15 changes: 8 additions & 7 deletions src/jngl/sprite.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "ShaderProgram.hpp"
#include "Vec2.hpp"

#include <string_view>
#include <vector>

namespace jngl {
Expand All @@ -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;

Expand Down Expand Up @@ -72,10 +73,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 @@ -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> 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 @@ -47,11 +47,11 @@ void setSpriteAlpha(unsigned char alpha) {
setSpriteColor(spriteColorRed, spriteColorGreen, spriteColorBlue, 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 @@ -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();
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 unsigned char spriteColorRed, spriteColorGreen, spriteColorBlue, spriteColorAlpha,
colorRed, colorGreen, colorBlue, colorAlpha;
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 @@ -52,6 +52,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

0 comments on commit b0fd5a4

Please sign in to comment.