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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user