Timeouts, IO and Idle Functions...
- Timeouts
- Monitoring IO
- Idle Functions
- Key Snooper Functions
- Quit Functions
You may be wondering how you make Inti do some
useful work when in the main loop. Well, you have several options. You
can register a method to be called every "interval" milliseconds,
register a method to monitor IO, register a method to be called when
nothing else is happening, register a method to be called on all key
events and register a method to be called when an instance of the main
loop is left. This registration is handled by five special signal
classes defined in
<inti/main.h>.
There is a static instance of each signal class declared in the Main
namespace. These are:
- timeout_signal
- input_signal
- idle_signal
- key_snooper_signal
- quit_signal
These might look similar to the protected widget signals you are
already familiar with but they're different.
Timeouts
Using the following method you can connect a method to the timeout_signal
to be called every "interval" milliseconds.
Connection
connect(SlotType *slot, int interval);
|
The slot argument is a slot created with a method that has the
following prototype:
bool
MyClass::signal_handler();
|
The
interval argument is the time in
milliseconds that is to elapse between each call. Your method will be
called every "interval" milliseconds until it returns
false,
at which point the timeout connection is destroyed and will not be
called again.
The connection method returns a
Connection class. Unlike widget signals, you must keep a copy of this
Connection and specifically call Connection::disconnect() when the
timeout is no longer required. Connection::block() and
Connection::unblock() are undefined for this connection type.
The code to set up a timeout connection should look like this. In your
class interface include a Connection and a signal handler.
class
MyClass
{
Connection timeout_connection;
protected:
bool on_timeout();
public:
MyClass();
~MyClass();
}
|
then in the class implementation do something like this:
MyClass::MyClass()
{
...
timeout_connection =
Main::timeout_signal.connect(slot(this,
&MyClass::on_timeout), 150);
}
MyClass::~MyClass()
{
timeout_connection.disconnect();
}
bool
MyClass::on_timeout()
{
// put your code here.
// return true to continue
calling this method. return false to end the timeout.
return true;
} |
Monitoring IO
A nifty feature of GDK (the library that underlies
GTK), is the ability to have it check for data on a file descriptor for
you (as returned by open(2) or socket(2)). This is especially useful for
networking applications. To connect a method to the input_signal
to be called when a condition becomes true on a file descriptor, use the
following:
Connection
connect(SlotType *slot, int source,
GdkInputCondition condition);
|
Where the slot argument is a slot created with a method that
has the following prototype:
void
MyClass::signal_handler(int source,
GdkInputCondition condition);
|
The
source argument is the file
descriptor you wish to have watched, and the
condition argument
specifies what you want GDK to look for. This may be one of:
- GDK_INPUT_READ - Call your function when there is data ready for
reading on your file descriptor.
- GDK_INPUT_WRITE - Call your function when the file descriptor is
ready for writing.
The connection method returns a
Connection class. Unlike widget signals, you must keep a copy of this
Connection and specifically call Connection::disconnect() when you no
longer wish to monitor IO. Connection::block() and Connection::unblock()
are undefined for this connection type.
Idle Functions
What if you have a method which you want to be
called when nothing else is happening? You can use the following method
to connect it to the idle_signal.
Connection
connect(SlotType *slot, int priority =
G_PRIORITY_DEFAULT_IDLE);
|
The slot argument is a slot created with a method that has the
following prototype:
bool
MyClass::signal_handler();
|
The
priority argument is the priority
which should not be above G_PRIORITY_HIGH_IDLE. Note that you will
interfere with GTK+ if you use a priority above GTK_PRIORITY_RESIZE.
Your
signal_handler will continue to be called whenever the
opportunity arises as long as it returns
true. Returning
false
will stop your idle method from being called.
The connection method returns a
Connection class. Unlike widget signals, you must keep a copy of this
Connection and specifically call Connection::disconnect() when you no
longer wish do idle processing. Connection::block() and
Connection::unblock() are undefined for this connection type.
Key Snooper
Functions
Key snooper functions are called on all key events
before delivering them normally so they can be used to implement custom
key event handling. To connect a method to the key_snooper_signal
use the following:
Connection
connect(SlotType *slot);
|
Where the slot argument is a slot created with a method that
has the following prototype:
bool
MyClass::signal_handler(Gtk::Widget& widget, const
Gdk::EventKey& event);
|
The
widget argument is the widget to
which the event will be delivered. The
event argument is the
key event. It is the snooper's responsibility to pass the key event on
to the widget, but care must taken that it is not passed twice. Return
true
to stop further processing. Return
false to continue.
The connection method returns a
Connection class. Unlike widget signals, you must keep a copy of this
Connection and specifically call Connection::disconnect() when you no
longer wish to snoop key events. Connection::block() and
Connection::unblock() are undefined for this connection type.
Quit Functions
If you ever find a reason to connect a method to
the quit_signal to be called when an instance of the main loop
is left you can use the following:
Connection
connect(SlotType *slot, unsigned int
main_level = 0);
|
Where the slot argument is a slot created with a method that
has the following prototype:
bool
MyClass::signal_handler();
|
The main_level argument is the level at
which termination your method shall be called. You can pass 0 here to
have the method called at the termination of the current main loop. If
your method returns false it will removed from the list of quit handlers.