Complex Attribute Implementation File
List of: Discussion Topic
Subjects: Attributes
Contents: Kernel

ACIS debugging functions that print entity information to a specified debug file are used with this example. They are declared in the file kerndata/data/debug.hxx. The function debug_old_pointer formats an entity pointer into a string for printing, but does not place the entity in the debug list, since it assumes it is already there. The string contains the decimal value of the pointer and an integer index for the pointer. The index is used to cross-reference it in the debug printout. This example uses debug_old_pointer because the body is probably already on the debugging list. This assumption is valid since, when debugging a body, the attribute will be printed to the debug file after the body is printed.

To create the .cxx file for the complex color attribute example, the following changes need to be made to the simple color attribute .cxx file:


1. Output the body pointer to the debug file using debug_old_pointer.


2. Save the body pointer in the save file by adding it to the entity list and writing the index returned during the list.add to the file. When the file is restored, the attribute is reconstructed with the correct body pointer. (list is an argument to save_common, the function defined by SAVE_DEF.)


3. Add a body pointer to RESTORE_DEF. When a pointer is restored, it is read as an integer index that must be cast into a pointer of the appropriate type. The next phase of part restoration converts the index into a valid pointer.


4. Add a body pointer in the COPY_DEF section. The from pointer is an argument to the copy_common function that points to the attribute being copied. If the attribute contains pointers to other attributes or entities, the pointer in the copy must be set to an integer index returned from doing a lookup of the original pointer in the ENTITY_LIST list. The integer is cast into the appropriate type for assignment to the pointer in the copy that is later converted to the correct pointer. The ENTITY_LIST list is an argument to the copy_common function.


5. Insert pointer data in the SCAN_DEF section. The SCAN_DEF macro defines the function copy_scan. When a body is being copied, all data is scanned to find all pointers and convert them into indices. If the attribute contains any pointers, they must be added to the ENTITY_LIST list, which is an argument to the function.


6. Insert pointer data in the FIX_POINTER_DEF section. The final stage of restoring a body from a file, or of copying the body, is to convert all indices stored in pointer data fields into real pointers. FIX_POINTER_DEF is a macro that defines the function, fix_pointers. The read_array function looks up the integer index in the ENTITY array and returns the corresponding ENTITY pointer.


7. Add the body pointer to the constructor.


8. Add the my_body initialization to the constructor.


9. Add a function to set the body pointer.

Except for the addition of the body pointers, Example 3-9 is identical to Example 3-6 . The changes are shown in bold.

C++ Example

// Implementation of color attribute
#include <stdio.h>
#include <memory.h>
#include "kernel/acis.hxx"
#include "color_attrib.hxx"
#include "kerndata/data/datamsc.hxx"

// Define macros for this attribute and its parent, to simplify
// later stuff and make it suitable for making into macros.
#define THIS() ATTRIB_COL
#define THIS_LIB NONE
#define PARENT() ATTRIB_ABC
#define PARENT_LIB NONE

// Identifier used externally to identify a particular entity
// type. This is used in the save/restore system for translating
// to/from external file format.
#define ATTRIB_COL_NAME "color"

// Implement the standard attribute functions.
ATTRIB_DEF("color_attribute")

// Define color names for printout

static char* col_name[] = {


"black",


"red",


"green",


"blue",


"cyan",


"yellow",


"magenta",


"white"

};


debug_string("Color", col_name[color_data], fp);

debug_old_pointer("Body pointer", (ENTITY*)my_body, fp);

SAVE_DEF

write_int(color_data);
// Save specific data

write_ptr((ENTITY*)my_body, list);

RESTORE_DEF

set_color(read_int());

set_the_body((BODY*)read_ptr());

COPY_DEF

set_color(from->color());

set_the_body((BODY*)list.lookup((ENTITY*)(from->the_body())));

SCAN_DEF

list.add((ENTITY*)my_body);

FIX_POINTER_DEF

my_body = (BODY*)read_array(array, (int)my_body);

TERMINATE_DEF

// make a color attribute

ATTRIB_COL::ATTRIB_COL(

ENTITY* owner,

int col,

BODY* the_body
) : ATTRIB_ABC(owner)
{

// Initialize members.

color_data = col;

my_body = the_body;
}

// Set the member data.
void ATTRIB_COL::set_color(

int new_col

)
{

backup();

color_data = new_col;
}

// Set the body function.
void ATTRIB_COL::set_the_body(

BODY* the_new_body

)
{

backup();

my_body = the_new_body;
}

// Virtual function called when an owner entity is being split.
void ATTRIB_COL::split_owner(

ENTITY* new_ent

)
{

// Duplicate the attribute on the new entity

new ATTRIB_COL(new_ent, color_data);
}

// Virtual function called when two entities are to be merged.
void ATTRIB_COL::merge_owner(

ENTITY* other_ent,

logical delete_owner )
{

// If the owner of this attribute is going to be deleted, and

// there is no color attached to the other entity, then we

// transfer ourselves to that other entity.


if(delete_owner) {


ATTRIB* other_att = find_attrib(



other_ent,



ATTRIB_ABC_TYPE,



ATTRIB_COL_TYPE


);



if(other_att == NULL) {



// No color on other entity, so transfer ourselves



move(other_ent);


}

}
}

Example 3-9. Complex Color Attribute color_attrib.cxx File
PDF/KERN/03ATT.PDF
HTM/DATA/KERN/KERN/03ATT/0022.HTM