refactor: fase 5 — singletons a std::unique_ptr (elimina new/delete manual)
5 singletons afectats: Audio, Screen, Director, Resource::Cache, Resource::List. - static T* instance → static std::unique_ptr<T> instance - init(): new T() adoptat immediatament per unique_ptr (ownership RAII) - destroy(): instance.reset() (sense delete manual) - get(): retorna instance.get() - Destructors moguts a public perquè std::default_delete hi pugui accedir (ctors privats + copy/move deleted → encapsulació efectiva mantinguda) Ordre de destrucció preservat: SDL_AppQuit segueix cridant destroy() en l'ordre invers a init() — la RAII automàtica no s'activa fins al final del programa (LIFO de variables static). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,19 +24,16 @@
|
||||
#include "game/options.hpp" // Para Options::audio
|
||||
|
||||
// Singleton
|
||||
Audio* Audio::instance = nullptr;
|
||||
std::unique_ptr<Audio> Audio::instance;
|
||||
|
||||
// Inicializa la instancia única del singleton
|
||||
void Audio::init() { Audio::instance = new Audio(); }
|
||||
void Audio::init() { Audio::instance = std::unique_ptr<Audio>(new Audio()); }
|
||||
|
||||
// Libera la instancia
|
||||
void Audio::destroy() {
|
||||
delete Audio::instance;
|
||||
Audio::instance = nullptr;
|
||||
}
|
||||
void Audio::destroy() { Audio::instance.reset(); }
|
||||
|
||||
// Obtiene la instancia
|
||||
auto Audio::get() -> Audio* { return Audio::instance; }
|
||||
auto Audio::get() -> Audio* { return Audio::instance.get(); }
|
||||
|
||||
// Constructor
|
||||
Audio::Audio() { initSDLAudio(); }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint> // Para int8_t, uint8_t
|
||||
#include <memory> // Para std::unique_ptr
|
||||
#include <string> // Para string
|
||||
#include <utility> // Para move
|
||||
|
||||
@@ -35,6 +36,7 @@ class Audio {
|
||||
static void init(); // Inicializa el objeto Audio
|
||||
static void destroy(); // Libera el objeto Audio
|
||||
static auto get() -> Audio*; // Obtiene el puntero al objeto Audio
|
||||
~Audio(); // Destructor (públic per a std::unique_ptr)
|
||||
Audio(const Audio&) = delete; // Evitar copia
|
||||
auto operator=(const Audio&) -> Audio& = delete; // Evitar asignación
|
||||
|
||||
@@ -101,11 +103,10 @@ class Audio {
|
||||
|
||||
// --- Métodos ---
|
||||
Audio(); // Constructor privado
|
||||
~Audio(); // Destructor privado
|
||||
void initSDLAudio(); // Inicializa SDL Audio
|
||||
|
||||
// --- Variables miembro ---
|
||||
static Audio* instance; // Instancia única de Audio
|
||||
static std::unique_ptr<Audio> instance; // Instancia única de Audio
|
||||
|
||||
Music music_; // Estado de la música
|
||||
bool enabled_{true}; // Estado general del audio
|
||||
|
||||
@@ -55,19 +55,18 @@ namespace {
|
||||
} // namespace
|
||||
#endif // __EMSCRIPTEN__
|
||||
|
||||
Screen* Screen::instance_ = nullptr;
|
||||
std::unique_ptr<Screen> Screen::instance_;
|
||||
|
||||
void Screen::init() {
|
||||
instance_ = new Screen();
|
||||
instance_ = std::unique_ptr<Screen>(new Screen());
|
||||
}
|
||||
|
||||
void Screen::destroy() {
|
||||
delete instance_;
|
||||
instance_ = nullptr;
|
||||
instance_.reset();
|
||||
}
|
||||
|
||||
auto Screen::get() -> Screen* {
|
||||
return instance_;
|
||||
return instance_.get();
|
||||
}
|
||||
|
||||
Screen::Screen() {
|
||||
|
||||
@@ -13,6 +13,8 @@ class Screen {
|
||||
static void destroy();
|
||||
static auto get() -> Screen*;
|
||||
|
||||
~Screen(); // públic per a std::unique_ptr
|
||||
|
||||
// Presentació — rep el buffer ARGB de 320x200 de JD8
|
||||
void present(Uint32* pixel_data);
|
||||
|
||||
@@ -62,7 +64,6 @@ class Screen {
|
||||
|
||||
private:
|
||||
Screen();
|
||||
~Screen();
|
||||
|
||||
void adjustWindowSize();
|
||||
void calculateMaxZoom();
|
||||
@@ -70,7 +71,7 @@ class Screen {
|
||||
void applyFallbackPresentation(); // Logical presentation + scale mode per al path SDL_Renderer
|
||||
void ensureFallbackInternalTexture(); // Recrea internal_texture_sdl_ si cal (fallback path)
|
||||
|
||||
static Screen* instance_;
|
||||
static std::unique_ptr<Screen> instance_;
|
||||
|
||||
SDL_Window* window_{nullptr};
|
||||
SDL_Renderer* renderer_{nullptr};
|
||||
|
||||
@@ -20,14 +20,11 @@ extern unsigned char* LoadPalette(unsigned char* data);
|
||||
|
||||
namespace Resource {
|
||||
|
||||
Cache* Cache::instance = nullptr;
|
||||
std::unique_ptr<Cache> Cache::instance;
|
||||
|
||||
void Cache::init() { instance = new Cache(); }
|
||||
void Cache::destroy() {
|
||||
delete instance;
|
||||
instance = nullptr;
|
||||
}
|
||||
auto Cache::get() -> Cache* { return instance; }
|
||||
void Cache::init() { instance = std::unique_ptr<Cache>(new Cache()); }
|
||||
void Cache::destroy() { instance.reset(); }
|
||||
auto Cache::get() -> Cache* { return instance.get(); }
|
||||
|
||||
namespace {
|
||||
auto basename(const std::string& path) -> std::string {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -20,6 +21,7 @@ namespace Resource {
|
||||
static void destroy();
|
||||
static auto get() -> Cache*;
|
||||
|
||||
~Cache() = default;
|
||||
Cache(const Cache&) = delete;
|
||||
auto operator=(const Cache&) -> Cache& = delete;
|
||||
|
||||
@@ -39,7 +41,6 @@ namespace Resource {
|
||||
|
||||
private:
|
||||
Cache() = default;
|
||||
~Cache() = default;
|
||||
|
||||
enum class LoadStage {
|
||||
MUSICS,
|
||||
@@ -66,7 +67,7 @@ namespace Resource {
|
||||
int loaded_count_{0};
|
||||
std::string current_loading_name_;
|
||||
|
||||
static Cache* instance;
|
||||
static std::unique_ptr<Cache> instance;
|
||||
};
|
||||
|
||||
} // namespace Resource
|
||||
|
||||
@@ -9,19 +9,16 @@
|
||||
|
||||
namespace Resource {
|
||||
|
||||
List* List::instance = nullptr;
|
||||
std::unique_ptr<List> List::instance;
|
||||
|
||||
void List::init(const std::string& yaml_path) {
|
||||
instance = new List();
|
||||
instance = std::unique_ptr<List>(new List());
|
||||
instance->loadFromYaml(yaml_path);
|
||||
}
|
||||
|
||||
void List::destroy() {
|
||||
delete instance;
|
||||
instance = nullptr;
|
||||
}
|
||||
void List::destroy() { instance.reset(); }
|
||||
|
||||
auto List::get() -> List* { return instance; }
|
||||
auto List::get() -> List* { return instance.get(); }
|
||||
|
||||
void List::loadFromYaml(const std::string& yaml_path) {
|
||||
auto bytes = ResourceHelper::loadFile(yaml_path);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
@@ -25,6 +26,7 @@ namespace Resource {
|
||||
static void destroy();
|
||||
static auto get() -> List*;
|
||||
|
||||
~List() = default;
|
||||
List(const List&) = delete;
|
||||
auto operator=(const List&) -> List& = delete;
|
||||
|
||||
@@ -44,7 +46,6 @@ namespace Resource {
|
||||
};
|
||||
|
||||
List() = default;
|
||||
~List() = default;
|
||||
|
||||
void loadFromYaml(const std::string& yaml_path);
|
||||
void loadFromString(const std::string& yaml_content);
|
||||
@@ -55,7 +56,7 @@ namespace Resource {
|
||||
|
||||
std::unordered_map<std::string, Item> file_list_;
|
||||
|
||||
static List* instance;
|
||||
static std::unique_ptr<List> instance;
|
||||
};
|
||||
|
||||
} // namespace Resource
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
// Cheats del joc original — declarats a jinput.cpp
|
||||
extern void JI_moveCheats(Uint8 new_key);
|
||||
|
||||
Director* Director::instance_ = nullptr;
|
||||
std::unique_ptr<Director> Director::instance_;
|
||||
|
||||
Director::~Director() = default;
|
||||
|
||||
@@ -79,7 +79,7 @@ std::unique_ptr<scenes::Scene> Director::createNextScene() {
|
||||
}
|
||||
|
||||
void Director::init() {
|
||||
instance_ = new Director();
|
||||
instance_ = std::unique_ptr<Director>(new Director());
|
||||
Gamepad::init();
|
||||
|
||||
// Registre d'escenes. Cada entrada = un state_key (`num_piramide`)
|
||||
@@ -116,12 +116,11 @@ void Director::init() {
|
||||
|
||||
void Director::destroy() {
|
||||
Gamepad::destroy();
|
||||
delete instance_;
|
||||
instance_ = nullptr;
|
||||
instance_.reset();
|
||||
}
|
||||
|
||||
auto Director::get() -> Director* {
|
||||
return instance_;
|
||||
return instance_.get();
|
||||
}
|
||||
|
||||
void Director::togglePause() {
|
||||
|
||||
@@ -52,11 +52,13 @@ class Director {
|
||||
void togglePause();
|
||||
auto isPaused() const -> bool { return paused_; }
|
||||
|
||||
private:
|
||||
Director() = default;
|
||||
public:
|
||||
~Director();
|
||||
|
||||
static Director* instance_;
|
||||
private:
|
||||
Director() = default;
|
||||
|
||||
static std::unique_ptr<Director> instance_;
|
||||
|
||||
void pollAllEvents(); // drenatge amb SDL_PollEvent, només per al bucle natiu
|
||||
|
||||
|
||||
Reference in New Issue
Block a user