Well, I guess posting no code isn't very smart of me.
Here is what I have but it really needs to be cleaned up and possibly rewritten.
Code:
#ifndef USERMESSAGE_H
#define USERMESSAGE_H
#ifndef _VECTOR_ // If vector has not been included
#include <vector> // Include it now...
#endif // End statement
// pfnMessageProc
// Type for a function pointer to a callback function.
typedef int ( *pfnMessageProc ) ( edict_t* pDest, void* pData );
// struct usermessage_s
// usermessage_t
// Structure containing data about a network message.
typedef struct usermessage_s
{
char szName[ 12 ]; // Name of message
int iId, // Id of message
iSize; // Size of message
pfnMessageProc pfnCallback; // Function to call when this message is started,
// finished or written to.
} usermessage_t;
// CUserMessageHandler
// Class to aid in the registration, lookup and capture of network messages.
class CUserMessageHandler
{
std::vector< usermessage_t > m_uMessages; // Vector list of all messages currently registered
int m_iCurrentMsg; // Id of the message currently being sent
// Find
// Iterates through the currently registered messages
// and returns the an iterator to the requested element.
// Search is case sensitive.
std::vector< usermessage_t >::iterator Find( const char* pszName )
{
std::vector< usermessage_t >::iterator iBegin = m_uMessages.begin( );
std::vector< usermessage_t >::iterator iEnd = m_uMessages.end( );
usermessage_t uCurrent;
while ( iBegin != iEnd )
{
uCurrent = *iBegin;
if ( uCurrent.szName )
{
if ( ! strcmp( uCurrent.szName, pszName ) )
return iBegin;
}
++iBegin;
}
return 0;
}
// Find
// Overloaded to lookup a message from it's id.
std::vector< usermessage_t >::iterator Find( int iId )
{
std::vector< usermessage_t >::iterator iBegin = m_uMessages.begin( );
std::vector< usermessage_t >::iterator iEnd = m_uMessages.end( );
usermessage_t uCurrent;
while ( iBegin != iEnd )
{
uCurrent = *iBegin;
if ( uCurrent.iId == iId )
{
return iBegin;
}
++iBegin;
}
return 0;
}
usermessage_t Dummy( void )
{
usermessage_t uDummy;
memset( &uDummy, 0, sizeof( usermessage_t ) );
return uDummy;
}
public:
// Reset
// Clear all user messages registered.
// Make sure this is done in ServerActivate otherwise they will repeat.
void Reset( void )
{
m_uMessages.clear( );
}
// Add
// Registers a message with the message handler.
// This is usually done in RegUserMsg and optionally you can pass a pointer to
// a function that gets called when the message is started, finished or written to.
void Add( const char* pszName, int iSize, int iId, pfnMessageProc pfnCallback )
{
usermessage_t uTemp;
strcpy( uTemp.szName, pszName );
uTemp.pfnCallback = pfnCallback;
uTemp.iSize = iSize;
uTemp.iId = iId;
m_uMessages.push_back( uTemp );
}
// Remove
// Removes a message from the handler by name.
void Remove( const char* pszName )
{
std::vector< usermessage_t >::iterator iIndex = Find( pszName );
if ( iIndex != 0 )
{
m_uMessages.erase( iIndex );
}
}
// Lookup
// Returns a usermessage_t pointer to a previously registered message.
usermessage_t Lookup( const char* pszName )
{
std::vector< usermessage_t >::iterator iIndex = Find( pszName );
if ( iIndex != 0 )
{
return *iIndex;
}
return Dummy( );
}
};
extern CUserMessageHandler gHandler;
#endif // USERMESSAGE_H
The idea for the Lookup method is to return a pointer to the element, if it was not found I could simply return NULL which cannot be done by value.