Files
yaze/src/app/gfx/arena.cc
scawful 41adb1b70e Enhance testing framework and UI integration for YAZE
- Added a comprehensive testing framework with support for unit, integration, and UI tests, improving overall test coverage and reliability.
- Integrated ImGui Test Engine for UI testing, allowing for real-time feedback and visualization of test results.
- Updated CMake configuration to conditionally include testing components based on build options, enhancing flexibility for developers.
- Introduced a new command in the CLI for running asset loading tests on ROMs, providing a straightforward way to validate functionality.
- Enhanced error handling and resource management during testing, ensuring stability and clarity in test execution.
- Improved user interface with a dedicated test dashboard for monitoring test progress and results, enhancing developer experience.
2025-09-25 13:26:56 -04:00

142 lines
3.6 KiB
C++

#include "app/gfx/arena.h"
#include <SDL.h>
#include "app/core/platform/sdl_deleter.h"
namespace yaze {
namespace gfx {
Arena& Arena::Get() {
static Arena instance;
return instance;
}
Arena::Arena() {
layer1_buffer_.fill(0);
layer2_buffer_.fill(0);
}
Arena::~Arena() {
// Safely clear all resources with proper error checking
for (auto& [key, texture] : textures_) {
// Don't rely on unique_ptr deleter during shutdown - manually manage
if (texture && key) {
[[maybe_unused]] auto* released = texture.release(); // Release ownership to prevent double deletion
}
}
textures_.clear();
for (auto& [key, surface] : surfaces_) {
// Don't rely on unique_ptr deleter during shutdown - manually manage
if (surface && key) {
[[maybe_unused]] auto* released = surface.release(); // Release ownership to prevent double deletion
}
}
surfaces_.clear();
}
SDL_Texture* Arena::AllocateTexture(SDL_Renderer* renderer, int width,
int height) {
if (!renderer) {
SDL_Log("Invalid renderer passed to AllocateTexture");
return nullptr;
}
if (width <= 0 || height <= 0) {
SDL_Log("Invalid texture dimensions: width=%d, height=%d", width, height);
return nullptr;
}
SDL_Texture* texture =
SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_STREAMING, width, height);
if (!texture) {
SDL_Log("Failed to create texture: %s", SDL_GetError());
return nullptr;
}
textures_[texture] =
std::unique_ptr<SDL_Texture, core::SDL_Texture_Deleter>(texture);
return texture;
}
void Arena::FreeTexture(SDL_Texture* texture) {
if (!texture) return;
auto it = textures_.find(texture);
if (it != textures_.end()) {
textures_.erase(it);
}
}
void Arena::Shutdown() {
// Clear all resources safely - let the unique_ptr deleters handle the cleanup
// while SDL context is still available
// Just clear the containers - the unique_ptr destructors will handle SDL cleanup
// This avoids double-free issues from manual destruction
textures_.clear();
surfaces_.clear();
}
void Arena::UpdateTexture(SDL_Texture* texture, SDL_Surface* surface) {
if (!texture || !surface) {
SDL_Log("Invalid texture or surface passed to UpdateTexture");
return;
}
if (surface->pixels == nullptr) {
SDL_Log("Surface pixels are nullptr");
return;
}
auto converted_surface =
std::unique_ptr<SDL_Surface, core::SDL_Surface_Deleter>(
SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA8888, 0),
core::SDL_Surface_Deleter());
if (!converted_surface) {
SDL_Log("SDL_ConvertSurfaceFormat failed: %s", SDL_GetError());
return;
}
void* pixels;
int pitch;
if (SDL_LockTexture(texture, nullptr, &pixels, &pitch) != 0) {
SDL_Log("SDL_LockTexture failed: %s", SDL_GetError());
return;
}
memcpy(pixels, converted_surface->pixels,
converted_surface->h * converted_surface->pitch);
SDL_UnlockTexture(texture);
}
SDL_Surface* Arena::AllocateSurface(int width, int height, int depth,
int format) {
SDL_Surface* surface =
SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, format);
if (!surface) {
SDL_Log("Failed to create surface: %s", SDL_GetError());
return nullptr;
}
surfaces_[surface] =
std::unique_ptr<SDL_Surface, core::SDL_Surface_Deleter>(surface);
return surface;
}
void Arena::FreeSurface(SDL_Surface* surface) {
if (!surface) return;
auto it = surfaces_.find(surface);
if (it != surfaces_.end()) {
surfaces_.erase(it);
}
}
} // namespace gfx
} // namespace yaze