1
0
mirror of https://github.com/wqking/eventpp.git synced 2024-12-27 00:17:02 +08:00
eventpp/doc/scopedremover.md
2019-05-31 19:53:37 +08:00

4.5 KiB

Class ScopedRemover reference

Table Of Contents

Description

ScopedRemover is a utility class that automatically removes listeners when ScopedRemover object goes out of scope.

API reference

Header

eventpp/utilities/scopedremover.h

Template parameters

template <typename DispatcherType>
class ScopedRemover;

DispatcherType can be CallbackList, EventDispatcher, EventQueue, HeterCallbackList, HeterEventDispatcher, or HeterEventQueue.

Member functions

explicit ScopedRemover(DispatcherType & dispatcher);

Constructs an instance of ScopedRemover.

Member functions for EventDispatcher and EventQueue

void reset();

void setDispatcher(DispatcherType & dispatcher);

typename DispatcherType::Handle appendListener(
		const typename DispatcherType::Event & event,
		const typename DispatcherType::Callback & listener
	);

typename DispatcherType::Handle prependListener(
		const typename DispatcherType::Event & event,
		const typename DispatcherType::Callback & listener
	);

typename DispatcherType::Handle insertListener(
		const typename DispatcherType::Event & event,
		const typename DispatcherType::Callback & listener,
		const typename DispatcherType::Handle & before
	);

Member functions for CallbackList

void reset();

void setCallbackList(CallbackListType & callbackList);

typename CallbackListType::Handle append(
		const typename CallbackListType::Callback & callback
	);

typename CallbackListType::Handle prepend(
		const typename CallbackListType::Callback & callback
	);

typename CallbackListType::Handle insert(
		const typename CallbackListType::Callback & callback,
		const typename CallbackListType::Handle & before
	);

The function reset() removes all listeners which added by ScopedRemover from the dispatcher or callback list, as if the ScopedRemover object has gone out of scope.
The function setDispatcher() and setCallbackList sets the dispatcher or callback list, and reset the ScopedRemover object.

The other member functions that have the same names with the corresponding underlying class (CallbackList, EventDispatcher, or EventQueue). Those functions add listener to the dispatcher.

Sample code

#include "eventpp/utilities/scopedremover.h"
#include "eventpp/eventdispatcher.h"

eventpp::EventDispatcher<int, void ()> dispatcher;
using Remover = eventpp::ScopedRemover<eventpp::EventDispatcher<int, void ()> >;
constexpr int event = 3;

dispatcher.appendListener(event, [&dataList]() {
	// listener A
});

{
	Remover r1(dispatcher);
	r1.prependListener(event, [&dataList]() {
		// listener B
	});
	{
		Remover r2(dispatcher);
		auto handle = r2.appendListener(event, [&dataList]() {
			// listener C
		});
		{
			Remover r3(dispatcher);
			r3.insertListener(event, [&dataList]() {
				// listener D
			}, handle);

			dispatcher.dispatch(event);
			// All listeners were triggered.
		}
		
		// listener D was removed

		dispatcher.dispatch(event);
		// Listeners A, B, C were triggered.
	}

	// listener C was removed

	dispatcher.dispatch(event);
	// Listeners A, B were triggered.
}

// listener B was removed

dispatcher.dispatch(event);
// Listeners A were triggered.

Automatic disconnection

ScopedRemover can be used to auto disconnect listeners when the object involved in the listeners is destroyed. For example, pseudo code,

Code without ScopedRemover

SomeDispatcher someDispatcher;

class MyClass
{
	MyClass()
	{
		someDispatcher.appendListener(SomeEvent, callback of myListener);
	}
	
	void myListener() {}
};

In above code, when the object of MyClass is destroyed and myListener is not removed from someDispatcher, when someDispatcher triggers SomeEvent, it will invoke on dangling pointer and the program will crash on segment fault.

Code with ScopedRemover

SomeDispatcher someDispatcher;

class MyClass
{
	MyClass() : scopedRemover(someDispatcher)
	{
		scopedRemover.appendListener(SomeEvent, callback of myListener);
	}
	
	void myListener() {}

	eventpp::ScopedRemover<SomeDispatcher> scopedRemover;
};

In above code, when the object of MyClass is destroyed, myListener is automatically removed from someDispatcher, someDispatcher will not invoke on any dangling pointer.