mirror of
https://github.com/wqking/eventpp.git
synced 2024-12-25 23:30:49 +08:00
Added more tutorials for EventQueue. Updated documents.
This commit is contained in:
parent
15d78b7bd2
commit
e6518f9c56
@ -18,6 +18,12 @@ dispatcher.appendListener(3, []() {}); // OK
|
||||
dispatcher.appendListener(3, [](std::string) {}); // OK
|
||||
```
|
||||
|
||||
## Warning
|
||||
|
||||
The heterogeneous classes are mostly for proof of concept purpose. Misusing them most likely means your application design has flaws.
|
||||
You should stick with the homogeneous classes, even though sometimes the heterogeneous classes look convenient (but with overhead).
|
||||
The heterogeneous classes may be not well maintained or supported in the future. You use them on your own risk.
|
||||
|
||||
## Usage
|
||||
|
||||
### Headers
|
||||
@ -78,3 +84,9 @@ The only difference is the `Prototype` in homo-classes becomes `PrototypeList` i
|
||||
In the homo-classes, `Prototype` is a single function type such as `void ()`.
|
||||
In the heter-classes, `PrototypeList` is a list of function types in `eventpp::HeterTuple`, such as `eventpp::HeterTuple<void (), void (std::string), void (int, int)>`.
|
||||
Note: Ideally it would be better to use `std::tuple` instead of `eventpp::HeterTuple`, but the problem is that the tuple is instantiated in HeterEventDispatcher which cause compile error that function type can't be instantiated.
|
||||
|
||||
## Differences between heterogeneous classes vs homogeneous classes
|
||||
|
||||
1. Heterogeneous classes has both overhead on performance and memory usage. Usually event system is the core component in an application, the performance is critical.
|
||||
2. Heterogeneous classes can't have the same API interface as homogeneous classes, because some APIs are impossible or very difficult to implement in heterogeneous classes.
|
||||
3. Heterogeneous classes doesn't support eventpp::ArgumentPassingAutoDetect. That means the event in the argument can't be detected automatically.
|
||||
|
@ -121,3 +121,239 @@ thread.join();
|
||||
> Should have triggered events with index = 10 and 11
|
||||
|
||||
**Remarks**
|
||||
|
||||
### Tutorial 3 -- prioritized dispatching
|
||||
|
||||
In tutorial 3, we will demonstrate how to make EventQueue dispatch higher priority event earlier.
|
||||
|
||||
```c++
|
||||
// First let's define the event struct. e is the event type, priority determines the priority.
|
||||
struct MyEvent
|
||||
{
|
||||
int e;
|
||||
int priority;
|
||||
};
|
||||
|
||||
// The comparison function object used by eventpp::OrderedQueueList.
|
||||
// The function compares the event by priority.
|
||||
struct MyCompare
|
||||
{
|
||||
template <typename T>
|
||||
bool operator() (const T & a, const T & b) const {
|
||||
return a.template getArgument<0>().priority > b.template getArgument<0>().priority;
|
||||
}
|
||||
};
|
||||
|
||||
// Define the EventQueue policy
|
||||
struct MyPolicy
|
||||
{
|
||||
template <typename Item>
|
||||
using QueueList = eventpp::OrderedQueueList<Item, MyCompare >;
|
||||
|
||||
static int getEvent(const MyEvent & event) {
|
||||
return event.e;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE("EventQueue tutorial 3, ordered queue")
|
||||
{
|
||||
std::cout << std::endl << "EventQueue tutorial 3, ordered queue" << std::endl;
|
||||
|
||||
using EQ = eventpp::EventQueue<int, void(const MyEvent &), MyPolicy>;
|
||||
EQ queue;
|
||||
|
||||
queue.appendListener(3, [](const MyEvent & event) {
|
||||
std::cout << "Get event " << event.e << "(should be 3)."
|
||||
<< " priority: " << event.priority << std::endl;
|
||||
});
|
||||
queue.appendListener(5, [](const MyEvent & event) {
|
||||
std::cout << "Get event " << event.e << "(should be 5)."
|
||||
<< " priority: " << event.priority << std::endl;
|
||||
});
|
||||
queue.appendListener(7, [](const MyEvent & event) {
|
||||
std::cout << "Get event " << event.e << "(should be 7)."
|
||||
<< " priority: " << event.priority << std::endl;
|
||||
});
|
||||
|
||||
// Add an event, the first number 5 is the event type, the second number 100 is the priority.
|
||||
// After the queue processes, the events will be processed from higher priority to lower priority.
|
||||
queue.enqueue(MyEvent{ 5, 100 });
|
||||
queue.enqueue(MyEvent{ 5, 200 });
|
||||
queue.enqueue(MyEvent{ 7, 300 });
|
||||
queue.enqueue(MyEvent{ 7, 400 });
|
||||
queue.enqueue(MyEvent{ 3, 500 });
|
||||
queue.enqueue(MyEvent{ 3, 600 });
|
||||
|
||||
queue.process();
|
||||
}
|
||||
```
|
||||
|
||||
**Output**
|
||||
> Get event 3(should be 3). priority: 600
|
||||
> Get event 3(should be 3). priority: 500
|
||||
> Get event 7(should be 7). priority: 400
|
||||
> Get event 7(should be 7). priority: 300
|
||||
> Get event 5(should be 5). priority: 200
|
||||
> Get event 5(should be 5). priority: 100
|
||||
|
||||
### Tutorial 4 -- typical event system
|
||||
|
||||
In tutorial 4, we will demonstrate how different event classes are used in a typical event system in an application.
|
||||
A typical event system may look like, there is a base event class, each event type has a corresponding event class
|
||||
that inherits from the base event. When emitting an event, a pointer/referent to the base event class is used,
|
||||
the event listener then cast the base event to proper derived event.
|
||||
|
||||
```c++
|
||||
// This is the definition of event types
|
||||
enum class EventType
|
||||
{
|
||||
// for MouseEvent
|
||||
mouse,
|
||||
|
||||
// for KeyboardEvent
|
||||
keyboard,
|
||||
|
||||
// for either MouseEvent or KeyboardEvent, it's used to demonstrate
|
||||
// how the listener detects event type dynamically
|
||||
input,
|
||||
|
||||
// for ChangedEvent
|
||||
changed
|
||||
};
|
||||
|
||||
// This is the base event. It has a getType function to return the actual event type.
|
||||
class Event
|
||||
{
|
||||
public:
|
||||
explicit Event(const EventType type) : type(type) {
|
||||
}
|
||||
|
||||
virtual ~Event() {
|
||||
}
|
||||
|
||||
EventType getType() const {
|
||||
return type;
|
||||
}
|
||||
|
||||
private:
|
||||
EventType type;
|
||||
};
|
||||
|
||||
class MouseEvent : public Event
|
||||
{
|
||||
public:
|
||||
MouseEvent(const int x, const int y)
|
||||
: Event(EventType::mouse), x(x), y(y)
|
||||
{
|
||||
}
|
||||
|
||||
int getX() const { return x; }
|
||||
int getY() const { return y; }
|
||||
|
||||
private:
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
class KeyboardEvent : public Event
|
||||
{
|
||||
public:
|
||||
explicit KeyboardEvent(const int key)
|
||||
: Event(EventType::keyboard), key(key)
|
||||
{
|
||||
}
|
||||
|
||||
int getKey() const { return key; }
|
||||
|
||||
private:
|
||||
int key;
|
||||
};
|
||||
|
||||
class ChangedEvent : public Event
|
||||
{
|
||||
public:
|
||||
explicit ChangedEvent(const std::string & text)
|
||||
: Event(EventType::changed), text(text)
|
||||
{
|
||||
}
|
||||
|
||||
std::string getText() const { return text; }
|
||||
|
||||
private:
|
||||
std::string text;
|
||||
};
|
||||
|
||||
// We will pass event as EventPointer, here it's std::shared_ptr<Event>.
|
||||
// It allows EventQueue to store the events in internal buffer without slicing the objects
|
||||
// in asynchronous API (EventQueue::enqueue and EventQueue::process, etc).
|
||||
// If we only use the synchronous API (EventDispatcher, or EventQueue::dispatch),
|
||||
// we can dispatch events as reference.
|
||||
using EventPointer = std::shared_ptr<Event>;
|
||||
|
||||
// We are going to dispatch event objects directly without specify the event type explicitly,
|
||||
// so we need to define policy to let eventpp know how to get the event type from the event object.
|
||||
struct EventPolicy
|
||||
{
|
||||
static EventType getEvent(const EventPointer & event) {
|
||||
return event->getType();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE("EventQueue tutorial 4, typical event system in an application")
|
||||
{
|
||||
std::cout << std::endl << "EventQueue tutorial 4, typical event system in an application" << std::endl;
|
||||
|
||||
using EQ = eventpp::EventQueue<EventType, void(const EventPointer &), EventPolicy>;
|
||||
EQ queue;
|
||||
|
||||
queue.appendListener(EventType::mouse, [](const EventPointer & event) {
|
||||
const MouseEvent * mouseEvent = static_cast<const MouseEvent *>(event.get());
|
||||
std::cout << "Received mouse event, x=" << mouseEvent->getX() << " y=" << mouseEvent->getY()
|
||||
<< std::endl;
|
||||
});
|
||||
queue.appendListener(EventType::keyboard, [](const EventPointer & event) {
|
||||
const KeyboardEvent * keyboardEvent = static_cast<const KeyboardEvent *>(event.get());
|
||||
std::cout << "Received keyboard event, key=" << (char)keyboardEvent->getKey()
|
||||
<< std::endl;
|
||||
});
|
||||
queue.appendListener(EventType::input, [](const EventPointer & event) {
|
||||
std::cout << "Received input event, ";
|
||||
if(event->getType() == EventType::mouse) {
|
||||
const MouseEvent * mouseEvent = static_cast<const MouseEvent *>(event.get());
|
||||
std::cout << "it's mouse event, x=" << mouseEvent->getX() << " y=" << mouseEvent->getY()
|
||||
<< std::endl;
|
||||
}
|
||||
else if(event->getType() == EventType::keyboard) {
|
||||
const KeyboardEvent * keyboardEvent = static_cast<const KeyboardEvent *>(event.get());
|
||||
std::cout << "it's keyboard event, key=" << (char)keyboardEvent->getKey() << std::endl;
|
||||
}
|
||||
else {
|
||||
std::cout << "it's an event that I don't understand." << std::endl;
|
||||
}
|
||||
});
|
||||
queue.appendListener(EventType::changed, [](const EventPointer & event) {
|
||||
const ChangedEvent * changedEvent = static_cast<const ChangedEvent *>(event.get());
|
||||
std::cout << "Received changed event, text=" << changedEvent->getText() << std::endl;
|
||||
});
|
||||
|
||||
// Asynchronous API, put events in to the event queue.
|
||||
queue.enqueue(std::make_shared<MouseEvent>(123, 567));
|
||||
queue.enqueue(std::make_shared<KeyboardEvent>('W'));
|
||||
queue.enqueue(std::make_shared<ChangedEvent>("This is new text"));
|
||||
queue.enqueue(EventType::input, std::make_shared<MouseEvent>(10, 20));
|
||||
// then process all events.
|
||||
queue.process();
|
||||
|
||||
// Synchronous API, dispatch events to the listeners directly.
|
||||
queue.dispatch(std::make_shared<KeyboardEvent>('Q'));
|
||||
queue.dispatch(EventType::input, std::make_shared<ChangedEvent>("Should not display"));
|
||||
}
|
||||
```
|
||||
|
||||
**Output**
|
||||
> Received mouse event, x=123 y=567
|
||||
> Received keyboard event, key=W
|
||||
> Received changed event, text=This is new text
|
||||
> Received input event, it's mouse event, x=10 y=20
|
||||
> Received keyboard event, key=Q
|
||||
> Received input event, it's an event that I don't understand.
|
||||
|
@ -231,7 +231,7 @@ queue.process();
|
||||
* Miscellaneous
|
||||
* [Performance benchmarks](doc/benchmark.md)
|
||||
* [FAQs, tricks, and tips](doc/faq.md)
|
||||
* Heterogeneous classes and functions, usually you don't need them
|
||||
* Heterogeneous classes and functions, for proof of concept, usually you don't need them
|
||||
* [Overview of heterogeneous classes](doc/heterogeneous.md)
|
||||
* [Class HeterCallbackList](doc/hetercallbacklist.md)
|
||||
* [Class HeterEventDispatcher](doc/hetereventdispatcher.md)
|
||||
|
@ -6,6 +6,7 @@ set(SRC_TUTORIAL
|
||||
tutorial_eventdispatcher.cpp
|
||||
tutorial_eventqueue.cpp
|
||||
tutorial_hetercallbacklist.cpp
|
||||
tutorial_hetereventdispatcher.cpp
|
||||
tutorial_argumentadapter.cpp
|
||||
)
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
// In the tutorials here, we define an event class hierarchy, Event is the base class.
|
||||
// The callback prototype in EventDispatcher is reference or pointer to Event,
|
||||
// then we should only be able to add listeners that only accept reference or pointer to Event,
|
||||
@ -231,3 +233,5 @@ TEST_CASE("ArgumentAdapter tutorial 3, conditional adapter")
|
||||
eventDispatcher.dispatch(EventType::input, KeyEvent(99));
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
namespace {
|
||||
|
||||
TEST_CASE("EventQueue tutorial 1, basic")
|
||||
{
|
||||
std::cout << std::endl << "EventQueue tutorial 1, basic" << std::endl;
|
||||
@ -148,13 +150,16 @@ TEST_CASE("EventQueue tutorial 3, ordered queue")
|
||||
EQ queue;
|
||||
|
||||
queue.appendListener(3, [](const MyEvent & event) {
|
||||
std::cout << "Get event " << event.e << "(should be 3)." << " priority: " << event.priority << std::endl;
|
||||
std::cout << "Get event " << event.e << "(should be 3)."
|
||||
<< " priority: " << event.priority << std::endl;
|
||||
});
|
||||
queue.appendListener(5, [](const MyEvent & event) {
|
||||
std::cout << "Get event " << event.e << "(should be 5)." << " priority: " << event.priority << std::endl;
|
||||
std::cout << "Get event " << event.e << "(should be 5)."
|
||||
<< " priority: " << event.priority << std::endl;
|
||||
});
|
||||
queue.appendListener(7, [](const MyEvent & event) {
|
||||
std::cout << "Get event " << event.e << "(should be 7)." << " priority: " << event.priority << std::endl;
|
||||
std::cout << "Get event " << event.e << "(should be 7)."
|
||||
<< " priority: " << event.priority << std::endl;
|
||||
});
|
||||
|
||||
// Add an event, the first number 5 is the event type, the second number 100 is the priority.
|
||||
@ -168,3 +173,156 @@ TEST_CASE("EventQueue tutorial 3, ordered queue")
|
||||
|
||||
queue.process();
|
||||
}
|
||||
|
||||
// In tutorial 4, we will demonstrate how different event classes are used in a typical event system in an application.
|
||||
// A typical event system may look like, there is a base event class, each event type has a corresponding event class
|
||||
// that inherits from the base event. When emitting an event, a pointer/referent to the base event class is used,
|
||||
// the event listener then cast the base event to proper derived event.
|
||||
|
||||
// This is the definition of event types
|
||||
enum class EventType
|
||||
{
|
||||
// for MouseEvent
|
||||
mouse,
|
||||
|
||||
// for KeyboardEvent
|
||||
keyboard,
|
||||
|
||||
// for either MouseEvent or KeyboardEvent, it's used to demonstrate
|
||||
// how the listener detects event type dynamically
|
||||
input,
|
||||
|
||||
// for ChangedEvent
|
||||
changed
|
||||
};
|
||||
|
||||
// This is the base event. It has a getType function to return the actual event type.
|
||||
class Event
|
||||
{
|
||||
public:
|
||||
explicit Event(const EventType type) : type(type) {
|
||||
}
|
||||
|
||||
virtual ~Event() {
|
||||
}
|
||||
|
||||
EventType getType() const {
|
||||
return type;
|
||||
}
|
||||
|
||||
private:
|
||||
EventType type;
|
||||
};
|
||||
|
||||
class MouseEvent : public Event
|
||||
{
|
||||
public:
|
||||
MouseEvent(const int x, const int y)
|
||||
: Event(EventType::mouse), x(x), y(y)
|
||||
{
|
||||
}
|
||||
|
||||
int getX() const { return x; }
|
||||
int getY() const { return y; }
|
||||
|
||||
private:
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
class KeyboardEvent : public Event
|
||||
{
|
||||
public:
|
||||
explicit KeyboardEvent(const int key)
|
||||
: Event(EventType::keyboard), key(key)
|
||||
{
|
||||
}
|
||||
|
||||
int getKey() const { return key; }
|
||||
|
||||
private:
|
||||
int key;
|
||||
};
|
||||
|
||||
class ChangedEvent : public Event
|
||||
{
|
||||
public:
|
||||
explicit ChangedEvent(const std::string & text)
|
||||
: Event(EventType::changed), text(text)
|
||||
{
|
||||
}
|
||||
|
||||
std::string getText() const { return text; }
|
||||
|
||||
private:
|
||||
std::string text;
|
||||
};
|
||||
|
||||
// We will pass event as EventPointer, here it's std::shared_ptr<Event>.
|
||||
// It allows EventQueue to store the events in internal buffer without slicing the objects
|
||||
// in asynchronous API (EventQueue::enqueue and EventQueue::process, etc).
|
||||
// If we only use the synchronous API (EventDispatcher, or EventQueue::dispatch),
|
||||
// we can dispatch events as reference.
|
||||
using EventPointer = std::shared_ptr<Event>;
|
||||
|
||||
// We are going to dispatch event objects directly without specify the event type explicitly,
|
||||
// so we need to define policy to let eventpp know how to get the event type from the event object.
|
||||
struct EventPolicy
|
||||
{
|
||||
static EventType getEvent(const EventPointer & event) {
|
||||
return event->getType();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE("EventQueue tutorial 4, typical event system in an application")
|
||||
{
|
||||
std::cout << std::endl << "EventQueue tutorial 4, typical event system in an application" << std::endl;
|
||||
|
||||
using EQ = eventpp::EventQueue<EventType, void(const EventPointer &), EventPolicy>;
|
||||
EQ queue;
|
||||
|
||||
queue.appendListener(EventType::mouse, [](const EventPointer & event) {
|
||||
const MouseEvent * mouseEvent = static_cast<const MouseEvent *>(event.get());
|
||||
std::cout << "Received mouse event, x=" << mouseEvent->getX() << " y=" << mouseEvent->getY()
|
||||
<< std::endl;
|
||||
});
|
||||
queue.appendListener(EventType::keyboard, [](const EventPointer & event) {
|
||||
const KeyboardEvent * keyboardEvent = static_cast<const KeyboardEvent *>(event.get());
|
||||
std::cout << "Received keyboard event, key=" << (char)keyboardEvent->getKey()
|
||||
<< std::endl;
|
||||
});
|
||||
queue.appendListener(EventType::input, [](const EventPointer & event) {
|
||||
std::cout << "Received input event, ";
|
||||
if(event->getType() == EventType::mouse) {
|
||||
const MouseEvent * mouseEvent = static_cast<const MouseEvent *>(event.get());
|
||||
std::cout << "it's mouse event, x=" << mouseEvent->getX() << " y=" << mouseEvent->getY()
|
||||
<< std::endl;
|
||||
}
|
||||
else if(event->getType() == EventType::keyboard) {
|
||||
const KeyboardEvent * keyboardEvent = static_cast<const KeyboardEvent *>(event.get());
|
||||
std::cout << "it's keyboard event, key=" << (char)keyboardEvent->getKey() << std::endl;
|
||||
}
|
||||
else {
|
||||
std::cout << "it's an event that I don't understand." << std::endl;
|
||||
}
|
||||
});
|
||||
queue.appendListener(EventType::changed, [](const EventPointer & event) {
|
||||
const ChangedEvent * changedEvent = static_cast<const ChangedEvent *>(event.get());
|
||||
std::cout << "Received changed event, text=" << changedEvent->getText() << std::endl;
|
||||
});
|
||||
|
||||
// Asynchronous API, put events in to the event queue.
|
||||
queue.enqueue(std::make_shared<MouseEvent>(123, 567));
|
||||
queue.enqueue(std::make_shared<KeyboardEvent>('W'));
|
||||
queue.enqueue(std::make_shared<ChangedEvent>("This is new text"));
|
||||
queue.enqueue(EventType::input, std::make_shared<MouseEvent>(10, 20));
|
||||
// then process all events.
|
||||
queue.process();
|
||||
|
||||
// Synchronous API, dispatch events to the listeners directly.
|
||||
queue.dispatch(std::make_shared<KeyboardEvent>('Q'));
|
||||
queue.dispatch(EventType::input, std::make_shared<ChangedEvent>("Should not display"));
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
121
tests/tutorial/tutorial_hetereventdispatcher.cpp
Normal file
121
tests/tutorial/tutorial_hetereventdispatcher.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
// eventpp library
|
||||
// Copyright (C) 2018 Wang Qi (wqking)
|
||||
// Github: https://github.com/wqking/eventpp
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Include the head
|
||||
#include "eventpp/hetereventdispatcher.h"
|
||||
|
||||
#include "tutorial.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
// This is the definition of event types
|
||||
enum class EventType
|
||||
{
|
||||
// for MouseEvent
|
||||
mouse,
|
||||
|
||||
// for KeyboardEvent
|
||||
keyboard,
|
||||
};
|
||||
|
||||
// This is the base event. It has a getType function to return the actual event type.
|
||||
class Event
|
||||
{
|
||||
public:
|
||||
explicit Event(const EventType type) : type(type) {
|
||||
}
|
||||
|
||||
virtual ~Event() {
|
||||
}
|
||||
|
||||
EventType getType() const {
|
||||
return type;
|
||||
}
|
||||
|
||||
private:
|
||||
EventType type;
|
||||
};
|
||||
|
||||
class MouseEvent : public Event
|
||||
{
|
||||
public:
|
||||
MouseEvent(const int x, const int y)
|
||||
: Event(EventType::mouse), x(x), y(y)
|
||||
{
|
||||
}
|
||||
|
||||
int getX() const { return x; }
|
||||
int getY() const { return y; }
|
||||
|
||||
private:
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
class KeyboardEvent : public Event
|
||||
{
|
||||
public:
|
||||
explicit KeyboardEvent(const int key)
|
||||
: Event(EventType::keyboard), key(key)
|
||||
{
|
||||
}
|
||||
|
||||
int getKey() const { return key; }
|
||||
|
||||
private:
|
||||
int key;
|
||||
};
|
||||
|
||||
// We are going to dispatch event objects directly without specify the event type explicitly, so we need to let eventpp
|
||||
// know how to get the event type from the event object. The event policy does that.
|
||||
// Note ArgumentPassingMode must be eventpp::ArgumentPassingIncludeEvent here,
|
||||
// the heterogeneous doesn't support eventpp::ArgumentPassingAutoDetect.
|
||||
struct EventPolicy
|
||||
{
|
||||
using ArgumentPassingMode = eventpp::ArgumentPassingIncludeEvent;
|
||||
|
||||
template <typename E>
|
||||
static EventType getEvent(const E & event) {
|
||||
return event.getType();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE("HeterEventDispatcher tutorial 1, basic")
|
||||
{
|
||||
std::cout << std::endl << "HeterEventDispatcher tutorial 1, basic" << std::endl;
|
||||
|
||||
// The namespace is eventpp
|
||||
// the second parameter is a HeterTuple of the listener prototypes.
|
||||
eventpp::HeterEventDispatcher<EventType, eventpp::HeterTuple<
|
||||
void (const MouseEvent &),
|
||||
void (const KeyboardEvent &)
|
||||
>,
|
||||
EventPolicy
|
||||
> dispatcher;
|
||||
|
||||
dispatcher.appendListener(EventType::mouse, [](const MouseEvent & event) {
|
||||
std::cout << "Received mouse event, x=" << event.getX() << " y=" << event.getY() << std::endl;
|
||||
});
|
||||
dispatcher.appendListener(EventType::keyboard, [](const KeyboardEvent & event) {
|
||||
std::cout << "Received keyboard event, key=" << (char)event.getKey() << std::endl;
|
||||
});
|
||||
|
||||
dispatcher.dispatch(MouseEvent(5, 38));
|
||||
dispatcher.dispatch(KeyboardEvent('W'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace
|
Loading…
x
Reference in New Issue
Block a user