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
|