#ifndef __FB_H__
#define __FB_H__
#include <map>
#include <string>
namespace FB
{
struct FunctionCall
{
virtual ~FunctionCall(void) throw() { }
virtual void execute(void* res, void* pars) const = 0;
};
struct MethodCall
{
virtual ~MethodCall(void) throw() { }
virtual void execute(void* instance, void* res, void* pars) const = 0;
};
template <typename Base>
class Registry
{
typedef std::map<std::string, Base*> RegistryMap;
RegistryMap m_map;
Registry(void) { }
Registry(const Registry&) { }
Registry& operator=(const Registry&) { return *this; }
public:
~Registry(void) throw()
{
for(RegistryMap::iterator iit = m_map.begin(); iit != m_map.end(); ++iit)
delete (*iit).second;
}
inline static Registry& getInstance(void)
{
static Registry s_registry;
return s_registry;
}
void registrate(std::string name, Base* call)
{
RegistryMap::iterator iit = m_map.find(name);
if(iit != m_map.end())
throw "binding already registered";
m_map[name] = call;
}
Base* operator[](std::string name) const
{
RegistryMap::const_iterator iit = m_map.find(name);
if(iit == m_map.end())
return 0;
else
return (*iit).second;
}
};
template <typename R>
class Function0p: public FunctionCall
{
public:
typedef R (*Type)();
private:
Type m_ptr;
Function0p(Type ptr): m_ptr(ptr) { }
Function0p(const Function0p&) { }
Function0p& operator=(const Function0p&) { return *this; }
public:
void execute(void* res, void*) const
{
*(reinterpret_cast<R*>(res)) = (*m_ptr)();
}
static void registrate(std::string name, Type ptr)
{
Function0p* function = new Function0p(ptr);
try
{
Registry<FunctionCall>::getInstance().registrate(name, function);
}
catch(...)
{
delete function;
throw;
}
}
};
template <>
class Function0p<void>: public FunctionCall
{
public:
typedef void (*Type)();
private:
Type m_ptr;
Function0p(Type ptr): m_ptr(ptr) { }
Function0p(const Function0p&) { }
Function0p& operator=(const Function0p&) { return *this; }
public:
void execute(void*, void*) const
{
(*m_ptr)();
}
static void registrate(std::string name, Type ptr)
{
Function0p* function = new Function0p(ptr);
try
{
Registry<FunctionCall>::getInstance().registrate(name, function);
}
catch(...)
{
delete function;
throw;
}
}
};
template <typename R, typename P0>
class Function1p: public FunctionCall
{
public:
#pragma pack(push)
#pragma pack(1)
struct Pars
{
P0 p0;
};
#pragma pack(pop)
typedef R (*Type)(P0);
private:
Type m_ptr;
Function1p(Type ptr): m_ptr(ptr) { }
Function1p(const Function1p&) { }
Function1p& operator=(const Function1p&) { return *this; }
public:
void execute(void* res, void* pars) const
{
Pars& lean = *reinterpret_cast<Pars*>(pars);
*(reinterpret_cast<R*>(res)) = (*m_ptr)(lean.p0);
}
static void registrate(std::string name, Type ptr)
{
Function1p* function = new Function1p(ptr);
try
{
Registry<FunctionCall>::getInstance().registrate(name, function);
}
catch(...)
{
delete function;
throw;
}
}
};
template <typename P0>
class Function1p<void, P0>: public FunctionCall
{
public:
#pragma pack(push)
#pragma pack(1)
struct Pars
{
P0 p0;
};
#pragma pack(pop)
typedef void (*Type)(P0);
private:
Type m_ptr;
Function1p(Type ptr): m_ptr(ptr) { }
Function1p(const Function1p&) { }
Function1p& operator=(const Function1p&) { return *this; }
public:
void execute(void*, void* pars) const
{
Pars& lean = *reinterpret_cast<Pars*>(pars);
(*m_ptr)(lean.p0);
}
static void registrate(std::string name, Type ptr)
{
Function1p* function = new Function1p(ptr);
try
{
Registry<FunctionCall>::getInstance().registrate(name, function);
}
catch(...)
{
delete function;
throw;
}
}
};
template <typename C, typename R>
class Method0p: public MethodCall
{
public:
typedef R (C::*Type)();
private:
Type m_ptr;
Method0p(Type ptr): m_ptr(ptr) { }
Method0p(const Method0p&) { }
Method0p& operator=(const Method0p&) { return *this; }
public:
void execute(void* instance, void* res, void*) const
{
*(reinterpret_cast<R*>(res)) = (reinterpret_cast<C*>(instance)->*m_ptr)();
}
static void registrate(std::string name, Type ptr)
{
Method0p* method = new Method0p(ptr);
try
{
Registry<MethodCall>::getInstance().registrate(name, method);
}
catch(...)
{
delete method;
throw;
}
}
};
template <typename C>
class Method0p<C, void>: public MethodCall
{
public:
typedef void (C::*Type)();
private:
Type m_ptr;
Method0p(Type ptr): m_ptr(ptr) { }
Method0p(const Method0p&) { }
Method0p& operator=(const Method0p&) { return *this; }
public:
void execute(void* instance, void*, void*) const
{
(reinterpret_cast<C*>(instance)->*m_ptr)();
}
static void registrate(std::string name, Type ptr)
{
Method0p* method = new Method0p(ptr);
try
{
Registry<MethodCall>::getInstance().registrate(name, method);
}
catch(...)
{
delete method;
throw;
}
}
};
template <typename C, typename R, typename P0>
class Method1p: public MethodCall
{
public:
#pragma pack(push)
#pragma pack(1)
struct Pars
{
P0 p0;
};
#pragma pack(pop)
typedef R (C::*Type)(P0);
private:
Type m_ptr;
Method1p(Type ptr): m_ptr(ptr) { }
Method1p(const Method1p&) { }
Method1p& operator=(const Method1p&) { return *this; }
public:
void execute(void* instance, void* res, void*) const
{
Pars& lean = *reinterpret_cast<Pars*>(pars);
*(reinterpret_cast<R*>(res)) = (reinterpret_cast<C*>(instance)->*m_ptr)(lean.p0);
}
static void registrate(std::string name, Type ptr)
{
Method1p* method = new Method1p(ptr);
try
{
Registry<MethodCall>::getInstance().registrate(name, method);
}
catch(...)
{
delete method;
throw;
}
}
};
template <typename C, typename P0>
class Method1p<C, void, P0>: public MethodCall
{
public:
#pragma pack(push)
#pragma pack(1)
struct Pars
{
P0 p0;
};
#pragma pack(pop)
typedef void (C::*Type)(P0);
private:
Type m_ptr;
Method1p(Type ptr): m_ptr(ptr) { }
Method1p(const Method1p&) { }
Method1p& operator=(const Method1p&) { return *this; }
public:
void execute(void* instance, void*, void* pars) const
{
Pars& lean = *reinterpret_cast<Pars*>(pars);
(reinterpret_cast<C*>(instance)->*m_ptr)(lean.p0);
}
static void registrate(std::string name, Type ptr)
{
Method1p* method = new Method1p(ptr);
try
{
Registry<MethodCall>::getInstance().registrate(name, method);
}
catch(...)
{
delete method;
throw;
}
}
};
template <typename R>
void registrateFunction(std::string name, R (*ptr)())
{
Function0p<R>::registrate(name, ptr);
}
template <typename C, typename R>
void registrateMethod(std::string name, R (C::*ptr)())
{
Method0p<C, R>::registrate(name, ptr);
}
struct FunctionRegistration
{
template <typename R>
inline FunctionRegistration(std::string name, R (*ptr)())
{
Function0p<R>::registrate(name, ptr);
}
template <typename R, typename P0>
inline FunctionRegistration(std::string name, R (*ptr)(P0))
{
Function1p<R, P0>::registrate(name, ptr);
}
};
struct MethodRegistration
{
template <typename C, typename R>
inline MethodRegistration(std::string name, R (C::*ptr)())
{
Method0p<C, R>::registrate(name, ptr);
}
template <typename C, typename R, typename P0>
inline MethodRegistration(std::string name, R (C::*ptr)(P0))
{
Method1p<C, R, P0>::registrate(name, ptr);
}
};
}
#define __FB_REGISTRATE_FUNCTION(function_name) \
static struct RegistrateFunction_##function_name \
{ \
\
inline RegistrateFunction_##function_name() { static FB::FunctionRegistration s_functionRegistration(#function_name, #function_name); } \
\
\
} registrateFunction_##function_name;
#define __FB_REGISTRATE_METHOD(class_name, method_name) \
static struct RegistrateMethod_##class_name_##method_name \
{ \
\
inline RegistrateMethod_##class_name_##method_name () { static FB::MethodRegistration s_methodRegistration(#class_name "_" #method_name, #class_name::##method_name); } \
\
\
} registrateMethod_##class_name_##method_name;
#define __FB_CALL_FUNCTION(function_name, res, pars) FB::Registry<FB::FunctionCall>::getInstance()[#function_name]->execute(res, pars)
#define __FB_CALL_METHOD(class_name, method_name, instance, res, pars) FB::Registry<FB::MethodCall>::getInstance()[#class_name "_" #method_name]->execute(instance, res, pars);
#endif
|