Remove MenuManager use of memtables (bug 5899 part 2, r=fyren).

This commit is contained in:
David Anderson 2013-08-31 11:50:28 -07:00
parent a25f9010cc
commit 435f2b8e39
6 changed files with 82 additions and 58 deletions

View File

@ -38,7 +38,6 @@
#include <sh_string.h>
#include <sh_list.h>
#include <ITextParsers.h>
#include "sm_memtable.h"
#include <IThreader.h>
#include <IPluginSys.h>
#include <am-thread-utils.h>

View File

@ -37,7 +37,6 @@
#include <sh_stack.h>
#include <sh_list.h>
#include <sh_string.h>
#include "sm_memtable.h"
#include "sm_globals.h"
using namespace SourceMod;

View File

@ -1,5 +1,5 @@
/**
* vim: set ts=4 :
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
@ -604,7 +604,7 @@ bool BaseMenuStyle::RedoClientMenu(int client, ItemOrder order)
}
CBaseMenu::CBaseMenu(IMenuHandler *pHandler, IMenuStyle *pStyle, IdentityToken_t *pOwner) :
m_pStyle(pStyle), m_Strings(512), m_Pagination(7), m_bShouldDelete(false), m_bCancelling(false),
m_pStyle(pStyle), m_Pagination(7), m_bShouldDelete(false), m_bCancelling(false),
m_pOwner(pOwner ? pOwner : g_pCoreIdent), m_bDeleting(false), m_bWillFreeHandle(false),
m_hHandle(BAD_HANDLE), m_pHandler(pHandler), m_nFlags(MENUFLAG_BUTTON_EXIT)
{
@ -627,94 +627,74 @@ Handle_t CBaseMenu::GetHandle()
bool CBaseMenu::AppendItem(const char *info, const ItemDrawInfo &draw)
{
if (m_Pagination == (unsigned)MENU_NO_PAGINATION
&& m_items.size() >= m_pStyle->GetMaxPageItems())
&& m_items.length() >= m_pStyle->GetMaxPageItems())
{
return false;
}
CItem item;
item.infoString = m_Strings.AddString(info);
item.info = info;
if (draw.display)
{
item.displayString = m_Strings.AddString(draw.display);
}
item.display = draw.display;
item.style = draw.style;
m_items.push_back(item);
m_items.append(item);
return true;
}
bool CBaseMenu::InsertItem(unsigned int position, const char *info, const ItemDrawInfo &draw)
{
if (m_Pagination == (unsigned)MENU_NO_PAGINATION
&& m_items.size() >= m_pStyle->GetMaxPageItems())
if (m_Pagination == (unsigned)MENU_NO_PAGINATION &&
m_items.length() >= m_pStyle->GetMaxPageItems())
{
return false;
}
if (position >= m_items.size())
{
if (position >= m_items.length())
return false;
}
CItem item;
item.infoString = m_Strings.AddString(info);
item.info = info;
if (draw.display)
{
item.displayString = m_Strings.AddString(draw.display);
}
item.display = draw.display;
item.style = draw.style;
CVector<CItem>::iterator iter = m_items.iterAt(position);
m_items.insert(iter, item);
m_items.insert(position, item);
return true;
}
bool CBaseMenu::RemoveItem(unsigned int position)
{
if (position >= m_items.size())
{
if (position >= m_items.length())
return false;
}
m_items.erase(m_items.iterAt(position));
if (m_items.size() == 0)
{
m_Strings.Reset();
}
m_items.remove(position);
return true;
}
void CBaseMenu::RemoveAllItems()
{
m_items.clear();
m_Strings.Reset();
}
const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =NULL */)
{
if (position >= m_items.size())
{
if (position >= m_items.length())
return NULL;
}
if (draw)
{
draw->display = m_Strings.GetString(m_items[position].displayString);
draw->display = m_items[position].display.chars();
draw->style = m_items[position].style;
}
return m_Strings.GetString(m_items[position].infoString);
return m_items[position].info.chars();
}
unsigned int CBaseMenu::GetItemCount()
{
return m_items.size();
return m_items.length();
}
bool CBaseMenu::SetPagination(unsigned int itemsPerPage)
@ -747,12 +727,12 @@ IMenuStyle *CBaseMenu::GetDrawStyle()
void CBaseMenu::SetDefaultTitle(const char *message)
{
m_Title.assign(message);
m_Title = message;
}
const char *CBaseMenu::GetDefaultTitle()
{
return m_Title.c_str();
return m_Title.chars();
}
void CBaseMenu::Cancel()
@ -844,7 +824,5 @@ IMenuHandler *CBaseMenu::GetHandler()
unsigned int CBaseMenu::GetBaseMemUsage()
{
return m_Title.size()
+ m_Strings.GetMemTable()->GetMemUsage()
+ (m_items.size() * sizeof(CItem));
return m_Title.length() + (m_items.length() * sizeof(CItem));
}

