Browse Source

Added support of init() and clean() member functons call on URL dispatching

master
Artyom Beilis 13 years ago
parent
commit
313dd99fd6
4 changed files with 161 additions and 6 deletions
  1. +11
    -0
      cppcms/application.h
  2. +132
    -6
      cppcms/url_dispatcher.h
  3. +8
    -0
      src/application.cpp
  4. +10
    -0
      src/hello_world.cpp

+ 11
- 0
cppcms/application.h View File

@@ -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();


+ 132
- 6
cppcms/url_dispatcher.h View File

@@ -23,7 +23,8 @@
#include <cppcms/defs.h>
#include <booster/function.h>
#include <booster/hold_ptr.h>
#include <cppcms/mem_bind.h>
#include <booster/traits/enable_if.h>
#include <booster/traits/is_base_of.h>
#include <string>
#include <list>

@@ -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<typename C>
void assign(std::string regex,void (C::*member)(),C *object)
{
assign(regex,util::mem_bind(member,object));
assign(regex,binder0<C>(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<typename C>
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<C>(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<typename C>
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<C>(member,object),e1,e2);
}
template<typename C>
///
/// 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<C>(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<typename C>
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<C>(member,object),e1,e2,e3,e4);
}

private:

template<typename C,typename Enable = void>
class page_guard {
public:
page_guard(C *o) {}
};

template<typename C>
class page_guard<C,typename booster::enable_if<booster::is_base_of< cppcms::application,C> >::type > {
public:
page_guard(C *o) :
object_(o)
{
object_->init();
}
~page_guard()
{
object_->clean();
}
private:
C *object_;
};

template<typename C>
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<C> guard(object);
(object->*member)();
}
};
template<typename C>
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<C> guard(object);
(object->*member)(p1);
}
};

template<typename C>
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<C> guard(object);
(object->*member)(p1,p2);
}
};
template<typename C>
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<C> guard(object);
(object->*member)(p1,p2,p3);
}
};
template<typename C>
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<C> guard(object);
(object->*member)(p1,p2,p3,p4);
}
};
friend class application;
void mount(std::string match,application &app,int part);


+ 8
- 0
src/application.cpp View File

@@ -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)) {


+ 10
- 0
src/hello_world.cpp View File

@@ -36,6 +36,7 @@
#include <stdlib.h>
#include <set>
#include <cppcms/config.h>
#include <cppcms/mem_bind.h>
#ifdef CPPCMS_USE_EXTERNAL_BOOST
# include <boost/bind.hpp>
#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:
<<"<body></html>\n";

}
void init()
{
std::cout << "There" << std::endl;
}
void num(std::string s)
{
response().set_plain_text_header();


Loading…
Cancel
Save