插件系统

[English]

公共头文件: #include "brookesia/lib_utils/plugin.hpp"

概述

plugin 提供通用插件注册表与实例管理机制,用于按名称注册、发现与创建插件实例。

特性

  • 模板化插件注册与查询,按名称获取实例

  • 支持延迟实例化与单例插件注册

  • 提供插件枚举、释放与清理接口

  • 支持宏生成注册符号,保证链接可见性

API 参考

Header File

Classes

template<typename T>
class PluginRegistry

Thread-safe registry for named plugin factories and cached instances.

模板参数

T -- Base class type exposed by the registry.

Public Static Functions

static inline std::shared_ptr<T> get_instance(const std::string &name)

Get a plugin instance by name.

Returns the cached instance when available, otherwise creates it through the registered factory.

备注

The returned shared_ptr shares ownership with the Registry. The instance remains valid as long as either the Registry or any returned shared_ptr holds a reference, ensuring thread-safe access even if release_instance() or remove_plugin() is called.

参数

name -- [in] Registered plugin name.

返回

Shared pointer to the plugin instance, or nullptr when the plugin is not registered or the factory is empty.

static inline std::map<std::string, std::shared_ptr<T>> get_all_instances()

Get instances for all registered plugins.

Missing cached instances are created on demand before they are returned.

备注

Each returned shared_ptr shares ownership with the Registry. The instances remain valid as long as either the Registry or any returned shared_ptr holds a reference, ensuring thread-safe access.

返回

Map from plugin name to shared plugin instance.

static inline size_t get_plugin_count()

Get the number of registered plugin names.

返回

Total number of registered plugins.

static inline bool has_plugin(const std::string &name)

Check whether a plugin name is registered.

参数

name -- [in] Plugin name to test.

返回

true when the plugin exists in the registry, or false otherwise.

static inline void release_instance(const std::string &name)

Release the cached instance for a registered plugin.

This keeps the factory registration intact and only drops the registry-held shared pointer.

参数

name -- [in] Plugin name.

static inline void release_all_instances()

Release all cached plugin instances without removing registrations.

static inline void remove_plugin(const std::string &name)

Remove a plugin registration and its cached instance.

参数

name -- [in] Plugin name to remove.

static inline void remove_all_plugins()

Remove all registered plugins and cached instances.

template<typename PluginType>
static inline void register_plugin(const std::string &name, FactoryFunc factory)

Register a plugin factory under a unique name.

模板参数

PluginType -- Concrete plugin type being registered.

参数
  • name -- [in] Plugin name. Existing registrations with the same name are kept unchanged.

  • factory -- [in] Factory used to lazily create instances.

Macros

_BROOKESIA_PLUGIN_CONCAT(a, b)
BROOKESIA_PLUGIN_CONCAT(a, b)
BROOKESIA_PLUGIN_CREATE_SYMBOL(symbol_name, static_var_name)

Create a linker-visible symbol that keeps a registrar object alive.

备注

The function is defined outside any namespace to ensure proper linking. The static variable reference ensures the registrar instance is not optimized away.

BROOKESIA_PLUGIN_REGISTER_PRE_MAIN_FUNCTION(symbol_name, function)

Auto-register a function to be invoked before main().

Generates a file-local static registrar whose constructor calls function exactly once during C++ static initialization - i.e. before the program enters main(). On ESP-IDF this also guarantees the function runs before app_main() is entered.

Typical use cases: plugin auto-registration, installing HAL hook callbacks, seeding global singletons, or any one-shot boot-time setup. This macro is the building block behind every other BROOKESIA_PLUGIN_REGISTER_* form.

Relative ordering between translation units that use this (or any other static initialization) is unspecified. If ordering matters, embed it inside function itself.

The generated static instance is also exported as an external symbol via BROOKESIA_PLUGIN_CREATE_SYMBOL so the linker keeps it alive when this TU lives in a static library. Remember to add -u <symbol_name> to the final link.

static void boot_time_setup() {
    // Runs before main / app_main.
}
BROOKESIA_PLUGIN_REGISTER_PRE_MAIN_FUNCTION(my_boot_setup_sym, boot_time_setup);

BROOKESIA_PLUGIN_REGISTER_PRE_MAIN_FUNCTION(my_inline_sym, [](){
    // ... inline pre-main work ...
});

参数
  • symbol_name -- Linker-visible identifier used with -u to keep the registrar alive.

  • function -- Callable expression (return value is ignored); typically a function pointer or a capture-less lambda.

