1.1 --- a/core/MenuStyle_Base.cpp Sun May 13 22:36:22 2007 +0000
1.2 +++ b/core/MenuStyle_Base.cpp Mon May 14 04:46:06 2007 +0000
1.3 @@ -17,9 +17,21 @@
1.4 #include "MenuStyle_Base.h"
1.5 #include "PlayerManager.h"
1.6 #include "MenuManager.h"
1.7 +#include "HandleSys.h"
1.8
1.9 -BaseMenuStyle::BaseMenuStyle() : m_WatchList(256)
1.10 +BaseMenuStyle::BaseMenuStyle() : m_WatchList(256), m_hHandle(BAD_HANDLE)
1.11 +{
1.12 +}
1.13 +
1.14 +Handle_t BaseMenuStyle::GetHandle()
1.15 {
1.16 + /* Don't create the handle until we need it */
1.17 + if (m_hHandle == BAD_HANDLE)
1.18 + {
1.19 + m_hHandle = g_Menus.CreateStyleHandle(this);
1.20 + }
1.21 +
1.22 + return m_hHandle;
1.23 }
1.24
1.25 void BaseMenuStyle::AddClientToWatch(int client)
1.26 @@ -56,7 +68,12 @@
1.27
1.28 /* Fire callbacks */
1.29 mh->OnMenuCancel(menu, client, reason);
1.30 - mh->OnMenuEnd(menu);
1.31 +
1.32 + /* Only fire end if there's a valid menu */
1.33 + if (menu)
1.34 + {
1.35 + mh->OnMenuEnd(menu);
1.36 + }
1.37
1.38 if (bAutoIgnore)
1.39 {
1.40 @@ -145,6 +162,7 @@
1.41 _CancelClientMenu(client, true, MenuCancel_Disconnect);
1.42
1.43 player->bInMenu = false;
1.44 + player->bInExternMenu = false;
1.45 }
1.46
1.47 static int do_lookup[256];
1.48 @@ -248,7 +266,11 @@
1.49 mh->OnMenuSelect(menu, client, item);
1.50 }
1.51
1.52 - mh->OnMenuEnd(menu);
1.53 + /* Only fire end for valid menus */
1.54 + if (menu)
1.55 + {
1.56 + mh->OnMenuEnd(menu);
1.57 + }
1.58 }
1.59
1.60 bool BaseMenuStyle::DoClientMenu(int client, IMenuPanel *menu, IMenuHandler *mh, unsigned int time)
1.61 @@ -276,13 +298,7 @@
1.62 menu_states_t &states = player->states;
1.63 if (player->bInMenu)
1.64 {
1.65 - /* We need to cancel the old menu */
1.66 - if (player->menuHoldTime)
1.67 - {
1.68 - RemoveClientFromWatch(client);
1.69 - }
1.70 - states.mh->OnMenuCancel(states.menu, client, MenuCancel_Interrupt);
1.71 - states.mh->OnMenuEnd(states.menu);
1.72 + _CancelClientMenu(client, true);
1.73 }
1.74
1.75 states.firstItem = 0;
1.76 @@ -291,6 +307,7 @@
1.77 states.mh = mh;
1.78 states.apiVers = SMINTERFACE_MENUMANAGER_VERSION;
1.79 player->bInMenu = true;
1.80 + player->bInExternMenu = false;
1.81 player->menuStartTime = gpGlobals->curtime;
1.82 player->menuHoldTime = time;
1.83
1.84 @@ -367,6 +384,7 @@
1.85
1.86 /* Finally, set our states */
1.87 player->bInMenu = true;
1.88 + player->bInExternMenu = false;
1.89 player->menuStartTime = gpGlobals->curtime;
1.90 player->menuHoldTime = time;
1.91
1.92 @@ -413,8 +431,10 @@
1.93 return true;
1.94 }
1.95
1.96 -CBaseMenu::CBaseMenu(IMenuStyle *pStyle) :
1.97 -m_pStyle(pStyle), m_Strings(512), m_Pagination(7), m_ExitButton(true), m_bShouldDelete(false), m_bCancelling(false)
1.98 +CBaseMenu::CBaseMenu(IMenuHandler *pHandler, IMenuStyle *pStyle, IdentityToken_t *pOwner) :
1.99 +m_pStyle(pStyle), m_Strings(512), m_Pagination(7), m_ExitButton(true),
1.100 +m_bShouldDelete(false), m_bCancelling(false), m_pOwner(pOwner ? pOwner : g_pCoreIdent),
1.101 +m_bDeleting(false), m_bWillFreeHandle(false), m_hHandle(BAD_HANDLE), m_pHandler(pHandler)
1.102 {
1.103 }
1.104
1.105 @@ -422,6 +442,16 @@
1.106 {
1.107 }
1.108
1.109 +Handle_t CBaseMenu::GetHandle()
1.110 +{
1.111 + if (!m_hHandle)
1.112 + {
1.113 + m_hHandle = g_Menus.CreateMenuHandle(this, m_pOwner);
1.114 + }
1.115 +
1.116 + return m_hHandle;
1.117 +}
1.118 +
1.119 bool CBaseMenu::AppendItem(const char *info, const ItemDrawInfo &draw)
1.120 {
1.121 if (m_Pagination == (unsigned)MENU_NO_PAGINATION
1.122 @@ -572,18 +602,48 @@
1.123
1.124 if (m_bShouldDelete)
1.125 {
1.126 - delete this;
1.127 + InternalDelete();
1.128 }
1.129 }
1.130
1.131 -void CBaseMenu::Destroy()
1.132 +void CBaseMenu::Destroy(bool releaseHandle)
1.133 {
1.134 + /* Check if we shouldn't be here */
1.135 + if (m_bDeleting)
1.136 + {
1.137 + return;
1.138 + }
1.139 +
1.140 + /* Save the destruction hint about our handle */
1.141 + m_bWillFreeHandle = releaseHandle;
1.142 +
1.143 + /* Now actually do stuff */
1.144 if (!m_bCancelling || m_bShouldDelete)
1.145 {
1.146 Cancel();
1.147 - delete this;
1.148 + InternalDelete();
1.149 } else {
1.150 m_bShouldDelete = true;
1.151 }
1.152 }
1.153
1.154 +void CBaseMenu::InternalDelete()
1.155 +{
1.156 + if (m_bWillFreeHandle && m_hHandle != BAD_HANDLE)
1.157 + {
1.158 + Handle_t hndl = m_hHandle;
1.159 + HandleSecurity sec;
1.160 +
1.161 + sec.pOwner = m_pOwner;
1.162 + sec.pIdentity = g_pCoreIdent;
1.163 +
1.164 + m_hHandle = BAD_HANDLE;
1.165 + m_bDeleting = true;
1.166 + g_HandleSys.FreeHandle(hndl, &sec);
1.167 + }
1.168 +
1.169 + m_pHandler->OnMenuDestroy(this);
1.170 +
1.171 + delete this;
1.172 +}
1.173 +