reinici real (execv) des del service menu
El Reiniciar fins ara recarregava recursos però no rellegia el preset ni recreava la finestra (idioma/dificultat/preset es quedaven pendents fins al pròxim arrencada manual). Ara Director rep argv al constructor i, quan Section::name passa a RESET, fa execv del propi binari (_execv a Windows). El procés es reemplaça → init complet amb tots els canvis aplicats. Refactor: extret shutdownSubsystems() de close() i compartit amb relaunch(). Si execv falla els subsistemes ja s'han destruït, no podem tornar al bucle: exit amb error. A Emscripten s'amaga l'opció Reiniciar al service menu (execv no existeix; el cheat code per teclat encara cau al reset clàssic com fallback).
This commit is contained in:
@@ -3,7 +3,9 @@
|
||||
|
||||
#include <SDL3/SDL.h> // Para SDL_SetLogPriority, SDL_LogCategory, SDL_LogPriority, SDL_Quit
|
||||
|
||||
#include <cerrno> // Para errno
|
||||
#include <cstdlib> // Para srand, exit, rand, EXIT_FAILURE
|
||||
#include <cstring> // Para std::strerror
|
||||
#include <ctime> // Para time
|
||||
#include <fstream> // Para ifstream, ofstream
|
||||
#include <iostream> // Para basic_ostream, operator<<, cerr
|
||||
@@ -11,6 +13,12 @@
|
||||
#include <stdexcept> // Para runtime_error
|
||||
#include <string> // Para allocator, basic_string, char_traits, operator+, string, operator==
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <process.h> // Per _execv
|
||||
#else
|
||||
#include <unistd.h> // Per execv
|
||||
#endif
|
||||
|
||||
#include "core/audio/audio.hpp" // Para Audio
|
||||
#include "core/input/input.hpp" // Para Input
|
||||
#include "core/locale/lang.hpp" // Para setLanguage
|
||||
@@ -71,7 +79,8 @@ namespace {
|
||||
} // namespace
|
||||
|
||||
// Constructor
|
||||
Director::Director() {
|
||||
Director::Director(int /*argc*/, char** argv)
|
||||
: argv_(argv) {
|
||||
Section::attract_mode = Section::AttractMode::TITLE_TO_DEMO;
|
||||
|
||||
// Establece el nivel de prioridad de la categoría de registro
|
||||
@@ -214,8 +223,8 @@ void Director::finishBoot() {
|
||||
}
|
||||
}
|
||||
|
||||
// Cierra todo y libera recursos del sistema y de los singletons
|
||||
void Director::close() {
|
||||
// Allibera tots els singletons i SDL (compartit entre close() i relaunch())
|
||||
void Director::shutdownSubsystems() {
|
||||
// Guarda las opciones actuales en el archivo de configuración
|
||||
Options::saveToFile();
|
||||
|
||||
@@ -228,15 +237,40 @@ void Director::close() {
|
||||
Screen::destroy(); // Libera el sistema de pantalla y renderizado
|
||||
Asset::destroy(); // Libera el gestor de archivos
|
||||
|
||||
std::cout << "\nBye!\n";
|
||||
|
||||
// Libera todos los recursos de SDL
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
// Cierra todo y libera recursos del sistema y de los singletons
|
||||
void Director::close() {
|
||||
shutdownSubsystems();
|
||||
std::cout << "\nBye!\n";
|
||||
// Apaga el sistema
|
||||
shutdownSystem(Section::options == Section::Options::SHUTDOWN);
|
||||
}
|
||||
|
||||
// Reemplaça el procés actual per ell mateix (reinici en calent). En cas d'èxit no torna.
|
||||
// Si no es pot reiniciar (Emscripten, argv invàlid), retorna i el caller fa el reset clàssic.
|
||||
void Director::relaunch() const {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// Al navegador el reinici real seria location.reload(); aquí caiem al reset intern.
|
||||
return;
|
||||
#else
|
||||
if (argv_ == nullptr || argv_[0] == nullptr) { return; }
|
||||
std::cout << "Relaunching " << argv_[0] << "...\n";
|
||||
shutdownSubsystems();
|
||||
#ifdef _WIN32
|
||||
_execv(argv_[0], argv_);
|
||||
#else
|
||||
execv(argv_[0], argv_);
|
||||
#endif
|
||||
// Si arribem aquí, execv ha fallat. Tots els subsistemes ja estan destruïts: no
|
||||
// podem reprendre el bucle. Sortim amb error.
|
||||
std::cerr << "Relaunch failed: " << std::strerror(errno) << "\n";
|
||||
std::exit(EXIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Carga los parametros
|
||||
void Director::loadParams() {
|
||||
// Carga los parametros para configurar el juego
|
||||
@@ -354,9 +388,11 @@ void Director::resetActiveSection() {
|
||||
|
||||
// Destruye la sección anterior y construye la nueva cuando Section::name cambia
|
||||
void Director::handleSectionTransition() {
|
||||
// RESET: recarga recursos y vuelve a LOGO (el propio reset() cambia Section::name)
|
||||
// RESET: intenta reinici real via execv; si no es pot (Emscripten o argv invàlid),
|
||||
// cau al reset intern (recarrega recursos i torna a LOGO, sense recrear Screen/Params).
|
||||
if (Section::name == Section::Name::RESET) {
|
||||
resetActiveSection(); // libera recursos actuales antes del reload
|
||||
relaunch(); // En èxit no torna; el binari es reemplaça
|
||||
resetActiveSection(); // Fallback: libera recursos actuales antes del reload
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
|
||||
#include <SDL3/SDL.h> // Para SDL_AppResult, SDL_Event
|
||||
|
||||
#include <memory> // Para unique_ptr
|
||||
#include <string> // Para string
|
||||
#include <cstdint> // Para std::uint8_t
|
||||
#include <memory> // Para unique_ptr
|
||||
#include <string> // Para string
|
||||
|
||||
#include "core/system/section.hpp" // Para Section::Name
|
||||
|
||||
#include <cstdint> // Para std::uint8_t
|
||||
|
||||
namespace Lang {
|
||||
enum class Code : std::uint8_t;
|
||||
}
|
||||
@@ -27,7 +26,7 @@ class Credits;
|
||||
class Director {
|
||||
public:
|
||||
// --- Constructor y destructor ---
|
||||
Director();
|
||||
Director(int argc, char** argv);
|
||||
~Director();
|
||||
|
||||
// --- Callbacks para SDL_MAIN_USE_CALLBACKS ---
|
||||
@@ -55,6 +54,7 @@ class Director {
|
||||
// --- Variables internas ---
|
||||
std::string executable_path_; // Ruta del ejecutable
|
||||
std::string system_folder_; // Carpeta del sistema para almacenar datos
|
||||
char** argv_ = nullptr; // argv original; usat per relaunch() (execv)
|
||||
|
||||
// --- Sección activa (una y sólo una viva en cada momento) ---
|
||||
std::unique_ptr<Preload> preload_;
|
||||
@@ -71,9 +71,11 @@ class Director {
|
||||
bool boot_loading_ = true; // True mientras Resource::loadStep está cargando incremental
|
||||
|
||||
// --- Inicialización y cierre del sistema ---
|
||||
void init(); // Inicializa la aplicación (pre-boot)
|
||||
static void finishBoot(); // Post-boot: inicializa lo que depende de recursos cargados
|
||||
static void close(); // Cierra y libera recursos
|
||||
void init(); // Inicializa la aplicación (pre-boot)
|
||||
static void finishBoot(); // Post-boot: inicializa lo que depende de recursos cargados
|
||||
static void shutdownSubsystems(); // Allibera singletons i SDL (sense apagar el sistema)
|
||||
static void close(); // Cierra y libera recursos
|
||||
void relaunch() const; // Reemplaça el procés via execv (fallback silenciós si no es pot)
|
||||
|
||||
// --- Configuración inicial ---
|
||||
static void loadParams(); // Carga los parámetros del programa
|
||||
|
||||
@@ -564,13 +564,21 @@ void ServiceMenu::addSettingsOptions() {
|
||||
}
|
||||
|
||||
void ServiceMenu::addSystemOptions() {
|
||||
// Al navegador no podem reiniciar el procés (execv no existeix), així que amaguem
|
||||
// l'opció en compte de mostrar un fals reset que no recarrega params/finestra.
|
||||
#ifdef __EMSCRIPTEN__
|
||||
constexpr bool RESET_HIDDEN = true;
|
||||
#else
|
||||
constexpr bool RESET_HIDDEN = false;
|
||||
#endif
|
||||
options_.push_back(std::make_unique<ActionOption>(
|
||||
Lang::getText("[SERVICE_MENU] RESET"),
|
||||
SettingsGroup::SYSTEM,
|
||||
[this]() -> void {
|
||||
Section::name = Section::Name::RESET;
|
||||
toggle();
|
||||
}));
|
||||
},
|
||||
RESET_HIDDEN));
|
||||
|
||||
options_.push_back(std::make_unique<ActionOption>(
|
||||
Lang::getText("[SERVICE_MENU] QUIT"),
|
||||
|
||||
+2
-2
@@ -12,8 +12,8 @@ Actualizando a la versión "Arcade Edition" en 08/05/2024
|
||||
|
||||
#include "core/system/director.hpp" // Para Director
|
||||
|
||||
auto SDL_AppInit(void** appstate, int /*argc*/, char** /*argv*/) -> SDL_AppResult {
|
||||
*appstate = new Director();
|
||||
auto SDL_AppInit(void** appstate, int argc, char** argv) -> SDL_AppResult {
|
||||
*appstate = new Director(argc, argv);
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user