Given an LqrCarver
object, it is possible to attach an arbitrary number of extra carvers to it:
these will passively undergo the same carving process as the root carver. In order for this to be
possible, the carvers must be all of the same size.
The function to use is simply:
LqrRetVal lqr_carver_attach( | LqrCarver* carver, |
LqrCarver* aux) ; |
This attaches aux
to carver
.
It is not necessary that the parent LqrCarver
is activated. In fact, a carver can be attached to a
carver which is itself attached to another one.
Needless to say, no resizing operation should be done directly on an LqrCarver
once it has been
attached to another LqrCarver
, and neither should the cancel method be invoked directly on them.
The carvers always have to be attached before loading visibility maps.
Attached carvers can be read-out in the same way as their parents. There are however also methods
to span all them, in a way very similar to that in which internally dumped LqrVMap
's are
accessed, but LqrVMapList
objects are substitued in this case by LqrCarverList
objects.
First, the starting point of the list has to be retreived through:
LqrCarverList* lqr_carver_list_start( | LqrCarver* carver) ; |
Then, one can iterate through the attached carvers by using these two functions:
LqrCarver* lqr_carver_list_current( | LqrCarverList* list) ; |
LqrCarverList* lqr_carver_list_next( | LqrCarverList* list) ; |
Here is a sample code usage:
Example 2.10. Accessing attached carvers #1
LqrCarver *aux; LqrCarverList *list; list = lqr_carver_list_start (carver); while (list) { aux = lqr_carver_list_current (list); /* ... do something on aux ... */ list = lqr_carver_list_next (list); }
The carvers will always be accessed in the order in which they were attached.
Alternatively, one can apply a function to all the elements of the list (and recursively to all the elements of their attached lists, if there are any), through this function:
LqrRetVal lqr_carver_list_foreach_recursive( | LqrCarverList* list, |
LqrCarverFunc func, | |
LqrDataTok data) ; |
To use this second method, you'll need to define a function first, as in the following sample code:
Example 2.11. Accessing attached carvers #2
LqrRetVal my_func (LqrCarver *aux, LqrDataTok data) { /* ... do something on aux ... */ return LQR_OK; } LqrCarverList *list; LqrDataTok data_tok; list = lqr_carver_list_start (carver); data_tok->data = NULL; lqr_carver_list_foreach_recursive (list, my_func, data_tok);
The data to be passed on to the LqrCarverFunc is of type LqrDataTok. This is defined as a union, with the following fields:
LqrCarver
* carver
gint integer
gpointer data
In the above example, no data is actually passed on to the function.
In actual code, the call to lqr_carver_list_foreach_recursive
should be
protected to test its return value, which is LQR_OK
if all my_func calls have been successful
(or if the list is empty), or it will hold the first non-successful return value from
my_func
.