Dawid Drozd 3688c145cb Reorganize project structure
commit f7dd4172cf535cf52601a8819cf5c8bfabcd1fe4
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 31 10:26:27 2018 +0200

    Improve Travis script

    Fixed after reordering project structure

commit d054e5c91762da15defa458404e355d7c670e301
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Mon Jul 30 15:11:21 2018 +0200

    Update Travis CI for linux and OSX

commit 63395f5a7e3dd9f2a52b2d6a254da89ec1d6e5e9
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Fri Jul 27 14:38:40 2018 +0200

    Secure EventBus from wrong usage

    For example user previously could do such thing:

    bus.listen<const MyEvent>(...)

    bus.listen<MyEvent>(...)

    Those we 2 different events :/

commit f9195316d3ba6313ee425e3194b65b32fe52d641
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Thu Jul 26 12:44:17 2018 +0200

    Update for better managing Debug/Release

    Updated project for easy switch between debug/release versions of library

    Thanks to that we can do only find_package and don't have to care about if's switching between
    debug/release

    Thanks: https://github.com/forexample/package-example

commit 7d708959d9e96176875ca882f0f69a72622added
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Wed Jul 25 13:45:55 2018 +0200

    Update clang-format style

commit beb1d3b863379490f321e43f3e42ab272954ea67
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 16:05:16 2018 +0200

    Add some docs

commit ca450dfeee2d4bc604bbb9bf0599f373c21a4173
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 15:49:52 2018 +0200

    Remove not needed includes

commit 6473b80e8e60408675bcc4adc88653390576c4bd
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 15:41:57 2018 +0200

    Code format

commit 8abb56e1dd4b71df2b05bb34bef0530567e4ff2e
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 15:41:40 2018 +0200

    Improve performance

    Thanks to that we don't need RTTI

commit 1feacbb1f9ae6a5ac2209a6dc1df5c868ead8fd4
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 15:14:16 2018 +0200

    Remove trash

commit b5dc5c05589b969dd61eb65b68e4cdce69c5a5fb
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 15:00:15 2018 +0200

    Fix include path

commit 9939fd09805191f0bdada6cb85193a291d519116
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 14:51:02 2018 +0200

    Update install lib

commit 9eaa09f9ec5a29045b03ffc7632878863a2b2b9b
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 14:50:47 2018 +0200

    Fix

commit 7a5b3323af0b728f7e511ac22ff5027c6d06402e
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 14:16:12 2018 +0200

    Update README

commit beb6599ee4385fdffc747dc866db46e160be1358
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 14:16:05 2018 +0200

    Add performance compare to Poco::NotifactionCenter

commit 1d25b997580a9ee09c9db86135b4ca9e1b1a10c6
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 14:14:08 2018 +0200

    Update clang-format

commit 4f4cb4a7e8a849c067a42085eb3e76c3df894bc7
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 13:04:30 2018 +0200

    Remove bad flag

    It is only working for GCC

commit 66a7945084607f94d9d0c803008398e8d281fd06
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 13:03:15 2018 +0200

    Remove deprecated stuff

    It was breaking encapsulation

commit 1e7500607b42bff3632250f623888b95a503dfd0
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 13:01:37 2018 +0200

    Update sample

commit 11a146bb9145fa55f9b9a39a9e033387007a7151
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 13:01:27 2018 +0200

    Add clang-format rules

commit 685562c632d9751f50a2f05b92ef9ebf53a5d6e0
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 12:47:10 2018 +0200

    Reorganize project layout

    Inspired by: https://www.youtube.com/watch?v=6sWec7b0JIc

commit 40d1d6487814730533d7dd7cbedbaf2b4e34ef19
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 12:45:55 2018 +0200

    Remove Catch2 submodule

    Switch to own dependency

commit ca21df04f392adcb027a5b4f25ffac085b51f48c
Author: Dawid Drozd <dawid.drozd@mobica.com>
Date:   Tue Jul 24 11:28:51 2018 +0200

    Remove old code
2018-07-31 11:33:35 +02:00
2018-07-31 11:33:35 +02:00
2018-07-31 11:33:35 +02:00
2018-07-31 11:33:35 +02:00
2018-07-31 11:33:35 +02:00
2018-07-31 11:33:35 +02:00
2017-09-10 14:01:26 +02:00
2018-07-31 11:33:35 +02:00
2018-07-31 11:33:35 +02:00
2018-07-31 11:33:35 +02:00
2017-09-10 14:32:21 +02:00
2015-10-07 18:11:14 +02:00
2018-07-31 11:33:35 +02:00

EventBus

Join the chat at https://gitter.im/EventBusCpp/Lobby Build Status

Simple and very fast event bus. The EventBus library is a convenient realization of the observer pattern. It works perfectly to supplement the implementation of MVC logic (model-view-controller) in event-driven UIs

EventBus Diagram

EventBus was created because I want something easy to use and faster than CCNotificationCenter from cocos2d-x library. Of course C++11 support was mandatory.

