Managed Class

A managed class is a basic class with the additional feature that it allows for dynamic members. We will limit this discussion to the extensions to the basic class. An explanation of that mechanism can be found elsewhere.

#include <diablosupport_class.h>
#ifndef CLASS
#define CLASS ins
#define ins_field_select_prefix INS
#define ins_function_prefix Ins

#define MANAGER_TYPE t_cfg *
#define MANAGER_NAME cfg
#define MANAGER_FIELD ins_manager

A managed class is, as it name suggests, managed by another class: the manager class. The manager class is specified by MANAGER_TYPE. It should contain a member of type t_manager with the (lowercase) name specified by MANAGER_FIELD. Thus, in our example, cfg should have the following declaration: MEMBER(t_manager, ins_manager, INS_MANAGER)

The managed class should contain a member of type specified by MANAGER_TYPE with (lowercase) name specified by MANAGER_NAME. Thus in our example:

MEMBER(t_cfg *, cfg, CFG)

Furthermore, a constructor, duplicator and destructor need to be defined. These declarations will automatically generate functions needed to manage the dynamic members. Note that these declarations are not allowed in basic classes.

CONSTRUCTOR({/*specified code*/})
DESTRUCTOR({/*specified code*/})
DUPLICATOR({/*specified code*/})

The constructor will result in the function t_ins * InsInit(t_cfg * cfg), which executes the code specified in the constructor and a function t_ins * InsNew(t_cfg * cfg), which allocates memory before it executes the specified code.
The specified code can access the instruction that will be returned through the variable ret.

Furthermore, the following functions will be created:

static void InsCallbackInstall(t_cfg * cfg, t_manager_callback_type type,
                               t_int32 prior, t_manager_callback_function fun,
                               void * data)
static void InsCallbackUninstall(t_cfg * cfg, t_manager_callback_type type,
                                 t_int32 prior, t_manager_callback_function fun,
                                 void * data)

They can be used to install extra callbacks when an instruction is created (type CB_NEW), duplicated (CB_DUP) or freed (CB_FREE). prior indicates when this callback should be executed in the timeline. For CB_FREE, dynamic members are handled at time -10, the free itself at time 0. For CB_NEW and CB_DUP, dynamic members are handled at time 10, while the new respectively dup are treated at time 0. The prior is used to indicate when the callback should be called.

The destructor results in the function void InsFree(t_ins * ins) which will execute the specified code and free the allocated memory.
The specified code can access the instruction that will be returned through the variable to_free.

The duplicator results in the function t_ins * InsDup(t_ins * ins). The specified code can access the instruction that will be duplicated through the variable to_dup and the instruction that will be returned through the variable ret.

...
DIABLO_CLASS_END
#undef BASECLASS
#define BASECLASS relocatable
#include <diabloobject_relocatable.class.h>
#undef BASECLASS