View File

@ -1,5 +1,5 @@
/**
* vim: set ts=4 :
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
@ -34,27 +34,32 @@
#include <IMenuManager.h>
#include <IPlayerHelpers.h>
#include <sh_string.h>
#include <sh_vector.h>
#include "sm_memtable.h"
#include <am-string.h>
#include <am-vector.h>
#include "sm_fastlink.h"
using namespace SourceMod;
using namespace SourceHook;
class CItem
{
public:
CItem()
{
infoString = -1;
displayString = -1;
info.setVoid();
display.setVoid();
style = 0;
access = 0;
}
CItem(ke::Moveable<CItem> other)
: info(ke::Move(other->info)),
display(ke::Move(other->display))
{
style = other->style;
access = other->access;
}
public:
int infoString;
int displayString;
ke::AString info;
ke::AString display;
unsigned int style;
unsigned int access;
};
@ -139,11 +144,10 @@ public:
private:
void InternalDelete();
protected:
String m_Title;
ke::AString m_Title;
IMenuStyle *m_pStyle;
BaseStringTable m_Strings;
unsigned int m_Pagination;
CVector<CItem> m_items;
ke::Vector<CItem> m_items;
bool m_bShouldDelete;
bool m_bCancelling;
IdentityToken_t *m_pOwner;

View File

@ -104,17 +104,29 @@ class AString
return chars()[index];
}
void setVoid() {
chars_ = NULL;
length_ = kInvalidLength;
}
bool isVoid() const {
return length_ == kInvalidLength;
}
size_t length() const {
assert(!isVoid());
return length_;
}
const char *chars() const {
if (!chars_)
return "";
return isVoid() ? NULL : "";
return chars_;
}
private:
static const size_t kInvalidLength = (size_t)-1;
void set(const char *str, size_t length) {
chars_ = new char[length + 1];
length_ = length;

View File

@ -85,6 +85,29 @@ class Vector : public AllocPolicy
nitems_++;
}
// Shift all elements including |at| up by one, and insert |item| at the
// given position. This is a linear-time operation.
bool insert(size_t at, const T &item) {
if (!moveUp(at))
return false;
new (&data_[at]) T(item);
return true;
}
bool insert(size_t at, Moveable<T> item) {
if (!moveUp(at))
return false;
new (&data_[at]) T(item);
return true;
}
// Shift all elements at the given position down, removing the given
// element. This is a linear-time operation.
void remove(size_t at) {
for (size_t i = at; i < length() - 1; i++)
data_[i] = T(Moveable<T>(data_[i + 1]));
pop();
}
T popCopy() {
T t = at(length() - 1);
pop();
@ -154,6 +177,15 @@ class Vector : public AllocPolicy
maxsize_ = 0;
}
bool moveUp(size_t at) {
if (!growIfNeeded(1))
return false;
nitems_++;
for (size_t i = nitems_ - 1; i > at; i--)
data_[i] = T(Moveable<T>(data_[i - 1]));
return true;
}
bool growIfNeeded(size_t needed)
{
if (!IsUintPtrAddSafe(nitems_, needed)) {