Skip to content

API Reference

dgliu edited this page Feb 14, 2026 · 1 revision

API Reference

本页面提供 MCCC (Multi-Channel Communication Controller) 库的完整 API 参考文档。


目录


AsyncBus<PayloadVariant>

核心消息总线类。基于无锁 MPSC 环形缓冲实现,支持多生产者单消费者模式。

模板参数 PayloadVariantstd::variant<T1, T2, ...>,定义总线可承载的所有消息类型。

Instance()

static AsyncBus& Instance();

获取全局单例引用。线程安全 (Meyers' singleton)。

  • 返回值: AsyncBus& -- 总线单例引用
  • 线程安全: 是 (C++11 静态局部变量保证)

Publish()

template <typename T>
bool Publish(T&& message);

发布一条消息到总线。使用发送者的默认优先级进行背压准入判断。

  • 模板参数: T -- 消息类型,必须是 PayloadVariant 的可选类型之一
  • 参数: message -- 待发布的消息,支持移动语义
  • 返回值: true 入队成功;false 队列已满或背压拒绝
  • 线程安全: 是 (lock-free CAS enqueue)

PublishWithPriority()

template <typename T>
bool PublishWithPriority(T&& message, MessagePriority priority);

以指定优先级发布消息。高优先级消息在背压场景下有更高的准入概率。

  • 模板参数: T -- 消息类型
  • 参数:
    • message -- 待发布的消息
    • priority -- 消息优先级 (LOW / MEDIUM / HIGH)
  • 返回值: true 入队成功;false 被背压丢弃
  • 线程安全: 是

PublishFast()

template <typename T>
bool PublishFast(T&& message);

快速发布,跳过背压检查和统计计数。适用于已知队列不会满的场景或对延迟极度敏感的热路径。

  • 模板参数: T -- 消息类型
  • 参数: message -- 待发布的消息
  • 返回值: true 入队成功;false 队列物理已满
  • 线程安全: 是

Subscribe<T>()

template <typename T>
uint32_t Subscribe(std::function<void(const T&)> callback);

订阅指定类型的消息。当总线分发该类型消息时,回调函数被调用。

  • 模板参数: T -- 要订阅的消息类型
  • 参数: callback -- 消息处理回调函数
  • 返回值: uint32_t -- 订阅 ID,用于后续取消订阅
  • 线程安全: 需要获取写锁 (shared_mutex),不应在热路径调用

Unsubscribe()

void Unsubscribe(uint32_t subscription_id);

取消订阅。

  • 参数: subscription_id -- Subscribe() 返回的订阅 ID
  • 线程安全: 需要获取写锁

ProcessBatch()

uint32_t ProcessBatch(uint32_t max_count = 256);

从队列中批量取出消息并通过回调表分发。使用 shared_mutex 读锁查找已注册的回调。

  • 参数: max_count -- 单批次最大处理消息数,默认 256
  • 返回值: uint32_t -- 实际处理的消息数量
  • 线程安全: 必须由单一消费者线程调用 (MPSC 约束)

ProcessBatchWith<Visitor>()

template <typename Visitor>
uint32_t ProcessBatchWith(Visitor&& visitor, uint32_t max_count = 256);

使用 std::visit + Visitor 模式批量处理消息。编译期分发,无需查找回调表,无 shared_mutex 开销。

  • 模板参数: Visitor -- 可调用对象,需为每个 PayloadVariant 中的类型提供 operator()
  • 参数:
    • visitor -- 访问者对象
    • max_count -- 单批次最大处理消息数
  • 返回值: uint32_t -- 实际处理的消息数量
  • 线程安全: 必须由单一消费者线程调用
  • 性能: 比 ProcessBatch() 快 19%~42%

MessagePriority

enum class MessagePriority : uint8_t {
    LOW    = 0,   // 背压准入阈值 60%
    MEDIUM = 1,   // 背压准入阈值 80%
    HIGH   = 2    // 背压准入阈值 99%
};

消息优先级枚举。当队列水位超过对应阈值时,该优先级的消息将被丢弃。

优先级 准入阈值 说明
LOW 60% 普通消息,队列超过 60% 容量时开始丢弃
MEDIUM 80% 重要消息,队列超过 80% 容量时开始丢弃
HIGH 99% 关键消息,仅在队列几乎满时才丢弃

MessageHeader

struct MessageHeader {
    uint64_t msg_id;         // 全局唯一消息 ID (原子递增)
    uint64_t timestamp_us;   // 微秒级时间戳 (steady_clock)
    uint32_t sender_id;      // 发送者 ID
    MessagePriority priority; // 消息优先级
};

消息头部结构,附加在每条消息的 MessageEnvelope 中。

字段 类型 说明
msg_id uint64_t 全局单调递增消息 ID
timestamp_us uint64_t 入队时间戳 (微秒,steady_clock)
sender_id uint32_t 发送者标识
priority MessagePriority 消息优先级

MessageEnvelope<PayloadVariant>

template <typename PayloadVariant>
struct MessageEnvelope {
    MessageHeader header;
    PayloadVariant payload;
};

消息信封,将消息头和有效载荷打包为一个传输单元。PayloadVariantstd::variant,承载具体消息类型。


BackpressureLevel

enum class BackpressureLevel : uint8_t {
    NORMAL   = 0,  // 队列水位 < 60%
    WARNING  = 1,  // 队列水位 60%~80%
    CRITICAL = 2,  // 队列水位 80%~99%
    FULL     = 3   // 队列水位 >= 99%
};

背压级别枚举,反映当前队列的拥塞状态。

级别 队列水位 行为
NORMAL < 60% 所有优先级消息均可入队
WARNING 60%~80% LOW 优先级消息被丢弃
CRITICAL 80%~99% LOW + MEDIUM 优先级消息被丢弃
FULL >= 99% HIGH 优先级有 1% 概率入队

PerformanceMode

enum class PerformanceMode : uint8_t {
    FULL_FEATURED = 0,  // 完整功能: 背压 + 统计 + 错误回调
    BARE_METAL    = 1,  // 裸机模式: 仅核心入队/出队
    NO_STATS      = 2   // 无统计: 背压保留,关闭计数器
};

运行时性能模式选择。

模式 背压 统计 错误回调 典型开销
FULL_FEATURED ~38ns/msg
BARE_METAL ~30ns/msg
NO_STATS 介于两者之间

BusStatisticsSnapshot

struct BusStatisticsSnapshot {
    uint64_t total_published;          // 累计发布消息数
    uint64_t total_processed;          // 累计处理消息数
    uint64_t total_dropped;            // 累计丢弃消息数
    uint64_t total_backpressure_drops; // 背压丢弃数
    uint64_t total_errors;             // 累计错误数
    uint64_t current_queue_size;       // 当前队列深度
    uint64_t peak_queue_size;          // 峰值队列深度
    uint64_t total_callbacks_invoked;  // 累计回调调用次数
    double   avg_process_time_us;      // 平均单批处理耗时 (微秒)
    double   queue_utilization;        // 队列利用率 (0.0~1.0)
};

总线运行时统计快照。仅在 FULL_FEATURED 模式下采集。

字段 类型 说明
total_published uint64_t 从启动到现在累计发布的消息数
total_processed uint64_t 累计被消费者处理的消息数
total_dropped uint64_t 累计被丢弃的消息数 (含背压和队列满)
total_backpressure_drops uint64_t 因背压准入机制丢弃的消息数
total_errors uint64_t 累计错误数
current_queue_size uint64_t 当前环形缓冲中的消息数量
peak_queue_size uint64_t 历史峰值队列深度
total_callbacks_invoked uint64_t 累计触发的回调次数
avg_process_time_us double 平均每次 ProcessBatch 调用的耗时 (微秒)
queue_utilization double 队列利用率,范围 0.0 ~ 1.0

FixedString<N>

固定容量字符串,栈上分配,无堆分配。适用于嵌入式场景下替代 std::string

template <std::size_t N>
class FixedString;

构造函数

FixedString();                          // 默认构造,空字符串
FixedString(const char* str);           // 从 C 字符串构造,超长截断
FixedString(const char* str, std::size_t len); // 从缓冲区构造
FixedString(const std::string& str);    // 从 std::string 构造

TruncateToCapacity

标签类型,用于显式标记构造时允许截断。

static constexpr TruncateToCapacity_t TruncateToCapacity{};
FixedString(TruncateToCapacity_t, const char* str);

c_str()

const char* c_str() const noexcept;

返回以 null 结尾的 C 字符串指针。

size()

std::size_t size() const noexcept;

返回当前字符串长度 (不含 null 终止符)。


FixedVector<T, N>

固定容量向量,栈上分配,无堆分配。

template <typename T, std::size_t N>
class FixedVector;

push_back()

bool push_back(const T& value);
bool push_back(T&& value);

追加元素到末尾。容量满时返回 false

emplace_back()

template <typename... Args>
bool emplace_back(Args&&... args);

原地构造元素到末尾。容量满时返回 false

erase_unordered()

void erase_unordered(std::size_t index);

O(1) 无序删除: 将最后一个元素移动到被删除位置,然后缩减 size。不保持元素顺序。

  • 参数: index -- 要删除的元素索引
  • 复杂度: O(1)

clear()

void clear() noexcept;

清空所有元素,size 归零。不调用析构函数 (要求 T 为 trivially destructible 或由调用者管理)。


FixedFunction<Sig, Cap>

固定容量类型擦除可调用对象包装器,使用 SBO (Small Buffer Optimization) 内联存储。

template <typename Sig, std::size_t Cap = 64>
class FixedFunction;

// 偏特化
template <typename R, typename... Args, std::size_t Cap>
class FixedFunction<R(Args...), Cap>;
  • 模板参数:
    • Sig -- 函数签名,如 void(int)
    • Cap -- 内联缓冲区大小 (字节),默认 64

编译期大小检查

// 构造时 static_assert: sizeof(Callable) <= Cap
// 如果可调用对象超过内联缓冲区容量,编译失败

当捕获体超过 Cap 字节时,static_assert 触发编译错误,避免运行时堆分配。

operator bool

explicit operator bool() const noexcept;

检查是否持有有效的可调用对象。

operator()

R operator()(Args... args) const;

调用持有的可调用对象。未持有时行为未定义 (应先检查 operator bool)。


make_overloaded

template <typename... Ts>
auto make_overloaded(Ts&&... ts);

辅助函数,将多个 lambda/可调用对象组合为一个 overloaded visitor,用于 std::visit 分发。

用法示例:

auto visitor = make_overloaded(
    [](const SensorData& d) { /* 处理传感器数据 */ },
    [](const ControlCmd& c)  { /* 处理控制命令 */ },
    [](const auto&)          { /* 默认处理 */ }
);

bus.ProcessBatchWith(visitor);

Component<PayloadVariant>

运行时动态订阅组件基类。使用 std::weak_ptr 防止悬挂回调。

template <typename PayloadVariant>
class Component : public std::enable_shared_from_this<Component<PayloadVariant>>;

SubscribeSafe()

template <typename T, typename Handler>
uint32_t SubscribeSafe(AsyncBus<PayloadVariant>& bus, Handler&& handler);

安全订阅: 内部捕获 weak_ptr<Component>,回调触发时自动检查组件是否仍存活。如果组件已析构,回调静默跳过。

  • 模板参数: T -- 要订阅的消息类型
  • 参数:
    • bus -- 总线引用
    • handler -- 消息处理函数
  • 返回值: 订阅 ID
  • 线程安全: 依赖 Subscribe() 的写锁

SubscribeSimple()

template <typename T, typename Handler>
uint32_t SubscribeSimple(AsyncBus<PayloadVariant>& bus, Handler&& handler);

简单订阅: 不使用 weak_ptr,由调用者保证组件生命周期覆盖订阅期。性能略优于 SubscribeSafe()


StaticComponent<Derived, PayloadVariant>

编译期静态分发组件基类。使用 CRTP (Curiously Recurring Template Pattern) 实现零开销消息分发。

template <typename Derived, typename PayloadVariant>
class StaticComponent;

MakeVisitor()

auto MakeVisitor();

生成 visitor 对象,自动将 PayloadVariant 中的每个类型路由到 Derived 类中对应的 void Handle(const T&) 方法。未提供 Handle 重载的类型将被静默忽略。

用法示例:

class MyComponent : public StaticComponent<MyComponent, MyPayload> {
public:
    void Handle(const SensorData& data) { /* ... */ }
    void Handle(const ControlCmd& cmd)   { /* ... */ }
    // StatusMsg 类型无 Handle,自动忽略
};

MyComponent comp;
bus.ProcessBatchWith(comp.MakeVisitor());

HasHandler<D, T> (SFINAE Trait)

template <typename D, typename T, typename = void>
struct HasHandler : std::false_type {};

template <typename D, typename T>
struct HasHandler<D, T, std::void_t<decltype(
    std::declval<D>().Handle(std::declval<const T&>()))>>
    : std::true_type {};

编译期检测 Derived 类是否为类型 T 提供了 Handle(const T&) 方法。

  • HasHandler<MyComponent, SensorData>::value -- true
  • HasHandler<MyComponent, StatusMsg>::value -- false

MakeVisitor() 内部使用此 trait 实现条件分发: 有 Handler 则调用,无则忽略。