Move ForwardSys from core to logic (bug 5953, r=fyren).

--HG--
rename : core/ForwardSys.cpp => core/logic/ForwardSys.cpp
rename : core/ForwardSys.h => core/logic/ForwardSys.h
This commit is contained in:
Nicholas Hastings
2013-10-09 08:43:08 -04:00
parent 1d1b5d1c6d
commit 1ba6b2653a
22 changed files with 127 additions and 133 deletions
+1
View File
@@ -63,6 +63,7 @@ files = [
'DebugReporter.cpp',
'Database.cpp',
'smn_database.cpp',
'ForwardSys.cpp',
]
if AMBuild.target['platform'] == 'windows':
files.append('thread/WinThreads.cpp')
+794
View File
@@ -0,0 +1,794 @@
/**
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#include "ForwardSys.h"
#include "DebugReporter.h"
#include "common_logic.h"
CForwardManager g_Forwards;
/**
* Genesis turns to its source, reduction occurs stepwise although the essence is all one.
* End of line. FTL system check.
*
* :TODO: WHAT NEEDS TO BE TESTED IN THIS BEAST
* VARARG FUNCTIONS:
* - Pushing no varargs
*/
// :TODO: IMPORTANT!!! The result pointer arg in the execute function maybe invalid if the forward fails
// so later evaluation of this result may cause problems on higher levels of abstraction. DOCUMENT OR FIX ALL FORWARDS!
CForwardManager::~CForwardManager()
{
CStack<CForward *>::iterator iter;
for (iter=m_FreeForwards.begin(); iter!=m_FreeForwards.end(); iter++)
{
delete (*iter);
}
m_FreeForwards.popall();
}
void CForwardManager::OnSourceModAllInitialized()
{
scripts->AddPluginsListener(this);
sharesys->AddInterface(NULL, this);
}
IForward *CForwardManager::CreateForward(const char *name, ExecType et, unsigned int num_params, const ParamType *types, ...)
{
CForward *fwd;
va_list ap;
va_start(ap, types);
fwd = CForward::CreateForward(name, et, num_params, types, ap);
va_end(ap);
if (fwd)
{
scripts->AddFunctionsToForward(name, fwd);
m_managed.push_back(fwd);
}
return fwd;
}
IChangeableForward *CForwardManager::CreateForwardEx(const char *name, ExecType et, int num_params, const ParamType *types, ...)
{
CForward *fwd;
va_list ap;
va_start(ap, types);
fwd = CForward::CreateForward(name, et, num_params, types, ap);
va_end(ap);
if (fwd)
{
m_unmanaged.push_back(fwd);
}
return fwd;
}
void CForwardManager::OnPluginLoaded(IPlugin *plugin)
{
/* Attach any globally managed forwards */
List<CForward *>::iterator iter;
CForward *fwd;
for (iter=m_managed.begin(); iter!=m_managed.end(); iter++)
{
fwd = (*iter);
IPluginFunction *pFunc = plugin->GetBaseContext()->GetFunctionByName(fwd->GetForwardName());
if (pFunc)
{
fwd->AddFunction(pFunc);
}
}
}
void CForwardManager::OnPluginUnloaded(IPlugin *plugin)
{
List<CForward *>::iterator iter;
CForward *fwd;
for (iter=m_managed.begin(); iter!=m_managed.end(); iter++)
{
fwd = (*iter);
fwd->RemoveFunctionsOfPlugin(plugin);
}
for (iter=m_unmanaged.begin(); iter!=m_unmanaged.end(); iter++)
{
fwd = (*iter);
fwd->RemoveFunctionsOfPlugin(plugin);
}
}
IForward *CForwardManager::FindForward(const char *name, IChangeableForward **ifchng)
{
List<CForward *>::iterator iter;
CForward *fwd;
for (iter=m_managed.begin(); iter!=m_managed.end(); iter++)
{
fwd = (*iter);
if (strcmp(fwd->GetForwardName(), name) == 0)
{
if (ifchng)
{
*ifchng = NULL;
}
return fwd;
}
}
for (iter=m_unmanaged.begin(); iter!=m_unmanaged.end(); iter++)
{
fwd = (*iter);
if (strcmp(fwd->GetForwardName(), name) == 0)
{
if (ifchng)
{
*ifchng = fwd;
}
return fwd;
}
}
if (ifchng)
{
*ifchng = NULL;
}
return NULL;
}
void CForwardManager::ReleaseForward(IForward *forward)
{
ForwardFree(static_cast<CForward *>(forward));
}
void CForwardManager::ForwardFree(CForward *fwd)
{
if (fwd == NULL)
{
return;
}
m_FreeForwards.push(fwd);
m_managed.remove(fwd);
}
CForward *CForwardManager::ForwardMake()
{
CForward *fwd;
if (m_FreeForwards.empty())
{
fwd = new CForward;
} else {
fwd = m_FreeForwards.front();
m_FreeForwards.pop();
}
return fwd;
}
void CForwardManager::OnPluginPauseChange(IPlugin *plugin, bool paused)
{
if(paused)
return;
/* Attach any globally managed forwards */
List<CForward *>::iterator iter;
CForward *fwd;
for (iter=m_managed.begin(); iter!=m_managed.end(); iter++)
{
fwd = (*iter);
IPluginFunction *pFunc = plugin->GetBaseContext()->GetFunctionByName(fwd->GetForwardName());
// Only add functions, if they aren't registered yet!
if (pFunc && !fwd->IsFunctionRegistered(pFunc))
{
fwd->AddFunction(pFunc);
}
}
}
/*************************************
* ACTUAL FORWARD API IMPLEMENTATION *
*************************************/
CForward *CForward::CreateForward(const char *name, ExecType et, unsigned int num_params, const ParamType *types, va_list ap)
{
ParamType _types[SP_MAX_EXEC_PARAMS];
if (num_params > SP_MAX_EXEC_PARAMS)
{
return NULL;
}
if (types == NULL && num_params)
{
for (unsigned int i=0; i<num_params; i++)
{
_types[i] = (ParamType)va_arg(ap, int);
if (_types[i] == Param_VarArgs && (i != num_params - 1))
{
return NULL;
}
}
types = _types;
} else {
for (unsigned int i=0; i<num_params; i++)
{
_types[i] = types[i];
if (types[i] == Param_VarArgs && (i != num_params - 1))
{
return NULL;
}
}
}
/* First parameter can never be varargs */
if (num_params && _types[0] == Param_VarArgs)
{
return NULL;
}
CForward *pForward = g_Forwards.ForwardMake();
pForward->m_IterGuard = NULL;
pForward->m_curparam = 0;
pForward->m_ExecType = et;
snprintf(pForward->m_name, FORWARDS_NAME_MAX, "%s", name ? name : "");
for (unsigned int i=0; i<num_params; i++)
{
pForward->m_types[i] = _types[i];
}
if (num_params && _types[num_params-1] == Param_VarArgs)
{
pForward->m_varargs = num_params--;
} else {
pForward->m_varargs = false;
}
pForward->m_numparams = num_params;
pForward->m_errstate = SP_ERROR_NONE;
pForward->m_functions.clear();
return pForward;
}
int CForward::Execute(cell_t *result, IForwardFilter *filter)
{
if (m_errstate)
{
int err = m_errstate;
Cancel();
return err;
}
FuncIter iter = m_functions.begin();
IPluginFunction *func;
cell_t cur_result = 0;
cell_t high_result = 0;
cell_t low_result = 0;
int err;
unsigned int success=0;
unsigned int num_params = m_curparam;
FwdParamInfo temp_info[SP_MAX_EXEC_PARAMS];
FwdParamInfo *param;
ParamType type;
/* Save local, reset */
memcpy(temp_info, m_params, sizeof(m_params));
m_curparam = 0;
FuncIteratorGuard guard(&m_IterGuard, &iter);
while (iter != m_functions.end())
{
func = (*iter);
if (filter)
filter->Preprocess(func, temp_info);
for (unsigned int i=0; i<num_params; i++)
{
int err = SP_ERROR_PARAM;
param = &temp_info[i];
if (i >= m_numparams || m_types[i] == Param_Any)
{
type = param->pushedas;
}
else
{
type = m_types[i];
}
if ((i >= m_numparams) || (type & SP_PARAMFLAG_BYREF))
{
/* If we're byref or we're vararg, we always push everything by ref.
* Even if they're byval, we must push them byref.
*/
if (type == Param_String)
{
err = func->PushStringEx((char *)param->byref.orig_addr, param->byref.cells, param->byref.sz_flags, param->byref.flags);
}
else if (type == Param_Float || type == Param_Cell)
{
err = func->PushCellByRef(&param->val);
}
else
{
err = func->PushArray(param->byref.orig_addr, param->byref.cells, param->byref.flags);
assert(type == Param_Array || type == Param_FloatByRef || type == Param_CellByRef);
}
}
else
{
/* If we're not byref or not vararg, our job is a bit easier. */
assert(type == Param_Cell || type == Param_Float);
err = func->PushCell(param->val);
}
if (err != SP_ERROR_NONE)
{
g_DbgReporter.GenerateError(func->GetParentContext(),
func->GetFunctionID(),
err,
"Failed to push parameter while executing forward");
continue;
}
}
/* Call the function and deal with the return value. */
if ((err=func->Execute(&cur_result)) == SP_ERROR_NONE)
{
success++;
switch (m_ExecType)
{
case ET_Event:
{
if (cur_result > high_result)
{
high_result = cur_result;
}
break;
}
case ET_Hook:
{
if (cur_result > high_result)
{
high_result = cur_result;
if ((ResultType)high_result == Pl_Stop)
{
goto done;
}
}
break;
}
case ET_LowEvent:
{
/* Check if the current result is the lowest so far (or if it's the first result) */
if (cur_result < low_result || success == 1)
{
low_result = cur_result;
}
break;
}
default:
{
break;
}
}
}
if (!guard.Triggered())
iter++;
}
done:
if (success)
{
switch (m_ExecType)
{
case ET_Ignore:
{
cur_result = 0;
break;
}
case ET_Event:
case ET_Hook:
{
cur_result = high_result;
break;
}
case ET_LowEvent:
{
cur_result = low_result;
break;
}
default:
{
break;
}
}
if (result)
{
*result = cur_result;
}
}
return SP_ERROR_NONE;
}
int CForward::PushCell(cell_t cell)
{
if (m_curparam < m_numparams)
{
if (m_types[m_curparam] == Param_Any)
{
m_params[m_curparam].pushedas = Param_Cell;
} else if (m_types[m_curparam] != Param_Cell) {
return SetError(SP_ERROR_PARAM);
}
} else {
if (!m_varargs || m_numparams > SP_MAX_EXEC_PARAMS)
{
return SetError(SP_ERROR_PARAMS_MAX);
}
m_params[m_curparam].pushedas = Param_Cell;
}
m_params[m_curparam++].val = cell;
return SP_ERROR_NONE;
}
int CForward::PushFloat(float number)
{
if (m_curparam < m_numparams)
{
if (m_types[m_curparam] == Param_Any)
{
m_params[m_curparam].pushedas = Param_Float;
} else if (m_types[m_curparam] != Param_Float) {
return SetError(SP_ERROR_PARAM);
}
} else {
if (!m_varargs || m_numparams > SP_MAX_EXEC_PARAMS)
{
return SetError(SP_ERROR_PARAMS_MAX);
}
m_params[m_curparam].pushedas = Param_Float;
}
m_params[m_curparam++].val = *(cell_t *)&number;
return SP_ERROR_NONE;
}
int CForward::PushCellByRef(cell_t *cell, int flags)
{
if (m_curparam < m_numparams)
{
if (m_types[m_curparam] == Param_Any)
{
m_params[m_curparam].pushedas = Param_CellByRef;
} else if (m_types[m_curparam] != Param_CellByRef) {
return SetError(SP_ERROR_PARAM);
}
} else {
if (!m_varargs || m_numparams > SP_MAX_EXEC_PARAMS)
{
return SetError(SP_ERROR_PARAMS_MAX);
}
m_params[m_curparam].pushedas = Param_CellByRef;
}
_Int_PushArray(cell, 1, flags);
m_curparam++;
return SP_ERROR_NONE;
}
int CForward::PushFloatByRef(float *num, int flags)
{
if (m_curparam < m_numparams)
{
if (m_types[m_curparam] == Param_Any)
{
m_params[m_curparam].pushedas = Param_FloatByRef;
} else if (m_types[m_curparam] != Param_FloatByRef) {
return SetError(SP_ERROR_PARAM);
}
} else {
if (!m_varargs || m_numparams > SP_MAX_EXEC_PARAMS)
{
return SetError(SP_ERROR_PARAMS_MAX);
}
m_params[m_curparam].pushedas = Param_FloatByRef;
}
_Int_PushArray((cell_t *)num, 1, flags);
m_curparam++;
return SP_ERROR_NONE;
}
void CForward::_Int_PushArray(cell_t *inarray, unsigned int cells, int flags)
{
m_params[m_curparam].byref.cells = cells;
m_params[m_curparam].byref.flags = flags;
m_params[m_curparam].byref.orig_addr = inarray;
}
int CForward::PushArray(cell_t *inarray, unsigned int cells, int flags)
{
/* We don't allow this here */
if (!inarray)
{
return SetError(SP_ERROR_PARAM);
}
if (m_curparam < m_numparams)
{
if (m_types[m_curparam] == Param_Any)
{
m_params[m_curparam].pushedas = Param_Array;
} else if (m_types[m_curparam] != Param_Array) {
return SetError(SP_ERROR_PARAM);
}
} else {
if (!m_varargs || m_curparam > SP_MAX_EXEC_PARAMS)
{
return SetError(SP_ERROR_PARAMS_MAX);
}
m_params[m_curparam].pushedas = Param_Array;
}
_Int_PushArray(inarray, cells, flags);
m_curparam++;
return SP_ERROR_NONE;
}
void CForward::_Int_PushString(cell_t *inarray, unsigned int cells, int sz_flags, int cp_flags)
{
m_params[m_curparam].byref.cells = cells; /* Notice this contains the char count not cell count */
m_params[m_curparam].byref.flags = cp_flags;
m_params[m_curparam].byref.orig_addr = inarray;
m_params[m_curparam].byref.sz_flags = sz_flags;
}
int CForward::PushString(const char *string)
{
if (m_curparam < m_numparams)
{
if (m_types[m_curparam] == Param_Any)
{
m_params[m_curparam].pushedas = Param_String;
} else if (m_types[m_curparam] != Param_String) {
return SetError(SP_ERROR_PARAM);
}
} else {
if (!m_varargs || m_curparam > SP_MAX_EXEC_PARAMS)
{
return SetError(SP_ERROR_PARAMS_MAX);
}
m_params[m_curparam].pushedas = Param_String;
}
_Int_PushString((cell_t *)string, strlen(string)+1, SM_PARAM_STRING_COPY, 0);
m_curparam++;
return SP_ERROR_NONE;
}
int CForward::PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags)
{
if (m_curparam < m_numparams)
{
if (m_types[m_curparam] == Param_Any)
{
m_params[m_curparam].pushedas = Param_String;
} else if (m_types[m_curparam] != Param_String) {
return SetError(SP_ERROR_PARAM);
}
} else {
if (!m_varargs || m_curparam > SP_MAX_EXEC_PARAMS)
{
return SetError(SP_ERROR_PARAMS_MAX);
}
m_params[m_curparam].pushedas = Param_String;
}
_Int_PushString((cell_t *)buffer, length, sz_flags, cp_flags);
m_curparam++;
return SP_ERROR_NONE;
}
void CForward::Cancel()
{
if (!m_curparam)
{
return;
}
m_curparam = 0;
m_errstate = SP_ERROR_NONE;
}
bool CForward::AddFunction(IPluginContext *pContext, funcid_t index)
{
IPluginFunction *pFunc = pContext->GetFunctionById(index);
if (!pFunc)
{
return false;
}
return AddFunction(pFunc);
}
bool CForward::RemoveFunction(IPluginContext *pContext, funcid_t index)
{
IPluginFunction *pFunc = pContext->GetFunctionById(index);
if (!pFunc)
{
return false;
}
return RemoveFunction(pFunc);
}
bool CForward::RemoveFunction(IPluginFunction *func)
{
bool found = false;
FuncIter iter;
List<IPluginFunction *> *lst;
if (func->IsRunnable())
{
lst = &m_functions;
} else {
lst = &m_paused;
}
for (iter=lst->begin(); iter!=lst->end(); iter++)
{
if ((*iter) == func)
{
m_IterGuard->FixIteratorChain(iter);
found = true;
lst->erase(iter);
break;
}
}
/* Cancel a call, if any */
if (found || m_curparam)
{
func->Cancel();
}
return found;
}
unsigned int CForward::RemoveFunctionsOfPlugin(IPlugin *plugin)
{
FuncIter iter;
IPluginFunction *func;
unsigned int removed = 0;
IPluginContext *pContext = plugin->GetBaseContext();
for (iter=m_functions.begin(); iter!=m_functions.end();)
{
func = (*iter);
if (func->GetParentContext() == pContext)
{
iter = m_functions.erase(iter);
removed++;
} else {
iter++;
}
}
return removed;
}
bool CForward::AddFunction(IPluginFunction *func)
{
if (m_curparam)
{
return false;
}
if (func->IsRunnable())
{
m_functions.push_back(func);
} else {
m_paused.push_back(func);
}
return true;
}
bool CForward::IsFunctionRegistered(IPluginFunction *func)
{
FuncIter iter;
List<IPluginFunction *> *lst;
if (func->IsRunnable())
{
lst = &m_functions;
} else {
lst = &m_paused;
}
for (iter=m_functions.begin(); iter!=m_functions.end(); iter++)
{
if ((*iter) == func)
{
return true;
}
}
return false;
}
const char *CForward::GetForwardName()
{
return m_name;
}
unsigned int CForward::GetFunctionCount()
{
return m_functions.size();
}
ExecType CForward::GetExecType()
{
return m_ExecType;
}
+189
View File
@@ -0,0 +1,189 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_FORWARDSYSTEM_H_
#define _INCLUDE_SOURCEMOD_FORWARDSYSTEM_H_
#include <IForwardSys.h>
#include <IPluginSys.h>
#include "common_logic.h"
#include <sh_list.h>
#include <sh_stack.h>
#include "ISourceMod.h"
using namespace SourceHook;
typedef List<IPluginFunction *>::iterator FuncIter;
/* :TODO: a global name max define for sourcepawn, should mirror compiler's sNAMEMAX */
#define FORWARDS_NAME_MAX 64
class FuncIteratorGuard
{
bool triggered;
FuncIteratorGuard **pprev;
FuncIter *iter;
FuncIteratorGuard *next;
public:
FuncIteratorGuard(FuncIteratorGuard **pprev, FuncIter *iter)
: triggered(false), pprev(pprev), iter(iter), next(*pprev)
{
*pprev = this;
}
~FuncIteratorGuard()
{
*pprev = next;
}
inline bool Triggered()
{
bool t = triggered;
triggered = false;
return t;
}
/**
* This should not read from |this| before the NULL check, because FwdSys
* can call (NULL)->FixIteratorChain().
*/
void FixIteratorChain(FuncIter &other)
{
FuncIteratorGuard *guard = this;
while (guard != NULL)
{
if (*guard->iter == other)
{
*(guard->iter) = ++(*(guard->iter));
guard->triggered = true;
}
guard = guard->next;
}
}
};
class CForward : public IChangeableForward
{
public: //ICallable
virtual int PushCell(cell_t cell);
virtual int PushCellByRef(cell_t *cell, int flags);
virtual int PushFloat(float number);
virtual int PushFloatByRef(float *number, int flags);
virtual int PushArray(cell_t *inarray, unsigned int cells, int flags);
virtual int PushString(const char *string);
virtual int PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags);
virtual void Cancel();
public: //IForward
virtual const char *GetForwardName();
virtual unsigned int GetFunctionCount();
virtual ExecType GetExecType();
virtual int Execute(cell_t *result, IForwardFilter *filter);
public: //IChangeableForward
virtual bool RemoveFunction(IPluginFunction *func);
virtual unsigned int RemoveFunctionsOfPlugin(IPlugin *plugin);
virtual bool AddFunction(IPluginFunction *func);
virtual bool AddFunction(IPluginContext *ctx, funcid_t index);
virtual bool RemoveFunction(IPluginContext *ctx, funcid_t index);
public:
static CForward *CreateForward(const char *name,
ExecType et,
unsigned int num_params,
const ParamType *types,
va_list ap);
bool IsFunctionRegistered(IPluginFunction *func);
private:
void _Int_PushArray(cell_t *inarray, unsigned int cells, int flags);
void _Int_PushString(cell_t *inarray, unsigned int cells, int sz_flags, int cp_flags);
inline int SetError(int err)
{
m_errstate = err;
return err;
}
protected:
/* :TODO: I want a caching list type here.
* Destroying these things and using new/delete for their members feels bad.
*/
mutable List<IPluginFunction *> m_functions;
mutable List<IPluginFunction *> m_paused;
FuncIteratorGuard *m_IterGuard;
/* Type and name information */
FwdParamInfo m_params[SP_MAX_EXEC_PARAMS];
ParamType m_types[SP_MAX_EXEC_PARAMS];
char m_name[FORWARDS_NAME_MAX+1];
unsigned int m_numparams;
unsigned int m_varargs;
ExecType m_ExecType;
/* State information */
unsigned int m_curparam;
int m_errstate;
};
class CForwardManager :
public IForwardManager,
public IPluginsListener,
public SMGlobalClass
{
friend class CForward;
public:
~CForwardManager();
public: //IForwardManager
IForward *CreateForward(const char *name,
ExecType et,
unsigned int num_params,
const ParamType *types,
...);
IChangeableForward *CreateForwardEx(const char *name,
ExecType et,
int num_params,
const ParamType *types,
...);
IForward *FindForward(const char *name, IChangeableForward **ifchng);
void ReleaseForward(IForward *forward);
public: //IPluginsListener
void OnPluginLoaded(IPlugin *plugin);
void OnPluginUnloaded(IPlugin *plugin);
void OnPluginPauseChange(IPlugin *plugin, bool paused);
public: //SMGlobalClass
void OnSourceModAllInitialized();
protected:
CForward *ForwardMake();
void ForwardFree(CForward *fwd);
private:
CStack<CForward *> m_FreeForwards;
List<CForward *> m_managed;
List<CForward *> m_unmanaged;
};
extern CForwardManager g_Forwards;
#endif //_INCLUDE_SOURCEMOD_FORWARDSYSTEM_H_
+3 -2
View File
@@ -48,6 +48,7 @@
#include "NativeOwner.h"
#include "HandleSys.h"
#include "ExtensionSys.h"
#include "ForwardSys.h"
sm_core_t smcore;
IHandleSys *handlesys = &g_HandleSys;
@@ -60,7 +61,7 @@ IVEngineServer *engine;
IShareSys *sharesys = &g_ShareSys;
IRootConsole *rootmenu;
IPluginManager *pluginsys = g_PluginSys.GetOldAPI();
IForwardManager *forwardsys;
IForwardManager *forwardsys = &g_Forwards;
ITimerSystem *timersys;
ServerGlobals serverGlobals;
IPlayerManager *playerhelpers;
@@ -124,6 +125,7 @@ static sm_logic_t logic =
&g_ShareSys,
&g_Extensions,
&g_HandleSys,
&g_Forwards,
NULL,
-1.0f
};
@@ -140,7 +142,6 @@ static void logic_init(const sm_core_t* core, sm_logic_t* _logic)
engine = core->engine;
g_pSM = core->sm;
rootmenu = core->rootmenu;
forwardsys = core->forwardsys;
timersys = core->timersys;
playerhelpers = core->playerhelpers;
adminsys = core->adminsys;
+3 -2
View File
@@ -41,6 +41,7 @@
#include <sp_vm_api.h>
#include <sh_vector.h>
#include <IExtensionSys.h>
#include <IForwardSys.h>
using namespace SourceMod;
using namespace SourcePawn;
@@ -50,7 +51,7 @@ using namespace SourceHook;
* Add 1 to the RHS of this expression to bump the intercom file
* This is to prevent mismatching core/logic binaries
*/
#define SM_LOGIC_MAGIC (0x0F47C0DE - 24)
#define SM_LOGIC_MAGIC (0x0F47C0DE - 25)
#if defined SM_LOGIC
class IVEngineServer
@@ -229,7 +230,6 @@ struct sm_core_t
IVEngineServer *engine;
IFileSystem *filesystem;
IRootConsole *rootmenu;
IForwardManager *forwardsys;
ITimerSystem *timersys;
IPlayerManager *playerhelpers;
IAdminSystem *adminsys;
@@ -298,6 +298,7 @@ struct sm_logic_t
IShareSys *sharesys;
IExtensionSys *extsys;
IHandleSys *handlesys;
IForwardManager *forwardsys;
IdentityToken_t *core_ident;
float sentinel;
};