ds@730: /**
dvander@2883: * vim: set ts=4 sw=4 tw=99 noet :
ds@1330: * =============================================================================
dvander@1231: * SourceMod
ds@1947: * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
ds@1330: * =============================================================================
dvander@370: *
ds@1330: * This program is free software; you can redistribute it and/or modify it under
ds@1330: * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330: * Free Software Foundation.
dvander@1231: *
ds@1330: * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
ds@1330: * details.
dvander@1231: *
ds@1330: * You should have received a copy of the GNU General Public License along with
ds@1330: * this program. If not, see .
dvander@1231: *
ds@1330: * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330: * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330: * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330: * by the Valve Corporation. You must obey the GNU General Public License in
ds@1330: * all respects for all other code used. Additionally, AlliedModders LLC grants
ds@1330: * this exception to all derivative works. AlliedModders LLC defines further
ds@1330: * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330: * or .
dvander@370: *
dvander@370: * Version: $Id$
dvander@370: */
dvander@370:
dvander@180: #include
dvander@351: #include
dvander@351: #include
dvander@180: #include "ForwardSys.h"
dvander@180: #include "PluginSys.h"
dvander@336: #include "ShareSys.h"
dvander@1339: #include "DebugReporter.h"
dvander@180:
dvander@186: CForwardManager g_Forwards;
dvander@186:
dvander@183: /**
ds@729: * Genesis turns to its source, reduction occurs stepwise although the essence is all one.
dvander@183: * End of line. FTL system check.
dvander@183: *
dvander@282: * :TODO: WHAT NEEDS TO BE TESTED IN THIS BEAST
dvander@183: * VARARG FUNCTIONS:
dvander@183: * - Pushing no varargs
dvander@183: */
dvander@183:
faluco@226: // :TODO: IMPORTANT!!! The result pointer arg in the execute function maybe invalid if the forward fails
faluco@226: // so later evaluation of this result may cause problems on higher levels of abstraction. DOCUMENT OR FIX ALL FORWARDS!
faluco@226:
faluco@641: CForwardManager::~CForwardManager()
faluco@641: {
faluco@641: CStack::iterator iter;
faluco@641: for (iter=m_FreeForwards.begin(); iter!=m_FreeForwards.end(); iter++)
faluco@641: {
faluco@641: delete (*iter);
faluco@641: }
faluco@641: m_FreeForwards.popall();
faluco@641: }
faluco@641:
dvander@211: void CForwardManager::OnSourceModAllInitialized()
dvander@211: {
dvander@211: g_PluginSys.AddPluginsListener(this);
dvander@336: g_ShareSys.AddInterface(NULL, this);
dvander@211: }
dvander@211:
ds@559: IForward *CForwardManager::CreateForward(const char *name, ExecType et, unsigned int num_params, const ParamType *types, ...)
dvander@186: {
dvander@186: CForward *fwd;
dvander@186: va_list ap;
dvander@186: va_start(ap, types);
dvander@186:
dvander@186: fwd = CForward::CreateForward(name, et, num_params, types, ap);
dvander@186:
dvander@186: va_end(ap);
dvander@186:
dvander@211: if (fwd)
dvander@211: {
ds@611: g_PluginSys.AddFunctionsToForward(name, fwd);
ds@611:
dvander@211: m_managed.push_back(fwd);
dvander@211: }
dvander@211:
dvander@186: return fwd;
dvander@186: }
dvander@186:
ds@559: IChangeableForward *CForwardManager::CreateForwardEx(const char *name, ExecType et, int num_params, const ParamType *types, ...)
dvander@186: {
dvander@186: CForward *fwd;
dvander@186: va_list ap;
dvander@186: va_start(ap, types);
dvander@186:
dvander@186: fwd = CForward::CreateForward(name, et, num_params, types, ap);
dvander@186:
dvander@186: va_end(ap);
dvander@186:
dvander@211: if (fwd)
dvander@211: {
dvander@211: m_unmanaged.push_back(fwd);
dvander@211: }
dvander@211:
dvander@186: return fwd;
dvander@186: }
dvander@186:
dvander@211: void CForwardManager::OnPluginLoaded(IPlugin *plugin)
dvander@211: {
dvander@211: /* Attach any globally managed forwards */
dvander@211: List::iterator iter;
dvander@211: CForward *fwd;
dvander@211:
dvander@211: for (iter=m_managed.begin(); iter!=m_managed.end(); iter++)
dvander@211: {
dvander@211: fwd = (*iter);
dvander@327: IPluginFunction *pFunc = plugin->GetBaseContext()->GetFunctionByName(fwd->GetForwardName());
dvander@211: if (pFunc)
dvander@211: {
dvander@211: fwd->AddFunction(pFunc);
dvander@211: }
dvander@211: }
dvander@211: }
dvander@211:
dvander@211: void CForwardManager::OnPluginUnloaded(IPlugin *plugin)
dvander@211: {
dvander@211: List::iterator iter;
dvander@211: CForward *fwd;
dvander@211:
dvander@211: for (iter=m_managed.begin(); iter!=m_managed.end(); iter++)
dvander@211: {
dvander@211: fwd = (*iter);
dvander@211: fwd->RemoveFunctionsOfPlugin(plugin);
dvander@211: }
dvander@232:
dvander@232: for (iter=m_unmanaged.begin(); iter!=m_unmanaged.end(); iter++)
dvander@232: {
dvander@232: fwd = (*iter);
dvander@232: fwd->RemoveFunctionsOfPlugin(plugin);
dvander@232: }
dvander@211: }
dvander@211:
dvander@186: IForward *CForwardManager::FindForward(const char *name, IChangeableForward **ifchng)
dvander@186: {
dvander@186: List::iterator iter;
dvander@186: CForward *fwd;
dvander@186:
dvander@186: for (iter=m_managed.begin(); iter!=m_managed.end(); iter++)
dvander@186: {
dvander@186: fwd = (*iter);
dvander@186: if (strcmp(fwd->GetForwardName(), name) == 0)
dvander@186: {
dvander@186: if (ifchng)
dvander@186: {
dvander@186: *ifchng = NULL;
dvander@186: }
dvander@186: return fwd;
dvander@186: }
dvander@186: }
dvander@186:
dvander@186: for (iter=m_unmanaged.begin(); iter!=m_unmanaged.end(); iter++)
dvander@186: {
dvander@186: fwd = (*iter);
dvander@186: if (strcmp(fwd->GetForwardName(), name) == 0)
dvander@186: {
dvander@186: if (ifchng)
dvander@186: {
dvander@186: *ifchng = fwd;
dvander@186: }
dvander@186: return fwd;
dvander@186: }
dvander@186: }
dvander@186:
dvander@186: if (ifchng)
dvander@186: {
dvander@186: *ifchng = NULL;
dvander@186: }
dvander@186:
dvander@186: return NULL;
dvander@186: }
dvander@186:
dvander@186: void CForwardManager::ReleaseForward(IForward *forward)
dvander@186: {
dvander@186: ForwardFree(static_cast(forward));
dvander@186: }
dvander@186:
dvander@186: void CForwardManager::ForwardFree(CForward *fwd)
dvander@186: {
dvander@2234: if (fwd == NULL)
dvander@2234: {
dvander@2234: return;
dvander@2234: }
dvander@2234:
dvander@186: m_FreeForwards.push(fwd);
faluco@291: m_managed.remove(fwd);
dvander@186: }
dvander@186:
dvander@186: CForward *CForwardManager::ForwardMake()
dvander@186: {
dvander@186: CForward *fwd;
dvander@186: if (m_FreeForwards.empty())
dvander@186: {
dvander@186: fwd = new CForward;
dvander@186: } else {
dvander@186: fwd = m_FreeForwards.front();
dvander@186: m_FreeForwards.pop();
dvander@186: }
dvander@186: return fwd;
dvander@186: }
dvander@186:
faluco@430: void CForwardManager::OnPluginPauseChange(IPlugin *plugin, bool paused)
faluco@430: {
dvander@526: /* No longer used */
faluco@430: }
faluco@430:
dvander@186: /*************************************
dvander@186: * ACTUAL FORWARD API IMPLEMENTATION *
dvander@186: *************************************/
dvander@186:
ds@559: CForward *CForward::CreateForward(const char *name, ExecType et, unsigned int num_params, const ParamType *types, va_list ap)
dvander@180: {
dvander@180: ParamType _types[SP_MAX_EXEC_PARAMS];
dvander@180:
dvander@180: if (num_params > SP_MAX_EXEC_PARAMS)
dvander@180: {
dvander@180: return NULL;
dvander@180: }
dvander@180:
dvander@180: if (types == NULL && num_params)
dvander@180: {
dvander@180: for (unsigned int i=0; im_IterGuard = NULL;
dvander@180: pForward->m_curparam = 0;
dvander@180: pForward->m_ExecType = et;
dvander@180: snprintf(pForward->m_name, FORWARDS_NAME_MAX, "%s", name ? name : "");
dvander@180:
dvander@180: for (unsigned int i=0; im_types[i] = _types[i];
dvander@180: }
dvander@180:
dvander@529: if (num_params && _types[num_params-1] == Param_VarArgs)
dvander@180: {
dvander@183: pForward->m_varargs = num_params--;
dvander@180: } else {
dvander@180: pForward->m_varargs = false;
dvander@180: }
dvander@180:
dvander@180: pForward->m_numparams = num_params;
dvander@180: pForward->m_errstate = SP_ERROR_NONE;
dvander@180:
dvander@961: pForward->m_functions.clear();
dvander@961:
dvander@180: return pForward;
dvander@180: }
dvander@180:
dvander@180: int CForward::Execute(cell_t *result, IForwardFilter *filter)
dvander@180: {
dvander@180: if (m_errstate)
dvander@180: {
dvander@180: int err = m_errstate;
dvander@180: Cancel();
dvander@180: return err;
dvander@180: }
dvander@180:
dvander@180: FuncIter iter = m_functions.begin();
dvander@180: IPluginFunction *func;
dvander@180: cell_t cur_result = 0;
dvander@180: cell_t high_result = 0;
ds@2181: cell_t low_result = 0;
dvander@180: int err;
dvander@2890: unsigned int success=0;
dvander@183: unsigned int num_params = m_curparam;
dvander@183: FwdParamInfo temp_info[SP_MAX_EXEC_PARAMS];
dvander@183: FwdParamInfo *param;
dvander@183: ParamType type;
dvander@180:
dvander@183: /* Save local, reset */
dvander@183: memcpy(temp_info, m_params, sizeof(m_params));
dvander@183: m_curparam = 0;
dvander@183:
dvander@2890: FuncIteratorGuard guard(&m_IterGuard, &iter);
dvander@2890:
dvander@2890: while (iter != m_functions.end())
dvander@180: {
dvander@180: func = (*iter);
dvander@183:
dvander@2883: if (filter)
dvander@2883: filter->Preprocess(func, temp_info);
dvander@2883:
dvander@183: for (unsigned int i=0; i= m_numparams || m_types[i] == Param_Any)
dvander@183: {
dvander@183: type = param->pushedas;
ds@2181: }
ds@2181: else
ds@2181: {
dvander@183: type = m_types[i];
dvander@183: }
ds@2181:
dvander@183: if ((i >= m_numparams) || (type & SP_PARAMFLAG_BYREF))
dvander@180: {
dvander@183: /* If we're byref or we're vararg, we always push everything by ref.
dvander@183: * Even if they're byval, we must push them byref.
dvander@183: */
faluco@192: if (type == Param_String)
dvander@180: {
dvander@1339: err = func->PushStringEx((char *)param->byref.orig_addr, param->byref.cells, param->byref.sz_flags, param->byref.flags);
ds@2181: }
ds@2181: else if (type == Param_Float || type == Param_Cell)
ds@2181: {
dvander@1339: err = func->PushCellByRef(¶m->val);
ds@2181: }
ds@2181: else
ds@2181: {
dvander@1339: err = func->PushArray(param->byref.orig_addr, param->byref.cells, param->byref.flags);
dvander@183: assert(type == Param_Array || type == Param_FloatByRef || type == Param_CellByRef);
dvander@180: }
ds@2181: }
ds@2181: else
ds@2181: {
dvander@183: /* If we're not byref or not vararg, our job is a bit easier. */
dvander@183: assert(type == Param_Cell || type == Param_Float);
dvander@1339: err = func->PushCell(param->val);
dvander@1339: }
ds@2181:
dvander@1339: if (err != SP_ERROR_NONE)
dvander@1339: {
ds@2181: g_DbgReporter.GenerateError(func->GetParentContext(),
ds@2181: func->GetFunctionID(),
ds@2181: err,
ds@2181: "Failed to push parameter while executing forward");
dvander@1339: continue;
dvander@180: }
dvander@180: }
dvander@183:
dvander@211: /* Call the function and deal with the return value. */
dvander@2890: if ((err=func->Execute(&cur_result)) == SP_ERROR_NONE)
ds@2181: {
dvander@180: success++;
dvander@180: switch (m_ExecType)
dvander@180: {
dvander@180: case ET_Event:
dvander@180: {
dvander@180: if (cur_result > high_result)
dvander@180: {
dvander@180: high_result = cur_result;
dvander@180: }
dvander@180: break;
dvander@180: }
dvander@180: case ET_Hook:
dvander@180: {
dvander@180: if (cur_result > high_result)
dvander@180: {
dvander@180: high_result = cur_result;
dvander@180: if ((ResultType)high_result == Pl_Stop)
dvander@180: {
ds@1140: goto done;
dvander@180: }
dvander@180: }
dvander@180: break;
dvander@180: }
ds@2181: case ET_LowEvent:
dvander@180: {
pred@2183: /* Check if the current result is the lowest so far (or if it's the first result) */
pred@2183: if (cur_result < low_result || success == 1)
dvander@180: {
ds@2181: low_result = cur_result;
dvander@180: }
dvander@180: break;
dvander@180: }
dvander@351: default:
dvander@351: {
dvander@351: break;
dvander@351: }
dvander@180: }
dvander@180: }
dvander@2890:
dvander@2890: if (!guard.Triggered())
dvander@2890: iter++;
dvander@180: }
dvander@180:
ds@1140: done:
ds@2181:
dvander@447: if (success)
dvander@180: {
ds@2181: switch (m_ExecType)
dvander@447: {
ds@2181: case ET_Ignore:
ds@2181: {
ds@2181: cur_result = 0;
ds@2181: break;
ds@2181: }
ds@2181: case ET_Event:
ds@2181: case ET_Hook:
ds@2181: {
ds@2181: cur_result = high_result;
ds@2181: break;
ds@2181: }
ds@2181: case ET_LowEvent:
ds@2181: {
ds@2181: cur_result = low_result;
ds@2181: break;
ds@2181: }
ds@2181: default:
ds@2181: {
ds@2181: break;
ds@2181: }
dvander@447: }
ds@2181:
dvander@447: if (result)
dvander@447: {
dvander@447: *result = cur_result;
dvander@447: }
dvander@180: }
dvander@180:
dvander@180: return SP_ERROR_NONE;
dvander@180: }
dvander@180:
dvander@180: int CForward::PushCell(cell_t cell)
dvander@180: {
dvander@180: if (m_curparam < m_numparams)
dvander@180: {
dvander@183: if (m_types[m_curparam] == Param_Any)
dvander@180: {
dvander@183: m_params[m_curparam].pushedas = Param_Cell;
dvander@183: } else if (m_types[m_curparam] != Param_Cell) {
dvander@180: return SetError(SP_ERROR_PARAM);
dvander@180: }
dvander@180: } else {
dvander@180: if (!m_varargs || m_numparams > SP_MAX_EXEC_PARAMS)
dvander@180: {
dvander@180: return SetError(SP_ERROR_PARAMS_MAX);
dvander@180: }
dvander@183: m_params[m_curparam].pushedas = Param_Cell;
dvander@180: }
dvander@180:
dvander@183: m_params[m_curparam++].val = cell;
dvander@180:
dvander@180: return SP_ERROR_NONE;
dvander@180: }
dvander@180:
dvander@180: int CForward::PushFloat(float number)
dvander@180: {
dvander@180: if (m_curparam < m_numparams)
dvander@180: {
dvander@183: if (m_types[m_curparam] == Param_Any)
dvander@180: {
dvander@183: m_params[m_curparam].pushedas = Param_Float;
dvander@183: } else if (m_types[m_curparam] != Param_Float) {
dvander@180: return SetError(SP_ERROR_PARAM);
dvander@180: }
dvander@180: } else {
dvander@180: if (!m_varargs || m_numparams > SP_MAX_EXEC_PARAMS)
dvander@180: {
dvander@180: return SetError(SP_ERROR_PARAMS_MAX);
dvander@180: }
dvander@183: m_params[m_curparam].pushedas = Param_Float;
dvander@180: }
dvander@180:
dvander@183: m_params[m_curparam++].val = *(cell_t *)&number;
dvander@180:
dvander@180: return SP_ERROR_NONE;
dvander@180: }
dvander@180:
ds@585: int CForward::PushCellByRef(cell_t *cell, int flags)
dvander@180: {
dvander@180: if (m_curparam < m_numparams)
dvander@180: {
faluco@192: if (m_types[m_curparam] == Param_Any)
dvander@180: {
faluco@192: m_params[m_curparam].pushedas = Param_CellByRef;
faluco@192: } else if (m_types[m_curparam] != Param_CellByRef) {
dvander@180: return SetError(SP_ERROR_PARAM);
dvander@180: }
dvander@180: } else {
dvander@180: if (!m_varargs || m_numparams > SP_MAX_EXEC_PARAMS)
dvander@180: {
dvander@180: return SetError(SP_ERROR_PARAMS_MAX);
dvander@180: }
faluco@192: m_params[m_curparam].pushedas = Param_CellByRef;
dvander@180: }
dvander@180:
ds@585: _Int_PushArray(cell, 1, flags);
dvander@180: m_curparam++;
dvander@180:
dvander@180: return SP_ERROR_NONE;
dvander@180: }
dvander@180:
ds@585: int CForward::PushFloatByRef(float *num, int flags)
dvander@180: {
dvander@180: if (m_curparam < m_numparams)
dvander@180: {
faluco@192: if (m_types[m_curparam] == Param_Any)
dvander@180: {
faluco@192: m_params[m_curparam].pushedas = Param_FloatByRef;
faluco@192: } else if (m_types[m_curparam] != Param_FloatByRef) {
dvander@180: return SetError(SP_ERROR_PARAM);
dvander@180: }
dvander@180: } else {
dvander@180: if (!m_varargs || m_numparams > SP_MAX_EXEC_PARAMS)
dvander@180: {
dvander@180: return SetError(SP_ERROR_PARAMS_MAX);
dvander@180: }
faluco@192: m_params[m_curparam].pushedas = Param_FloatByRef;
dvander@180: }
dvander@180:
ds@585: _Int_PushArray((cell_t *)num, 1, flags);
dvander@180: m_curparam++;
dvander@180:
dvander@180: return SP_ERROR_NONE;
dvander@180: }
dvander@180:
dvander@180: void CForward::_Int_PushArray(cell_t *inarray, unsigned int cells, int flags)
dvander@180: {
dvander@183: m_params[m_curparam].byref.cells = cells;
dvander@183: m_params[m_curparam].byref.flags = flags;
dvander@183: m_params[m_curparam].byref.orig_addr = inarray;
dvander@180: }
dvander@180:
dvander@589: int CForward::PushArray(cell_t *inarray, unsigned int cells, int flags)
dvander@180: {
dvander@180: /* We don't allow this here */
dvander@180: if (!inarray)
dvander@180: {
dvander@180: return SetError(SP_ERROR_PARAM);
dvander@180: }
dvander@180:
dvander@180: if (m_curparam < m_numparams)
dvander@180: {
dvander@183: if (m_types[m_curparam] == Param_Any)
dvander@180: {
dvander@183: m_params[m_curparam].pushedas = Param_Array;
dvander@183: } else if (m_types[m_curparam] != Param_Array) {
dvander@180: return SetError(SP_ERROR_PARAM);
dvander@180: }
dvander@180: } else {
dvander@180: if (!m_varargs || m_curparam > SP_MAX_EXEC_PARAMS)
dvander@180: {
dvander@180: return SetError(SP_ERROR_PARAMS_MAX);
dvander@180: }
dvander@183: m_params[m_curparam].pushedas = Param_Array;
dvander@180: }
dvander@180:
dvander@180: _Int_PushArray(inarray, cells, flags);
dvander@180:
dvander@180: m_curparam++;
dvander@180:
dvander@180: return SP_ERROR_NONE;
dvander@180: }
dvander@180:
faluco@192: void CForward::_Int_PushString(cell_t *inarray, unsigned int cells, int sz_flags, int cp_flags)
faluco@192: {
faluco@192: m_params[m_curparam].byref.cells = cells; /* Notice this contains the char count not cell count */
faluco@192: m_params[m_curparam].byref.flags = cp_flags;
faluco@192: m_params[m_curparam].byref.orig_addr = inarray;
faluco@192: m_params[m_curparam].byref.sz_flags = sz_flags;
faluco@192: }
faluco@192:
dvander@180: int CForward::PushString(const char *string)
dvander@180: {
dvander@180: if (m_curparam < m_numparams)
dvander@180: {
dvander@183: if (m_types[m_curparam] == Param_Any)
dvander@180: {
dvander@183: m_params[m_curparam].pushedas = Param_String;
faluco@188: } else if (m_types[m_curparam] != Param_String) {
dvander@180: return SetError(SP_ERROR_PARAM);
dvander@180: }
dvander@180: } else {
dvander@180: if (!m_varargs || m_curparam > SP_MAX_EXEC_PARAMS)
dvander@180: {
dvander@180: return SetError(SP_ERROR_PARAMS_MAX);
dvander@180: }
dvander@183: m_params[m_curparam].pushedas = Param_String;
dvander@180: }
dvander@180:
dvander@211: _Int_PushString((cell_t *)string, strlen(string)+1, SM_PARAM_STRING_COPY, 0);
dvander@180: m_curparam++;
dvander@180:
dvander@180: return SP_ERROR_NONE;
dvander@180: }
dvander@180:
faluco@192: int CForward::PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags)
dvander@180: {
dvander@180: if (m_curparam < m_numparams)
dvander@180: {
dvander@183: if (m_types[m_curparam] == Param_Any)
dvander@180: {
dvander@183: m_params[m_curparam].pushedas = Param_String;
faluco@188: } else if (m_types[m_curparam] != Param_String) {
dvander@180: return SetError(SP_ERROR_PARAM);
dvander@180: }
dvander@180: } else {
dvander@180: if (!m_varargs || m_curparam > SP_MAX_EXEC_PARAMS)
dvander@180: {
dvander@180: return SetError(SP_ERROR_PARAMS_MAX);
dvander@180: }
dvander@183: m_params[m_curparam].pushedas = Param_String;
dvander@180: }
dvander@180:
faluco@192: _Int_PushString((cell_t *)buffer, length, sz_flags, cp_flags);
dvander@180: m_curparam++;
dvander@180:
dvander@180: return SP_ERROR_NONE;
dvander@180: }
dvander@180:
dvander@180: void CForward::Cancel()
dvander@180: {
dvander@180: if (!m_curparam)
dvander@180: {
dvander@180: return;
dvander@180: }
dvander@180:
dvander@183: m_curparam = 0;
dvander@180: m_errstate = SP_ERROR_NONE;
dvander@180: }
dvander@180:
dvander@327: bool CForward::AddFunction(IPluginContext *pContext, funcid_t index)
dvander@180: {
dvander@327: IPluginFunction *pFunc = pContext->GetFunctionById(index);
dvander@180:
dvander@180: if (!pFunc)
dvander@180: {
dvander@180: return false;
dvander@180: }
dvander@180:
dvander@180: return AddFunction(pFunc);
dvander@180: }
dvander@180:
ds@621: bool CForward::RemoveFunction(IPluginContext *pContext, funcid_t index)
ds@621: {
ds@621: IPluginFunction *pFunc = pContext->GetFunctionById(index);
ds@621:
ds@621: if (!pFunc)
ds@621: {
ds@621: return false;
ds@621: }
ds@621:
ds@621: return RemoveFunction(pFunc);
ds@621: }
ds@621:
dvander@180: bool CForward::RemoveFunction(IPluginFunction *func)
dvander@180: {
dvander@180: bool found = false;
dvander@180: FuncIter iter;
dvander@527: List *lst;
dvander@527:
dvander@527: if (func->IsRunnable())
dvander@527: {
dvander@527: lst = &m_functions;
dvander@527: } else {
dvander@527: lst = &m_paused;
dvander@527: }
dvander@180:
dvander@525: for (iter=m_functions.begin(); iter!=m_functions.end(); iter++)
dvander@180: {
dvander@180: if ((*iter) == func)
dvander@180: {
dvander@2890: m_IterGuard->FixIteratorChain(iter);
dvander@180: found = true;
dvander@527: lst->erase(iter);
faluco@430: break;
dvander@180: }
dvander@180: }
dvander@180:
dvander@180: /* Cancel a call, if any */
dvander@183: if (found || m_curparam)
dvander@180: {
dvander@180: func->Cancel();
dvander@180: }
dvander@180:
dvander@180: return found;
dvander@180: }
dvander@180:
dvander@180: unsigned int CForward::RemoveFunctionsOfPlugin(IPlugin *plugin)
dvander@180: {
dvander@180: FuncIter iter;
dvander@180: IPluginFunction *func;
dvander@180: unsigned int removed = 0;
dvander@327: IPluginContext *pContext = plugin->GetBaseContext();
dvander@180: for (iter=m_functions.begin(); iter!=m_functions.end();)
dvander@180: {
dvander@180: func = (*iter);
dvander@327: if (func->GetParentContext() == pContext)
dvander@180: {
dvander@180: iter = m_functions.erase(iter);
dvander@180: removed++;
dvander@180: } else {
dvander@180: iter++;
dvander@180: }
dvander@180: }
dvander@180:
dvander@180: return removed;
dvander@180: }
dvander@180:
dvander@180: bool CForward::AddFunction(IPluginFunction *func)
dvander@180: {
dvander@180: if (m_curparam)
dvander@180: {
dvander@180: return false;
dvander@180: }
dvander@180:
dvander@527: if (func->IsRunnable())
dvander@527: {
dvander@527: m_functions.push_back(func);
dvander@527: } else {
dvander@527: m_paused.push_back(func);
dvander@527: }
dvander@180:
dvander@180: return true;
dvander@180: }
dvander@180:
dvander@615: const char *CForward::GetForwardName()
dvander@180: {
dvander@180: return m_name;
dvander@180: }
dvander@180:
dvander@615: unsigned int CForward::GetFunctionCount()
dvander@180: {
dvander@180: return m_functions.size();
dvander@180: }
dvander@180:
dvander@615: ExecType CForward::GetExecType()
dvander@180: {
dvander@180: return m_ExecType;
dvander@180: }