core/systems/ForwardSys.cpp
author Borja Ferrer <faluco@alliedmods.net>
Fri Nov 17 23:22:32 2006 +0000 (2006-11-17)
changeset 188 8951baf7cb3c
parent 187 b93ea22fafe4
child 192 dee91851dcd4
permissions -rw-r--r--
fixed string pushing
fixed CFunction::_PushString not counting the null terminator
dvander@180
     1
#include <assert.h>
dvander@180
     2
#include "ForwardSys.h"
dvander@180
     3
#include "PluginSys.h"
dvander@180
     4
dvander@186
     5
CForwardManager g_Forwards;
dvander@186
     6
dvander@183
     7
/**
dvander@183
     8
 * Gensis turns to its source, reduction occurs stepwise although the essence is all one.
dvander@183
     9
 * End of line.  FTL system check.
dvander@183
    10
 *
dvander@183
    11
 * :TODO: Implement the manager.  ho ho ho
dvander@183
    12
 *
dvander@183
    13
 * :TODO: WHAT NEEDS TO BE TESTED IN THIS BEAST (X=done, -=TODO)
dvander@183
    14
 * NORMAL FUNCTIONS:
dvander@183
    15
 * X Push cells
dvander@183
    16
 * X Push cells byref (copyback tested = yes)
faluco@187
    17
 * X Push floats
faluco@187
    18
 * X Push floats byref (copyback tested = yes)
faluco@187
    19
 * X Push arrays  (copyback tested = yes)
faluco@188
    20
 * X Push strings (copyback tested = yes)
dvander@183
    21
 * VARARG FUNCTIONS:
dvander@183
    22
 * - Pushing no varargs
dvander@183
    23
 * - Push vararg cells (copyback should be verified to not happen = ??)
dvander@183
    24
 * - Push vararg cells byref (copyback tested = ??)
dvander@183
    25
 * - Push vararg floats (copyback should be verified to not happen = ??)
dvander@183
    26
 * - Push vararg floats byref (copyback tested = ??)
dvander@183
    27
 * - Push vararg arrays  (copyback tested = ??)
dvander@183
    28
 * - Push vararg strings (copyback tested = ??)
dvander@183
    29
 */
dvander@183
    30
dvander@186
    31
IForward *CForwardManager::CreateForward(const char *name, ExecType et, unsigned int num_params, ParamType *types, ...)
dvander@186
    32
{
dvander@186
    33
	CForward *fwd;
dvander@186
    34
	va_list ap;
dvander@186
    35
	va_start(ap, types);
dvander@186
    36
	
dvander@186
    37
	fwd = CForward::CreateForward(name, et, num_params, types, ap);
dvander@186
    38
dvander@186
    39
	va_end(ap);
dvander@186
    40
dvander@186
    41
	return fwd;
dvander@186
    42
}
dvander@186
    43
dvander@186
    44
IChangeableForward *CForwardManager::CreateForwardEx(const char *name, ExecType et, int num_params, ParamType *types, ...)
dvander@186
    45
{
dvander@186
    46
	CForward *fwd;
dvander@186
    47
	va_list ap;
dvander@186
    48
	va_start(ap, types);
dvander@186
    49
dvander@186
    50
	fwd = CForward::CreateForward(name, et, num_params, types, ap);
dvander@186
    51
dvander@186
    52
	va_end(ap);
dvander@186
    53
dvander@186
    54
	return fwd;
dvander@186
    55
}
dvander@186
    56
dvander@186
    57
