BETA optimizations

This commit is contained in:
David Anderson 2005-11-22 04:14:07 +00:00
parent 7ed757dc0d
commit cbcc91cc09
7 changed files with 213 additions and 121 deletions

View File

@ -328,6 +328,14 @@ int CLangMngr::GetKeyEntry(String &key)
* FORMATTING ROUTINES
*/
#define FMTPM_NEXTPARAM() \
if (*param > numParams) { \
LogError(amx, AMX_ERR_PARAMS, "String formatted incorrectly - parameter %d (total %d)", *param, numParams); \
return 0; \
} \
_addr = params[*param]; \
addr = get_amxaddr(amx, _addr); \
(*param)++;
#define MAX_LEVELS 4
@ -342,14 +350,7 @@ size_t do_amx_format_parameter(AMX *amx, cell *params, const char **fmtstr, int
const char *fmtsrc = *fmtstr;
char ctrl_code;
int numParams = params[0] / sizeof(cell);
if (*param > numParams)
{
LogError(amx, AMX_ERR_PARAMS, "String formatted incorrectly - parameter %d (total %d)", *param, numParams);
return 0;
}
cell _addr = params[*param];
cell *addr = get_amxaddr(amx, _addr);
(*param)++;
cell _addr, *addr;
if (level >= MAX_LEVELS)
{
@ -382,6 +383,7 @@ size_t do_amx_format_parameter(AMX *amx, cell *params, const char **fmtstr, int
{
case 's':
{
FMTPM_NEXTPARAM();
get_amxstring_r(amx, _addr, tmp_buf, 2047);
return _snprintf(output, maxlen, fmtptr, tmp_buf);
break;
@ -389,6 +391,7 @@ size_t do_amx_format_parameter(AMX *amx, cell *params, const char **fmtstr, int
case 'g':
case 'f':
{
FMTPM_NEXTPARAM();
return _snprintf(output, maxlen, fmtptr, *(REAL *)addr);
break;
}
@ -396,11 +399,13 @@ size_t do_amx_format_parameter(AMX *amx, cell *params, const char **fmtstr, int
case 'd':
case 'c':
{
FMTPM_NEXTPARAM();
return _snprintf(output, maxlen, fmtptr, (int)addr[0]);
break;
}
case 'L':
{
FMTPM_NEXTPARAM();
const char *pLangName = NULL;
const char *def = NULL, *key = NULL;
int status;
@ -428,8 +433,7 @@ size_t do_amx_format_parameter(AMX *amx, cell *params, const char **fmtstr, int
if (!pLangName || !isalpha(pLangName[0]))
pLangName = "en";
//next parameter!
_addr = params[*param];
(*param)++;
FMTPM_NEXTPARAM();
key = get_amxstring(amx, _addr, 1, tmpLen);
def = g_langMngr.GetDef(pLangName, key, status);
@ -467,27 +471,14 @@ size_t do_amx_format_parameter(AMX *amx, cell *params, const char **fmtstr, int
}
}
#define DUMP_CP_BUFFER(expr) \
if (sofar > 0) { \
if (sofar <= (int)maxlen) { \
memcpy(output, save, sofar); \
output += sofar; \
maxlen -= sofar; \
sofar = 0; \
} else { \
expr; \
} \
}
size_t do_amx_format(AMX *amx, cell *params, int *param, const char **lex, char *output, size_t maxlen, int level)
{
int sofar = 0;
{
size_t written;
size_t orig_maxlen = maxlen;
const char *save = *lex;
register const char *lexptr = save;
while (*lexptr)
while (*lexptr && maxlen)
{
switch (*lexptr)
{
@ -496,13 +487,13 @@ size_t do_amx_format(AMX *amx, cell *params, int *param, const char **lex, char
lexptr++;
if (*lexptr == '%' || *lexptr == '\0')
{
sofar+=2;
*output++ = *lexptr++;
*output++ = *lexptr++;
maxlen -= 2;
} else {
DUMP_CP_BUFFER(break);
written = do_amx_format_parameter(amx, params, &lexptr, param, output, maxlen, level + 1);
output += written;
maxlen -= written;
save = lexptr;
}
break;
}
@ -510,7 +501,6 @@ size_t do_amx_format(AMX *amx, cell *params, int *param, const char **lex, char
{
if (level)
{
DUMP_CP_BUFFER(break);
lexptr++;
switch (*lexptr)
{
@ -532,18 +522,16 @@ size_t do_amx_format(AMX *amx, cell *params, int *param, const char **lex, char
}
lexptr++;
maxlen--;
save = lexptr;
break;
}
}
default:
{
lexptr++;
sofar++;
*output++ = *lexptr++;
maxlen--;
}
}
}
DUMP_CP_BUFFER(;);
*output = '\0';
*lex = lexptr;

View File

@ -68,8 +68,11 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags,
m_iRepeat = iRepeat;
}
m_bAfterStart = (iFlags & 4) ? true : false;
m_bBeforeEnd = (iFlags & 8) ? true : false;
type = 0;
if (iFlags & 4)
type = 1;
if (iFlags & 8)
type = 2;
m_fNextExecTime = fCurrentTime + m_fBase;
@ -80,12 +83,25 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags,
{
m_ParamSize = m_iParamLen;
cell *temp = new cell[m_ParamSize];
memset(temp, 0, sizeof(cell) * m_ParamSize);
if (m_pParams != NULL)
delete [] m_pParams;
m_pParams = temp;
}
memcpy(m_pParams, pParams, sizeof(cell)*iParamsLen);
cell *dest = m_pParams;
__asm
{
push esi;
push edi;
push ecx;
mov esi, pParams;
mov edi, dest;
mov ecx, iParamsLen;
rep movsd;
pop esi;
pop edi;
pop ecx;
};
//memcpy(m_pParams, pParams, sizeof(cell) * iParamsLen);
m_pParams[iParamsLen] = 0;
} else {
m_iParamLen = 0;
@ -102,18 +118,7 @@ void CTaskMngr::CTask::clear()
m_iFunc = -1;
}
m_iParamLen = 0;
m_pPlugin = NULL;
m_iId = 0;
m_fBase = 0.0f;
m_iRepeat = 0;
m_bLoop = false;
m_bAfterStart = false;
m_bBeforeEnd = false;
m_iParamLen = 0;
m_fNextExecTime = 0.0f;
}
@ -132,24 +137,29 @@ void CTaskMngr::CTask::resetNextExecTime(float fCurrentTime)
m_fNextExecTime = fCurrentTime + m_fBase;
}
void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft)
bool CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft)
{
bool execute = false;
bool done = false;
if (m_bAfterStart)
switch (type)
{
if (fCurrentTime - fTimeLeft + 1.0f >= m_fBase)
execute = true;
}
else if (m_bBeforeEnd)
{
if (fTimeLimit != 0.0f && (fTimeLeft + fTimeLimit * 60.0f) - fCurrentTime - 1.0f <= m_fBase)
execute = true;
}
else if (m_fNextExecTime <= fCurrentTime)
{
execute = true;
case 1:
{
if (fCurrentTime - fTimeLeft + 1.0f >= m_fBase)
execute = true;
break;
}
case 2:
{
if (fTimeLimit != 0.0f && (fTimeLeft + fTimeLimit * 60.0f) - fCurrentTime - 1.0f <= m_fBase)
execute = true;
break;
}
default:
{
execute = (m_fNextExecTime <= fCurrentTime) ? true : false;
}
}
if (execute)
@ -165,9 +175,6 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
executeForwards(m_iFunc, m_iId);
}
}
if (isFree())
return;
// set new exec time OR remove the task if needed
if (m_bLoop)
@ -178,14 +185,11 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
done = true;
}
if (done)
{
clear();
g_FreeTasks->push(this);
} else {
if (!done)
m_fNextExecTime += m_fBase;
}
}
return done;
}
CTaskMngr::CTask::CTask()
@ -199,8 +203,7 @@ CTaskMngr::CTask::CTask()
m_iRepeat = 0;
m_bLoop = false;
m_bAfterStart = false;
m_bBeforeEnd = false;
type = 0;
m_fNextExecTime = 0.0f;
@ -233,11 +236,9 @@ CTaskMngr::CTaskMngr()
CTaskMngr::~CTaskMngr()
{
while (!g_FreeTasks->empty())
g_FreeTasks->pop();
clear();
delete g_FreeTasks;
m_Tasks.clear();
g_FreeTasks = NULL;
}
void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft)
@ -256,30 +257,32 @@ void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlag
CTask *pTmp = g_FreeTasks->front();
g_FreeTasks->pop();
pTmp->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
m_Tasks.unshift(pTmp);
} else {
// not found: make a new one
CTask *pTmp = new CTask;
pTmp->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
m_Tasks.put(pTmp);
m_Tasks.unshift(pTmp);
}
}
int CTaskMngr::removeTasks(int iId, AMX *pAmx)
{
CTaskDescriptor descriptor(iId, pAmx);
TaskListIter iter = m_Tasks.find(descriptor);
List<CTask *>::iterator iter, end=m_Tasks.end();
int i = 0;
while (iter)
for (iter=m_Tasks.begin(); iter!=end; )
{
if (!iter->isFree())
if ( descriptor == (*iter) )
{
iter->clear();
g_FreeTasks->push(iter->getTask());
g_FreeTasks->push( (*iter) );
iter = m_Tasks.erase(iter);
++i;
} else {
iter++;
}
++i;
iter = m_Tasks.find(++iter, descriptor);
}
return i;
@ -288,15 +291,17 @@ int CTaskMngr::removeTasks(int iId, AMX *pAmx)
int CTaskMngr::changeTasks(int iId, AMX *pAmx, float fNewBase)
{
CTaskDescriptor descriptor(iId, pAmx);
TaskListIter iter = m_Tasks.find(descriptor);
List<CTask *>::iterator iter, end=m_Tasks.end();
int i = 0;
while (iter)
for (iter=m_Tasks.begin(); iter!=end; iter++)
{
iter->changeBase(fNewBase);
iter->resetNextExecTime(*m_pTmr_CurrentTime);
++i;
iter = m_Tasks.find(++iter, descriptor);
if ( descriptor == (*iter) )
{
(*iter)->changeBase(fNewBase);
(*iter)->resetNextExecTime(*m_pTmr_CurrentTime);
++i;
}
}
return i;
@ -304,24 +309,49 @@ int CTaskMngr::changeTasks(int iId, AMX *pAmx, float fNewBase)
bool CTaskMngr::taskExists(int iId, AMX *pAmx)
{
return m_Tasks.find(CTaskDescriptor(iId, pAmx));
CTaskDescriptor descriptor(iId, pAmx);
List<CTask *>::iterator iter, end=m_Tasks.end();
for (iter=m_Tasks.begin(); iter!=end; iter++)
{
if ( descriptor == (*iter) )
return true;
}
return false;
}
void CTaskMngr::startFrame()
{
for (TaskListIter iter = m_Tasks.begin(); iter; ++iter)
List<CTask *>::iterator iter, end=m_Tasks.end();
CTask *pTask;
int ignored=0, used=0;
for (TaskListIter iter = m_Tasks.begin(); iter!=end;)
{
if (iter->isFree())
continue;
iter->executeIfRequired(*m_pTmr_CurrentTime, *m_pTmr_TimeLimit, *m_pTmr_TimeLeft);
pTask = (*iter);
if (pTask->executeIfRequired(*m_pTmr_CurrentTime, *m_pTmr_TimeLimit, *m_pTmr_TimeLeft))
{
pTask->clear();
iter = m_Tasks.erase(iter);
g_FreeTasks->push(pTask);
used++;
} else {
iter++;
ignored++;
}
}
}
void CTaskMngr::clear()
{
for (TaskListIter iter = m_Tasks.begin(); iter; ++iter)
while (!g_FreeTasks->empty())
{
if (!iter->isFree())
iter->clear();
delete g_FreeTasks->front();
g_FreeTasks->pop();
}
List<CTask *>::iterator iter, end=m_Tasks.end();
for (iter=m_Tasks.begin(); iter!=end; iter++)
delete (*iter);
m_Tasks.clear();
}

View File

@ -32,6 +32,8 @@
#ifndef CTASK_H
#define CTASK_H
#include "sh_list.h"
class CTaskMngr
{
public:
@ -45,18 +47,19 @@ public:
int m_iFunc;
int m_iRepeat;
bool m_bLoop;
bool m_bAfterStart;
bool m_bBeforeEnd;
int type;
float m_fBase; // for normal tasks, stores the interval, for the others, stores the amount of time before start / after end
int m_iParamLen;
cell *m_pParams;
cell m_ParamSize;
bool m_bFree;
// execution
float m_fNextExecTime;
bool m_bFree;
bool m_bLoop;
public:
void set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime);
void clear();
@ -65,7 +68,7 @@ public:
CPluginMngr::CPlugin *getPlugin() const;
int getTaskId() const;
void executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft); // also removes the task if needed
bool executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft); // also removes the task if needed
void changeBase(float fNewBase);
void resetNextExecTime(float fCurrentTime);
@ -91,17 +94,17 @@ public:
m_bFree = bFree;
}
friend bool operator == (const CTask &left, const CTaskDescriptor &right)
friend bool operator == (const CTaskDescriptor &right, const CTask *left)
{
if (right.m_bFree)
return left.isFree();
return left->isFree();
return !left.isFree() && (right.m_pAmx ? left.getPlugin()->getAMX() == right.m_pAmx : true) && left.getTaskId() == right.m_iId;
return !left->isFree() && (right.m_pAmx ? left->getPlugin()->getAMX() == right.m_pAmx : true) && left->getTaskId() == right.m_iId;
}
};
/*** CTaskMngr priv members ***/
typedef CList<CTask, CTaskDescriptor> TaskList;
typedef List<CTask *> TaskList;
typedef TaskList::iterator TaskListIter;
TaskList m_Tasks;

