Keywords: notionnotes

Subsections

- 2.1 Object creation
- 2.2 Safe references
- 2.3 Dynamic dispatch

# 2 Object system implementation

First, to get things clear, what are considered objects here are C structures containing a properly initialised structure defined in ioncore/obj.h as the first element (or the first element of the structure which is the first element and so on which gives rise to inheritance). The WObj structure contains a pointer to a WObjDescr class type info structure and a list of so called “watches”. The WObjDescr structure simply lists the class name, a table of dynamic functions and a pointer to deinitialisation function (or “destructor”).

## 2.1 Object creation

Object instances are created using the `CREATEOBJ_IMPL` macro, but by convention for each class `WFoo` a construction method `create_foo` is provided.

## 2.2 Safe references

NOTE: This subsection appears out-of-date, it seems the WWatch infrastructure was removed from Ion3.

Notion does not do any reference counting, garbage collecting or other fancy things related to automatic safe freeing of objects with its simplistic object system. Instead special watches (the WWatch structure) may be used to create safe references to objects that might be destroyed during the time the specific pointer is needed. When an object is destroyed, its list of watches is processed, setting the pointers in the watches to NULL and the watch handlers for each watch are called.

## 2.3 Dynamic dispatch

To override a method means to reimplement it specifically for a given subtype. This is used in Notion to allow subclasses to override of their superclasses' methods.

Overridable methods are specified as `DYNFUN`, for example `region_fitrep` in ioncore/region.h:

    DYNFUN bool region_fitrep(WRegion *reg, WWindow *par, const WFitParams *fp);

Dynamic functions can be called with `CALL_DYN` or `CALL_DYN_RET`. When a subclass desires to override a dynamic function, it does so by specifying a DynFunTab. For example, the function table for WGroup overrides `region_fitrep` with `group_fitrep`:

    static DynFunTab group_dynfuntab[]={
        {(DynFun*)region_fitrep,
         (DynFun*)group_fitrep},
        ...
        END_DYNFUNTAB
    };
    EXTL_EXPORT
    IMPLCLASS(WGroup, WRegion, group_deinit, group_dynfuntab);

Whenever `region_fitrep` is called on a region that is actually a WGroup, `group_fitrep` is called instead.