EventBus main goals:

  • Fast
  • Easy to use
  • Strongly typed
  • Free
  • tiny (~15 KB)
  • Decouples notification senders and receivers
  • on every platform you need (crossplatform)

Brief @ presentation

Presentation google docs

Sample

You can checkout sample/
If you want to play with sample online checkout this link: wandbox.org

Usage

  1. Store bus
// store it in controller / singleton / std::sharted_ptr whatever you want
Dexode::EventBus bus;
  1. Define events
namespace Event // optional namespace
{
	struct Gold
	{
		int goldReceived = 0;
	};
	
	struct OK {}; // Simple event when user press "OK" button
}
  1. Subscribe
// ...
bus.listen<Event::Gold>
			([](const auto& event) // listen with lambda
			{
				std::cout << "I received gold: " << event.goldReceived << "!" << std::endl;
			});
			
HudLayer* hudLayer;
// Hud layer will receive info about gold
bus.listen<Event::Gold>(std::bind(&HudLayer::onGoldReceived,hudLayer,std::placeholders::_1));
  1. Notify
//Inform listeners about event
bus.notify(Event::Gold{12}); // 1 way

bus.notify<Event::Gold>({12}); // 2 way

Event::Gold myGold{12};
bus.notify(myGold); // 3 way

Lambda listener:

struct SampleEvent {};
Dexode::EventBus bus;
//...
int token = bus.listen<SampleEvent>([](const SampleEvent& event) // register listener
{
});

//If we want unlisten exact listener we can use token for it
bus.unlistenAll(token);

Listener is identified by token. Token is returned from EventBus::listen methods. We can register multiple listeners on one token:

Dexode::EventBus bus;
struct SampleEvent {};
//...
int token = bus.listen<SimpleEvent>([](const auto& event) // register listener
{
});

bus.listen<SimpleEvent>(token, [](const auto& event) // another listener
{
});

bus.unlistenAll(token);//Now those two lambdas will be removed from listeners

If you don't want to handle manually with token you can use EventCollector class. It is useful when we want to have multiple listeners in one class. So above example could look like this:

Dexode::EventBus bus;
struct SampleEvent {};
Dexode::EventCollector collector{&bus};
//...
collector.listen<SampleEvent>([](const SampleEvent& event) // register listener
{
});

collector.listen<SampleEvent>([](const SampleEvent& event) // another listener
{
});

collector.unlistenAll();//Now those two lambdas will be removed from listeners

Or as component of class:

class Example
{
public:
	Example(const std::shared_ptr<Dexode::EventBus>& bus)
			: _collector{bus}
	{
		_collector.listen<SimpleEvent>(std::bind(&Example::onEvent1, this, std::placeholders::_1));
		_collector.listen<OtherEvent>(std::bind(&Example::onEvent2, this, std::placeholders::_1));
	}

	void onEvent1(const SimpleEvent& event)
	{
	}

	void onEvent2(const OtherEvent& event)
	{
	}

private:
	Dexode::EventCollector _collector;// use RAII
};

//EventCollector sample
std::shared_ptr<Dexode::EventBus> bus;
Example ex{bus};
//...
bus.notify<int>("event1", 2);

Add to your project

EventBus can be added as ADD_SUBDIRECTORY to your cmake file. Then simply link it via TARGET_LINK_LIBRARIES
Example:

ADD_SUBDIRECTORY(lib/EventBus)
ADD_EXECUTABLE(MyExecutable
		main.cpp
		)

TARGET_LINK_LIBRARIES(MyExecutable PUBLIC Dexode::EventBus)

Also if you want you can install library and add it at any way you want.
Eg.

mkdir -p lib/build/
cd lib/build
cmake -DCMAKE_BUILD_TYPE=Relase -DCMAKE_INSTALL_PREFIX=~/.local/ ..

cmake --build . --target install
# OR
make && make install

Now in Release/install library is placed.

Performance

I have prepared some performance results. You can read about them here
Small example:

check10NotificationsFor1kListeners                                     263 ns        263 ns    2668786 sum=-1.76281G
check10NotificationsFor1kListeners_CCNotificationCenter              11172 ns      11171 ns      62865 sum=54.023M

checkNotifyFor10kListenersWhenNoOneListens                              18 ns         18 ns   38976599 sum=0
checkNotifyFor10kListenersWhenNoOneListens_CCNotificationCenter     127388 ns     127378 ns       5460 sum=0

Future plans

  • Write more and better tests
  • Thread safe EventBus ?
  • Verbose messages for easy debugging ?
  • Generating graph flow ?
  • Add nice documentation like in POCO
  • ...

Issues ?

Please report here issue / question / whatever in 99% I will answer ;)

Thanks to

For modern cmake refer

License

EventBus source code can be used according to the Apache License, Version 2.0.
For more information see LICENSE file

If you don't like to read to much here is sumup about license Apache 2.0

Description
A lightweight and very fast event bus / event framework for C++17
Readme Apache-2.0
Languages
C++ 85%
CMake 15%