IForward *CForwardManager::FindForward(const char *name, IChangeableForward **ifchng)
dvander@186
    58
{
dvander@186
    59
	List<CForward *>::iterator iter;
dvander@186
    60
	CForward *fwd;
dvander@186
    61
dvander@186
    62
	for (iter=m_managed.begin(); iter!=m_managed.end(); iter++)
dvander@186
    63
	{
dvander@186
    64
		fwd = (*iter);
dvander@186
    65
		if (strcmp(fwd->GetForwardName(), name) == 0)
dvander@186
    66
		{
dvander@186
    67
			if (ifchng)
dvander@186
    68
			{
dvander@186
    69
				*ifchng = NULL;
dvander@186
    70
			}
dvander@186
    71
			return fwd;
dvander@186
    72
		}
dvander@186
    73
	}
dvander@186
    74
dvander@186
    75
	for (iter=m_unmanaged.begin(); iter!=m_unmanaged.end(); iter++)
dvander@186
    76
	{
dvander@186
    77
		fwd = (*iter);
dvander@186
    78
		if (strcmp(fwd->GetForwardName(), name) == 0)
dvander@186
    79
		{
dvander@186
    80
			if (ifchng)
dvander@186
    81
			{
dvander@186
    82
				*ifchng = fwd;
dvander@186
    83
			}
dvander@186
    84
			return fwd;
dvander@186
    85
		}
dvander@186
    86
	}
dvander@186
    87
dvander@186
    88
	if (ifchng)
dvander@186
    89
	{
dvander@186
    90
		*ifchng = NULL;
dvander@186
    91
	}
dvander@186
    92
dvander@186
    93
	return NULL;
dvander@186
    94
}
dvander@186
    95
dvander@186
    96
void CForwardManager::ReleaseForward(IForward *forward)
dvander@186
    97
{
dvander@186
    98
	ForwardFree(static_cast<CForward *>(forward));
dvander@186
    99
}
dvander@186
   100
dvander@186
   101
void CForwardManager::ForwardFree(CForward *fwd)
dvander@186
   102
{
dvander@186
   103
	m_FreeForwards.push(fwd);
dvander@186
   104
}
dvander@186
   105
dvander@186
   106
CForward *CForwardManager::ForwardMake()
dvander@186
   107
{
dvander@186
   108
	CForward *fwd;
dvander@186
   109
	if (m_FreeForwards.empty())
dvander@186
   110
	{
dvander@186
   111
		fwd = new CForward;
dvander@186
   112
	} else {
dvander@186
   113
		fwd = m_FreeForwards.front();
dvander@186
   114
		m_FreeForwards.pop();
dvander@186
   115
	}
dvander@186
   116
	return fwd;
dvander@186
   117
}
dvander@186
   118
dvander@186
   119
/*************************************
dvander@186
   120
 * ACTUAL FORWARD API IMPLEMENTATION *
dvander@186
   121
 *************************************/
dvander@186
   122
dvander@180
   123
CForward *CForward::CreateForward(const char *name, ExecType et, unsigned int num_params, ParamType *types, va_list ap)
dvander@180
   124
{
dvander@180
   125
	ParamType _types[SP_MAX_EXEC_PARAMS];
dvander@180
   126
dvander@180
   127
	if (num_params > SP_MAX_EXEC_PARAMS)
dvander@180
   128
	{
dvander@180
   129
		return NULL;
dvander@180
   130
	}
dvander@180
   131
	
dvander@180
   132
	if (types == NULL && num_params)
dvander@180
   133
	{
dvander@180
   134
		for (unsigned int i=0; i<num_params; i++)
dvander@180
   135
		{
dvander@180
   136
			_types[i] = va_arg(ap, ParamType);
dvander@180
   137
			if (_types[i] == Param_VarArgs && (i != num_params - 1))
dvander@180
   138
			{
dvander@180
   139
				return NULL;
dvander@180
   140
			}
dvander@180
   141
		}
dvander@180
   142
		types = _types;
dvander@180
   143
	} else {
dvander@180
   144
		for (unsigned int i=0; i<num_params; i++)
dvander@180
   145
		{
dvander@180
   146
			if (types[i] == Param_VarArgs && (i != num_params - 1))
dvander@180
   147
			{
dvander@180
   148
				return NULL;
dvander@180
   149
			}
dvander@180
   150
		}
dvander@180
   151
	}
dvander@180
   152
dvander@180
   153
	/* First parameter can never be varargs */
dvander@180
   154
	if (types[0] == Param_VarArgs)
dvander@180
   155
	{
dvander@180
   156
		return NULL;
dvander@180
   157
	}
dvander@180
   158
dvander@186
   159
	CForward *pForward = g_Forwards.ForwardMake();
dvander@180
   160
	pForward->m_curparam = 0;
dvander@180
   161
	pForward->m_ExecType = et;
dvander@180
   162
	snprintf(pForward->m_name, FORWARDS_NAME_MAX, "%s", name ? name : "");
dvander@180
   163
	
dvander@180
   164
	for (unsigned int i=0; i<num_params; i++)
dvander@180
   165
	{
dvander@180
   166
		pForward->m_types[i] = types[i];
dvander@180
   167
	}
dvander@180
   168
dvander@180
   169
	if (num_params && types[num_params-1] == Param_VarArgs)
dvander@180
   170
	{
dvander@183
   171
		pForward->m_varargs = num_params--;
dvander@180
   172
	} else {
dvander@180
   173
		pForward->m_varargs = false;
dvander@180
   174
	}
dvander@180
   175
dvander@180
   176
	pForward->m_numparams = num_params;
dvander@180
   177
	pForward->m_errstate = SP_ERROR_NONE;
dvander@180
   178
dvander@180
   179
	return pForward;
dvander@180
   180
}
dvander@180
   181
