diff --git a/extensions/topmenus/TopMenu.cpp b/extensions/topmenus/TopMenu.cpp index 07894858..43d62ea9 100644 --- a/extensions/topmenus/TopMenu.cpp +++ b/extensions/topmenus/TopMenu.cpp @@ -49,6 +49,7 @@ TopMenu::TopMenu(ITopMenuObjectCallbacks *callbacks) m_SerialNo = 1; m_pTitle = callbacks; m_max_clients = 0; + m_bCacheTitles = true; if (playerhelpers->IsServerActivated()) { @@ -421,6 +422,13 @@ bool TopMenu::DisplayMenu(int client, unsigned int hold_time, TopMenuPosition po return false; } + if (!m_bCacheTitles) + { + char renderbuf[128]; + m_pTitle->OnTopMenuDisplayTitle(this, client, 0, renderbuf, sizeof(renderbuf)); + pClient->root->SetDefaultTitle(renderbuf); + } + bool return_value = false; if (position == TopMenuPosition_LastCategory && @@ -460,6 +468,18 @@ bool TopMenu::DisplayCategory(int client, unsigned int category, unsigned int ho topmenu_player_category_t *player_cat = &(pClient->cats[category]); + // Refresh the title if the topmenu wants that. + if (!m_bCacheTitles) + { + char renderbuf[128]; + m_Categories[category]->obj->callbacks->OnTopMenuDisplayTitle(this, + client, + m_Categories[category]->obj->object_id, + renderbuf, + sizeof(renderbuf)); + player_cat->menu->SetDefaultTitle(renderbuf); + } + pClient->last_category = category; if (last_position) { @@ -473,6 +493,11 @@ bool TopMenu::DisplayCategory(int client, unsigned int category, unsigned int ho return return_value; } +void TopMenu::SetTitleCaching(bool cache_titles) +{ + m_bCacheTitles = cache_titles; +} + void TopMenu::OnMenuSelect2(IBaseMenu *menu, int client, unsigned int item, unsigned int item_on_page) { const char *item_name = menu->GetItemInfo(item, NULL); @@ -691,9 +716,12 @@ void TopMenu::UpdateClientRoot(int client, IGamePlayer *pGamePlayer) } /* Set the menu's title */ - char renderbuf[128]; - m_pTitle->OnTopMenuDisplayTitle(this, client, 0, renderbuf, sizeof(renderbuf)); - root_menu->SetDefaultTitle(renderbuf); + if (m_bCacheTitles) + { + char renderbuf[128]; + m_pTitle->OnTopMenuDisplayTitle(this, client, 0, renderbuf, sizeof(renderbuf)); + root_menu->SetDefaultTitle(renderbuf); + } /* The client is now fully updated */ pClient->root = root_menu; @@ -810,13 +838,16 @@ void TopMenu::UpdateClientCategory(int client, unsigned int category, bool bSkip } /* Set the menu's title */ - char renderbuf[128]; - cat->obj->callbacks->OnTopMenuDisplayTitle(this, - client, - cat->obj->object_id, - renderbuf, - sizeof(renderbuf)); - cat_menu->SetDefaultTitle(renderbuf); + if (m_bCacheTitles) + { + char renderbuf[128]; + cat->obj->callbacks->OnTopMenuDisplayTitle(this, + client, + cat->obj->object_id, + renderbuf, + sizeof(renderbuf)); + cat_menu->SetDefaultTitle(renderbuf); + } /* We're done! */ player_cat->menu = cat_menu; diff --git a/extensions/topmenus/TopMenu.h b/extensions/topmenus/TopMenu.h index 6752cd23..d85a0abd 100644 --- a/extensions/topmenus/TopMenu.h +++ b/extensions/topmenus/TopMenu.h @@ -154,6 +154,7 @@ public: //ITextListener_SMC SMCResult ReadSMC_LeavingSection(const SMCStates *states); public: unsigned int CalcMemUsage(); + void SetTitleCaching(bool cache_titles); private: void SortCategoriesIfNeeded(); void SortCategoryIfNeeded(unsigned int category); @@ -181,6 +182,7 @@ private: ITopMenuObjectCallbacks *m_pTitle; /* Title callbacks */ int m_max_clients; /* Maximum number of clients */ bool m_bCatsNeedResort; /* True if categories need a resort */ + bool m_bCacheTitles; /* True if the categorie titles should be cached */ }; unsigned int strncopy(char *dest, const char *src, size_t count); diff --git a/extensions/topmenus/smn_topmenus.cpp b/extensions/topmenus/smn_topmenus.cpp index d0d74289..2cd8db6b 100644 --- a/extensions/topmenus/smn_topmenus.cpp +++ b/extensions/topmenus/smn_topmenus.cpp @@ -374,6 +374,23 @@ static cell_t GetTopMenuName(IPluginContext *pContext, const cell_t *params) return strncopy(buffer, str, params[4]); } +static cell_t SetTopMenuTitleCaching(IPluginContext *pContext, const cell_t *params) +{ + HandleError err; + TopMenu *pMenu; + HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); + + if ((err = handlesys->ReadHandle(params[1], hTopMenuType, &sec, (void **)&pMenu)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); + } + + bool cache_titles = params[2]==1?true:false; + pMenu->SetTitleCaching(cache_titles); + return 0; +} + sp_nativeinfo_t g_TopMenuNatives[] = { {"AddToTopMenu", AddToTopMenu}, @@ -384,5 +401,6 @@ sp_nativeinfo_t g_TopMenuNatives[] = {"FindTopMenuCategory", FindTopMenuCategory}, {"GetTopMenuInfoString", GetTopMenuInfoString}, {"GetTopMenuObjName", GetTopMenuName}, + {"SetTopMenuTitleCaching", SetTopMenuTitleCaching}, {NULL, NULL}, }; diff --git a/plugins/include/topmenus.inc b/plugins/include/topmenus.inc index 9c0e678b..f5ca0f67 100644 --- a/plugins/include/topmenus.inc +++ b/plugins/include/topmenus.inc @@ -258,6 +258,17 @@ native bool:DisplayTopMenu(Handle:topmenu, client, TopMenuPosition:position); */ native TopMenuObject:FindTopMenuCategory(Handle:topmenu, const String:name[]); +/** + * Change the menu title caching behaviour of the TopMenu. By default the titles are cached to reduce overhead. + * If you need dynamic menu titles, which can change everytime the menu is displayed to a user, set this to false. + * + * @param topmenu TopMenu Handle. + * @param cache_titles Cache the menu titles and don't call the handler with TopMenuAction_DisplayTitle everytime the menu is drawn? + * @noreturn + * @error Invalid TopMenu Handle + */ +native SetTopMenuTitleCaching(Handle:topmenu, bool:cache_titles); + /** * Do not edit below this line! */ @@ -286,5 +297,6 @@ public __ext_topmenus_SetNTVOptional() MarkNativeAsOptional("RemoveFromTopMenu"); MarkNativeAsOptional("DisplayTopMenu"); MarkNativeAsOptional("FindTopMenuCategory"); + MarkNativeAsOptional("SetTopMenuTitleCaching"); } #endif