Menu

[r2392]: / framework / trunk / cppcms / plugin.h  Maximize  Restore  History

Download this file

126 lines (110 with data), 3.7 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2008-2016 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// See accompanying file COPYING.TXT file for licensing details.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef CPPCMS_PLUGIN_H
#define CPPCMS_PLUGIN_H
#include <cppcms/defs.h>
#include <cppcms/cppcms_error.h>
#include <booster/callback.h>
#include <booster/hold_ptr.h>
#include <string>
namespace cppcms {
namespace plugin {
class CPPCMS_API manager {
public:
///
/// Get the instance of the manager
///
static manager &instance();
typedef booster::intrusive_ptr<booster::refcounted> refcounted_ptr;
///
/// Functions registered as plugin entry points
///
typedef refcounted_ptr (*entry_point_type)();
///
/// Get plugin entry by plugin name, entry point name and type
///
/// For example
/// \code
/// booster::callback<cppcms::application *(cppcms::service &)> cb = cppcms::plugin::manager::entry<cppcms::application *(cppcms::service &)>("foo","application");
/// cppcms::application *app =cb(service());
/// attach(app,"/plugins/foo(/.*)",1); // attach new application
/// \endcode
///
/// Or
///
/// \code
/// cppcms::application *app = cppcms::plugin::manager::entry<cppcms::application *(cppcms::service &)>("myapi","app::generator")(service());
/// attach(app,"/plugins/foo(/.*)",1);
/// \endcode
///
/// \ver{v1_2}
template<typename Signature>
static
booster::callback<Signature>
entry(std::string const &name)
{
typedef booster::callback<Signature> callback_type;
typedef typename callback_type::callable_type callable_type;
typedef typename callback_type::pointer_type pointer_type;
entry_point_type plugin_call = instance().get_entry(name);
if(!plugin_call)
throw cppcms_error("Could not find plugin `" + name + "'");
refcounted_ptr call = plugin_call();
if(!call)
throw cppcms_error("Failed to create callback from `" + name + "'");
callable_type *real_call = dynamic_cast<callable_type *>(call.get());
if(!real_call) {
throw booster::bad_cast();
}
pointer_type ptr(real_call);
callback_type result(ptr);
return result;
}
///
/// Get entry point that creates a base of booster::callback::callable_type
///
entry_point_type get_entry(std::string const &name);
///
/// Addes entry to the plugin manager - thread safe function
///
void add_entry(char const *name,entry_point_type entry);
///
/// Removes entry from the plugin manager - thread safe function
///
void remove_entry(entry_point_type entry);
private:
manager();
~manager();
manager(manager const &);
void operator=(manager const &);
struct _data;
booster::hold_ptr<_data> d;
};
#define CPPCMS_NAMED_PLUGIN_ENTRY(type,call,name) \
namespace { \
struct stpg_##__LINE__ { \
static booster::intrusive_ptr<booster::refcounted> entry() \
{ \
typedef booster::callback<type> ct; \
ct cb = &call; \
booster::refcounted *tmp = cb.get_pointer().get(); \
booster::intrusive_ptr<booster::refcounted> ptr(tmp); \
return ptr; \
} \
stpg_##__LINE__() { \
cppcms::plugin::manager::instance().add_entry(name,&entry); \
} \
~stpg_##__LINE__() { \
cppcms::plugin::manager::instance().remove_entry(&entry); \
} \
} instance_of_stpg_##__LINE__; \
}
#define CPPCMS_PLUGIN_ENTRY(type,call) CPPCMS_NAMED_PLUGIN_ENTRY(type,call,#call)
} // plugin
} // cppcms
#endif
MongoDB Logo MongoDB