在Plugin源码阅读过程中,遇到如下宏定义:
#define APPBASE_PLUGIN_REQUIRES_VISIT( r, visitor, elem ) \
visitor( appbase::app().register_plugin<elem>() );
#define APPBASE_PLUGIN_REQUIRES( PLUGINS ) \
virtual void plugin_for_each_dependency( plugin_processor&& l ) override { \
BOOST_PP_SEQ_FOR_EACH( APPBASE_PLUGIN_REQUIRES_VISIT, l, PLUGINS ) \
}
BOOST_PP_SEQ_FOR_EACH
宏用于将一个序列中参数依次按照指定宏进行展开:
BOOST_PP_SEQ_FOR_EACH(macro, data, seq)
macro
一个以格式macro(r, data, elem)定义的三元宏。该宏被BOOST_PP_SEQ_FOR_EACH按照seq中每个元素进行展开。展开该宏,需要用到下一个BOOST_PP_FOR的重复项、备用数据data和当前元素。
data
备用数据,用于传给macro
seq
用于供macro按照哪个序列进行展开
用法:
BOOST_PP_SEQ_FOR_EACH是一个重复项的宏。
如果序列是(a)(b)(c),则展开为:
macro(r, data, a) macro(r, data, b) macro(r, data, c)
例如database_api_plugin
类中定义了:
APPBASE_PLUGIN_REQUIRES(
(gamebank::plugins::json_rpc::json_rpc_plugin)
(gamebank::plugins::chain::chain_plugin)
)
展开宏APPBASE_PLUGIN_REQUIRES
:
virtual void plugin_for_each_dependency( plugin_processor&& l ) override
{
BOOST_PP_SEQ_FOR_EACH( APPBASE_PLUGIN_REQUIRES_VISIT, l, (json_rpc_plugin)(chain_plugin) )
}
继续展开BOOST_PP_SEQ_FOR_EACH
:
virtual void plugin_for_each_dependency( plugin_processor&& l ) override
{
APPBASE_PLUGIN_REQUIRES_VISIT(r, l, json_rpc_plugin)
APPBASE_PLUGIN_REQUIRES_VISIT(r, l, chain_plugin)
}
继续展开APPBASE_PLUGIN_REQUIRES_VISIT
,最终得到:
//plugin_processor在class abstract_plugin中定义:
//typedef std::function<void(abstract_plugin&)> plugin_processor;
virtual void plugin_for_each_dependency( plugin_processor&& l ) override
{
l( appbase::app().register_plugin<json_rpc_plugin>() );
l( appbase::app().register_plugin<chain_plugin>() );
}
plugin_for_each_dependency
是虚函数,在抽象基类abstract_plugin
中定义为接口,并在各个final插件中实现,它负责注册依赖的插件到application
回到database_api_plugin
, 它依赖json_rpc_plugin
和chain_plugin
,不仅需要把他们插件注册到application
,而且要在初始化和启动database_api_plugin
插件的同时,初始化和启动它的依赖插件json_rpc_plugin
和chain_plugin
。
初始化和启动database_api_plugin
代码如下:
//完全继承自plugin<T>
virtual void initialize(const variables_map& options) override final
{
if( _state == registered )
{
_state = initialized;
//1:注册json_rpc_plugin和chain_plugin到database_api_plugin
//2:初始化json_rpc_plugin和chain_plugin
this->plugin_for_each_dependency( [&]( abstract_plugin& plug ){ plug.initialize( options ); } );
//database_api_plugin::plugin_initialize()
this->plugin_initialize( options );
//注册到database_api_plugin到application
app().plugin_initialized( *this );
}
if (_state != initialized)
BOOST_THROW_EXCEPTION( std::runtime_error("Initial state was not registered, so final state cannot be initialized.") );
}
...
//完全继承自plugin<T>
virtual void startup() override final
{
if( _state == initialized )
{
_state = started;
//1:注册json_rpc_plugin和chain_plugin
//2:启动json_rpc_plugin和chain_plugin
this->plugin_for_each_dependency( [&]( abstract_plugin& plug ){ plug.startup(); } );
//database_api_plugin::plugin_startup
this->plugin_startup();
app().plugin_started( *this );
}
if (_state != started )
BOOST_THROW_EXCEPTION( std::runtime_error("Initial state was not initialized, so final state cannot be started.") );
}
未避免重复初始化和启动插件,abstract_plugin定义了插件状态
enum state {
registered, ///< the plugin is constructed but doesn't do anything
initialized, ///< the plugin has initlaized any state required but is idle
started, ///< the plugin is actively running
stopped ///< the plugin is no longer running
};
- 当且仅当插件状态为registered时才被执行初始化
- 当且仅当插件状态为initialized时才被启动
网友评论