From 5220dc9084672abb53371872ea77d0eddf24885e Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Tue, 30 Jul 2019 17:11:43 +0100 Subject: [PATCH 1/2] Add independent 'favourites' playlist size setting --- command.h | 4 + config.def.h | 4 + configuration.c | 16 ++ configuration.h | 1 + intl/msg_hash_lbl.h | 2 + intl/msg_hash_us.h | 16 ++ menu/cbs/menu_cbs_ok.c | 4 + menu/cbs/menu_cbs_sublabel.c | 4 + menu/menu_displaylist.c | 27 +++- menu/menu_displaylist.h | 4 - menu/menu_driver.c | 1 + menu/menu_setting.c | 48 +++++- msg_hash.h | 3 + playlist.c | 240 ++++++++++++++++++----------- playlist.h | 12 ++ retroarch.c | 53 +++++-- tasks/task_content.c | 1 + tasks/task_database.c | 3 - tasks/task_netplay_find_content.c | 4 +- tasks/task_pl_thumbnail_download.c | 4 - tasks/task_playlist_manager.c | 4 - ui/drivers/qt/ui_qt_window.cpp | 4 - 22 files changed, 324 insertions(+), 135 deletions(-) diff --git a/command.h b/command.h index ab375eca2e..db0ffb3d1c 100644 --- a/command.h +++ b/command.h @@ -106,6 +106,10 @@ enum event_command CMD_EVENT_HISTORY_DEINIT, /* Initializes history playlist. */ CMD_EVENT_HISTORY_INIT, + /* Deinitializes favourties playlist. */ + CMD_EVENT_FAVORITES_DEINIT, + /* Initializes favourties playlist. */ + CMD_EVENT_FAVORITES_INIT, /* Deinitializes core information. */ CMD_EVENT_CORE_INFO_DEINIT, /* Initializes core information. */ diff --git a/config.def.h b/config.def.h index 7c78d83a08..1696872ff4 100644 --- a/config.def.h +++ b/config.def.h @@ -792,6 +792,10 @@ static const bool network_on_demand_thumbnails = false; /* Number of entries that will be kept in content history playlist file. */ static const unsigned default_content_history_size = 100; +/* Number of entries that will be kept in content favorites playlist file. + * -1 == 'unlimited' (99999) */ +static const int default_content_favorites_size = 100; + /* Sort all playlists (apart from histories) alphabetically */ static const bool playlist_sort_alphabetical = true; diff --git a/configuration.c b/configuration.c index 1c19511224..0482e44a02 100644 --- a/configuration.c +++ b/configuration.c @@ -1881,6 +1881,7 @@ static struct config_int_setting *populate_settings_int(settings_t *settings, in #ifdef HAVE_D3D12 SETTING_INT("d3d12_gpu_index", &settings->ints.d3d12_gpu_index, true, DEFAULT_D3D12_GPU_INDEX, false); #endif + SETTING_INT("content_favorites_size", &settings->ints.content_favorites_size, true, default_content_favorites_size, false); *size = count; @@ -3126,6 +3127,21 @@ static bool config_load_file(const char *path, settings_t *settings) if (!config_entry_exists(conf, "user_language")) msg_hash_set_uint(MSG_HASH_USER_LANGUAGE, frontend_driver_get_user_language()); + /* If this is the first run of an existing installation + * after the independent favourites playlist size limit was + * added, set the favourites limit according to the current + * history playlist size limit. (Have to do this, otherwise + * users with large custom history size limits may lose + * favourites entries when updating RetroArch...) */ + if ( config_entry_exists(conf, "content_history_size") && + !config_entry_exists(conf, "content_favorites_size")) + { + if (settings->uints.content_history_size > 999) + settings->ints.content_favorites_size = -1; + else + settings->ints.content_favorites_size = (int)settings->uints.content_history_size; + } + ret = true; end: if (conf) diff --git a/configuration.h b/configuration.h index 976465a39e..0651898d19 100644 --- a/configuration.h +++ b/configuration.h @@ -401,6 +401,7 @@ typedef struct settings #ifdef HAVE_D3D12 int d3d12_gpu_index; #endif + int content_favorites_size; } ints; struct diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index f433e13eb6..220a6ef5d0 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -201,6 +201,8 @@ MSG_HASH(MENU_ENUM_LABEL_CONTENT_DATABASE_DIRECTORY, "content_database_path") MSG_HASH(MENU_ENUM_LABEL_CONTENT_HISTORY_SIZE, "content_history_size") +MSG_HASH(MENU_ENUM_LABEL_CONTENT_FAVORITES_SIZE, + "content_favorites_size") MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_ENTRY_REMOVE, "playlist_entry_remove_enable") MSG_HASH(MENU_ENUM_LABEL_CONTENT_SETTINGS, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index ed13497a41..d35518b31f 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -605,6 +605,14 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_SIZE, "History List Size" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_FAVORITES_SIZE, + "Favorites List Size" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_FAVORITES_SIZE, + "Limit the number of entries in the favorites playlist. Once limit is reached, new additions will be prevented until old entries are removed. Setting a value of -1 allows 'unlimited' (99999) entries. WARNING: Reducing the value will delete existing entries!" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_REMOVE, "Allow to remove entries" @@ -4379,6 +4387,10 @@ MSG_HASH( MSG_ADDED_TO_FAVORITES, "Added to favorites" ) +MSG_HASH( + MSG_ADD_TO_FAVORITES_FAILED, + "Failed to add favorite: playlist full" + ) MSG_HASH( MSG_SET_CORE_ASSOCIATION, "Core set: " @@ -4887,6 +4899,10 @@ MSG_HASH( MSG_LOADING_HISTORY_FILE, "Loading history file" ) +MSG_HASH( + MSG_LOADING_FAVORITES_FILE, + "Loading favorites file" + ) MSG_HASH( MSG_LOADING_STATE, "Loading state" diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 1f9eb35a29..9623d5d51b 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -4332,6 +4332,7 @@ static int action_ok_delete_entry(const char *path, #ifdef HAVE_IMAGEVIEWER char *def_conf_img_path = NULL; #endif + char *def_conf_fav_path = NULL; menu_handle_t *menu = NULL; playlist_t *playlist = playlist_get_cached(); @@ -4347,6 +4348,7 @@ static int action_ok_delete_entry(const char *path, #ifdef HAVE_IMAGEVIEWER def_conf_img_path = playlist_get_conf_path(g_defaults.image_history); #endif + def_conf_fav_path = playlist_get_conf_path(g_defaults.content_favorites); if (string_is_equal(conf_path, def_conf_path)) playlist = g_defaults.content_history; @@ -4360,6 +4362,8 @@ static int action_ok_delete_entry(const char *path, else if (string_is_equal(conf_path, def_conf_img_path)) playlist = g_defaults.image_history; #endif + else if (string_is_equal(conf_path, def_conf_fav_path)) + playlist = g_defaults.content_favorites; if (playlist) { diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index e06c8ebcaf..4290a1adf2 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -234,6 +234,7 @@ default_sublabel_macro(action_bind_sublabel_video_disable_composition, MENU_ default_sublabel_macro(action_bind_sublabel_video_smooth, MENU_ENUM_SUBLABEL_VIDEO_SMOOTH) default_sublabel_macro(action_bind_sublabel_history_list_enable, MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE) default_sublabel_macro(action_bind_sublabel_content_history_size, MENU_ENUM_SUBLABEL_CONTENT_HISTORY_SIZE) +default_sublabel_macro(action_bind_sublabel_content_favorites_size, MENU_ENUM_SUBLABEL_CONTENT_FAVORITES_SIZE) default_sublabel_macro(action_bind_sublabel_menu_input_unified_controls, MENU_ENUM_SUBLABEL_INPUT_UNIFIED_MENU_CONTROLS) default_sublabel_macro(action_bind_sublabel_quit_press_twice, MENU_ENUM_SUBLABEL_QUIT_PRESS_TWICE) default_sublabel_macro(action_bind_sublabel_onscreen_notifications_enable, MENU_ENUM_SUBLABEL_VIDEO_FONT_ENABLE) @@ -2544,6 +2545,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_CONTENT_HISTORY_SIZE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_content_history_size); break; + case MENU_ENUM_LABEL_CONTENT_FAVORITES_SIZE: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_content_favorites_size); + break; case MENU_ENUM_LABEL_NETPLAY_USE_MITM_SERVER: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_use_mitm_server); break; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index d344c7c8eb..f4aedc77ef 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -1669,12 +1669,29 @@ end: static void menu_displaylist_set_new_playlist( menu_handle_t *menu, const char *path) { - menu->db_playlist_file[0] = '\0'; + unsigned playlist_size = COLLECTION_SIZE; + const char *playlist_file_name = path_basename(path); + settings_t *settings = config_get_ptr(); + + menu->db_playlist_file[0] = '\0'; if (playlist_get_cached()) playlist_free_cached(); - if (playlist_init_cached(path, COLLECTION_SIZE)) + /* Get proper playlist capacity */ + if (settings && !string_is_empty(playlist_file_name)) + { + if (string_is_equal(playlist_file_name, file_path_str(FILE_PATH_CONTENT_HISTORY)) || + string_is_equal(playlist_file_name, file_path_str(FILE_PATH_CONTENT_MUSIC_HISTORY)) || + string_is_equal(playlist_file_name, file_path_str(FILE_PATH_CONTENT_VIDEO_HISTORY)) || + string_is_equal(playlist_file_name, file_path_str(FILE_PATH_CONTENT_IMAGE_HISTORY))) + playlist_size = settings->uints.content_history_size; + else if (string_is_equal(playlist_file_name, file_path_str(FILE_PATH_CONTENT_FAVORITES))) + if (settings->ints.content_favorites_size >= 0) + playlist_size = (unsigned)settings->ints.content_favorites_size; + } + + if (playlist_init_cached(path, playlist_size)) strlcpy( menu->db_playlist_file, path, @@ -6493,6 +6510,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist_build_info_t build_list[] = { {MENU_ENUM_LABEL_HISTORY_LIST_ENABLE, PARSE_ONLY_BOOL}, {MENU_ENUM_LABEL_CONTENT_HISTORY_SIZE, PARSE_ONLY_UINT}, + {MENU_ENUM_LABEL_CONTENT_FAVORITES_SIZE, PARSE_ONLY_INT }, {MENU_ENUM_LABEL_PLAYLIST_ENTRY_RENAME, PARSE_ONLY_BOOL}, {MENU_ENUM_LABEL_PLAYLIST_ENTRY_REMOVE, PARSE_ONLY_UINT}, {MENU_ENUM_LABEL_PLAYLIST_SORT_ALPHABETICAL, PARSE_ONLY_BOOL}, @@ -8541,12 +8559,11 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, setting->get_string_representation(setting, val_s, sizeof(val_s)); snprintf(val_d, sizeof(val_d), "%d", setting->enum_idx); - if (menu_entries_append_enum(info->list, + menu_entries_append_enum(info->list, val_s, val_d, MENU_ENUM_LABEL_NO_ITEMS, - setting_type, val, 0)) - count++; + setting_type, val, 0); if (!checked_found && val == orig_value) { diff --git a/menu/menu_displaylist.h b/menu/menu_displaylist.h index e0c2304a03..077ba7cd1b 100644 --- a/menu/menu_displaylist.h +++ b/menu/menu_displaylist.h @@ -26,10 +26,6 @@ #include "../msg_hash.h" #include "../setting_list.h" -#ifndef COLLECTION_SIZE -#define COLLECTION_SIZE 99999 -#endif - RETRO_BEGIN_DECLS /* NOTE: Order matters - only add new entries at diff --git a/menu/menu_driver.c b/menu/menu_driver.c index 0f17c4f5d1..ccc1226f70 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -2465,6 +2465,7 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) menu_entries_ctl(MENU_ENTRIES_CTL_DEINIT, NULL); command_event(CMD_EVENT_HISTORY_DEINIT, NULL); + command_event(CMD_EVENT_FAVORITES_DEINIT, NULL); menu_dialog_reset(); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 72659bc3ff..ec0db9a831 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -91,6 +91,7 @@ #include "../gfx/video_display_server.h" #include "../managers/cheat_manager.h" #include "../verbosity.h" +#include "../playlist.h" #include "../tasks/tasks_internal.h" @@ -6029,6 +6030,32 @@ void general_write_handler(rarch_setting_t *setting) } break; + case MENU_ENUM_LABEL_CONTENT_FAVORITES_SIZE: + { + unsigned new_capacity; + + /* Get new size */ + if (settings->ints.content_favorites_size < 0) + new_capacity = COLLECTION_SIZE; + else + new_capacity = (unsigned)settings->ints.content_favorites_size; + + /* Check whether capacity has changed */ + if (new_capacity != playlist_capacity(g_defaults.content_favorites)) + { + /* Remove excess entries, if required */ + while (playlist_size(g_defaults.content_favorites) > new_capacity) + playlist_delete_index( + g_defaults.content_favorites, + playlist_size(g_defaults.content_favorites) - 1); + + /* In all cases, need to close and reopen + * playlist file (to update maximum capacity) */ + command_event(CMD_EVENT_FAVORITES_DEINIT, NULL); + command_event(CMD_EVENT_FAVORITES_INIT, NULL); + } + } + break; default: break; } @@ -13287,12 +13314,31 @@ static bool setting_append_list( general_write_handler, general_read_handler); (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; - menu_settings_list_current_add_range(list, list_info, 0, 0, 1.0, true, false); + menu_settings_list_current_add_range(list, list_info, 0.0f, (float)COLLECTION_SIZE, 1.0f, true, false); END_SUB_GROUP(list, list_info, parent_group); START_SUB_GROUP(list, list_info, "Playlist", &group_info, &subgroup_info, parent_group); + /* Favourites size is traditionally associtated with + * history size, but they are in fact unrelated. We + * therefore place this entry outside the "History" + * sub group. */ + CONFIG_INT( + list, list_info, + &settings->ints.content_favorites_size, + MENU_ENUM_LABEL_CONTENT_FAVORITES_SIZE, + MENU_ENUM_LABEL_VALUE_CONTENT_FAVORITES_SIZE, + default_content_favorites_size, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; + (*list)[list_info->index - 1].offset_by = -1; + menu_settings_list_current_add_range(list, list_info, -1.0f, 999.0f, 1.0f, true, true); + CONFIG_BOOL( list, list_info, &settings->bools.playlist_entry_rename, diff --git a/msg_hash.h b/msg_hash.h index 58c4060799..c877a914e7 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -201,6 +201,7 @@ enum msg_hash_enums MSG_RESAMPLER_QUALITY_HIGHEST, MSG_DISCORD_CONNECTION_REQUEST, MSG_ADDED_TO_FAVORITES, + MSG_ADD_TO_FAVORITES_FAILED, MSG_SET_CORE_ASSOCIATION, MSG_RESET_CORE_ASSOCIATION, MSG_CORE_ASSOCIATION_RESET, @@ -287,6 +288,7 @@ enum msg_hash_enums MSG_FRAMES, MSG_FOUND_SHADER, MSG_LOADING_HISTORY_FILE, + MSG_LOADING_FAVORITES_FILE, MSG_COULD_NOT_READ_STATE_FROM_MOVIE, MSG_MOVIE_FILE_IS_NOT_A_VALID_BSV1_FILE, MSG_OVERRIDES_SAVED_SUCCESSFULLY, @@ -1031,6 +1033,7 @@ enum msg_hash_enums /* Playlists */ MENU_LABEL(HISTORY_LIST_ENABLE), MENU_LABEL(CONTENT_HISTORY_SIZE), + MENU_LABEL(CONTENT_FAVORITES_SIZE), MENU_LABEL(PLAYLIST_ENTRY_REMOVE), MENU_LABEL(PLAYLIST_ENTRY_RENAME), MENU_LABEL(GOTO_FAVORITES), diff --git a/playlist.c b/playlist.c index a112a2b7d8..9f02c03864 100644 --- a/playlist.c +++ b/playlist.c @@ -70,6 +70,7 @@ typedef struct char *current_items_string; bool in_items; bool in_subsystem_roms; + bool capacity_exceeded; } JSONContext; static playlist_t *playlist_cached = NULL; @@ -244,6 +245,57 @@ void playlist_get_index(playlist_t *playlist, *entry = &playlist->entries[idx]; } +/** + * playlist_free_entry: + * @entry : Playlist entry handle. + * + * Frees playlist entry. + **/ +static void playlist_free_entry(struct playlist_entry *entry) +{ + if (!entry) + return; + + if (entry->path != NULL) + free(entry->path); + if (entry->label != NULL) + free(entry->label); + if (entry->core_path != NULL) + free(entry->core_path); + if (entry->core_name != NULL) + free(entry->core_name); + if (entry->db_name != NULL) + free(entry->db_name); + if (entry->crc32 != NULL) + free(entry->crc32); + if (entry->subsystem_ident != NULL) + free(entry->subsystem_ident); + if (entry->subsystem_name != NULL) + free(entry->subsystem_name); + if (entry->subsystem_roms != NULL) + string_list_free(entry->subsystem_roms); + + entry->path = NULL; + entry->label = NULL; + entry->core_path = NULL; + entry->core_name = NULL; + entry->db_name = NULL; + entry->crc32 = NULL; + entry->subsystem_ident = NULL; + entry->subsystem_name = NULL; + entry->subsystem_roms = NULL; + entry->runtime_status = PLAYLIST_RUNTIME_UNKNOWN; + entry->runtime_hours = 0; + entry->runtime_minutes = 0; + entry->runtime_seconds = 0; + entry->last_played_year = 0; + entry->last_played_month = 0; + entry->last_played_day = 0; + entry->last_played_hour = 0; + entry->last_played_minute = 0; + entry->last_played_second = 0; +} + /** * playlist_delete_index: * @playlist : Playlist handle. @@ -254,11 +306,22 @@ void playlist_get_index(playlist_t *playlist, void playlist_delete_index(playlist_t *playlist, size_t idx) { + struct playlist_entry *entry_to_delete = NULL; + if (!playlist) return; + if (idx >= playlist->size) + return; + playlist->size = playlist->size - 1; + /* Free unwanted entry */ + entry_to_delete = (struct playlist_entry *)(playlist->entries + idx); + if (entry_to_delete) + playlist_free_entry(entry_to_delete); + + /* Shift remaining entries to fill the gap */ memmove(playlist->entries + idx, playlist->entries + idx + 1, (playlist->size - idx) * sizeof(struct playlist_entry)); @@ -315,57 +378,6 @@ bool playlist_entry_exists(playlist_t *playlist, return false; } -/** - * playlist_free_entry: - * @entry : Playlist entry handle. - * - * Frees playlist entry. - **/ -static void playlist_free_entry(struct playlist_entry *entry) -{ - if (!entry) - return; - - if (entry->path != NULL) - free(entry->path); - if (entry->label != NULL) - free(entry->label); - if (entry->core_path != NULL) - free(entry->core_path); - if (entry->core_name != NULL) - free(entry->core_name); - if (entry->db_name != NULL) - free(entry->db_name); - if (entry->crc32 != NULL) - free(entry->crc32); - if (entry->subsystem_ident != NULL) - free(entry->subsystem_ident); - if (entry->subsystem_name != NULL) - free(entry->subsystem_name); - if (entry->subsystem_roms != NULL) - string_list_free(entry->subsystem_roms); - - entry->path = NULL; - entry->label = NULL; - entry->core_path = NULL; - entry->core_name = NULL; - entry->db_name = NULL; - entry->crc32 = NULL; - entry->subsystem_ident = NULL; - entry->subsystem_name = NULL; - entry->subsystem_roms = NULL; - entry->runtime_status = PLAYLIST_RUNTIME_UNKNOWN; - entry->runtime_hours = 0; - entry->runtime_minutes = 0; - entry->runtime_seconds = 0; - entry->last_played_year = 0; - entry->last_played_month = 0; - entry->last_played_day = 0; - entry->last_played_hour = 0; - entry->last_played_minute = 0; - entry->last_played_second = 0; -} - void playlist_update(playlist_t *playlist, size_t idx, const struct playlist_entry *update_entry) { @@ -1538,6 +1550,20 @@ size_t playlist_size(playlist_t *playlist) return playlist->size; } +/** + * playlist_capacity: + * @playlist : Playlist handle. + * + * Gets maximum capacity of playlist. + * Returns: maximum capacity of playlist. + **/ +size_t playlist_capacity(playlist_t *playlist) +{ + if (!playlist) + return 0; + return playlist->cap; +} + static JSON_Parser_HandlerResult JSONStartArrayHandler(JSON_Parser parser) { JSONContext *pCtx = (JSONContext*)JSON_Parser_GetUserData(parser); @@ -1601,13 +1627,24 @@ static JSON_Parser_HandlerResult JSONStartObjectHandler(JSON_Parser parser) if (pCtx->in_items && pCtx->object_depth == 2) { - if (pCtx->array_depth == 1) + if ((pCtx->array_depth == 1) && !pCtx->capacity_exceeded) { if (pCtx->playlist->size < pCtx->playlist->cap) pCtx->current_entry = &pCtx->playlist->entries[pCtx->playlist->size]; else - /* hit max item limit */ - return JSON_Parser_Abort; + { + /* Hit max item limit. + * Note: We can't just abort here, since there may + * be more metadata to read at the end of the file... */ + RARCH_WARN("JSON file contains more entries than current playlist capacity. Excess entries will be discarded.\n"); + pCtx->capacity_exceeded = true; + pCtx->current_entry = NULL; + /* In addition, since we are discarding excess entries, + * the playlist must be flagged as being modified + * (i.e. the playlist is not the same as when it was + * last saved to disk...) */ + pCtx->playlist->modified = true; + } } } @@ -1620,7 +1657,7 @@ static JSON_Parser_HandlerResult JSONEndObjectHandler(JSON_Parser parser) if (pCtx->in_items && pCtx->object_depth == 2) { - if (pCtx->array_depth == 1) + if ((pCtx->array_depth == 1) && !pCtx->capacity_exceeded) pCtx->playlist->size++; } @@ -1656,7 +1693,6 @@ static JSON_Parser_HandlerResult JSONStringHandler(JSON_Parser parser, char *pVa { if (*pCtx->current_entry_val) free(*pCtx->current_entry_val); - *pCtx->current_entry_val = strdup(pValue); } else @@ -1756,45 +1792,54 @@ static JSON_Parser_HandlerResult JSONObjectMemberHandler(JSON_Parser parser, cha pCtx->current_items_string = strdup(pValue); } - if (string_is_equal(pValue, "path")) - pCtx->current_entry_val = &pCtx->current_entry->path; - else if (string_is_equal(pValue, "label")) - pCtx->current_entry_val = &pCtx->current_entry->label; - else if (string_is_equal(pValue, "core_path")) - pCtx->current_entry_val = &pCtx->current_entry->core_path; - else if (string_is_equal(pValue, "core_name")) - pCtx->current_entry_val = &pCtx->current_entry->core_name; - else if (string_is_equal(pValue, "crc32")) - pCtx->current_entry_val = &pCtx->current_entry->crc32; - else if (string_is_equal(pValue, "db_name")) - pCtx->current_entry_val = &pCtx->current_entry->db_name; - else if (string_is_equal(pValue, "subsystem_ident")) - pCtx->current_entry_val = &pCtx->current_entry->subsystem_ident; - else if (string_is_equal(pValue, "subsystem_name")) - pCtx->current_entry_val = &pCtx->current_entry->subsystem_name; - else if (string_is_equal(pValue, "subsystem_roms")) - pCtx->current_entry_string_list_val = &pCtx->current_entry->subsystem_roms; - else if (string_is_equal(pValue, "runtime_hours")) - pCtx->current_entry_uint_val = &pCtx->current_entry->runtime_hours; - else if (string_is_equal(pValue, "runtime_minutes")) - pCtx->current_entry_uint_val = &pCtx->current_entry->runtime_minutes; - else if (string_is_equal(pValue, "runtime_seconds")) - pCtx->current_entry_uint_val = &pCtx->current_entry->runtime_seconds; - else if (string_is_equal(pValue, "last_played_year")) - pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_year; - else if (string_is_equal(pValue, "last_played_month")) - pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_month; - else if (string_is_equal(pValue, "last_played_day")) - pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_day; - else if (string_is_equal(pValue, "last_played_hour")) - pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_hour; - else if (string_is_equal(pValue, "last_played_minute")) - pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_minute; - else if (string_is_equal(pValue, "last_played_second")) - pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_second; + if (!pCtx->capacity_exceeded) + { + if (string_is_equal(pValue, "path")) + pCtx->current_entry_val = &pCtx->current_entry->path; + else if (string_is_equal(pValue, "label")) + pCtx->current_entry_val = &pCtx->current_entry->label; + else if (string_is_equal(pValue, "core_path")) + pCtx->current_entry_val = &pCtx->current_entry->core_path; + else if (string_is_equal(pValue, "core_name")) + pCtx->current_entry_val = &pCtx->current_entry->core_name; + else if (string_is_equal(pValue, "crc32")) + pCtx->current_entry_val = &pCtx->current_entry->crc32; + else if (string_is_equal(pValue, "db_name")) + pCtx->current_entry_val = &pCtx->current_entry->db_name; + else if (string_is_equal(pValue, "subsystem_ident")) + pCtx->current_entry_val = &pCtx->current_entry->subsystem_ident; + else if (string_is_equal(pValue, "subsystem_name")) + pCtx->current_entry_val = &pCtx->current_entry->subsystem_name; + else if (string_is_equal(pValue, "subsystem_roms")) + pCtx->current_entry_string_list_val = &pCtx->current_entry->subsystem_roms; + else if (string_is_equal(pValue, "runtime_hours")) + pCtx->current_entry_uint_val = &pCtx->current_entry->runtime_hours; + else if (string_is_equal(pValue, "runtime_minutes")) + pCtx->current_entry_uint_val = &pCtx->current_entry->runtime_minutes; + else if (string_is_equal(pValue, "runtime_seconds")) + pCtx->current_entry_uint_val = &pCtx->current_entry->runtime_seconds; + else if (string_is_equal(pValue, "last_played_year")) + pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_year; + else if (string_is_equal(pValue, "last_played_month")) + pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_month; + else if (string_is_equal(pValue, "last_played_day")) + pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_day; + else if (string_is_equal(pValue, "last_played_hour")) + pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_hour; + else if (string_is_equal(pValue, "last_played_minute")) + pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_minute; + else if (string_is_equal(pValue, "last_played_second")) + pCtx->current_entry_uint_val = &pCtx->current_entry->last_played_second; + else + { + /* ignore unknown members */ + } + } else { - /* ignore unknown members */ + pCtx->current_entry_val = NULL; + pCtx->current_entry_uint_val = NULL; + pCtx->current_entry_string_list_val = NULL; } } } @@ -1950,7 +1995,14 @@ static bool playlist_read_file( if (!JSON_Parser_Parse(context.parser, chunk, length, JSON_False)) { - RARCH_WARN("Error parsing chunk:\n---snip---\n%s\n---snip---\n", chunk); + /* Note: Chunk may not be null-terminated. + * It is therefore dangerous to print its contents. + * Setting a size limit here mitigates the issue, but + * in general this is not good practice... + * Addendum: RARCH_WARN() actually limits the printed + * buffer size anyway, so this warning message is most + * likely worthless... */ + RARCH_WARN("Error parsing chunk:\n---snip---\n%.*s\n---snip---\n", 4096, chunk); JSONLogError(&context); goto json_cleanup; } diff --git a/playlist.h b/playlist.h index ce29f849cb..f112616f2a 100644 --- a/playlist.h +++ b/playlist.h @@ -26,6 +26,9 @@ RETRO_BEGIN_DECLS +/* Default maximum playlist size */ +#define COLLECTION_SIZE 99999 + typedef struct content_playlist playlist_t; enum playlist_runtime_status @@ -103,6 +106,15 @@ void playlist_clear(playlist_t *playlist); **/ size_t playlist_size(playlist_t *playlist); +/** + * playlist_capacity: + * @playlist : Playlist handle. + * + * Gets maximum capacity of playlist. + * Returns: maximum capacity of playlist. + **/ +size_t playlist_capacity(playlist_t *playlist); + /** * playlist_get_index: * @playlist : Playlist handle. diff --git a/retroarch.c b/retroarch.c index c0c8af58d0..8a7e35f3fd 100644 --- a/retroarch.c +++ b/retroarch.c @@ -4141,13 +4141,6 @@ TODO: Add a setting for these tweaks */ } g_defaults.content_history = NULL; - if (g_defaults.content_favorites) - { - playlist_write_file(g_defaults.content_favorites); - playlist_free(g_defaults.content_favorites); - } - g_defaults.content_favorites = NULL; - if (g_defaults.music_history) { playlist_write_file(g_defaults.music_history); @@ -4191,13 +4184,6 @@ TODO: Add a setting for these tweaks */ settings->paths.path_content_history, content_history_size); - RARCH_LOG("%s: [%s].\n", - msg_hash_to_str(MSG_LOADING_HISTORY_FILE), - settings->paths.path_content_favorites); - g_defaults.content_favorites = playlist_init( - settings->paths.path_content_favorites, - content_history_size); - RARCH_LOG("%s: [%s].\n", msg_hash_to_str(MSG_LOADING_HISTORY_FILE), settings->paths.path_content_music_history); @@ -4224,6 +4210,34 @@ TODO: Add a setting for these tweaks */ #endif } break; + case CMD_EVENT_FAVORITES_DEINIT: + if (g_defaults.content_favorites) + { + playlist_write_file(g_defaults.content_favorites); + playlist_free(g_defaults.content_favorites); + g_defaults.content_favorites = NULL; + } + break; + case CMD_EVENT_FAVORITES_INIT: + { + settings_t *settings = configuration_settings; + unsigned content_favorites_size; + + if (settings->ints.content_favorites_size < 0) + content_favorites_size = COLLECTION_SIZE; + else + content_favorites_size = (unsigned)settings->ints.content_favorites_size; + + command_event(CMD_EVENT_FAVORITES_DEINIT, NULL); + + RARCH_LOG("%s: [%s].\n", + msg_hash_to_str(MSG_LOADING_FAVORITES_FILE), + settings->paths.path_content_favorites); + g_defaults.content_favorites = playlist_init( + settings->paths.path_content_favorites, + content_favorites_size); + } + break; case CMD_EVENT_CORE_INFO_DEINIT: core_info_deinit_list(); core_info_free_current_core(); @@ -4322,6 +4336,16 @@ TODO: Add a setting for these tweaks */ { struct string_list *str_list = (struct string_list*)data; + /* Check whether favourties playlist is at capacity */ + if (playlist_size(g_defaults.content_favorites) >= + playlist_capacity(g_defaults.content_favorites)) + { + runloop_msg_queue_push( + msg_hash_to_str(MSG_ADD_TO_FAVORITES_FAILED), 1, 180, true, NULL, + MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_ERROR); + return false; + } + if (str_list) { if (str_list->size >= 6) @@ -5150,6 +5174,7 @@ int rarch_main(int argc, char *argv[], void *data) libretro_free_system_info(&runloop_system.info); command_event(CMD_EVENT_HISTORY_DEINIT, NULL); + command_event(CMD_EVENT_FAVORITES_DEINIT, NULL); configuration_settings = (settings_t*)calloc(1, sizeof(settings_t)); diff --git a/tasks/task_content.c b/tasks/task_content.c index 6d91017eff..6ab6885575 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -658,6 +658,7 @@ static bool content_load(content_ctx_info_t *info) #endif command_event(CMD_EVENT_HISTORY_INIT, NULL); + command_event(CMD_EVENT_FAVORITES_INIT, NULL); command_event(CMD_EVENT_RESUME, NULL); command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL); diff --git a/tasks/task_database.c b/tasks/task_database.c index 54e4b766e6..abc3207c2f 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -42,9 +42,6 @@ #include "../gfx/video_display_server.h" #endif #include "../verbosity.h" -#ifndef COLLECTION_SIZE -#define COLLECTION_SIZE 99999 -#endif typedef struct database_state_handle { diff --git a/tasks/task_netplay_find_content.c b/tasks/task_netplay_find_content.c index df762f1ba6..7192e62366 100644 --- a/tasks/task_netplay_find_content.c +++ b/tasks/task_netplay_find_content.c @@ -270,7 +270,7 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) continue; RARCH_LOG("[lobby] searching playlist: %s\n", lpl_path); - playlist = playlist_init(lpl_path, 99999); + playlist = playlist_init(lpl_path, COLLECTION_SIZE); playlist_size = playlist_get_size(playlist); for (j = 0; j < playlist_size; j++) @@ -344,7 +344,7 @@ static void task_netplay_crc_scan_handler(retro_task_t *task) continue; RARCH_LOG("[lobby] searching rom %d/%d (%s) in playlist: %s\n", i + 1, game_list->size, game_list->elems[i].data, lpl_path); - playlist = playlist_init(lpl_path, 99999); + playlist = playlist_init(lpl_path, COLLECTION_SIZE); playlist_size = playlist_get_size(playlist); for (k = 0; k < playlist_size && !found[i]; k++) diff --git a/tasks/task_pl_thumbnail_download.c b/tasks/task_pl_thumbnail_download.c index 20649b1a3d..2c87be242f 100644 --- a/tasks/task_pl_thumbnail_download.c +++ b/tasks/task_pl_thumbnail_download.c @@ -39,10 +39,6 @@ #endif #endif -#ifndef COLLECTION_SIZE -#define COLLECTION_SIZE 99999 -#endif - enum pl_thumb_status { PL_THUMB_BEGIN = 0, diff --git a/tasks/task_playlist_manager.c b/tasks/task_playlist_manager.c index 0de83ef450..5a59ff86a6 100644 --- a/tasks/task_playlist_manager.c +++ b/tasks/task_playlist_manager.c @@ -29,10 +29,6 @@ #include "../file_path_special.h" #include "../playlist.h" -#ifndef COLLECTION_SIZE -#define COLLECTION_SIZE 99999 -#endif - enum pl_manager_status { PL_MANAGER_BEGIN = 0, diff --git a/ui/drivers/qt/ui_qt_window.cpp b/ui/drivers/qt/ui_qt_window.cpp index 74a124e8c0..883d6ed8a7 100644 --- a/ui/drivers/qt/ui_qt_window.cpp +++ b/ui/drivers/qt/ui_qt_window.cpp @@ -95,10 +95,6 @@ extern "C" { #define TIMER_MSEC 1000 /* periodic timer for gathering statistics */ #define STATUS_MSG_THROTTLE_MSEC 250 -#ifndef COLLECTION_SIZE -#define COLLECTION_SIZE 99999 -#endif - #define GENERIC_FOLDER_ICON "/xmb/dot-art/png/folder.png" #define HIRAGANA_START 0x3041U #define HIRAGANA_END 0x3096U From 9617856c5c3e5e642eb702ac7eea13abf6d13012 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Wed, 31 Jul 2019 11:32:19 +0100 Subject: [PATCH 2/2] Remove favourites init/deinit from command event, and replace with seperate functions in retroarch.h/.c --- command.h | 4 --- menu/menu_driver.c | 2 +- menu/menu_setting.c | 4 +-- retroarch.c | 63 ++++++++++++++++++++++++-------------------- retroarch.h | 4 +++ tasks/task_content.c | 2 +- 6 files changed, 42 insertions(+), 37 deletions(-) diff --git a/command.h b/command.h index db0ffb3d1c..ab375eca2e 100644 --- a/command.h +++ b/command.h @@ -106,10 +106,6 @@ enum event_command CMD_EVENT_HISTORY_DEINIT, /* Initializes history playlist. */ CMD_EVENT_HISTORY_INIT, - /* Deinitializes favourties playlist. */ - CMD_EVENT_FAVORITES_DEINIT, - /* Initializes favourties playlist. */ - CMD_EVENT_FAVORITES_INIT, /* Deinitializes core information. */ CMD_EVENT_CORE_INFO_DEINIT, /* Initializes core information. */ diff --git a/menu/menu_driver.c b/menu/menu_driver.c index ccc1226f70..e33a5c360e 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -2465,7 +2465,7 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) menu_entries_ctl(MENU_ENTRIES_CTL_DEINIT, NULL); command_event(CMD_EVENT_HISTORY_DEINIT, NULL); - command_event(CMD_EVENT_FAVORITES_DEINIT, NULL); + rarch_favorites_deinit(); menu_dialog_reset(); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index ec0db9a831..223652c23a 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -6051,8 +6051,8 @@ void general_write_handler(rarch_setting_t *setting) /* In all cases, need to close and reopen * playlist file (to update maximum capacity) */ - command_event(CMD_EVENT_FAVORITES_DEINIT, NULL); - command_event(CMD_EVENT_FAVORITES_INIT, NULL); + rarch_favorites_deinit(); + rarch_favorites_init(); } } break; diff --git a/retroarch.c b/retroarch.c index 8a7e35f3fd..226d11474e 100644 --- a/retroarch.c +++ b/retroarch.c @@ -4210,34 +4210,6 @@ TODO: Add a setting for these tweaks */ #endif } break; - case CMD_EVENT_FAVORITES_DEINIT: - if (g_defaults.content_favorites) - { - playlist_write_file(g_defaults.content_favorites); - playlist_free(g_defaults.content_favorites); - g_defaults.content_favorites = NULL; - } - break; - case CMD_EVENT_FAVORITES_INIT: - { - settings_t *settings = configuration_settings; - unsigned content_favorites_size; - - if (settings->ints.content_favorites_size < 0) - content_favorites_size = COLLECTION_SIZE; - else - content_favorites_size = (unsigned)settings->ints.content_favorites_size; - - command_event(CMD_EVENT_FAVORITES_DEINIT, NULL); - - RARCH_LOG("%s: [%s].\n", - msg_hash_to_str(MSG_LOADING_FAVORITES_FILE), - settings->paths.path_content_favorites); - g_defaults.content_favorites = playlist_init( - settings->paths.path_content_favorites, - content_favorites_size); - } - break; case CMD_EVENT_CORE_INFO_DEINIT: core_info_deinit_list(); core_info_free_current_core(); @@ -5174,7 +5146,7 @@ int rarch_main(int argc, char *argv[], void *data) libretro_free_system_info(&runloop_system.info); command_event(CMD_EVENT_HISTORY_DEINIT, NULL); - command_event(CMD_EVENT_FAVORITES_DEINIT, NULL); + rarch_favorites_deinit(); configuration_settings = (settings_t*)calloc(1, sizeof(settings_t)); @@ -24776,6 +24748,39 @@ enum retro_language rarch_get_language_from_iso(const char *iso639) return lang; } +void rarch_favorites_init(void) +{ + settings_t *settings = configuration_settings; + unsigned content_favorites_size; + + if (!settings) + return; + + if (settings->ints.content_favorites_size < 0) + content_favorites_size = COLLECTION_SIZE; + else + content_favorites_size = (unsigned)settings->ints.content_favorites_size; + + rarch_favorites_deinit(); + + RARCH_LOG("%s: [%s].\n", + msg_hash_to_str(MSG_LOADING_FAVORITES_FILE), + settings->paths.path_content_favorites); + g_defaults.content_favorites = playlist_init( + settings->paths.path_content_favorites, + content_favorites_size); +} + +void rarch_favorites_deinit(void) +{ + if (g_defaults.content_favorites) + { + playlist_write_file(g_defaults.content_favorites); + playlist_free(g_defaults.content_favorites); + g_defaults.content_favorites = NULL; + } +} + /* Libretro core loader */ static void retro_run_null(void) diff --git a/retroarch.h b/retroarch.h index d7e84ee857..87a97c44bc 100644 --- a/retroarch.h +++ b/retroarch.h @@ -380,6 +380,10 @@ void rarch_log_file_deinit(void); enum retro_language rarch_get_language_from_iso(const char *lang); +void rarch_favorites_init(void); + +void rarch_favorites_deinit(void); + /* Audio */ #ifdef HAVE_AUDIOMIXER diff --git a/tasks/task_content.c b/tasks/task_content.c index 6ab6885575..00326d5e6d 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -658,7 +658,7 @@ static bool content_load(content_ctx_info_t *info) #endif command_event(CMD_EVENT_HISTORY_INIT, NULL); - command_event(CMD_EVENT_FAVORITES_INIT, NULL); + rarch_favorites_init(); command_event(CMD_EVENT_RESUME, NULL); command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL);