Unsolved a router for websocket messages, is there anything wrong with this implementation
-
I've built a router that is similar in syntax to laravel's router
I know "get" and "post" will sound just like http, but I'm using them for convenience.
here is the implementation:
router.h#ifndef ROUTER_H #define ROUTER_H #include "message.h" class CNTRLR{}; //MSVC will throw C2440 when using reinterpret_cast with undefined classes using MemberCallback = void (CNTRLR::*)(Message &); struct MemberCallbackInfo { CNTRLR *instance; MemberCallback ptr; }; typedef QMap<QString,MemberCallbackInfo> MemberCallbacks; class Router { public: explicit Router(); void route(Message &message); template <class T> static void registerRoute(MemberCallbacks *callBacks, const QString& action, T *instance, void (T::*ptr)(Message &)){MemberCallbackInfo obj={reinterpret_cast<CNTRLR *>(instance), reinterpret_cast<MemberCallback>(ptr)}; callBacks->insert(action, obj);} template <class T> static void get (const QString& action, T *instance, void (T::*ptr)(Message &)){registerRoute(&getRoutes,action,instance,ptr);} template <class T> static void post (const QString& action, T *instance, void (T::*ptr)(Message &)){registerRoute(&postRoutes,action,instance,ptr);} private: static MemberCallbacks getRoutes; static MemberCallbacks postRoutes; }; typedef Router Route; #endif // ROUTER_H
router.cpp
#include "router.h" MemberCallbacks Router::getRoutes; MemberCallbacks Router::postRoutes; Router::Router() { } void Router::route(Message &message) { if(message.method()=="GET") { MemberCallbackInfo cb= getRoutes.value(message.action()); (cb.instance->*cb.ptr)(message); } else if(message.method()=="POST") { MemberCallbackInfo cb= postRoutes.value(message.action()); (cb.instance->*cb.ptr)(message); } }
now if I want to route something I just have to type something like this from anywhere I want in the app
Route::post("user/auth", this, &AuthController::authenticate);
I've used a tricky way to store member function pointers and I'm not sure if it's type safe
I used template functions so that I can make sure that the instance and the member function pointer are of the same class,
I'm storing the info in a struct called "MemberCallbackInfo".class CNTRLR is just a dummy class.
according to the Standard (section 5.2.10/9), you can use reinterpret_cast to store a member function for one class inside a member function pointer for an unrelated class,
and that is what I did with the dummy class.is there a more elegant way(like utilizing Qt's signals,slots and Qt's metaobject system) to implement such router while keeping the same routing syntax above ?