dvander@180
   182
int CForward::Execute(cell_t *result, IForwardFilter *filter)
dvander@180
   183
{
dvander@180
   184
	if (m_errstate)
dvander@180
   185
	{
dvander@180
   186
		int err = m_errstate;
dvander@180
   187
		Cancel();
dvander@180
   188
		return err;
dvander@180
   189
	}
dvander@180
   190
dvander@180
   191
	if (filter)
dvander@180
   192
	{
dvander@180
   193
		filter->OnExecuteBegin();
dvander@180
   194
	}
dvander@180
   195
dvander@180
   196
	FuncIter iter = m_functions.begin();
dvander@180
   197
	IPluginFunction *func;
dvander@180
   198
	cell_t cur_result = 0;
dvander@180
   199
	cell_t high_result = 0;
dvander@180
   200
	int err;
dvander@180
   201
	unsigned int failed=0, success=0;
dvander@180
   202
	unsigned int save_numcopy = 0;
dvander@183
   203
	unsigned int num_params = m_curparam;
dvander@183
   204
	FwdParamInfo temp_info[SP_MAX_EXEC_PARAMS];
dvander@183
   205
	FwdParamInfo *param;
dvander@183
   206
	ParamType type;
dvander@180
   207
dvander@183
   208
	/* Save local, reset */
dvander@183
   209
	memcpy(temp_info, m_params, sizeof(m_params));
dvander@183
   210
	m_curparam = 0;
dvander@183
   211
dvander@180
   212
	for (iter=m_functions.begin(); iter!=m_functions.end(); iter++)
dvander@180
   213
	{
dvander@180
   214
		func = (*iter);
dvander@183
   215
dvander@183
   216
		for (unsigned int i=0; i<num_params; i++)
dvander@180
   217
		{
dvander@183
   218
			param = &temp_info[i];
dvander@183
   219
			if (i >= m_numparams || m_types[i] == Param_Any)
dvander@183
   220
			{
dvander@183
   221
				type = param->pushedas;
dvander@183
   222
			} else {
dvander@183
   223
				type = m_types[i];
dvander@183
   224
			}
dvander@183
   225
			if ((i >= m_numparams) || (type & SP_PARAMFLAG_BYREF))
dvander@180
   226
			{
dvander@183
   227
				/* If we're byref or we're vararg, we always push everything by ref.
dvander@183
   228
				 * Even if they're byval, we must push them byref.
dvander@183
   229
				 */
dvander@183
   230
				if (type == Param_String) 
dvander@180
   231
				{
dvander@183
   232
					func->PushStringEx((char *)param->byref.orig_addr, param->byref.flags);
dvander@183
   233
				} else if (type == Param_Float || type == Param_Cell) {
dvander@183
   234
					func->PushCellByRef(&param->val, 0); 
dvander@183
   235
				} else {
dvander@183
   236
					func->PushArray(param->byref.orig_addr, param->byref.cells, NULL, param->byref.flags);
dvander@183
   237
					assert(type == Param_Array || type == Param_FloatByRef || type == Param_CellByRef);
dvander@180
   238
				}
dvander@183
   239
			} else {
dvander@183
   240
				/* If we're not byref or not vararg, our job is a bit easier. */
dvander@183
   241
				assert(type == Param_Cell || type == Param_Float);
dvander@183
   242
				func->PushCell(param->val);
dvander@180
   243
			}
dvander@180
   244
		}
dvander@183
   245
		
dvander@180
   246
		/* Call the function and deal with the return value.
dvander@180
   247
		 * :TODO: only pass reader if we know we have an array in the list
dvander@180
   248
		 */
dvander@183
   249
		if ((err=func->Execute(&cur_result)) != SP_ERROR_NONE)
dvander@180
   250
		{
dvander@180
   251
			bool handled = false;
dvander@180
   252
			if (filter)
dvander@180
   253
			{
dvander@180
   254
				handled = filter->OnErrorReport(this, func, err);
dvander@180
   255
			}
dvander@180
   256
			if (!handled)
dvander@180
   257
			{
dvander@180
   258
				/* :TODO: invoke global error reporting here */
dvander@180
   259
			}
dvander@180
   260
			failed++;
dvander@180
   261
		} else {
dvander@180
   262
			success++;
dvander@180
   263
			switch (m_ExecType)
dvander@180
   264
			{
dvander@180
   265
			case ET_Event:
dvander@180
   266
				{
dvander@180
   267
					if (cur_result > high_result)
dvander@180
   268
					{
dvander@180
   269
						high_result = cur_result;
dvander@180
   270
					}
dvander@180
   271
					break;
dvander@180
   272
				}
dvander@180
   273
			case ET_Hook:
dvander@180
   274
				{
dvander@180
   275
					if (cur_result > high_result)
dvander@180
   276
					{
dvander@180
   277
						high_result = cur_result;
dvander@180
   278
						if ((ResultType)high_result == Pl_Stop)
dvander@180
   279
						{
dvander@180
   280
							iter = m_functions.end();
dvander@180
   281
							break;
dvander@180
   282
						}
dvander@180
   283
					}
dvander@180
   284
					break;
dvander@180
   285
				}
dvander@180
   286
			case ET_Custom:
dvander@180
   287
				{
dvander@180
   288
					if (filter)
dvander@180
   289
					{
dvander@180
   290
						if (filter->OnFunctionReturn(this, func, &cur_result) == Pl_Stop)
dvander@180
   291
						{
dvander@180
   292
							iter = m_functions.end();
dvander@180
   293
						}
dvander@180
   294
					}
dvander@180
   295
					break;
dvander@180
   296
				}
dvander@180
   297
			}
dvander@180
   298
		}
dvander@180
   299
	}
dvander@180
   300
dvander@180
   301
	if (m_ExecType == ET_Event || m_ExecType == ET_Hook)
dvander@180
   302
	{
dvander@180
   303
		cur_result = high_result;
dvander@180
   304
	} else if (m_ExecType == ET_Ignore) {
dvander@180
   305
		cur_result = 0;
dvander@180
   306
	}
dvander@180
   307
dvander@180
   308
	*result = cur_result;
dvander@180
   309
dvander@180
   310
	if (filter)
dvander@180
   311
	{
dvander@180
   312
		filter->OnExecuteEnd(&cur_result, success, failed);
dvander@180
   313
	}
dvander@180
   314
dvander@180
   315
	return SP_ERROR_NONE;
dvander@180
   316
}
dvander@180
   317
