Added default font and exception throwing to replace some nullptr returns

This commit is contained in:
2021-12-11 12:10:56 -05:00
parent d2826f08fe
commit 10e2b3c538
10 changed files with 62 additions and 22 deletions

View File

@@ -1,6 +1,12 @@
[display]
target_fps = 61
show_fps = true
window_width = 800
window_height = 600
window_title = "Roguelike Algorithm Visualizer"
[overlay]
show_fps = true
[font]
default_font_name = "Consolas-Regular"
default_font_size = 12

View File

@@ -17,7 +17,7 @@ void Engine::start_loop() {
if(renderer == nullptr) {
throw MissingRendererException();
}
auto render_params = RendererParams{this->config.window_title, this->config.window_width, this->config.window_height};
auto render_params = RendererParams{this->config.window_title, this->config.window_width, this->config.window_height, this->config.default_font};
renderer->initialize(render_params);
renderer->flush();
auto game_params = GameInitArgs{this->config.target_fps, this->config.window_width, this->config.window_height};
@@ -47,12 +47,14 @@ Engine::Engine(std::unique_ptr<Game> game, std::unique_ptr<Renderer> renderer,
this->input_processor = std::move(input_processor);
EngineConfig new_config = EngineConfig();
load_config("engine.toml", [&new_config](const toml::table& table) {
new_config.show_fps = table["display"]["show_fps"].value_or<bool>(DEFAULT_SHOW_FPS);
new_config.show_fps = table["overlay"]["show_fps"].value_or<bool>(DEFAULT_SHOW_FPS);
new_config.window_width = table["display"]["window_width"].value_or(DEFAULT_WINDOW_WIDTH);
new_config.window_height = table["display"]["window_height"].value_or(DEFAULT_WINDOW_HEIGHT);
new_config.target_fps = table["display"]["target_fps"].value_or(DEFAULT_TARGET_FPS);
new_config.window_title = table["display"]["window_title"].value_or(DEFAULT_WINDOW_TITLE);
auto default_font_path = fmt::format("fonts/{}.ttf", table["font"]["default_font_name"].value_or(DEFAULT_FONT_NAME));
auto default_font_size = table["font"]["default_font_size"].value_or(DEFAULT_FONT_SIZE);
new_config.default_font = TextRenderDetails{default_font_path, default_font_size, COLOR_WHITE};
});
this->config = new_config;
}
@@ -64,7 +66,7 @@ Engine::render_fps(std::chrono::time_point<std::chrono::system_clock> end,
std::chrono::duration<double> dur = end - lastframe;
if(this->config.show_fps) {
//printf("fps: %f\n", frames/dur.count());
this->renderer->draw_text(DEFAULT_FONT, fmt::format("{:.2f}", frames/dur.count()), 0, 0);
this->renderer->draw_text(std::nullopt, fmt::format("{:.2f}", frames/dur.count()), 0, 0);
}
return end;
}

View File

@@ -22,12 +22,8 @@
#define DEFAULT_WINDOW_HEIGHT 600
#define DEFAULT_WINDOW_TITLE "RLEngine"
#define DEFAULT_SHOW_FPS false
static const TextRenderDetails DEFAULT_FONT = TextRenderDetails(
"fonts/Consolas-Regular.ttf",
12,
COLOR_WHITE
);
#define DEFAULT_FONT_NAME "Consolas-Regular"
#define DEFAULT_FONT_SIZE 12
struct EngineConfig {
unsigned int target_fps;

View File

@@ -50,6 +50,7 @@ struct RendererParams {
std::string title;
int width;
int height;
TextRenderDetails default_font;
};
class Renderer {
@@ -57,7 +58,7 @@ public:
virtual void initialize(RendererParams params)=0;
virtual void flush() = 0;
virtual void draw_point(int x, int y, Color color) = 0;
virtual void draw_text(TextRenderDetails details, std::string text,int x, int y)=0;
virtual void draw_text(std::optional<TextRenderDetails> details, std::string text,int x, int y)=0;
virtual void draw_sprite(Sprite sprite, int x, int y)=0;
};

View File

@@ -12,8 +12,7 @@ std::shared_ptr<TTF_Font> SdlFontManager::load_resource(SdlFontArgs args) {
std::string path = get_resource_path(args.font_path);
TTF_Font *font = TTF_OpenFont(path.c_str(), args.size);
if(font == nullptr) {
printf("Could not load font: %s\n", TTF_GetError());
return nullptr;
throw MissingFontException(path, TTF_GetError());
}
return std::shared_ptr<TTF_Font>(font, TTF_CloseFont);
}

View File

@@ -25,4 +25,21 @@ class SdlFontManager : public ResourceManager<std::shared_ptr<TTF_Font>, std::st
};
class MissingFontException : public std::exception {
private:
std::string msg;
public:
[[nodiscard]] const char *what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW override {
return msg.c_str();
}
explicit MissingFontException(const std::string& missing_font, std::string reason) {
msg = fmt::format("Unable to load font [{}] because: {}", missing_font, reason);
}
};
#endif //RLA_IIPP_SDLFONTMANAGER_HPP

View File

@@ -47,9 +47,10 @@ void SdlRenderer::draw_point(int x, int y, Color color) {
SDL_RenderDrawPoint(this->renderer.get(), x, y);
}
void SdlRenderer::draw_text(TextRenderDetails details, std::string text, int x, int y) {
std::shared_ptr<TTF_Font> font = this->font_manager->fetch_resource(SdlFontArgs(details.size, details.font_path));
std::shared_ptr<SDL_Texture> texture = this->texture_manager->load_text_as_texture(text, font, details.color);
void SdlRenderer::draw_text(std::optional<TextRenderDetails> details, std::string text, int x, int y) {
TextRenderDetails unpacked_details = details.value_or(this->renderer_params.default_font);
std::shared_ptr<TTF_Font> font = this->font_manager->fetch_resource(SdlFontArgs(unpacked_details.size, unpacked_details.font_path));
std::shared_ptr<SDL_Texture> texture = this->texture_manager->load_text_as_texture(text, font, unpacked_details.color);
render_texture(x, y, texture, nullptr);
}

View File

@@ -18,7 +18,7 @@ struct SDL_WindowDeleter {
class SdlRenderer : public Renderer {
public:
~SdlRenderer();
void draw_text(TextRenderDetails details, std::string text, int x, int y) override;
void draw_text(std::optional<TextRenderDetails> details, std::string text, int x, int y) override;
void initialize(RendererParams params) override;
void flush() override;
void draw_point(int x, int y, Color color) override;
@@ -31,7 +31,6 @@ private:
std::shared_ptr<SDL_Renderer> renderer = nullptr;
std::unique_ptr<SdlTextureManager> texture_manager = nullptr;
std::unique_ptr<SdlFontManager> font_manager = nullptr;
void render_texture(int x, int y, const std::shared_ptr<SDL_Texture>& texture, SDL_Rect *src);
};

View File

@@ -16,7 +16,7 @@ std::shared_ptr<SDL_Texture> SdlTextureManager::load_resource(TextureManagerFetc
std::string full_path = get_resource_path(args.path);
SDL_Surface* surface = load_surface(full_path);
if(surface == nullptr) {
return nullptr;
throw MissingTextureException(full_path, SDL_GetError());
}
if(args.color_key.has_value()) {
Color color_key = args.color_key.value();
@@ -24,6 +24,9 @@ std::shared_ptr<SDL_Texture> SdlTextureManager::load_resource(TextureManagerFetc
}
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer.get(), surface);
SDL_FreeSurface(surface);
if(texture == nullptr) {
throw MissingTextureException(full_path, SDL_GetError());
}
return std::shared_ptr<SDL_Texture>(texture, SDL_DestroyTexture);
}
@@ -39,9 +42,12 @@ std::string SdlTextureManager::get_key(TextureManagerFetchArgs args) {
std::shared_ptr<SDL_Texture> SdlTextureManager::load_text_as_texture(const std::string& text, const std::shared_ptr<TTF_Font>& font, Color color) {
SDL_Surface *surface = TTF_RenderText_Solid(font.get(), text.c_str(), {color.r, color.g, color.b});
if(surface == nullptr) {
return nullptr;
throw MissingTextureException("font", SDL_GetError());
}
SDL_Texture *texture = SDL_CreateTextureFromSurface(this->renderer.get(), surface);
SDL_FreeSurface(surface);
if(texture == nullptr) {
throw MissingTextureException("font", SDL_GetError());
}
return std::shared_ptr<SDL_Texture>(texture, SDL_DestroyTexture);
}

View File

@@ -34,5 +34,18 @@ private:
static SDL_Surface* load_surface(const std::string& path);
};
class MissingTextureException: public std::exception {
private:
std::string msg;
public:
[[nodiscard]] const char *what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW override {
return msg.c_str();
}
MissingTextureException(const std::string& path, const std::string& error) {
msg = fmt::format("Failed ot load texture at path [{}] because: {}", path, error);
}
};
#endif //RLA_IIPP_SDLTEXTUREMANAGER_HPP