BROOKESIA_PLUGIN_REGISTER_WITH_CONSTRUCTOR(BaseType, PluginType, name, creator, symbol_name)

Register a plugin using a custom creator expression.

备注

Automatically creates a fixed symbol name based on PluginType for linker -u option. Internally delegates to BROOKESIA_PLUGIN_REGISTER_PRE_MAIN_FUNCTION for the static-init dispatch; the only extra machinery here is the pointer-type-coercion helper that adapts shared/unique pointers returned by the creator into the registry's shared_ptr<BaseType> factory signature.

参数
  • BaseType -- Registry base type.

  • PluginType -- Concrete plugin type to register.

  • name -- Plugin name used by PluginRegistry.

  • creator -- Creator expression returning shared_ptr or unique_ptr compatible with the registry.

  • symbol_name -- Linker symbol exported for -u.

BROOKESIA_PLUGIN_REGISTER(BaseType, PluginType, name, ...)

Register a plugin constructed with std::make_shared.

// Example usage:
BROOKESIA_PLUGIN_REGISTER(BaseService, MyPlugin, "my_plugin");
BROOKESIA_PLUGIN_REGISTER(BaseService, MyPlugin, "my_plugin", arg1, arg2);

参数
  • BaseType -- Registry base type.

  • PluginType -- Concrete plugin type to register.

  • name -- Plugin name used by PluginRegistry.

  • ... -- Optional constructor arguments forwarded to PluginType.

BROOKESIA_PLUGIN_REGISTER_SINGLETON(BaseType, PluginType, name, instance_expr)

Register a singleton object in the plugin registry.

This macro allows registering a singleton instance to the plugin registry. It uses a custom no-op deleter to prevent the shared_ptr from destroying the singleton. Automatically generates a fixed symbol name based on PluginType for linker -u option.

// Example usage:
BROOKESIA_PLUGIN_REGISTER_SINGLETON(
    BaseService,
    MySingleton,
    "my_singleton",
    MySingleton::get_instance()
);
// Creates symbol: _MySingleton_symbol_<line_number>
// Use: target_link_libraries(${COMPONENT_LIB} INTERFACE "-u _MySingleton_symbol_<line_number>")

参数
  • BaseType -- Registry base type.

  • PluginType -- Singleton type to register.

  • name -- Plugin name used by PluginRegistry.

  • instance_expr -- Expression that yields a singleton instance reference, for example Type::get_instance().

BROOKESIA_PLUGIN_REGISTER_WITH_SYMBOL(BaseType, PluginType, name, symbol_name, ...)

Register a plugin constructed with std::make_shared and a custom linker symbol.

// Example usage:
BROOKESIA_PLUGIN_REGISTER_WITH_SYMBOL(BaseService, MyPlugin, "my_plugin", "custom_symbol_name");
BROOKESIA_PLUGIN_REGISTER_WITH_SYMBOL(BaseService, MyPlugin, "my_plugin", "custom_symbol_name", arg1, arg2);
// Use: target_link_libraries(${COMPONENT_LIB} INTERFACE "-u custom_symbol_name")

参数
  • BaseType -- Registry base type.

  • PluginType -- Concrete plugin type to register.

  • name -- Plugin name used by PluginRegistry.

  • symbol_name -- Custom linker symbol exported for -u.

  • ... -- Optional constructor arguments forwarded to PluginType.

BROOKESIA_PLUGIN_REGISTER_SINGLETON_WITH_SYMBOL(BaseType, PluginType, name, instance_expr, symbol_name)

Register a singleton object with a custom linker symbol.

This macro allows registering a singleton instance to the plugin registry. It uses a custom no-op deleter to prevent the shared_ptr from destroying the singleton. Uses the provided custom symbol name for linker -u option.

// Example usage:
BROOKESIA_PLUGIN_REGISTER_SINGLETON_WITH_SYMBOL(
    BaseService,
    MySingleton,
    "my_singleton",
    MySingleton::get_instance(),
    "custom_symbol_name"
);
// Use: target_link_libraries(${COMPONENT_LIB} INTERFACE "-u custom_symbol_name")

参数
  • BaseType -- Registry base type.

  • PluginType -- Singleton type to register.

  • name -- Plugin name used by PluginRegistry.

  • instance_expr -- Expression that yields a singleton instance reference.

  • symbol_name -- Custom linker symbol exported for -u.