deserializing by function pointer, but can't get the syntax right

86 Views Asked by At

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
0

There are 0 best solutions below