dvander@180
   318
int CForward::PushCell(cell_t cell)
dvander@180
   319
{
dvander@180
   320
	if (m_curparam < m_numparams)
dvander@180
   321
	{
dvander@183
   322
		if (m_types[m_curparam] == Param_Any)
dvander@180
   323
		{
dvander@183
   324
			m_params[m_curparam].pushedas = Param_Cell;
dvander@183
   325
		} else if (m_types[m_curparam] != Param_Cell) {
dvander@180
   326
			return SetError(SP_ERROR_PARAM);
dvander@180
   327
		}
dvander@180
   328
	} else {
dvander@180
   329
		if (!m_varargs || m_numparams > SP_MAX_EXEC_PARAMS)
dvander@180
   330
		{
dvander@180
   331
			return SetError(SP_ERROR_PARAMS_MAX);
dvander@180
   332
		}
dvander@183
   333
		m_params[m_curparam].pushedas = Param_Cell;
dvander@180
   334
	}
dvander@180
   335
dvander@183
   336
	m_params[m_curparam++].val = cell;
dvander@180
   337
dvander@180
   338
	return SP_ERROR_NONE;
dvander@180
   339
}
dvander@180
   340
dvander@180
   341
int CForward::PushFloat(float number)
dvander@180
   342
{
dvander@180
   343
	if (m_curparam < m_numparams)
dvander@180
   344
	{
dvander@183
   345
		if (m_types[m_curparam] == Param_Any)
dvander@180
   346
		{
dvander@183
   347
			m_params[m_curparam].pushedas = Param_Float;
dvander@183
   348
		} else if (m_types[m_curparam] != Param_Float) {
dvander@180
   349
			return SetError(SP_ERROR_PARAM);
dvander@180
   350
		}
dvander@180
   351
	} else {
dvander@180
   352
		if (!m_varargs || m_numparams > SP_MAX_EXEC_PARAMS)
dvander@180
   353
		{
dvander@180
   354
			return SetError(SP_ERROR_PARAMS_MAX);
dvander@180
   355
		}
dvander@183
   356
		m_params[m_curparam].pushedas = Param_Float;
dvander@180
   357
	}
dvander@180
   358
dvander@183
   359
	m_params[m_curparam++].val = *(cell_t *)&number;
dvander@180
   360
dvander@180
   361
	return SP_ERROR_NONE;
dvander@180
   362
}
dvander@180
   363
