Example #1
0
// Process all the currently active triggers
void eventProcessTriggers(UDWORD currTime)
{
	ACTIVE_TRIGGER	*psCurr, *psNext, *psNew;
	TRIGGER_DATA	*psData;

	// Process all the current triggers
	psAddedTriggers = NULL;
	updateTime = currTime;
	while(psTrigList && psTrigList->testTime <= currTime)
	{
		psCurr = psTrigList;
		psTrigList = psTrigList->psNext;

		// Run the trigger
		if (eventFireTrigger(psCurr))	// This might mark the trigger for deletion
		{
			if (psCurr->deactivated || psCurr->type == TR_WAIT)
			{
				// remove the trigger
				eventFreeTrigger(psCurr);
			}
			else if (psCurr->type == TR_PAUSE)
			{
				// restarted a paused event - replace the old trigger
				if (psCurr->trigger != -1)
				{
					if (eventInitTrigger(&psNew, psCurr->psContext, psCurr->event, psCurr->trigger, updateTime))
					{
						psNew->psNext = psAddedTriggers;
						psAddedTriggers = psNew;
					}
				}

				// remove the TR_PAUSE trigger
				eventFreeTrigger(psCurr);
			}
			else
			{
				// Add the trigger again
				psData = psCurr->psContext->psCode->psTriggerData + psCurr->trigger;
				psCurr->testTime = currTime + psData->time;
				psCurr->psNext = psAddedTriggers;
				psAddedTriggers = psCurr;
			}
		}
	}

	// Delete marked triggers now
	eventPruneLists();

	// Now add all the new triggers
	for(psCurr = psAddedTriggers; psCurr; psCurr=psNext)
	{
		psNext = psCurr->psNext;
		eventAddTrigger(psCurr);
	}
	//clear out after added them all
	psAddedTriggers = NULL;
}
Example #2
0
// Activate a callback trigger
void eventFireCallbackTrigger(TRIGGER_TYPE callback)
{
	ACTIVE_TRIGGER	*psPrev = NULL, *psCurr, *psNext;
	TRIGGER_DATA	*psTrigDat;
	BOOL		fired;

	if (interpProcessorActive())
	{
		ASSERT(false, "eventFireCallbackTrigger: script interpreter is already running");
		return;
	}

	//this can be called from eventProcessTriggers and so will wipe out all the current added ones
	//psAddedTriggers = NULL;
	for (psCurr = psCallbackList; psCurr && psCurr->type <= (int)callback; psCurr = psNext)
	{
		psNext = psCurr->psNext;
		if (psCurr->type == (int)callback)
		{
			// see if the callback should be fired
			fired = false;
			if (psCurr->type != TR_PAUSE)
			{
				ASSERT(psCurr->trigger >= 0 && psCurr->trigger < psCurr->psContext->psCode->numTriggers,
				       "eventFireCallbackTrigger: invalid trigger number");
				psTrigDat = psCurr->psContext->psCode->psTriggerData + psCurr->trigger;
			}
			else
			{
				psTrigDat = NULL;
			}
			if (psTrigDat && psTrigDat->code)
			{
				if (!interpRunScript(psCurr->psContext, IRT_TRIGGER, psCurr->trigger, 0))
				{
					ASSERT(false, "eventFireCallbackTrigger: trigger %s: code failed",
					       eventGetTriggerID(psCurr->psContext->psCode, psCurr->trigger));
					psPrev = psCurr;
					continue;
				}
				if (!stackPopParams(1, VAL_BOOL, &fired))
				{
					ASSERT(false, "eventFireCallbackTrigger: trigger %s: code failed",
					       eventGetTriggerID(psCurr->psContext->psCode, psCurr->trigger));
					psPrev = psCurr;
					continue;
				}
			}
			else
			{
				fired = true;
			}

			// run the event
			if (fired)
			{
				DB_TRIGINF(psCurr,1);
				DB_TRACE(" fired",1);

				// remove the trigger from the list
				if (psPrev == NULL)
				{
					psCallbackList = psCallbackList->psNext;
				}
				else
				{
					psPrev->psNext = psNext;
				}

				psFiringTrigger = psCurr;
				if (!interpRunScript(psCurr->psContext, IRT_EVENT, psCurr->event, psCurr->offset)) // this could set psCurr->deactivated
				{
					ASSERT(false, "eventFireCallbackTrigger: event %s: code failed",
					       eventGetEventID(psCurr->psContext->psCode, psCurr->event));
				}
				if (psCurr->deactivated)
				{
					// don't need to add the trigger again - just free it
					eventFreeTrigger(psCurr);
				}
				else
				{
					// make sure the trigger goes back into the system
					psCurr->psNext = psAddedTriggers;
					psAddedTriggers = psCurr;
				}
			}
			else
			{
				psPrev = psCurr;
			}
		}
		else
		{
			psPrev = psCurr;
		}
	}

	// Delete marked triggers now
	eventPruneLists();

	// Now add all the new triggers
	for(psCurr = psAddedTriggers; psCurr; psCurr=psNext)
	{
		psNext = psCurr->psNext;
		eventAddTrigger(psCurr);
	}
	//clear out after added them all
	psAddedTriggers = NULL;
}
Example #3
0
// Remove an object from the event system
void eventRemoveContext(SCRIPT_CONTEXT *psContext)
{
	ACTIVE_TRIGGER *psCurr, *psPrev, *psNext;
	VAL_CHUNK		*psCChunk, *psNChunk;
	SCRIPT_CONTEXT	*psCCont, *psPCont=NULL;
	SDWORD			i, chunkStart;
	INTERP_VAL		*psVal;

	// Get rid of all it's triggers
	while(psTrigList && psTrigList->psContext == psContext)
	{
		psNext = psTrigList->psNext;
		eventFreeTrigger(psTrigList);
		psTrigList = psNext;
	}

	for (psPrev = NULL, psCurr = psTrigList; psCurr; psCurr = psNext)
	{
		psNext = psCurr->psNext;
		if (psCurr->psContext == psContext)
		{
			eventFreeTrigger(psCurr);
			if (psPrev)
			{
				psPrev->psNext = psNext;
			}
		}
		else
		{
			psPrev = psCurr;
		}
	}
	// Get rid of all it's callback triggers
	while(psCallbackList && psCallbackList->psContext == psContext)
	{
		psNext = psCallbackList->psNext;
		eventFreeTrigger(psCallbackList);
		psCallbackList = psNext;
	}

	for (psPrev = NULL, psCurr = psCallbackList; psCurr; psCurr = psNext)
	{
		psNext = psCurr->psNext;
		if (psCurr->psContext == psContext)
		{
			eventFreeTrigger(psCurr);
			if (psPrev)
			{
				psPrev->psNext = psNext;
			}
		}
		else
		{
			psPrev = psCurr;
		}
	}

	// Call the release function for all the values
	if (asReleaseFuncs != NULL)
	{
		psCChunk = psContext->psGlobals;
		chunkStart = 0;
		for(i=0; i<psContext->psCode->numGlobals; i++)
		{
			if (i - chunkStart >= CONTEXT_VALS)
			{
				chunkStart += CONTEXT_VALS;
				psCChunk = psCChunk->psNext;
				ASSERT( psCChunk != NULL,
					"eventRemoveContext: not enough value chunks" );
			}
			psVal = psCChunk->asVals + (i - chunkStart);
			if (psVal->type < numFuncs && asReleaseFuncs[psVal->type] != NULL)
			{
				asReleaseFuncs[psVal->type](psVal);
			}
		}
	}

	// Free it's variables
	for(psCChunk = psContext->psGlobals; psCChunk; psCChunk = psNChunk)
	{
		psNChunk = psCChunk->psNext;
		// FIXME FIXME FIXME - this is commented away because it made loading
		// different savegames many times crash for inexplicable reasons. It
		// will probably leak memory, though!
/*		for(i=0;i < CONTEXT_VALS ; i++)
		{
			if (psCChunk->asVals[i].type == VAL_STRING && psCChunk->asVals[i].v.sval)
			{
				free(psCChunk->asVals[i].v.sval);
				psCChunk->asVals[i].v.sval = NULL;
			}
		}*/
		free(psCChunk);
	}
	psContext->psGlobals = NULL;

	// Remove it from the context list
	if (psContext == psContList)
	{
		psCCont = psContList;
		psContList = psContList->psNext;
		free(psCCont);
	}
	else
	{
		for(psCCont = psContList; psCCont && psCCont!=psContext;
			psCCont = psCCont->psNext)
		{
			psPCont = psCCont;
		}
		if (psCCont)
		{
			psPCont->psNext = psCCont->psNext;
			free(psContext);
		}
		else
		{
			ASSERT( false, "eventRemoveContext: context not found" );
		}
	}
}