在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宏用于將一個(gè)序列中參數(shù)依次按照指定宏進(jìn)行展開:
BOOST_PP_SEQ_FOR_EACH(macro, data, seq)
macro
一個(gè)以格式macro(r, data, elem)定義的三元宏。該宏被BOOST_PP_SEQ_FOR_EACH按照seq中每個(gè)元素進(jìn)行展開。展開該宏,需要用到下一個(gè)BOOST_PP_FOR的重復(fù)項(xiàng)、備用數(shù)據(jù)data和當(dāng)前元素。
data
備用數(shù)據(jù),用于傳給macro
seq
用于供macro按照哪個(gè)序列進(jìn)行展開
用法:
BOOST_PP_SEQ_FOR_EACH是一個(gè)重復(fù)項(xiàng)的宏。
如果序列是(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) )
}
繼續(xù)展開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)
}
繼續(xù)展開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是虛函數(shù),在抽象基類abstract_plugin中定義為接口,并在各個(gè)final插件中實(shí)現(xiàn),它負(fù)責(zé)注冊(cè)依賴的插件到application
回到database_api_plugin, 它依賴json_rpc_plugin和chain_plugin,不僅需要把他們插件注冊(cè)到application,而且要在初始化和啟動(dòng)database_api_plugin插件的同時(shí),初始化和啟動(dòng)它的依賴插件json_rpc_plugin和chain_plugin。
初始化和啟動(dòng)database_api_plugin代碼如下:
//完全繼承自plugin<T>
virtual void initialize(const variables_map& options) override final
{
if( _state == registered )
{
_state = initialized;
//1:注冊(cè)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 );
//注冊(cè)到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:注冊(cè)json_rpc_plugin和chain_plugin
//2:啟動(dòng)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.") );
}
未避免重復(fù)初始化和啟動(dòng)插件,abstract_plugin定義了插件狀態(tài)
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
};
- 當(dāng)且僅當(dāng)插件狀態(tài)為registered時(shí)才被執(zhí)行初始化
- 當(dāng)且僅當(dāng)插件狀態(tài)為initialized時(shí)才被啟動(dòng)