Commits

izdubar committed a68a3c8

* add a delay before loading per-game config file (same as Art, to not spam when navigating very fast)
* corrected the mutual exclusion
* corrected the init and re-init of submenu elements cache

Comments (0)

Files changed (9)

include/menusys.h

 
 void menuAppendItem(menu_item_t* item);
 
+void submenuRebuildCache(submenu_list_t* submenu);
 submenu_list_t* submenuAppendItem(submenu_list_t** submenu, int icon_id, char *text, int id, int text_id);
 void submenuRemoveItem(submenu_list_t** submenu, int id);
 void submenuDestroy(submenu_list_t** submenu);
 void menuAddHint(menu_item_t *menu, int text_id, int icon_id);
 void menuRemoveHints(menu_item_t *menu);
 
-void menuRefreshState(menu_item_t *menu, int themeChanged);
-
 #endif
 
 void thmInit();
 void thmReloadScreenExtents();
-void thmAddElements(char* path, char* separator);
+void thmAddElements(char* path, char* separator, int mode);
 char* thmGetValue();
 GSTEXTURE* thmGetTexture(unsigned int id);
 void thmEnd();
 int loadConfig(int types);
 int saveConfig(int types, int showUI);
 void applyConfig(int themeID, int langID, int newVMode, int newVSync);
+void moduleUpdateMenu(int mode, int themeChanged);
 void handleHdlSrv();
 void shutdown();
 
 	// update Themes
 	char path[255];
 	sprintf(path, "%sTHM", ethPrefix);
-	thmAddElements(path, "\\");
+	thmAddElements(path, "\\", ethGameList.mode);
 
 #ifdef VMC
 	sprintf(path, "%sVMC", ethPrefix);
 	// update Themes
 	char path[255];
 	sprintf(path, "%sTHM", hddPrefix);
-	thmAddElements(path, "/");
+	thmAddElements(path, "/", hddGameList.mode);
 
 #ifdef VMC
 	sprintf(path, "%sVMC", hddPrefix);
 static void menuLoadConfig(void* data) {
 	load_config_request_t* req = data;
 
-	// already outdated
-	if (req->itemId != selected_item->item->current->item.id)
+	WaitSema(menuSemaId);
+	if (itemConfig || (req->itemId != itemIdConfig))
 		return;
 
-	WaitSema(menuSemaId);
-	itemIdConfig = selected_item->item->current->item.id;
 	itemConfig = req->list->itemGetConfig(itemIdConfig);
 	SignalSema(menuSemaId);
 
 
 static void menuRequestConfig() {
 	item_list_t* list = selected_item->item->userdata;
-	//if (guiInactiveFrames < list->delay)
-	//	return;
+	if (guiInactiveFrames < list->delay)
+		return;
 
 	WaitSema(menuSemaId);
 	if (itemIdConfig != selected_item->item->current->item.id) {
 			itemConfig = NULL;
 		}
 
+		itemIdConfig = selected_item->item->current->item.id;
+
 		load_config_request_t* req = malloc(sizeof(load_config_request_t));
-		req->itemId = selected_item->item->current->item.id;
+		req->itemId = itemIdConfig;
 		req->list = list;
 		ioPutRequest(IO_MENU_LOAD_CONFIG, req);
 	}
 	newitem->prev = cur;
 }
 
+void submenuRebuildCache(submenu_list_t* submenu) {
+	while (submenu) {
+		if (submenu->item.cache_id)
+			free(submenu->item.cache_id);
+		if(submenu->item.cache_uid)
+			free(submenu->item.cache_uid);
 
-static submenu_list_t* AllocSubMenuItem(int icon_id, char *text, int id, int text_id) {
-	submenu_list_t* it;
-	
-	it = malloc(sizeof(submenu_list_t));
+		int size = gTheme->gameCacheCount * sizeof(int);
+		submenu->item.cache_id = malloc(size);
+		memset(submenu->item.cache_id, -1, size);
+		submenu->item.cache_uid = malloc(size);
+		memset(submenu->item.cache_uid, -1, size);
+
+		submenu = submenu->next;
+	}
+}
+
+static submenu_list_t* submenuAllocItem(int icon_id, char *text, int id, int text_id) {
+	submenu_list_t* it = (submenu_list_t*) malloc(sizeof(submenu_list_t));
 	
 	it->prev = NULL;
 	it->next = NULL;
 	it->item.text = text;
 	it->item.text_id = text_id;
 	it->item.id = id;
-	
-	// no cache entry yet
-	int size = gTheme->gameCacheCount * sizeof(int);
-	it->item.cache_id = malloc(size);
-	memset(it->item.cache_id, -1, size);
-	it->item.cache_uid = malloc(size);
-	memset(it->item.cache_uid, -1, size);
+	submenuRebuildCache(it);
 	
 	return it;
 }
 
 submenu_list_t* submenuAppendItem(submenu_list_t** submenu, int icon_id, char *text, int id, int text_id) {
 	if (*submenu == NULL) {
-		*submenu = AllocSubMenuItem(icon_id, text, id, text_id);
+		*submenu = submenuAllocItem(icon_id, text, id, text_id);
 		return *submenu; 
 	}
 	
 		cur = cur->next;
 	
 	// create new item
-	submenu_list_t *newitem = AllocSubMenuItem(icon_id, text, id, text_id);
+	submenu_list_t *newitem = submenuAllocItem(icon_id, text, id, text_id);
 	
 	// link
 	cur->next = newitem;
 	}
 }
 
