Previous: Pages, Up: Objects



6.2.6 Linking and unlinking

The life cycle of an object.

An object can “live” in the following three locations:

When an object is created, a transaction (see Transactions and topological sorting) is active. Every transaction uses a temp. Transactions working with graphic objects use the temp of the current transaction page, transactions working with non-graphic objects use the obj_temp object.

The newly created object is initialized to have the temp as its parent (we say that the object is linked in the temp). Then, inside the transaction, it can be relinked into an object in the universe. If not, it is relinked into the zombie after the end of the transaction. From there, it can be then relinked via the temp into an object in the universe.

The objects in the zombie are deleted automatically when their reference count becomes zero. If an object is relinked, its children are not – their parent pointers remain unchanged. For example, if you unlink a page, it goes to the obj-zombie, but the page's contents stay linked in the page. When you undo the last action, the page is resurrected with its contents as well.

An example of the zombie structure.

In the picture, you can see an example of object structure of zombie. There are two zombie objects: one for graphic objects (gos) and one for the non-graphic ones (obj). Every object linked in the zombie points to its previous parent from where it was unlinked; as observed in the picture, the previous parent might be in the zombie as well. All the pointing objects from zombie keep a reference of the parent so that the pointer does not get invalid.

The zombie and temp objects cannot be accessed directly; instead, there are these functions that do the linking:

     obj_link(struct obj* obj, struct obj* father);
     obj_unlink(struct obj* obj);
     obj_relink(struct obj *obj, struct obj *father, struct obj *old_father);
     
     go_link_after(struct go *go, struct go_group *group, struct go *after);
     go_unlink(struct go *go);
     go_relink(struct go *go, struct go_group *group, struct go *after);

and their various special cases for convenience. They use the temp internally.