I'm trying to deserialize event handlers for a project I'm working on. However, I tried to be super clever with the event handlers, and since I didn't start out with serialization issues in mind, I worry that I've coded myself into a corner. The event handler style that I came up with I'm actually quite happy with. But now that I want to deserialize them, I'm trying to figure out an easy way to have the event handlers register their types in a map with the handler type as the key, and a deserialization function pointer as the value. However, I'm having problems getting the syntax for the function pointer correct. I've tried a number of different ways with the compiler giving a different error every time. I've gotten it down to one simple error message, but I just can't get over this hump. Can anyone tell me what I'm doing wrong?
Here's the header file for the event handlers:
#ifndef MESSAGE_JOINT_H
#define MESSAGE_JOINT_H
#include "Events.h"
#include "MessageReceiver.h"
namespace Events
{
class MessageReceiver;
class MessageJoint
{
public:
MessageJoint( Ogre::String id, MessageReceiver* receiver );
MessageJoint( const MessageJoint & rhs );
void FireEvent( MessageReceiver* from );
void SetData( boost::any d ){ data = d; }
void SetIdentifier( Ogre::String id ){ identifier = id; }
virtual void HandleEvent( boost::any ) = 0;
void TuneIn( MessageReceiver* r )
{
listeners.push_back( r );
}
Ogre::String GetIdentifier(){ return identifier; }
MessageReceiver* owner;
std::vector< MessageReceiver* > listeners;
boost::any data;
private:
typedef void (*Deserialize)(Events::MessageReceiver*);
static std::unordered_map<Ogre::String,Deserialize> mRegisteredAddresses;
static void Register( Ogre::String name, Deserialize f){ mRegisteredAddresses[name] = f;}
Ogre::String identifier;
};
}
#define MESSAGE_JOINT_CLASS( A ) class Joint ## A : public Events::MessageJoint \
{ \
public: \
static const Ogre::String c ## A ## Id; \
void HandleEvent( boost::any ); \
MessageJoint* _Deserialize( Events::MessageReceiver* r){ \
return new Joint ## A( r ); } \
Joint ## A ( Events::MessageReceiver* receiver ) \
: Events::MessageJoint( Ogre::String( "Joint ## A"), receiver ) \
{Register(GetIdentifier(),&Joint ## A::_Deserialize);} \
};
#endif
Here's some example declarations for some events:
#define JOINTOPENMENUOBJECTMANAGER "OpenMenuObjectManager"
MESSAGE_JOINT_CLASS( OpenMenuObjectManager )
#define JOINTCLOSEMENUOBJECTMANAGER "CloseMenuObjectManager"
MESSAGE_JOINT_CLASS( CloseMenuObjectManager )
And then then implementations for those declarations:
const Ogre::String SwissArmyKnife::JointOpenMenuObjectManager::cOpenMenuObjectManagerId = JOINTOPENMENUOBJECTMANAGER;
void SwissArmyKnife::JointOpenMenuObjectManager::HandleEvent( boost::any data )
{
SwissArmyKnife* sak = static_cast< SwissArmyKnife* >( owner );
sak->SetInputState( SwissArmyKnife::IS_MN_MENU );
}
const Ogre::String SwissArmyKnife::JointCloseMenuObjectManager::cCloseMenuObjectManagerId = JOINTCLOSEMENUOBJECTMANAGER;
void SwissArmyKnife::JointCloseMenuObjectManager::HandleEvent( boost::any data )
{
SwissArmyKnife* sak = static_cast< SwissArmyKnife* >( owner );
sak->SetInputState( SwissArmyKnife::IS_MAIN );
}
And when I try to compile with the recent changes for deserialization, I get error messages like the following:
1>c:\source\swissarmyknife\swissarmyknife\actors.h(214): error C2664: 'Events::MessageJoint::Register' : cannot convert parameter 2 from 'Events::MessageJoint *(__thiscall Actors::JointChangeState::* )(Events::MessageReceiver *)' to 'Events::MessageJoint::Deserialize'
1> There is no context in which this conversion is possible
1>c:\source\swissarmyknife\swissarmyknife\actors.h(214): error C2664: 'Events::MessageJoint::Register' : cannot convert parameter 2 from 'Events::MessageJoint *(__thiscall Actors::JointChangeState::* )(Events::MessageReceiver *)' to 'Events::MessageJoint::Deserialize'
1> There is no context in which this conversion is possible
1>c:\source\swissarmyknife\swissarmyknife\guicontrols.h(115): error C2664: 'Events::MessageJoint::Register' : cannot convert parameter 2 from 'Events::MessageJoint *(__thiscall GuiControls::JointGuiPropertyChanged::* )(Events::MessageReceiver *)' to 'Events::MessageJoint::Deserialize'
1> There is no context in which this conversion is possible
1>c:\source\swissarmyknife\swissarmyknife\menuobject.h(84): error C2664: 'Events::MessageJoint::Register' : cannot convert parameter 2 from 'Events::MessageJoint *(__thiscall GuiControls::JointCloseMenu::* )(Events::MessageReceiver *)' to 'Events::MessageJoint::Deserialize'
1> There is no context in which this conversion is possible