/// 事件回调
typedef EventCallback = void Function(dynamic arg);

/// 事件总线
class EventBus {
  EventBus._internal();

  static final EventBus _singleton = EventBus._internal();

  factory EventBus() => _singleton;

  // 保存事件订阅者的订阅关系，key:事件名(id)，value: 对应事件的订阅者队列
  final _registry = <Object, List<EventCallback>?>{};

  /// 添加订阅者
  void register(eventName, EventCallback f) {
    _registry[eventName] ??= <EventCallback>[];
    _registry[eventName]!.add(f);
  }

  /// 移除订阅者
  void unRegister(eventName, [EventCallback? callback]) {
    var list = _registry[eventName];
    if (eventName == null || list == null) return;
    if (callback == null) {
      _registry[eventName] = null;
    } else {
      list.remove(callback);
    }
  }

  /// 发送事件
  void post(eventName, [arg]) {
    var list = _registry[eventName];
    if (list == null) return;
    int len = list.length - 1;
    // 反向遍历，防止订阅者在回调中移除自身带来的下标错位
    for (var i = len; i > -1; --i) {
      list[i](arg);
    }
  }
}

/// 暴露单例
var eventBus = EventBus();
