1
@comment $Id: gpsm.texi,v 1.2 2001/05/04 08:02:10 richi Exp $
3
@node GLAME Project Structure Management, Plugin Interface, Swapfile API, Top
4
@chapter GLAME Project Structure Management
6
The project structure management including track metadata and coupling
7
with the swapfile/filter API.
9
The structure is build out of gpsm-items which can be either groups
10
(gpsm_grp_t) or swapfile files (gpsm_swfile_t). Think of the structure
11
as of a tree with leafs all being swapfile files (or equivalent types,
12
if they ever will appear) and the interior nodes being groups. Groups
13
(generic: items) have horizontal (samples) and vertical (tracks) extend,
14
items have horizontal (samples) and vertical (track) positions.
16
Usage of the gpsm API is by the various GUI widgets that handle the
17
swapfile and the filters such as the swapfile gui and the timeline
18
gui. Also use by the scheme scripts is the preferred way to work on the
19
swapfile. Consistent updating of all interfaces can be realized by
20
registering appropriate signal handlers to the gpsm-items
21
emitter. Signals are sent out by all gpsm API functions and have to be
22
sent out manually by everyone operating on the swapfile/gpsm-items _not_
23
using the gpsm API functions.
27
* Generic operations on items::
30
* GPSM signals and their semantics::
31
* Undo and redo support::
35
@node Generic operations on items, The group item, , GLAME Project Structure Management
36
@section Generic operations on items
38
Every item in the project tree has information of its parent, a signal
39
emitter where you can attach handlers to, a label and last but not least
40
a 2D position and a 2D size. Those elements can be accessed using the
44
@deftypefun {gpsm_item_t *} gpsm_item_parent (gpsm_item_t *@var{item})
45
Returns the parent item of the provided item or NULL, if the item is
46
the root of a gpsm tree.
50
@tindex glsig_emitter_t
51
@deftypefun {glsig_emitter_t *} gpsm_item_emitter (gpsm_item_t *@var{item})
52
Returns the signal emitter of the provided item.
56
@deftypefun {const char *} gpsm_item_label (gpsm_item_t *@var{item})
57
Returns the label of the provided item. Note that the result is strictly
62
@deftypefun {long} gpsm_item_hposition (gpsm_item_t *@var{item})
63
@deftypefunx {long} gpsm_item_vposition (gpsm_item_t *@var{item})
64
@deftypefunx {long} gpsm_item_hsize (gpsm_item_t *@var{item})
65
@deftypefunx {long} gpsm_item_vsize (gpsm_item_t *@var{item})
66
These functions return the actual position (horizontal or vertical) or
67
the actual size (horizontal or vertical) of the provided item. Both
68
horizontal position and size are measured in samples. Both vertical
69
position and size are measured in tracks. Positions and sizes are
74
Common operations you can carry out on an items are item destruction,
75
insertion and removal, setting of the label and flattening.
78
@deftypefun void gpsm_item_destroy (gpsm_item_t *@var{item})
79
Destroys the provided gpsm item. The item is first removed from its
80
group, if necessary and then destructed in child-first order. Appropriate
81
signals are send out for this operation, namely @code{GPSM_SIG_ITEM_REMOVE}
82
(and the @code{GPSM_SIG_GRP_REMOVEITEM} signal to the items group) if
83
removal is required and @code{GPSM_SIG_ITEM_DESTROY}.
88
@deftypefun int gpsm_grp_insert (gpsm_grp_t *@var{group}, gpsm_item_t *@var{item}, long @var{hposition}, long @var{vposition})
89
Inserts the specified gpsm-item into the group at the specified
90
position. Random (non-overlapping) h-/v-positioning is performed if you
91
pass -1 to h-/v-position. May fail, as overlapping items are not
92
allowed. Returns 0 on success and -1 on error. Appropriate signals are
93
send out for this operation, namely @code{GPSM_SIG_GRP_NEWITEM} to the
98
@deftypefun void gpsm_item_remove (gpsm_item_t *@var{item})
99
Removes the specified gpsm-item from its current group. The items
100
position will be (0,0) after this operation. If the item was not member
101
of a group this is a NOP. Appropriate signals are send out for this
102
operation, namely @code{GPSM_SIG_ITEM_REMOVE} and the
103
@code{GPSM_SIG_GRP_REMOVEITEM} signal to the items group.
107
@deftypefun void gpsm_item_set_label (gpsm_item_t *@var{item}, const char *@var{label})
108
Updates the label of the specified gpsm-item. Note that this will cause
109
a @code{GPSM_SIG_ITEM_CHANGED} signal to be send out.
113
@deftypefun void gpsm_flatten (gpsm_item_t *@var{item})
114
Flattens a gpsm item, that is, out of a possible deep tree of
115
horizontally and vertically spreaded swfiles make a set of vertically
116
aligned (read: starting at position zero and ending at the maximum
117
position) swfiles. Returns a new group with new swfiles, one for each
118
vertical track. The data is COWed from the original tree. In the
119
special case of providing a swfile as item a new group with a COW copy
120
of this item is returned (without paying attention to hposition of the
121
item). On failure NULL is returned. Note that this feature greatly
122
simplifies operations such as play and export (i.e. where you only want
123
to _read_ from the files).
128
@node The group item, The swfile item, Generic operations on items, GLAME Project Structure Management
129
@section The group item
131
Group items form the back of the gpsm tree, they contain an arbitrary number
132
of items positioned relative to their parent. You can access a groups items
133
via the following generic iterators:
137
@deftypefn Iterator {} gpsm_grp_foreach_item (gpsm_grp_t *@var{group}, gpsm_item_t *@var{item}) @{ @}
138
You can iterate through all items contained in the specified @var{group}
139
using the iterator (which acts like a for statement with the second
140
parameter as running variable). Note that you may not delete instances
146
@deftypefn Iterator {} gpsm_grp_safe_foreach_item (gpsm_grp_t *@var{group}, void *@var{dummy}, gpsm_item_t *@var{item}) @{ @}
147
You can iterate through all items contained in the specified @var{group}
148
using the iterator (which acts like a for statement with the second
149
parameter as running variable). You may delete the actual @var{item} within
150
this iterator, but you have to specify another @var{dummy} pointer to use for
155
There are a few operations specialized to work on group items only, namely
156
group creation and tree searching.
159
@deftypefun {gpsm_grp_t *} gpsm_newgrp (const char *@var{label})
160
Creates a new empty gpsm group with the specified @var{label}. You have
161
to insert it into a gpsm group yourself. Returns a gpsm group or NULL on
167
@deftypefun {gpsm_grp_t *} gpsm_find_grp_label (gpsm_grp_t *@var{root}, gpsm_item_t *@var{start}, const char *@var{label})
168
Find a gpsm-grp by label in the subtree specified by root. The search is
169
started at the item start (or at the root, if you specify NULL). You can
170
find all occurences by specifying the previous result as start. Returns
171
a gpsm-grp, if found or NULL, if not.
176
@tindex gpsm_swfile_t
177
@deftypefun {gpsm_swfile_t *} gpsm_find_swfile_label (gpsm_grp_t *@var{root}, gpsm_item_t *@var{start}, const char *@var{label})
178
Find a gpsm-swfile by label in the subtree specified by root. The search
179
is started at the item start (or at the root, if you specify NULL). You
180
can find all occurences by specifying the previous result as
181
start. Returns a gpsm-swfile, if found or NULL, if not.
186
@tindex gpsm_swfile_t
187
@deftypefun {gpsm_swfile_t *} gpsm_find_swfile_filename (gpsm_grp_t *@var{root}, gpsm_item_t *@var{start}, long @var{filename})
188
Find a gpsm-swfile by filename in the subtree specified by root. The
189
search is started at the item start (or at the root, if you specify
190
NULL). You can find all occurences by specifying the previous result as
191
start. Returns a gpsm-swfile, if found or NULL, if not. */
196
@tindex gpsm_swfile_t
197
@deftypefun {gpsm_swfile_t *} gpsm_find_swfile_vposition (gpsm_grp_t *@var{root}, gpsm_item_t *@var{start}, long @var{vposition})
198
Find a gpsm-swfile by vposition in the subtree specified by root. The
199
search is started at the item start (or at the root, if you specify
200
NULL). You can find all occurences by specifying the previous result as
201
start. Returns a gpsm-swfile, if found or NULL, if not.
205
@node The swfile item, GPSM signals and their semantics, The group item, GLAME Project Structure Management
206
@section The swfile item
208
The swfile items are the leafs of the gpsm tree, they are the connection
209
between the backing store and the different views. Swfiles provide a
210
swapfile filename, a samplerate and a position which can be accessed
211
using the following functions:
213
@tindex gpsm_swfile_t
214
@deftypefun long gpsm_swfile_filename (gpsm_swfile_t *@var{swfile})
215
Returns the swapfile filename of the gpsm swfile item.
218
@tindex gpsm_swfile_t
219
@deftypefun int gpsm_swfile_samplerate (gpsm_swfile_t *@var{swfile})
220
Returns the samplerate of the gpsm swfile item.
223
@tindex gpsm_swfile_t
224
@deftypefun float gpsm_swfile_position (gpsm_swfile_t *@var{swfile})
225
Returns the stream position of the gpsm swfile item.
229
There exist a quite large number of specialized operations on swfile items,
230
including file creation, copying and linking, setting of the data and
231
notifying gpsm and its users about changes to the swapfile file data.
233
@tindex gpsm_swfile_t
234
@deftypefun {gpsm_swfile_t *} gpsm_newswfile (const char *@var{label})
235
Creates a new spare swapfile to operate with. You have to insert it into
236
a gpsm group yourself. Returns a gpsm-swfile or NULL on error.
239
@tindex gpsm_swfile_t
240
@deftypefun {gpsm_swfile_t *} gpsm_swfile_cow (gpsm_swfile_t *@var{swfile})
241
Creates a new swapfile with contents from the swapfile specified by the
242
gpsm-swfile. Returns a gpsm-swfile or NULL on error.
245
@tindex gpsm_swfile_t
246
@deftypefun {gpsm_swfile_t *} gpsm_swfile_link (gpsm_swfile_t *@var{swfile})
247
Creates a new gpsm-swfile with the swapfile of the specified gpsm-swfile
248
as backing store. Returns a gpsm-swfile or NULL on error.
251
@tindex gpsm_swfile_t
252
@deftypefun void gpsm_swfile_set (gpsm_swfile_t *@var{swfile}, int @var{samplerate}, float @var{position})
253
@deftypefunx void gpsm_swfile_set_samplerate (gpsm_swfile_t *@var{swfile}, int @var{samplerate})
254
@deftypefunx void gpsm_swfile_set_position (gpsm_swfile_t *@var{swfile}, float @var{position})
255
Updates the samplerate and/or position of the specified
256
gpsm-swfile. Note that this information is per gpsm-swfile, not per
257
swapfile! Note that this will cause a @code{GPSM_SIG_ITEM_CHANGED}
258
signal to be send out.
261
@deftypefun void gpsm_notify_swapfile_change (long @var{filename}, long @var{pos}, long @var{size})
262
@deftypefunx void gpsm_notify_swapfile_cut (long @var{filename}, long @var{pos}, long @var{size})
263
@deftypefunx void gpsm_notify_swapfile_insert (long @var{filename}, long @var{pos}, long @var{size})
264
@strong{After} you've done an operation on a swapfile such as modifying
265
or cutting/inserting via @code{sw_sendfile()} you have to notify the
266
GPSM about this change. The swfiles sizes will be updated and
267
appropriate signals will be send out. Note that it is generally better
268
to make changes to a swapfile through gpsm functions (which dont exist
272
@deftypefun void gpsm_invalidate_swapfile (long @var{filename})
273
If you have done changes to a swapfile which you cannot (or would not
274
like to) specify explicitly you can tell gpsm and its users to start
275
from scratch with this file. Note that this is a costly operation and it
276
is generally better to use the finer grained notify functions above.
281
@node GPSM signals and their semantics, Undo and redo support, The swfile item, GLAME Project Structure Management
282
@section GPSM signals and their semantics
284
There are a vast number of signals send out by the gpsm subsystem which
285
are described syntactically and semantically here. Signal names are
286
constructed with the prefix @code{GPSM_SIG} the infix denoting the type
287
of object and the type of the first argument it is sent to such as
288
@code{ITEM}, @code{SWFILE} and @code{GRP} and a suffix denoting the
289
semantics. A list of available signals follows.
291
The first group is the signals sent to all type of items (thus the
295
@item GPSM_SIG_ITEM_CHANGED
296
@code{GPSM_SIG_ITEM_CHANGED} has one parameter, the gpsm-item. The
297
signal will be sent out @strong{after} a change to any of the items data
298
elements. Note that @code{GPSM_SIG_ITEM_CHANGED} delivery is not
299
suppressed, if the change has a semantically more specific signal like
300
one of the @code{GPSM_SIG_GRP_*} or @code{GPSM_SIG_SWFILE_*}
301
signals. Also a @code{GPSM_SIG_ITEM_CHANGED} signal is sent out on item
304
@item GPSM_SIG_ITEM_DESTROY
305
@code{GPSM_SIG_ITEM_DESTROY} has one parameter, the gpsm-item. The
306
signal will be sent out @strong{before} item destruction. Note that
307
items attached to a group will generally recieve a
308
@code{GPSM_SIG_GRP_REMOVEITEM} signal before destruction, i.e.
309
@code{gpsm_item_destroy()} will remove them first, then destruct.
311
@item GPSM_SIG_ITEM_REMOVE
312
@code{GPSM_SIG_ITEM_REMOVE} has one parameter, the gpsm-item. The signal
313
will be sent out @strong{before} item removal from its group. The
314
@code{GPSM_SIG_GRP_REMOVEITEM} signal will be send out to the group
319
The second group is the signals sent to groups only (thus the @code{GRP}
321
Both @code{GPSM_SIG_GRP_NEWITEM} and @code{GPSM_SIG_GRP_REMOVEITEM} have
322
two parameters, the gpsm-grp as the first and the gpsm-item to be
323
inserted/removed as second one. The @code{GPSM_SIG_GRP_REMOVEITEM}
324
signal is sent out before item removal and after the item recieved the
325
@code{GPSM_SIG_ITEM_REMOVE} signal, the @code{NEWITEM} signal after item
328
@strong{NOTE}: If the actual item is a group it is certainly possible
329
for it to contain children!
331
@strong{NOTE2}: You may want to attach/remove signal handlers to the
332
item (and the possible childrens of a group)
336
@item GPSM_SIG_GRP_NEWITEM
337
@item GPSM_SIG_GRP_REMOVEITEM
340
The third and last group is the signals sent out to swfiles only (thus
341
the @code{SWFILE} infix).
342
The @code{GPSM_SIG_SWFILE_*} have three parameters, the first is the
343
gpsm-swfile itself, the second is a long position, the third a long size
344
specifying position and size of the inserted / cutted / changed data in
345
samples. This signal is sent _after_ the actual operation was carried
349
@item GPSM_SIG_SWFILE_INSERT
350
@item GPSM_SIG_SWFILE_CUT
351
@item GPSM_SIG_SWFILE_CHANGED
355
@node Undo and redo support, , GPSM signals and their semantics, GLAME Project Structure Management
356
@section Undo and redo support
358
GPSM provides an easy way to support undo and redo at the scope of a
359
GPSM group (or a single swfile). To be able to do this you need to
360
manually save the state of a group before operating on it, undo and
361
redo then can automatically roll back to these saved states.
363
The maximum number of saved states can be configured by using the
364
following function (it is safe to call it before or after @code{gpsm_init()}):
366
@deftypefun int gpsm_set_max_saved_ops (int @var{max})
367
Changes (or just queries, if max < 0) the maximum number of states saved
368
for undo/redo. Returns the actual set value.
371
The following functions treating with undo and redo are available:
374
@deftypefun int gpsm_op_prepare (gpsm_item_t *@var{item})
375
Save the current state of the provided subtree for later undo. Returns
376
0 on success, -1 on failure.
380
@deftypefun int gpsm_op_can_undo (gpsm_item_t *@var{item})
381
Returns 1 if undo is pending for the subtree item and can be undone at
382
this point, else returns 0.
386
@deftypefun int gpsm_op_undo (gpsm_item_t *@var{item})
387
Rolls back to the latest saved state of the provided subtree. Returns 0
388
on success, -1 on error (such as no undo pending or possible). Saves
389
the actual state for later redo.
393
@deftypefun int gpsm_op_undo_and_forget (gpsm_item_t *@var{item})
394
Rolls back to the latest saved state of the provided subtree. Returns 0
395
on success, -1 on error (such as no undo pending or possible). Does not
396
save the actual state for later redo.
400
@deftypefun int gpsm_op_can_redo (gpsm_item_t *@var{item})
401
Returns 1 if redo is pending for the subtree item and can be redone at
402
this point, else returns 0.
406
@deftypefun int gpsm_op_redo (gpsm_item_t *@var{item})
407
Rolls back to the state before the previous undo to the provided
408
subtree. Returns 0 on success, -1 on error (such as no redo pending or
409
possible). Saves the actual state for later undo.
413
@deftypefun int gpsm_op_redo_and_forget (gpsm_item_t *@var{item})
414
Rolls back to the state before the previous undo to the provided
415
subtree. Returns 0 on success, -1 on error (such as no redo pending or
416
possible). Does not save the actual state for later undo.
420
@deftypefun int gpsm_op_forget (gpsm_item_t *@var{item})
421
Kills off the latest saved state of the provided subtree. Returns 0 on
422
success, -1 on error (no pending undo or redo).