Skip to content

Commit 9ae096f

Browse files
committed
Created ResourceManager class, Improved efficiency
Use ResourceManager to load and manage fonts and textures. This removes the need for constant calling of getRenderer from RenderWindow.hpp It also reduces code for fixing memory leak. Rather than manually freeing the memory for each texture, the ResourceManager class handles it automatically when the program exits. ResourceManager also uses an unordered_map to cache loaded textures and fonts, improving efficiency by avoiding redundant loading operations. The file size of Meowstro.cpp has decreased a bit thanks to this but there are still many more improvements needed to dismantle the code and make it more modular, maintainable, and testable.
1 parent 64d962f commit 9ae096f

File tree

8 files changed

+187
-146
lines changed

8 files changed

+187
-146
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ set(SOURCES
4040
src/Font.cpp
4141
src/Sprite.cpp
4242
src/GameStats.cpp
43+
src/ResourceManager.cpp
4344
)
4445

4546
set(HEADERS
@@ -50,6 +51,7 @@ set(HEADERS
5051
include/Font.hpp
5152
include/Sprite.hpp
5253
include/GameStats.hpp
54+
include/ResourceManager.hpp
5355
)
5456

5557
add_executable(meowstro ${SOURCES} ${HEADERS})

include/Font.hpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,8 @@ Description: Font class, handles the logic when rendering a true type font text
55
*/
66
#ifndef FONT_H
77
#define FONT_H
8-
/*
9-
It is very important to note that I didn't download the necessary library (ttf) in order to work.
10-
Nor have I downloaded the font that we decided to use for the project, that being Comic Sans.
11-
As I was literally passing out while writing this because it was so late and rarely have time.
12-
This also explains why there is no driver file to test, again, passing out, so hypothetically this should work.
13-
*/
14-
#include <SDL.h> // Not sure if this needs to be .hpp, again, verge of passing out
8+
9+
#include <SDL.h>
1510
#include <SDL_ttf.h>
1611
#include <string>
1712

@@ -21,7 +16,7 @@ class Font
2116
{
2217
public:
2318
Font(); // Basic Constructor
24-
~Font(); // Destructor (fancy)
19+
~Font(); // Destructor
2520
bool load(const string& fontPath, int fontSz); // Allows us to add a font file
2621
void unload(); // Clean up (or unload) the font
2722

include/RenderWindow.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
#pragma once
22
#include <SDL.h>
3-
#include <SDL_image.h>
43
#include "Entity.hpp"
54

65
class RenderWindow
76
{
87
public:
98
RenderWindow(const char *title, int w, int h, Uint32 windowFlags = SDL_WINDOW_SHOWN);
10-
SDL_Texture *loadTexture(const char *filePath);
119
void clear();
1210
void render(Entity& entity);
1311
void display();

include/ResourceManager.hpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#pragma once
2+
3+
#include <SDL.h>
4+
#include <SDL_image.h>
5+
#include <unordered_map>
6+
#include <string>
7+
#include "Font.hpp"
8+
9+
class ResourceManager {
10+
public:
11+
ResourceManager(SDL_Renderer* renderer);
12+
~ResourceManager();
13+
14+
// Texture management
15+
SDL_Texture* loadTexture(const std::string& filePath);
16+
SDL_Texture* createTextTexture(const std::string& fontPath, int fontSize, const std::string& text, SDL_Color color);
17+
18+
// Font management
19+
Font* getFont(const std::string& fontPath, int fontSize);
20+
21+
// Manual cleanup (called automatically in destructor)
22+
void cleanup();
23+
24+
private:
25+
SDL_Renderer* renderer;
26+
std::unordered_map<std::string, SDL_Texture*> textures;
27+
std::unordered_map<std::string, Font*> fonts;
28+
29+
// Helper to generate unique keys
30+
std::string generateFontKey(const std::string& fontPath, int fontSize) const;
31+
std::string generateTextKey(const std::string& fontPath, int fontSize, const std::string& text, SDL_Color color) const;
32+
};

src/Font.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33

44
using namespace std;
55

6-
Font::Font() : font(nullptr) {} // Init ptr 2 nullptr
6+
Font::Font() : font(nullptr) {}
77

88
Font::~Font()
99
{
10-
unload(); // Makin sure memory is nice n tidy
10+
unload();
1111
}
1212

1313
bool Font::load(const string& fontPath, int fontSz)

src/RenderWindow.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,6 @@ RenderWindow::RenderWindow(const char *title, int w, int h, Uint32 windowFlags)
1313
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
1414
SDL_SetRenderDrawColor(renderer, 100, 115, 180, 185);
1515
}
16-
17-
SDL_Texture *RenderWindow::loadTexture(const char *filePath)
18-
{
19-
SDL_Texture *texture = NULL;
20-
texture = IMG_LoadTexture(renderer, filePath);
21-
22-
if (texture == NULL)
23-
std::cout << "IMG_LoadTexture failed. ERROR: " << SDL_GetError() << std::endl;
24-
25-
return texture;
26-
}
2716
void RenderWindow::clear()
2817
{
2918
SDL_RenderClear(renderer);

src/ResourceManager.cpp

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include "ResourceManager.hpp"
2+
#include <iostream>
3+
4+
ResourceManager::ResourceManager(SDL_Renderer* renderer) : renderer(renderer) {}
5+
6+
ResourceManager::~ResourceManager() {
7+
cleanup();
8+
}
9+
10+
SDL_Texture* ResourceManager::loadTexture(const std::string& filePath) {
11+
// Check if texture already loaded
12+
auto it = textures.find(filePath);
13+
if (it != textures.end()) {
14+
return it->second;
15+
}
16+
17+
// Load new texture
18+
SDL_Texture* texture = IMG_LoadTexture(renderer, filePath.c_str());
19+
if (!texture) {
20+
std::cerr << "Failed to load texture: " << filePath << " SDL_Error: " << SDL_GetError() << std::endl;
21+
return nullptr;
22+
}
23+
24+
// Cache the texture
25+
textures[filePath] = texture;
26+
return texture;
27+
}
28+
29+
SDL_Texture* ResourceManager::createTextTexture(const std::string& fontPath, int fontSize, const std::string& text, SDL_Color color) {
30+
std::string textKey = generateTextKey(fontPath, fontSize, text, color);
31+
32+
// Check if text texture already exists
33+
auto it = textures.find(textKey);
34+
if (it != textures.end()) {
35+
return it->second;
36+
}
37+
38+
// Get or load font
39+
Font* font = getFont(fontPath, fontSize);
40+
if (!font) {
41+
return nullptr;
42+
}
43+
44+
// Create text texture
45+
SDL_Texture* textTexture = font->renderText(renderer, text, color);
46+
if (textTexture) {
47+
textures[textKey] = textTexture;
48+
}
49+
50+
return textTexture;
51+
}
52+
53+
Font* ResourceManager::getFont(const std::string& fontPath, int fontSize) {
54+
std::string fontKey = generateFontKey(fontPath, fontSize);
55+
56+
// Check if font already loaded
57+
auto it = fonts.find(fontKey);
58+
if (it != fonts.end()) {
59+
return it->second;
60+
}
61+
62+
// Load new font
63+
Font* font = new Font();
64+
if (!font->load(fontPath, fontSize)) {
65+
delete font;
66+
return nullptr;
67+
}
68+
69+
// Cache the font
70+
fonts[fontKey] = font;
71+
return font;
72+
}
73+
74+
void ResourceManager::cleanup() {
75+
// Clean up all textures
76+
for (auto& pair : textures) {
77+
if (pair.second) {
78+
SDL_DestroyTexture(pair.second);
79+
}
80+
}
81+
textures.clear();
82+
83+
// Clean up all fonts
84+
for (auto& pair : fonts) {
85+
if (pair.second) {
86+
delete pair.second;
87+
}
88+
}
89+
fonts.clear();
90+
}
91+
92+
std::string ResourceManager::generateFontKey(const std::string& fontPath, int fontSize) const {
93+
return fontPath + "_" + std::to_string(fontSize);
94+
}
95+
96+
std::string ResourceManager::generateTextKey(const std::string& fontPath, int fontSize, const std::string& text, SDL_Color color) const {
97+
return fontPath + "_" + std::to_string(fontSize) + "_" + text + "_" +
98+
std::to_string(color.r) + "_" + std::to_string(color.g) + "_" +
99+
std::to_string(color.b) + "_" + std::to_string(color.a);
100+
}

0 commit comments

Comments
 (0)