-
Notifications
You must be signed in to change notification settings - Fork 11
quick_guide
You can just drag the source code into your C++ project.
Or use cmake to build a dynamic or static library, just
$ cd <folder where you checkout the source>
$ mkdir build
$ cd build
$ cmake ../
$ make && sudo make install
By default, it will install header files to /usr/local/include
, and
library binary to /usr/local/lib
.
Available cmake options:
-
CMAKE_INSTALL_PREFIX
: this is a built-in cmake option, which you can use to specify where to install the headers and library. Default is/usr/local
. -
BUILD_UNIT_TEST
: A bool option to compile the unit test code. Default isOFF
. -
WITH_QT5
: A bool option to compile test code to compare this project with Qt5 signal-slot. Default:OFF
.
Use the template class CppEvent::Event<>
to declare an event. In mose cases, you need to use it as a member variable in your class, you can put it in any area of public
, protected
, private
as you want.
For example, suppose you are developing a GUI project, you may need a
clicked
event in a button class:
Example 1. Button class with 'clicked' event
class Button: public Widget
{
public:
Button(Widget* parent);
// Event connection interface
inline CppEvent::Event<>& clicked ()
{return clicked_;}
protected:
virtual void mousePress (MouseParams const & params);
private:
// Event implementation
CppEvent::Event<> clicked_;
};
void Button::mousePress(MouseParams const & params)
{
// Do sth...
clicked_.Fire();
}
Note: an event object is not copyable. e.g.
CppEvent::Event<> event1;
CppEvent::Event<> event2(event1); // Error
CppEvent::Event<> event3;
event3 = event1; // Error
Events can be connected to event handlers. In libCppEvent, event handlers are member functions bound to the specific object. Internally libCppEvent implement delegate in a way inspired by Fast C++ Delegate: Boost.Function 'drop-in' replacement and multicast by JaeWook Choi.
In libCppEvent you cannot connect event to any member function. You can only connect an event to member functions of a CppEvent::Observer or subclass. This design makes sure when the Observer object is deleted, all event connection will be removed safely.
Connection is established by Connect() method of the
CppEvent::Event<>
. The method requires 2 arguments.
- A pointer to a CppEvent::Trackable object
- A pointer to the member function of the receiver object
Example 2. Connect a button to a label widget.
class Widget: public CppEvent::Observer;
class Label: public Widget
{
public:
Dialog (Widget* parent);
void OnShowText ();
};
Button* btn = new Button;
Label* lbl = new Label;
btn->clicked().Connect(lbl, &Label::OnShowText);
Use Disconnect
method:
btn->clicked().Disconnect(lbl, &Label::OnShowText);
Events can have arbitrary number of arguments. Types of arguments are specified as arguments for template class CppEvent::Event<>
.
For example:
using namespace CppEvent;
Event<Widget* sender, bool toggled> event1;
Event<const String& str, size_t length> event2;
You can disconnect the event when being invoked in an observer:
void Label::OnShowText (Button* sender)
{
sender->clicked().Disconnect(this, &Label::OnShowText);
}
You can delete this when being invoked:
void Label::OnShowText ()
{
delete this;
}
Note: CppEvent::Event<>
support multicast, when you fire an event, it will invoke all connected methods.
A CppEvent::Event<>
object can be used as an event handler too, as it's
also a trackable object.
Example 4. Event chaining
Button* btn1 = new Button;
Button* btn2 = new Button;
btn1->clicked().Connect(btn2->clicked());
Click btn1 will fire clicked()
event in btn2.
Member function which is connected to an event can be virtual and abstract (pure virtual).
Example 5. Connect event to a virtual method
class Widget: public CppEvent::Trackable;
class AbstractDialog: public Widget
{
public:
AbstractDialog (Widget* parent)
{
ok_ = new Button;
ok->clicked().connect(this, &AbstractDialog::OnShowText);
}
virtual void OnShowText () = 0; // pure virtual
private:
Button* ok_;
};
class Dialog: public AbstractDialog
{
public:
Dialog (Widget* parent);
virtual void OnShowText () = override;
};
AbstractDialog *dlg = new Dialog();
btn1->clicked().Connect(dlg, &AbstractDialog::OnShowText);
Warning: By default, libCppEvent does not provide any protection in multi-thread environment. You should take care of the racecondition in your code.
TBD
Table of contents
- Quick Guide
- Delegate Implementation