-void menuRefreshState(menu_item_t* menu, int themeChanged) {
-	// refresh Hints
-	menuRemoveHints(menu);
-
-	menuAddHint(menu, _STR_SETTINGS, START_ICON);
-	item_list_t *support = menu->userdata;
-	if (!support->enabled)
-		menuAddHint(menu, _STR_START_DEVICE, CROSS_ICON);
-	else {
-		if (gUseInfoScreen && gTheme->infoElems.first)
-			menuAddHint(menu, _STR_INFO, CROSS_ICON);
-		else
-			menuAddHint(menu, _STR_RUN, CROSS_ICON);
-		if (support->itemGetCompatibility)
-			menuAddHint(menu, _STR_COMPAT_SETTINGS, TRIANGLE_ICON);
-		if (gEnableDandR) {
-			if (support->itemRename)
-				menuAddHint(menu, _STR_RENAME, CIRCLE_ICON);
-			if (support->itemDelete)
-				menuAddHint(menu, _STR_DELETE, SQUARE_ICON);
-		}
-	}
-
-	// refresh Cache
-	if (themeChanged) {
-		submenu_list_t *cur = menu->submenu;
-
-		while (cur) {
-			if (cur->item.cache_id)
-				free(cur->item.cache_id);
-			if(cur->item.cache_uid)
-				free(cur->item.cache_uid);
-
-			int size = gTheme->gameCacheCount * sizeof(int);
-			cur->item.cache_id = malloc(size);
-			memset(cur->item.cache_id, -1, size);
-			cur->item.cache_uid = malloc(size);
-			memset(cur->item.cache_uid, -1, size);
-
-			cur = cur->next;
-		}
-	}
-}
-
 char *menuItemGetText(menu_item_t* it) {
 	if (it->text_id >= 0)
 		return _l(it->text_id);
 	} else if(getKey(KEY_DOWN)){
 		menuNextV();
 	} else if(getKeyOn(KEY_CROSS)) {
-		if (selected_item->item->current && gUseInfoScreen && gTheme->infoElems.first) {
-			menuRequestConfig();
-
+		if (selected_item->item->current && gUseInfoScreen && gTheme->infoElems.first)
 			guiSwitchScreen(GUI_SCREEN_INFO);
-		} else
+		else
 			selected_item->item->execCross(selected_item->item);
 	} else if(getKeyOn(KEY_TRIANGLE)) {
 		selected_item->item->execTriangle(selected_item->item);
 void menuRenderInfo() {
 	submenu_list_t* cur = selected_item->item->current;
 
+	menuRequestConfig();
+
 	theme_element_t* elem = gTheme->infoElems.first;
 	while (elem) {
 		if (elem->drawElem)
 		selected_item->item->execCross(selected_item->item);
 	} else if(getKey(KEY_UP)) {
 		menuPrevV();
-		menuRequestConfig();
 	} else if(getKey(KEY_DOWN)){
 		menuNextV();
-		menuRequestConfig();
 	} else if(getKeyOn(KEY_CIRCLE)) {
 		guiSwitchScreen(GUI_SCREEN_MAIN);
 	} else if(getKey(KEY_L1)) {
 		menuPrevPage();
-		menuRequestConfig();
 	} else if(getKey(KEY_R1)) {
 		menuNextPage();
-		menuRequestConfig();
 	} else if (getKeyOn(KEY_L2)) {
 		menuFirstPage();
-		menuRequestConfig();
 	} else if (getKeyOn(KEY_R2)) {
 		menuLastPage();
-		menuRequestConfig();
 	}
 }
 
 static opl_io_module_t list_support[4];
 
+void moduleUpdateMenu(int mode, int themeChanged) {
+	if (mode == -1)
+		return;
+
+	opl_io_module_t* mod = &list_support[mode];
+
+	if (!mod->support)
+		return;
+
+	// refresh Hints
+	menuRemoveHints(&mod->menuItem);
+
+	menuAddHint(&mod->menuItem, _STR_SETTINGS, START_ICON);
+	if (!mod->support->enabled)
+		menuAddHint(&mod->menuItem, _STR_START_DEVICE, CROSS_ICON);
+	else {
+		if (gUseInfoScreen && gTheme->infoElems.first)
+			menuAddHint(&mod->menuItem, _STR_INFO, CROSS_ICON);
+		else
+			menuAddHint(&mod->menuItem, _STR_RUN, CROSS_ICON);
+		if (mod->support->itemGetCompatibility)
+			menuAddHint(&mod->menuItem, _STR_COMPAT_SETTINGS, TRIANGLE_ICON);
+		if (gEnableDandR) {
+			if (mod->support->itemRename)
+				menuAddHint(&mod->menuItem, _STR_RENAME, CIRCLE_ICON);
+			if (mod->support->itemDelete)
+				menuAddHint(&mod->menuItem, _STR_DELETE, SQUARE_ICON);
+		}
+	}
+
+	// refresh Cache
+	if (themeChanged)
+		submenuRebuildCache(mod->subMenu);
+}
+
 static void itemExecCross(struct menu_item *curMenu) {
 	item_list_t *support = curMenu->userdata;
 
 		}
 		else {
 			support->itemInit();
-			menuRefreshState(curMenu, 0);
+			moduleUpdateMenu(support->mode, 0);
 			if (!gAutoRefresh)
 				ioPutRequest(IO_MENU_UPDATE_DEFFERED, &list_support[support->mode]);
 		}
 		ioPutRequest(IO_MENU_UPDATE_DEFFERED, &list_support[support->mode]);
 }
 