View File

@ -3591,6 +3591,11 @@ static cell AMX_NATIVE_CALL amx_abort(AMX *amx, cell *params)
return 1;
}
static cell AMX_NATIVE_CALL get_tick_count(AMX *amx, cell *params)
{
return GetTickCount();
}
static cell AMX_NATIVE_CALL module_exists(AMX *amx, cell *params)
{
int len;
@ -3807,5 +3812,6 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
{"write_short", write_short},
{"write_string", write_string},
{"xvar_exists", xvar_exists},
{"get_tick_count", get_tick_count},
{NULL, NULL}
};

View File

@ -164,7 +164,7 @@
AdditionalIncludeDirectories="&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\dlls&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\engine&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\common&quot;;C:\Files\Programming\metamod\metamod"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
RuntimeLibrary="3"
StructMemberAlignment="3"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
@ -183,7 +183,7 @@
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib ..\JIT\natives-x86.obj"
OutputFile="memtestdebug/amxmodx_mm.dll"
Version="0.1"
Version="1.6.5.0"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
@ -372,10 +372,13 @@
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1"
OmitFramePointers="TRUE"
OptimizeForProcessor="0"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32"
IgnoreStandardIncludePath="FALSE"
@ -390,6 +393,7 @@
ProgramDataBaseFileName=".\jitrelease/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
@ -404,8 +408,8 @@
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitrelease/amxx_mm.pdb"
GenerateMapFile="FALSE"
ProgramDatabaseFile=".\jitrelease/amxmodx_mm.pdb"
GenerateMapFile="TRUE"
ImportLibrary=".\jitrelease/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
@ -636,6 +640,12 @@
</File>
<File
RelativePath="..\CTask.cpp">
<FileConfiguration
Name="JITRelease|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\CVault.cpp">
@ -684,6 +694,12 @@
</File>
<File
RelativePath="..\string.cpp">
<FileConfiguration
Name="JITRelease|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="2"/>
</FileConfiguration>
</File>
<File
RelativePath="..\strptime.cpp">

