0.8
Developer Topics

Black Screen

If you see a black screen when you run your application, make sure you call Window::show() at least once somewhere in your application.

Multiple Threads and Thread Safety

The EGT API is not thread safe, but there are well defined ways provided and supported to use the EGT API in a multi-threaded application by following a couple simple rules. The thread the main EventLoop is started on, usually through Application::run(), must not be directly accessed by a separate thread. This means any widgets or windows that are managed by that main thread should not be directly accessed by another thread.

Instead, EGT defines a solution to easily use multiple threads and interact with the API in a thread safe manner through the event loop and Asio. To call a function in the EGT API from another thread, you must egt::asio::post() or egt::asio::dispatch() a call to the EventLoop. This should not be confused with messaging. Calling egt::asio::post() or egt::asio::dispatch() is like calling a function; however, based on which variation you use it will either directly or indirectly happen in a thread safe manner.

For example, to change the position of a button from another thread, the following can be done.

asio::post(Application::instance().event().io(), std::bind(&Button::set_x, button, 5));

To run any code you want from another thread on the EventLoop thread, post() a lamba or function.

asio::post(Application::instance().event().io(), []() {
...
});

Widget Lifetime

There are various different forms of managing widget lifetime. They can be managed explicitly on the stack, and they can also be managed on the heap, usually through C++ smart pointers.

Everything is on the stack.

int main(int argc, const char** argv)
{
Application app(argc, argv);
TopWindow window;
Button button(window, "Press Me");
button.set_align(alignmask::center);
window.show();
return app.run();
}

Have EGT manage the lifetime of widgets.

void add_buttons_to_window(Window& win)
{
win.add(make_shared<Button>("button 1", Rect(Point(), Size(100, 40))));
win.add(make_shared<Button>("button 2"));
}
int main(int argc, const char** argv)
{
TopWindow win;
...
add_buttons_to_window(win);
...
return app.run()
}

Keep widgets around based on the scope of its owning object.

class MyWindow : public TopWindow
{
public:
explicit MyWindow(const Size& size)
: TopWindow(size),
m_grid(Tuple(2, 2))
{
add(m_grid);
}
protected:
StaticGrid m_grid;
};

Networking and Serial

See also
Event Loop

The underlying EventLoop implementation uses Asio, which you can directly access and is part of the full EGT API. Asio provides an excellent asynchronous networking implementation that you free with EGT. It can provide efficient non-blocking I/O to service thousands of connections at once. The asio transport handles all aspects of networking (DNS lookups, creating TCP sockets, connecting and listening, etc). It supports IPv4 and IPv6. It supports both plain and TLS secured sockets when the appropriate libraries are available.

The same is true for reading and writing to several other interfaces, including serial ports using the asio::serial_port object.

Outside of that, EGT provides some utility classes like experimental::HttpClientRequest that uses libcurl underneath for full HTTP/HTTPS support, and handles the integration of libcurl with Asio.

egt::v1::Size
SizeType< default_dim_type, detail::compatible::normal > Size
Helper type for a default size.
Definition: geometry.h:489
egt::v1::Widget::set_x
void set_x(default_dim_type x)
Set the x coordinate of the box.
Definition: widget.h:265
egt::v1::alignmask::center
egt::v1::Rect
RectType< default_dim_type, detail::compatible::normal > Rect
Helper type for a default rect.
Definition: geometry.h:910
egt::v1::Point
PointType< default_dim_type, detail::compatible::normal > Point
Helper type for a default point.
Definition: geometry.h:266
egt::v1::Application::instance
static Application & instance()
Reference to the main Application instance.