-static void initMenuForListSupport(opl_io_module_t* item) {
+static void initMenuForListSupport(int mode) {
+	opl_io_module_t* item = &list_support[mode];
 	item->menuItem.icon_id = item->support->iconId;
 	item->menuItem.text = NULL;
 	item->menuItem.text_id = item->support->textId;
 	item->menuItem.execCircle = &itemExecCircle;
 
 	item->menuItem.hints = NULL;
-	menuRefreshState(&item->menuItem, 0);
+	moduleUpdateMenu(mode, 0);
 
 	struct gui_update_t *mc = guiOpCreate(GUI_OP_ADD_MENU);
 	mc->menu.menu = &item->menuItem;
 	if (!list_support[mode].support) {
 		itemList->uip = 1; // stop updates until we're done with init
 		list_support[mode].support = itemList;
-		initMenuForListSupport(&list_support[mode]);
+		initMenuForListSupport(mode);
 		itemList->uip = 0;
 	}
 
 		// stop updates until we're done with init of the device
 		list_support[mode].support->uip = 1;
 		list_support[mode].support->itemInit();
-		menuRefreshState(&list_support[mode].menuItem, 0);
+		moduleUpdateMenu(mode, 0);
 		list_support[mode].support->uip = 0;
 
 		if (gAutoRefresh)
 // ----------------------- Updaters -------------------------
 // ----------------------------------------------------------
 static void updateMenuFromGameList(opl_io_module_t* mdl) {
-	if (!mdl)
-		return;
-
-	if (!mdl->support)
-		return;
-
 	// lock - gui has to be unused here
 	guiLock();
 
 static void menuDeferredUpdate(void* data) {
 	opl_io_module_t* mdl = data;
 
-	if (!mdl)
-		return;
-
 	if (!mdl->support)
 		return;
 
 
 	initAllSupport(0);
 
-	if (list_support[USB_MODE].support)
-		menuRefreshState(&list_support[USB_MODE].menuItem, changed);
-	if (list_support[ETH_MODE].support)
-		menuRefreshState(&list_support[ETH_MODE].menuItem, changed);
-	if (list_support[HDD_MODE].support)
-		menuRefreshState(&list_support[HDD_MODE].menuItem, changed);
-	if (list_support[APP_MODE].support)
-		menuRefreshState(&list_support[APP_MODE].menuItem, changed);
+	moduleUpdateMenu(USB_MODE, changed);
+	moduleUpdateMenu(ETH_MODE, changed);
+	moduleUpdateMenu(HDD_MODE, changed);
+	moduleUpdateMenu(APP_MODE, changed);
 
 	if (gAutoRefresh)
 		guiSetFrameHook(&menuUpdateHook);
 }
 
 static void moduleCleanup(opl_io_module_t* mod, int exception) {
-	if (!mod)
-		return;
-
 	if (!mod->support)
 		return;
 
 	guiThemesNames[nThemes + 1] = NULL;
 }
 
-void thmAddElements(char* path, char* separator) {
+void thmAddElements(char* path, char* separator, int mode) {
 	LOG("thmAddElements() path=%s sep=%s\n", path, separator);
 	nThemes += listDir(path, separator, THM_MAX_FILES - nThemes, &thmReadEntry);
 	LOG("thmAddElements() nThemes=%d\n", nThemes);
 	char* temp;
 	if (configGetStr(configGetByType(CONFIG_OPL), "theme", &temp)) {
 		LOG("Trying to set again theme: %s\n", temp);
-		thmSetGuiValue(thmFindGuiID(temp), 0);
+		if (thmSetGuiValue(thmFindGuiID(temp), 0))
+			moduleUpdateMenu(mode, 1);
 	}
 }
 
 	// initialize default internal
 	thmLoad(NULL);
 
-	thmAddElements(gBaseMCDir, "/");
+	thmAddElements(gBaseMCDir, "/", -1);
 }
 
 void thmReloadScreenExtents() {
 	usbFindPartition(usbPrefix, "ul.cfg");
 	char path[255];
 	sprintf(path, "%sTHM", usbPrefix);
-	thmAddElements(path, "/");
+	thmAddElements(path, "/", usbGameList.mode);
 
 #ifdef VMC
 	sprintf(path, "%sVMC", usbPrefix);