core/EventManager.cpp
changeset 2567 2995c3b5d7b0
parent 2538 f3392408c5ad
child 2708 023e747a3bb1
     1.1 --- a/core/EventManager.cpp	Sun Feb 01 20:39:23 2009 -0500
     1.2 +++ b/core/EventManager.cpp	Sat Feb 07 23:56:48 2009 -0500
     1.3 @@ -193,6 +193,9 @@
     1.4  			pHook->pPostHook->AddFunction(pFunction);
     1.5  		}
     1.6  
     1.7 +		/* Cache the name for post hooks */
     1.8 +		pHook->name = strdup(name);
     1.9 +
    1.10  		/* Increase reference count */
    1.11  		pHook->refCount++;
    1.12  
    1.13 @@ -296,6 +299,9 @@
    1.14  		/* Delete entry in trie */
    1.15  		sm_trie_delete(m_EventHooks, name);
    1.16  
    1.17 +		/* Free the cached name */
    1.18 +		free(pHook->name);
    1.19 +
    1.20  		/* And finally free structure memory */
    1.21  		delete pHook;
    1.22  	}
    1.23 @@ -365,14 +371,17 @@
    1.24  	{
    1.25  		RETURN_META_VALUE(MRES_IGNORED, false);
    1.26  	}
    1.27 -	
    1.28 -	/* Get the event name, we're going to need this for passing to post hooks */
    1.29 +
    1.30  	name = pEvent->GetName();
    1.31 -
    1.32 -	m_EventNames.push(name);
    1.33 -
    1.34 +	
    1.35  	if (sm_trie_retrieve(m_EventHooks, name, reinterpret_cast<void **>(&pHook)))
    1.36  	{
    1.37 +		/* Push the event onto the event stack.  The reference count is increased to make sure 
    1.38 +		 * the structure is not garbage collected in between now and the post hook.
    1.39 +		 */
    1.40 +		pHook->refCount++;
    1.41 +		m_EventStack.push(pHook);
    1.42 +
    1.43  		pForward = pHook->pPreHook;
    1.44  
    1.45  		if (pForward)
    1.46 @@ -400,6 +409,10 @@
    1.47  			RETURN_META_VALUE(MRES_SUPERCEDE, false);
    1.48  		}
    1.49  	}
    1.50 +	else
    1.51 +	{
    1.52 +		m_EventStack.push(NULL);
    1.53 +	}
    1.54  
    1.55  	RETURN_META_VALUE(MRES_IGNORED, true);
    1.56  }
    1.57 @@ -410,7 +423,6 @@
    1.58  	EventHook *pHook;
    1.59  	EventInfo info;
    1.60  	IChangeableForward *pForward;
    1.61 -	const char *name;
    1.62  	Handle_t hndl = 0;
    1.63  
    1.64  	/* The engine accepts NULL without crashing, so to prevent a crash in SM we ignore these */
    1.65 @@ -419,9 +431,9 @@
    1.66  		RETURN_META_VALUE(MRES_IGNORED, false);
    1.67  	}
    1.68  
    1.69 -	name = m_EventNames.front();
    1.70 +	pHook = m_EventStack.front();
    1.71  
    1.72 -	if (sm_trie_retrieve(m_EventHooks, name, reinterpret_cast<void **>(&pHook)))
    1.73 +	if (pHook != NULL)
    1.74  	{
    1.75  		pForward = pHook->pPostHook;
    1.76  
    1.77 @@ -438,7 +450,7 @@
    1.78  				pForward->PushCell(BAD_HANDLE);
    1.79  			}
    1.80  
    1.81 -			pForward->PushString(name);
    1.82 +			pForward->PushString(pHook->name);
    1.83  			pForward->PushCell(bDontBroadcast);
    1.84  			pForward->Execute(NULL);
    1.85  
    1.86 @@ -453,9 +465,19 @@
    1.87  				m_EventCopies.pop();
    1.88  			}
    1.89  		}
    1.90 +
    1.91 +		/* Decrement reference count, check if a delayed delete is needed */
    1.92 +		if (--pHook->refCount == 0)
    1.93 +		{
    1.94 +			assert(pHook->pPostHook == NULL);
    1.95 +			assert(pHook->pPreHook == NULL);
    1.96 +			sm_trie_delete(m_EventHooks, pHook->name);
    1.97 +			free(pHook->name);
    1.98 +			delete pHook;
    1.99 +		}
   1.100  	}
   1.101  
   1.102 -	m_EventNames.pop();
   1.103 +	m_EventStack.pop();
   1.104  
   1.105  	RETURN_META_VALUE(MRES_IGNORED, true);
   1.106  }