dvander@180
   364
int CForward::PushCellByRef(cell_t *cell, int flags)
dvander@180
   365
{
dvander@180
   366
	if (m_curparam < m_numparams)
dvander@180
   367
	{
dvander@180
   368
		if (m_types[m_curparam] != Param_CellByRef && m_types[m_curparam] != Param_Any)
dvander@180
   369
		{
dvander@180
   370
			return SetError(SP_ERROR_PARAM);
dvander@180
   371
		}
dvander@180
   372
	} else {
dvander@180
   373
		if (!m_varargs || m_numparams > SP_MAX_EXEC_PARAMS)
dvander@180
   374
		{
dvander@180
   375
			return SetError(SP_ERROR_PARAMS_MAX);
dvander@180
   376
		}
dvander@180
   377
	}
dvander@180
   378
dvander@183
   379
	_Int_PushArray(cell, 1, flags);
dvander@180
   380
	m_curparam++;
dvander@180
   381
dvander@180
   382
	return SP_ERROR_NONE;
dvander@180
   383
}
dvander@180
   384
dvander@180
   385
int CForward::PushFloatByRef(float *num, int flags)
dvander@180
   386
{
dvander@180
   387
	if (m_curparam < m_numparams)
dvander@180
   388
	{
dvander@180
   389
		if (m_types[m_curparam] != Param_FloatByRef && m_types[m_curparam] != Param_Any)
dvander@180
   390
		{
dvander@180
   391
			return SetError(SP_ERROR_PARAM);
dvander@180
   392
		}
dvander@180
   393
	} else {
dvander@180
   394
		if (!m_varargs || m_numparams > SP_MAX_EXEC_PARAMS)
dvander@180
   395
		{
dvander@180
   396
			return SetError(SP_ERROR_PARAMS_MAX);
dvander@180
   397
		}
dvander@180
   398
	}
dvander@180
   399
dvander@183
   400
	_Int_PushArray((cell_t *)num, 1, flags);
dvander@180
   401
	m_curparam++;
dvander@180
   402
dvander@180
   403
	return SP_ERROR_NONE;
dvander@180
   404
}
dvander@180
   405
dvander@180
   406
void CForward::_Int_PushArray(cell_t *inarray, unsigned int cells, int flags)
dvander@180
   407
{
dvander@183
   408
	m_params[m_curparam].byref.cells = cells;
dvander@183
   409
	m_params[m_curparam].byref.flags = flags;
dvander@183
   410
	m_params[m_curparam].byref.orig_addr = inarray;
dvander@180
   411
}
dvander@180
   412
dvander@180
   413