View File

@ -11,6 +11,8 @@
#ifndef _INCLUDE_SMM_LIST_H
#define _INCLUDE_SMM_LIST_H
#include "sh_stack.h"
//namespace SourceHook
//{
//This class is from CSDM for AMX Mod X
@ -25,6 +27,7 @@ public:
public:
ListNode(const T & o) : obj(o) { };
ListNode() { };
void Set(const T & o) { obj = o; }
~ListNode()
{
};
@ -59,9 +62,49 @@ public:
m_Head = NULL;
}
}
void unshift(const T &obj)
{
if (!m_Head->next)
{
push_back(obj);
return;
}
ListNode *node;
if (m_FreeStack.empty())
{
node = new ListNode(obj);
} else {
node = m_FreeStack.front();
m_FreeStack.pop();
node->Set(obj);
}
//is the list one item circular?
/*bool realign = false;
if (m_Head->next == m_Head->prev)
{
m_Head->next->next =
}*/
node->next = m_Head->next;
node->prev = m_Head;
m_Head->next->prev = node;
m_Head->next = node;
m_Size++;
}
void push_back(const T &obj)
{
ListNode *node = new ListNode(obj);
ListNode *node;
if (m_FreeStack.empty())
{
node = new ListNode(obj);
} else {
node = m_FreeStack.front();
m_FreeStack.pop();
node->Set(obj);
}
if (!m_Head->prev)
{
@ -95,6 +138,11 @@ public:
node = temp;
}
m_Size = 0;
while (!m_FreeStack.empty())
{
delete m_FreeStack.front();
m_FreeStack.pop();
}
}
bool empty()
{
@ -105,6 +153,7 @@ public:
return m_Head->prev->obj;
}
private:
typename CStack<ListNode *> m_FreeStack;
ListNode *m_Head;
size_t m_Size;
public:
@ -225,7 +274,7 @@ public:
pNode->next->prev = pNode->prev;
}
delete pNode;
m_FreeStack.push(pNode);
m_Size--;
return iter;

View File

@ -76,8 +76,8 @@ cell* get_amxaddr(AMX *amx, cell amx_addr)
int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max)
{
cell* dest = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
cell* start = dest;
register cell* dest = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
register cell* start = dest;
while (max-- && *source)
*dest++ = (cell)*source++;
@ -93,12 +93,12 @@ size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, int maxlen)
register char *dest = destination;
char *start = dest;
while (*source && maxlen-- > 0)
while (maxlen-- && *source)
*dest++=(char)(*source++);
if (dest)
*dest = '\0';
return --dest - start;
*dest = '\0';
return dest - start;
}
char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len)