1
0
mirror of https://github.com/wqking/eventpp.git synced 2024-12-27 16:41:11 +08:00
eventpp/doc/callbacklist.md
2018-05-19 17:42:41 +08:00

5.3 KiB

Class CallbackList reference

Table Of Contents

API reference

Header

eventpp/callbacklist.h

Template parameters

template <
	typename Prototype,
	typename Callback = void,
	typename Threading = MultipleThreading
>
class CallbackList;

Prototype: the callback prototype. It's C++ function type such as void(int, std::string, const MyClass *).
Callback: the underlying type to hold the callback. Default is void, which will be expanded to std::function.
Threading: threading model. Default is 'MultipleThreading'. Possible values:

  • MultipleThreading: the core data is protected with mutex. It's the default value.
  • SingleThreading: the core data is not protected and can't be accessed from multiple threads.

Public types

Handle: the handle type returned by appendListener, prependListener and insertListener. A handle can be used to insert a callback or remove a callback. To check if a Handle is empty, convert it to boolean, false is empty. Handle is copyable.
Callback: the callback storage type.

Functions

CallbackList() = default;
CallbackList(CallbackList &&) = delete;
CallbackList(const CallbackList &) = delete;
CallbackList & operator = (const CallbackList &) = delete;

CallbackList can not be copied, moved, or assigned.

Handle append(const Callback & callback);

Add the callback to the callback list.
The callback is added to the end of the callback list.
Return a handle which represents the callback. The handle can be used to remove this callback or insert other callback before this callback.
If append is called in another callback during the invoking of the callback list, the new callback is guaranteed not triggered during the same callback list invoking.
The time complexity is O(1).

Handle prepend(const Callback & callback);

Add the callback to the callback list.
The callback is added to the beginning of the callback list.
Return a handle which represents the callback. The handle can be used to remove this callback or insert other callback before this callback.
If prepend is called in another callback during the invoking of the callback list, the new callback is guaranteed not triggered during the same callback list invoking.
The time complexity is O(1).

Handle insert(const Callback & callback, const Handle before);

Insert the callback to the callback list before the callback handle before. If before is not found, callback is added at the end of the callback list.
Return a handle which represents the callback. The handle can be used to remove this callback or insert other callback before this callback.
If insert is called in another callback during the invoking of the callback list, the new callback is guaranteed not triggered during the same callback list invoking.
The time complexity is O(1).

bool remove(const Handle handle);

Remove the callback handle from the callback list.
Return true if the callback is removed successfully, false if the callback is not found.
The time complexity is O(1).

template <typename Func>  
void forEach(Func && func);

Apply func to all callbacks.
The func can be one of the three prototypes:

AnyReturnType func(const EventDispatcher::Handle &, const EventDispatcher::Callback &);
AnyReturnType func(const EventDispatcher::Handle &);
AnyReturnType func(const EventDispatcher::Callback &);

Note: the func can remove any callbacks, or add other callbacks, safely.

template <typename Func>  
bool forEachIf(Func && func);

Apply func to all callbacks. func must return a boolean value, and if the return value is false, forEachIf stops the looping immediately.
Return true if all callbacks are invoked, or event is not found, false if func returns false.

void operator() (Args ...args);

Invoke each callbacks in the callback list.
The callbacks are called with arguments args.
The callbacks are called in the thread same as the callee of operator().

Nested callback safety

  1. If a callback adds another callback to the callback list during a invoking, the new callback is guaranteed not to be triggered within the same invoking. This is guaranteed by an unsigned 64 bits integer counter. This rule will be broken is the counter is overflowed to zero in a invoking, but this rule will continue working on the subsequence invoking.
  2. Any callbacks that are removed during a invoking are guaranteed not triggered.
  3. All above points are not true in multiple threading. That's to say, if one thread is dispatching an event, the other thread add or remove a listener, the added or removed listener may be triggered during the dispatch.

Time complexities

  • append: O(1)
  • prepend: O(1)
  • insert: O(1)
  • remove: O(1)

Internal data structure

CallbackList uses doubly linked list to manage the callbacks.
Each node is linked by shared pointer. Using shared pointer allows the node be removed while iterating.