From 313dd99fd61393acd0ee22aa791873354297578b Mon Sep 17 00:00:00 2001 From: Artyom Beilis Date: Tue, 25 Jan 2011 21:37:38 +0000 Subject: [PATCH] Added support of init() and clean() member functons call on URL dispatching --- cppcms/application.h | 11 ++++ cppcms/url_dispatcher.h | 138 +++++++++++++++++++++++++++++++++++++++++++++--- src/application.cpp | 8 +++ src/hello_world.cpp | 10 ++++ 4 files changed, 161 insertions(+), 6 deletions(-) diff --git a/cppcms/application.h b/cppcms/application.h index 1188b94..8562797 100644 --- a/cppcms/application.h +++ b/cppcms/application.h @@ -263,6 +263,17 @@ namespace cppcms { /// virtual void main(std::string url); + /// + /// This member function called when URL is dispatched to this application, it is + /// useful when member functions of applications are called, by default does nothing + /// + virtual void init(); + + /// + /// This function is used for cleanup unused stuff, it should not throw + /// + virtual void clean(); + private: void recycle(); diff --git a/cppcms/url_dispatcher.h b/cppcms/url_dispatcher.h index 9f497ad..afccbbe 100644 --- a/cppcms/url_dispatcher.h +++ b/cppcms/url_dispatcher.h @@ -23,7 +23,8 @@ #include #include #include -#include +#include +#include #include #include @@ -112,49 +113,174 @@ namespace cppcms { /// assignment of \a member function of an \a object with signature void handler() /// as simple as assign(expr,&bar::foo,this); /// + /// In addition to calling \a member function it calls object->init() before call + /// and object->clean() after the call of the C is derived from cppcms::application + /// template void assign(std::string regex,void (C::*member)(),C *object) { - assign(regex,util::mem_bind(member,object)); + assign(regex,binder0(member,object)); } /// /// This template function is a shortcut to assign(regex,callback,int). It allows /// assignment of \a member function of an \a object with signature void handler(string) /// + /// In addition to calling \a member function it calls object->init() before call + /// and object->clean() after the call of the C is derived from cppcms::application + /// template void assign(std::string regex,void (C::*member)(std::string),C *object,int e1) { - assign(regex,util::mem_bind(member,object),e1); + assign(regex,binder1(member,object),e1); } /// /// This template function is a shortcut to assign(regex,callback,int,int). It allows /// assignment of \a member function of an \a object with signature void handler(string,string) /// + /// In addition to calling \a member function it calls object->init() before call + /// and object->clean() after the call of the C is derived from cppcms::application + /// template void assign(std::string regex,void (C::*member)(std::string,std::string),C *object,int e1,int e2) { - assign(regex,util::mem_bind(member,object),e1,e2); + assign(regex,binder2(member,object),e1,e2); } template /// /// This template function is a shortcut to assign(regex,callback,int,int,int). It allows /// assignment of \a member function of an \a object with signature void handler(string,string,string) /// + /// In addition to calling \a member function it calls object->init() before call + /// and object->clean() after the call of the C is derived from cppcms::application + /// void assign(std::string regex,void (C::*member)(std::string,std::string,std::string),C *object,int e1,int e2,int e3) { - assign(regex,util::mem_bind(member,object),e1,e2,e3); + assign(regex,binder3(member,object),e1,e2,e3); } /// /// This template function is a shortcut to assign(regex,callback,int,int,int,int). It allows /// assignment of \a member function of an \a object with signature void handler(string,string,string,string) /// + /// In addition to calling \a member function it calls object->init() before call + /// and object->clean() after the call of the C is derived from cppcms::application + /// template void assign(std::string regex,void (C::*member)(std::string,std::string,std::string,std::string),C *object,int e1,int e2,int e3,int e4) { - assign(regex,util::mem_bind(member,object),e1,e2,e3,e4); + assign(regex,binder4(member,object),e1,e2,e3,e4); } private: + + template + class page_guard { + public: + page_guard(C *o) {} + }; + + template + class page_guard >::type > { + public: + page_guard(C *o) : + object_(o) + { + object_->init(); + } + ~page_guard() + { + object_->clean(); + } + private: + C *object_; + }; + + template + struct binder0{ + typedef void (C::*member_type)(); + member_type member; + C *object; + + binder0(member_type m,C *o) : + member(m), + object(o) + { + } + void operator()() const + { + page_guard guard(object); + (object->*member)(); + } + }; + + template + struct binder1{ + typedef void (C::*member_type)(std::string); + member_type member; + C *object; + + binder1(member_type m,C *o) : + member(m), + object(o) + { + } + void operator()(std::string p1) const + { + page_guard guard(object); + (object->*member)(p1); + } + }; + + template + struct binder2{ + typedef void (C::*member_type)(std::string,std::string); + member_type member; + C *object; + + binder2(member_type m,C *o) : + member(m), + object(o) + { + } + void operator()(std::string p1,std::string p2) const + { + page_guard guard(object); + (object->*member)(p1,p2); + } + }; + template + struct binder3{ + typedef void (C::*member_type)(std::string,std::string,std::string); + member_type member; + C *object; + + binder3(member_type m,C *o) : + member(m), + object(o) + { + } + void operator()(std::string p1,std::string p2,std::string p3) const + { + page_guard guard(object); + (object->*member)(p1,p2,p3); + } + }; + template + struct binder4{ + typedef void (C::*member_type)(std::string,std::string,std::string,std::string); + member_type member; + C *object; + + binder4(member_type m,C *o) : + member(m), + object(o) + { + } + void operator()(std::string p1,std::string p2,std::string p3,std::string p4) const + { + page_guard guard(object); + (object->*member)(p1,p2,p3,p4); + } + }; friend class application; void mount(std::string match,application &app,int part); diff --git a/src/application.cpp b/src/application.cpp index 04194a3..df90599 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -165,6 +165,14 @@ void application::attach(application *app) add(*app); } +void application::init() +{ +} + +void application::clean() +{ +} + void application::main(std::string url) { if(!dispatcher().dispatch(url)) { diff --git a/src/hello_world.cpp b/src/hello_world.cpp index 636719f..359fb42 100644 --- a/src/hello_world.cpp +++ b/src/hello_world.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef CPPCMS_USE_EXTERNAL_BOOST # include #else // Internal Boost @@ -241,6 +242,10 @@ public: } }; +struct foo { + void bar() {} +} foo_instance; + class hello : public cppcms::application { public: @@ -256,6 +261,7 @@ public: dispatcher().assign("^/form$",&hello::form,this); dispatcher().assign("^/cache/?$",&hello::cached,this); dispatcher().assign("^/throw/?$",&hello::throw_it,this); + dispatcher().assign("^/foo$",&foo::bar,&foo_instance); dispatcher().assign("^/session/?$",&hello::session_test,this); dispatcher().assign("^/verylong/?$",&hello::verylong,this); dispatcher().assign(".*",&hello::hello_world,this); @@ -424,6 +430,10 @@ public: <<"\n"; } + void init() + { + std::cout << "There" << std::endl; + } void num(std::string s) { response().set_plain_text_header();