int CForward::PushArray(cell_t *inarray, unsigned int cells, cell_t **phys_addr, int flags)
dvander@180
   414
{
dvander@180
   415
	/* We don't allow this here */
dvander@180
   416
	if (!inarray)
dvander@180
   417
	{
dvander@180
   418
		return SetError(SP_ERROR_PARAM);
dvander@180
   419
	}
dvander@180
   420
dvander@180
   421
	if (m_curparam < m_numparams)
dvander@180
   422
	{
dvander@183
   423
		if (m_types[m_curparam] == Param_Any)
dvander@180
   424
		{
dvander@183
   425
			m_params[m_curparam].pushedas = Param_Array;
dvander@183
   426
		} else if (m_types[m_curparam] != Param_Array) {
dvander@180
   427
			return SetError(SP_ERROR_PARAM);
dvander@180
   428
		}
dvander@180
   429
	} else {
dvander@180
   430
		if (!m_varargs || m_curparam > SP_MAX_EXEC_PARAMS)
dvander@180
   431
		{
dvander@180
   432
			return SetError(SP_ERROR_PARAMS_MAX);
dvander@180
   433
		}
dvander@183
   434
		m_params[m_curparam].pushedas = Param_Array;
dvander@180
   435
	}
dvander@180
   436
dvander@180
   437
	if (phys_addr)
dvander@180
   438
	{
dvander@180
   439
		*phys_addr = NULL;
dvander@180
   440
	}
dvander@180
   441
dvander@180
   442
	_Int_PushArray(inarray, cells, flags);
dvander@180
   443
dvander@180
   444
	m_curparam++;
dvander@180
   445
dvander@180
   446
	return SP_ERROR_NONE;
dvander@180
   447
}
dvander@180
   448
dvander@180
   449
int CForward::PushString(const char *string)
dvander@180
   450
{
dvander@180
   451
	if (m_curparam < m_numparams)
dvander@180
   452
	{
dvander@183
   453
		if (m_types[m_curparam] == Param_Any)
dvander@180
   454
		{
dvander@183
   455
			m_params[m_curparam].pushedas = Param_String;
faluco@188
   456
		} else if (m_types[m_curparam] != Param_String) {
dvander@180
   457
			return SetError(SP_ERROR_PARAM);
dvander@180
   458
		}
dvander@180
   459
	} else {
dvander@180
   460
		if (!m_varargs || m_curparam > SP_MAX_EXEC_PARAMS)
dvander@180
   461
		{
dvander@180
   462
			return SetError(SP_ERROR_PARAMS_MAX);
dvander@180
   463
		}
dvander@183
   464
		m_params[m_curparam].pushedas = Param_String;
dvander@180
   465
	}
dvander@180
   466
dvander@183
   467
	_Int_PushArray((cell_t *)string, 0, 0);
dvander@180
   468
	m_curparam++;
dvander@180
   469
dvander@180
   470
	return SP_ERROR_NONE;
dvander@180
   471
}
dvander@180
   472
dvander@183
   473
int CForward::PushStringEx(char *string, int flags)
dvander@180
   474
{
dvander@180
   475
	if (m_curparam < m_numparams)
dvander@180
   476
	{
dvander@183
   477
		if (m_types[m_curparam] == Param_Any)
dvander@180
   478
		{
dvander@183
   479
			m_params[m_curparam].pushedas = Param_String;
faluco@188
   480
		} else if (m_types[m_curparam] != Param_String) {
dvander@180
   481
			return SetError(SP_ERROR_PARAM);
dvander@180
   482
		}
dvander@180
   483
	} else {
dvander@180
   484
		if (!m_varargs || m_curparam > SP_MAX_EXEC_PARAMS)
dvander@180
   485
		{
dvander@180
   486
			return SetError(SP_ERROR_PARAMS_MAX);
dvander@180
   487
		}
dvander@183
   488
		m_params[m_curparam].pushedas = Param_String;
dvander@180
   489
	}
dvander@180
   490
dvander@183
   491
	_Int_PushArray((cell_t *)string, 0, flags);
dvander@180
   492
	m_curparam++;
dvander@180
   493
dvander@180
   494
	return SP_ERROR_NONE;
dvander@180
   495
}
dvander@180
   496
dvander@180
   497
