mirror of
https://github.com/libretro/RetroArch
synced 2025-03-29 22:20:21 +00:00
RETRO_ENVIRONMENT_SHUTDOWN Fixes
- Ensure core is properly unloaded when RETRO_ENVIRONMENT_SHUTDOWN is called - Ensure menu stack is properly flushed when RETRO_ENVIRONMENT_SHUTDOWN is called
This commit is contained in:
parent
72513e29b2
commit
c6e83d23f5
@ -9239,7 +9239,7 @@ static int materialui_list_push(void *data, void *userdata,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (system->load_no_content)
|
||||
if (system && system->load_no_content)
|
||||
{
|
||||
MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(
|
||||
info->list,
|
||||
|
@ -7899,7 +7899,7 @@ static int ozone_list_push(void *data, void *userdata,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (system->load_no_content)
|
||||
if (system && system->load_no_content)
|
||||
{
|
||||
MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(
|
||||
info->list,
|
||||
|
@ -7107,7 +7107,7 @@ static int xmb_list_push(void *data, void *userdata,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (system->load_no_content)
|
||||
if (system && system->load_no_content)
|
||||
{
|
||||
MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(
|
||||
info->list,
|
||||
|
@ -8061,23 +8061,73 @@ int generic_menu_entry_action(
|
||||
}
|
||||
#endif
|
||||
|
||||
if (menu_st->pending_close_content)
|
||||
if (menu_st->pending_close_content ||
|
||||
menu_st->pending_env_shutdown_flush)
|
||||
{
|
||||
const char *content_path = path_get(RARCH_PATH_CONTENT);
|
||||
const char *menu_flush_to = msg_hash_to_str(MENU_ENUM_LABEL_MAIN_MENU);
|
||||
const char *content_path = menu_st->pending_env_shutdown_flush ?
|
||||
menu_st->pending_env_shutdown_content_path :
|
||||
path_get(RARCH_PATH_CONTENT);
|
||||
const char *deferred_path = menu ? menu->deferred_path : NULL;
|
||||
const char *flush_target = msg_hash_to_str(MENU_ENUM_LABEL_MAIN_MENU);
|
||||
size_t stack_offset = 1;
|
||||
bool reset_navigation = true;
|
||||
|
||||
/* Flush to playlist entry menu if launched via playlist */
|
||||
if (menu &&
|
||||
!string_is_empty(menu->deferred_path) &&
|
||||
!string_is_empty(content_path) &&
|
||||
string_is_equal(menu->deferred_path, content_path))
|
||||
menu_flush_to = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_RPL_ENTRY_ACTIONS);
|
||||
/* Loop backwards through the menu stack to
|
||||
* find a known reference point */
|
||||
while (menu_stack && (menu_stack->size >= stack_offset))
|
||||
{
|
||||
const char *parent_label = NULL;
|
||||
|
||||
command_event(CMD_EVENT_UNLOAD_CORE, NULL);
|
||||
menu_entries_flush_stack(menu_flush_to, 0);
|
||||
file_list_get_at_offset(menu_stack,
|
||||
menu_stack->size - stack_offset,
|
||||
NULL, &parent_label, NULL, NULL);
|
||||
|
||||
if (string_is_empty(parent_label))
|
||||
continue;
|
||||
|
||||
/* If core was launched via a playlist, flush
|
||||
* to playlist entry menu */
|
||||
if (string_is_equal(parent_label,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_RPL_ENTRY_ACTIONS)) &&
|
||||
(!string_is_empty(deferred_path) &&
|
||||
!string_is_empty(content_path) &&
|
||||
string_is_equal(deferred_path, content_path)))
|
||||
{
|
||||
flush_target = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_RPL_ENTRY_ACTIONS);
|
||||
break;
|
||||
}
|
||||
/* If core was launched via standalone cores menu,
|
||||
* flush to standalone cores menu */
|
||||
else if (string_is_equal(parent_label,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_CONTENTLESS_CORES_TAB)) ||
|
||||
string_is_equal(parent_label,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_CONTENTLESS_CORES_LIST)))
|
||||
{
|
||||
flush_target = parent_label;
|
||||
reset_navigation = false;
|
||||
break;
|
||||
}
|
||||
|
||||
stack_offset++;
|
||||
}
|
||||
|
||||
if (!menu_st->pending_env_shutdown_flush)
|
||||
command_event(CMD_EVENT_UNLOAD_CORE, NULL);
|
||||
|
||||
menu_entries_flush_stack(flush_target, 0);
|
||||
/* An annoyance - some menu drivers (Ozone...) call
|
||||
* RARCH_MENU_CTL_SET_PREVENT_POPULATE in awkward
|
||||
* places, which can cause breakage here when flushing
|
||||
* the menu stack. We therefore have to force a
|
||||
* RARCH_MENU_CTL_UNSET_PREVENT_POPULATE */
|
||||
menu_driver_ctl(RARCH_MENU_CTL_UNSET_PREVENT_POPULATE, NULL);
|
||||
menu_st->selection_ptr = 0;
|
||||
menu_st->pending_close_content = false;
|
||||
|
||||
if (reset_navigation)
|
||||
menu_st->selection_ptr = 0;
|
||||
|
||||
menu_st->pending_close_content = false;
|
||||
menu_st->pending_env_shutdown_flush = false;
|
||||
menu_st->pending_env_shutdown_content_path[0] = '\0';
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -501,6 +501,12 @@ struct menu_state
|
||||
/* Storage container for current menu datetime
|
||||
* representation string */
|
||||
char datetime_cache[255];
|
||||
/* Filled with current content path when a core calls
|
||||
* RETRO_ENVIRONMENT_SHUTDOWN. Value is required in
|
||||
* generic_menu_entry_action(), and must be cached
|
||||
* since RETRO_ENVIRONMENT_SHUTDOWN will cause
|
||||
* RARCH_PATH_CONTENT to be cleared */
|
||||
char pending_env_shutdown_content_path[PATH_MAX_LENGTH];
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
char input_dialog_kb_label_setting[256];
|
||||
@ -520,6 +526,9 @@ struct menu_state
|
||||
bool entries_nonblocking_refresh;
|
||||
/* 'Close Content'-hotkey menu resetting */
|
||||
bool pending_close_content;
|
||||
/* Flagged when a core calls RETRO_ENVIRONMENT_SHUTDOWN,
|
||||
* requiring the menu to be flushed on the next iteration */
|
||||
bool pending_env_shutdown_flush;
|
||||
/* Screensaver status
|
||||
* - Does menu driver support screensaver functionality?
|
||||
* - Is screensaver currently active? */
|
||||
|
@ -1875,6 +1875,7 @@ bool command_event(enum event_command cmd, void *data)
|
||||
break;
|
||||
case CMD_EVENT_UNLOAD_CORE:
|
||||
{
|
||||
bool load_dummy_core = data ? *(bool*)data : true;
|
||||
bool contentless = false;
|
||||
bool is_inited = false;
|
||||
content_ctx_info_t content_info = {0};
|
||||
@ -1936,7 +1937,7 @@ bool command_event(enum event_command cmd, void *data)
|
||||
else
|
||||
input_remapping_restore_global_config(true);
|
||||
|
||||
if (is_inited)
|
||||
if (is_inited && load_dummy_core)
|
||||
{
|
||||
#ifdef HAVE_MENU
|
||||
if ( (settings->uints.quit_on_close_content == QUIT_ON_CLOSE_CONTENT_CLI && global->launched_from_cli)
|
||||
|
96
runloop.c
96
runloop.c
@ -1900,48 +1900,34 @@ bool runloop_environment_cb(unsigned cmd, void *data)
|
||||
}
|
||||
|
||||
case RETRO_ENVIRONMENT_SHUTDOWN:
|
||||
RARCH_LOG("[Environ]: SHUTDOWN.\n");
|
||||
|
||||
/* This case occurs when a core (internally) requests
|
||||
* a shutdown event. Must save runtime log file here,
|
||||
* since normal command.c CMD_EVENT_CORE_DEINIT event
|
||||
* will not occur until after the current content has
|
||||
* been cleared (causing log to be skipped) */
|
||||
runloop_runtime_log_deinit(runloop_st,
|
||||
settings->bools.content_runtime_log,
|
||||
settings->bools.content_runtime_log_aggregate,
|
||||
settings->paths.directory_runtime_log,
|
||||
settings->paths.directory_playlist);
|
||||
|
||||
/* Similarly, since the CMD_EVENT_CORE_DEINIT will
|
||||
* be called *after* the runloop state has been
|
||||
* cleared, must also perform the following actions
|
||||
* here:
|
||||
* - Disable any active config overrides
|
||||
* - Unload any active input remaps */
|
||||
#ifdef HAVE_CONFIGFILE
|
||||
if (runloop_st->overrides_active)
|
||||
{
|
||||
/* Reload the original config */
|
||||
config_unload_override();
|
||||
runloop_st->overrides_active = false;
|
||||
}
|
||||
{
|
||||
#ifdef HAVE_MENU
|
||||
struct menu_state *menu_st = menu_state_get_ptr();
|
||||
#endif
|
||||
if ( runloop_st->remaps_core_active
|
||||
|| runloop_st->remaps_content_dir_active
|
||||
|| runloop_st->remaps_game_active
|
||||
|| !string_is_empty(runloop_st->name.remapfile)
|
||||
)
|
||||
{
|
||||
input_remapping_deinit(true);
|
||||
input_remapping_set_defaults(true);
|
||||
}
|
||||
else
|
||||
input_remapping_restore_global_config(true);
|
||||
/* This case occurs when a core (internally)
|
||||
* requests a shutdown event */
|
||||
RARCH_LOG("[Environ]: SHUTDOWN.\n");
|
||||
|
||||
runloop_st->shutdown_initiated = true;
|
||||
runloop_st->core_shutdown_initiated = true;
|
||||
#ifdef HAVE_MENU
|
||||
/* Ensure that menu stack is flushed appropriately
|
||||
* after the core has stopped running */
|
||||
if (menu_st)
|
||||
{
|
||||
const char *content_path = path_get(RARCH_PATH_CONTENT);
|
||||
|
||||
menu_st->pending_env_shutdown_flush = true;
|
||||
if (!string_is_empty(content_path))
|
||||
strlcpy(menu_st->pending_env_shutdown_content_path,
|
||||
content_path,
|
||||
sizeof(menu_st->pending_env_shutdown_content_path));
|
||||
else
|
||||
menu_st->pending_env_shutdown_content_path[0] = '\0';
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL:
|
||||
if (system)
|
||||
@ -6531,30 +6517,36 @@ static enum runloop_state_enum runloop_check_state(
|
||||
if (runloop_exec)
|
||||
runloop_exec = false;
|
||||
|
||||
if (runloop_st->core_shutdown_initiated &&
|
||||
settings->bools.load_dummy_on_core_shutdown)
|
||||
if (runloop_st->core_shutdown_initiated)
|
||||
{
|
||||
content_ctx_info_t content_info;
|
||||
bool load_dummy_core = false;
|
||||
|
||||
content_info.argc = 0;
|
||||
content_info.argv = NULL;
|
||||
content_info.args = NULL;
|
||||
content_info.environ_get = NULL;
|
||||
runloop_st->core_shutdown_initiated = false;
|
||||
|
||||
if (task_push_start_dummy_core(&content_info))
|
||||
/* Check whether dummy core should be loaded
|
||||
* instead of exiting RetroArch completely
|
||||
* (aborts shutdown if invoked) */
|
||||
if (settings->bools.load_dummy_on_core_shutdown)
|
||||
{
|
||||
/* Loads dummy core instead of exiting RetroArch completely.
|
||||
* Aborts core shutdown if invoked. */
|
||||
runloop_st->shutdown_initiated = false;
|
||||
runloop_st->core_shutdown_initiated = false;
|
||||
load_dummy_core = true;
|
||||
runloop_st->shutdown_initiated = false;
|
||||
}
|
||||
else
|
||||
quit_runloop = true;
|
||||
|
||||
/* Unload current core, and load dummy if
|
||||
* required */
|
||||
if (!command_event(CMD_EVENT_UNLOAD_CORE, &load_dummy_core))
|
||||
{
|
||||
runloop_st->shutdown_initiated = true;
|
||||
quit_runloop = true;
|
||||
}
|
||||
|
||||
if (!load_dummy_core)
|
||||
quit_runloop = true;
|
||||
}
|
||||
else
|
||||
quit_runloop = true;
|
||||
|
||||
runloop_st->core_running = false;
|
||||
runloop_st->core_running = false;
|
||||
|
||||
if (quit_runloop)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user