1
0
mirror of https://github.com/wqking/eventpp.git synced 2024-12-27 00:17:02 +08:00
eventpp/doc/eventmaker.md

144 lines
4.2 KiB
Markdown
Raw Normal View History

2020-01-23 21:42:16 +08:00
# Event maker macros reference
## Overview
`eventpp/utilities/eventmaker.h` contains several macros to generate event classes.
2020-01-23 21:42:16 +08:00
Without the macros, we may need to repeat the same code structure on lots of event classes.
For example,
```c++
// The base event
class Event
{
};
class EventMouseDown : public Event
{
public:
int getX() const;
int getY() const;
int getButton() const;
2020-01-23 21:42:16 +08:00
private:
int x;
int y;
int button;
2020-01-23 21:42:16 +08:00
};
class EventKeyDown : public Event
{
public:
int getKey() const;
2020-01-23 21:42:16 +08:00
private:
int key;
2020-01-23 21:42:16 +08:00
};
```
It's not rare that there are dozens of or even hundreds of event classes in a system, and we need to repeat the same code structure many times, which is boring and error prone.
The macros in eventmaker.h can reduce the work significantly.
## Header
eventpp/utilities/eventmaker.h
2020-01-23 21:42:16 +08:00
## Macro EVENTPP_MAKE_EVENT
```c++
#define EVENTPP_MAKE_EVENT(className, baseClassName, baseClassArgs, ...)
```
EVENTPP_MAKE_EVENT declares an event class.
**className**: the event class name.
**baseClassName**: the class name that the event inherits from. The macro requires a base class. If the class name contains comma (,), such as a template class, it should be enclosed within parenthesis. Examples, `Event`, `(AnotherEvent<int, char>)`.
**baseClassArgs**: the arguments passed to the base class. If the arguments contain comma (,), it should be enclosed within parenthesis. If there is no arguments for the base class, `()` can be used.
**The variadic arguments (...)**: the tuples of member data type and getter/setter function name. A tuple is elements in a pair of parenthesis. A tuple can contain 2 or 3 elements, the first element is the data type, the second element is the getter function name, and the optional third element is the setter function name. Some tuples examples: `(int, getX)`, `(std::string, getText, setText)`.
Note: the variadic arguments can't be empty. If the even class doesn't have data member, use `EVENTPP_MAKE_EMPTY_EVENT` instead.
The macro always generates a default constructor and a constructor that takes all data members and initialize them.
Code examples:
```c++
EVENTPP_MAKE_EVENT(
EventDraw, Event, EventType::draw,
(std::string, getText, setText), (int, getX), (double, getSize)
);
2020-01-23 21:42:16 +08:00
```
Generates class like (in pseudo code),
```c++
class EventDraw : public Event
{
public:
EventDraw(const std::string & text, const int x, const double size)
: Event(EventType::draw), text(text), x(x), size(size)
{
}
const std::string & getText() const {
return text;
}
void setText(const std::string & value) {
text = value;
}
const int getX() const {
return x;
}
const double getSize() const {
return size;
}
2020-01-23 21:42:16 +08:00
private:
std::string text;
int x;
double size;
2020-01-23 21:42:16 +08:00
};
```
```c++
EVENTPP_MAKE_EVENT(EventDraw, (Event<int, char>), EventType::draw,
(std::string, getText, setText), (int, getX), (double, getSize)
);
2020-01-23 21:42:16 +08:00
```
Similar to above example, except the base class is `Event<int, char>`.
```c++
EVENTPP_MAKE_EVENT(EventDraw, (Event<int, char>), (EventType::draw, 5),
(std::string, getText, setText), (int, getX), (double, getSize)
);
2020-01-23 21:42:16 +08:00
```
Similar to above example, except the base class is constructed with `(EventType::draw, 5)` instead of `(EventType::draw)`.
## Macro EVENTPP_MAKE_EMPTY_EVENT
```c++
#define EVENTPP_MAKE_EMPTY_EVENT(className, baseClassName, baseClassArgs)
```
Similar with `EVENTPP_MAKE_EVENT`, but EVENTPP_MAKE_EMPTY_EVENT declares event class which doesn't have any data member.
## Tip: add getter/setter prefix automatically
If you don't want to specify "get" or "set" prefix explictly, or you want the field definition looks like a property rather than getter/setter function, you can define some auxiliary macros to achieve that. For example,
```
// auto add "get" prefix
#define G(type, name) (type, get ## name)
// auto add "get" and "set" prefix
#define GS(type, name) (type, get ## name, set ## name)
EVENTPP_MAKE_EVENT(EventDrawGS, Event, EventType::draw,
GS(std::string, Text),
G(int, X),
G(double, Size)
);
```
Of course you need to choose better macro names than `G` and `GS`, or `#undef` them after using them.