core/MenuStyle_Base.cpp
changeset 790 9b1474d03470
parent 787 52283fe61d42
child 820 958de63aa9f5
     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 +