void CForward::Cancel()
dvander@180
   498
{
dvander@180
   499
	if (!m_curparam)
dvander@180
   500
	{
dvander@180
   501
		return;
dvander@180
   502
	}
dvander@180
   503
dvander@183
   504
	m_curparam = 0;
dvander@180
   505
	m_errstate = SP_ERROR_NONE;
dvander@180
   506
}
dvander@180
   507
dvander@180
   508
bool CForward::AddFunction(sp_context_t *ctx, funcid_t index)
dvander@180
   509
{
dvander@180
   510
	IPlugin *pPlugin = g_PluginMngr.FindPluginByContext(ctx);
dvander@180
   511
	if (!pPlugin)
dvander@180
   512
	{
dvander@180
   513
		return false;
dvander@180
   514
	}
dvander@180
   515
dvander@180
   516
	IPluginFunction *pFunc = pPlugin->GetFunctionById(index);
dvander@180
   517
	if (!pFunc)
dvander@180
   518
	{
dvander@180
   519
		return false;
dvander@180
   520
	}
dvander@180
   521
dvander@180
   522
	return AddFunction(pFunc);
dvander@180
   523
}
dvander@180
   524
dvander@180
   525
bool CForward::RemoveFunction(IPluginFunction *func)
dvander@180
   526
{
dvander@180
   527
	bool found = false;
dvander@180
   528
	FuncIter iter;
dvander@180
   529
	IPluginFunction *pNext = NULL;
dvander@180
   530
dvander@180
   531
	for (iter=m_functions.begin(); iter!=m_functions.end();)
dvander@180
   532
	{
dvander@180
   533
		if ((*iter) == func)
dvander@180
   534
		{
dvander@180
   535
			found = true;
dvander@180
   536
			/* If this iterator is being used, swap in a new one !*/
dvander@180
   537
			iter = m_functions.erase(iter);
dvander@180
   538
		} else {
dvander@180
   539
			iter++;
dvander@180
   540
		}
dvander@180
   541
	}
dvander@180
   542
dvander@180
   543
	/* Cancel a call, if any */
dvander@183
   544
	if (found || m_curparam)
dvander@180
   545
	{
dvander@180
   546
		func->Cancel();
dvander@180
   547
	}
dvander@180
   548
dvander@180
   549
	return found;
dvander@180
   550
}
dvander@180
   551
dvander@180
   552
unsigned int CForward::RemoveFunctionsOfPlugin(IPlugin *plugin)
dvander@180
   553
{
dvander@180
   554
	FuncIter iter;
dvander@180
   555
	IPluginFunction *func;
dvander@180
   556
	unsigned int removed = 0;
dvander@180
   557
	for (iter=m_functions.begin(); iter!=m_functions.end();)
dvander@180
   558
	{
dvander@180
   559
		func = (*iter);
dvander@180
   560
		if (func->GetParentPlugin() == plugin)
dvander@180
   561
		{
dvander@180
   562
			iter = m_functions.erase(iter);
dvander@180
   563
			removed++;
dvander@180
   564
		} else {
dvander@180
   565
			iter++;
dvander@180
   566
		}
dvander@180
   567
	}
dvander@180
   568
dvander@180
   569
	return removed;
dvander@180
   570
}
dvander@180
   571
dvander@180
   572
bool CForward::AddFunction(IPluginFunction *func)
dvander@180
   573
{
dvander@180
   574
	if (m_curparam)
dvander@180
   575
	{
dvander@180
   576
		return false;
dvander@180
   577
	}
dvander@180
   578
dvander@183
   579
	//:TODO: eventually we will tell the plugin we're using it
dvander@183
   580
	m_functions.push_back(func);
dvander@180
   581
dvander@180
   582
	return true;
dvander@180
   583
}
dvander@180
   584
dvander@180
   585
const char *CForward::GetForwardName()
dvander@180
   586
{
dvander@180
   587
	return m_name;
dvander@180
   588
}
dvander@180
   589
dvander@180
   590
unsigned int CForward::GetFunctionCount()
dvander@180
   591
{
dvander@180
   592
	return m_functions.size();
dvander@180
   593
}
dvander@180
   594
dvander@180
   595
ExecType CForward::GetExecType()
dvander@180
   596
{
dvander@180
   597
	return m_ExecType;
dvander@180
   598
}