ft_object_create( FT_Object *pobject, FT_Class clazz, FT_Pointer init_data ) { FT_Memory memory; FT_Error error; FT_Object obj; FT_ASSERT_IS_CLASS(clazz); memory = FT_CLASS__MEMORY(clazz); if ( !FT_ALLOC( obj, clazz->obj_size ) ) { obj->clazz = clazz; obj->ref_count = 1; if ( clazz->obj_init ) { error = clazz->obj_init( obj, init_data ); if ( error ) { /* IMPORTANT: call the destructor when an error */ /* was detected in the constructor !! */ if ( clazz->obj_done ) clazz->obj_done( obj ); FT_FREE( obj ); } } } *pobject = obj; return error; }
ft_object_new( FT_Class clazz, FT_Pointer init_data ) { FT_Memory memory; FT_Object obj; FT_ASSERT_IS_CLASS(clazz); memory = FT_CLASS__MEMORY(clazz); obj = ft_mem_alloc( clazz->obj_size, memory ); obj->clazz = clazz; obj->ref_count = 1; if ( clazz->obj_init ) { FT_CleanupStack stack = FT_MEMORY__CLEANUP(memory); ft_cleanup_push( stack, obj, (FT_CleanupFunc) ft_object_cleanup, NULL ); clazz->obj_init( obj, init_data ); ft_cleanup_pop( stack, obj, 0 ); } return obj; }
/* find or create the class corresponding to a given type */ static FT_Class ft_metaclass_get_class( FT_MetaClass meta, FT_Type ctype ) { FT_ClassHNodeRec keynode, *node, **pnode; FT_Memory memory; keynode.hnode.hash = (FT_UInt32)( ctype >> 2 ); keynode.type = type; pnode = (FT_ClassHNode) ft_hash_lookup( &meta->type_to_class, &noderec ); node = *pnode; if ( node != NULL ) return node->clazz; memory = FT_CLASS__MEMORY(meta); node = FT_MEM_SAFE_ALLOC( sizeof(*node) ); if ( node != NULL ) { FT_ClassRec* clazz; clazz = FT_MEM_SAFE_ALLOC( ctype->class_size ); if ( clazz == NULL ) { FT_FREE( node ); FT_XTHROW( FT_Err_Out_Of_Memory ); } } }
ft_object_create( FT_Object *pobject, FT_Class clazz, FT_Pointer init_data ) { FT_Memory memory; FT_Object obj; FT_ASSERT_IS_CLASS(clazz); memory = FT_CLASS__MEMORY(memory); obj = ft_mem_alloc( clazz->obj_size, memory ); obj->clazz = clazz; obj->ref_count = 1; *pobject = obj; if ( clazz->obj_init ) clazz->obj_init( obj, init_data ); }
static FT_Class ft_metaclass_get_class( FT_MetaClass meta, FT_Type ctype ) { FT_ClassHNodeRec keynode, *node, **pnode; FT_Memory memory; FT_ClassRec* clazz; FT_Class parent; FT_Error error; keynode.hnode.hash = FT_TYPE_HASH( ctype ); keynode.type = ctype; pnode = (FT_ClassHNode*) ft_hash_lookup( &meta->type_to_class, (FT_HashNode) &keynode ); node = *pnode; if ( node != NULL ) { clazz = (FT_ClassRec*) node->clazz; goto Exit; } memory = FT_CLASS__MEMORY(meta); clazz = NULL; parent = NULL; if ( ctype->super != NULL ) { FT_ASSERT( ctype->super->class_size <= ctype->class_size ); FT_ASSERT( ctype->super->obj_size <= ctype->obj_size ); parent = ft_metaclass_get_class( meta, ctype->super ); } if ( !FT_NEW( node ) ) { if ( !FT_ALLOC( clazz, ctype->class_size ) ) { if ( parent ) FT_MEM_COPY( (FT_ClassRec*)clazz, parent, parent->type->class_size ); clazz->object.clazz = (FT_Class) meta; clazz->object.ref_count = 1; clazz->memory = memory; clazz->library = FT_CLASS__LIBRARY(meta); clazz->super = parent; clazz->type = ctype; clazz->info = NULL; clazz->magic = FT_MAGIC_CLASS; clazz->class_done = ctype->class_done; clazz->obj_size = ctype->obj_size; clazz->obj_init = ctype->obj_init; clazz->obj_done = ctype->obj_done; if ( parent ) { if ( clazz->class_done == NULL ) clazz->class_done = parent->class_done; if ( clazz->obj_init == NULL ) clazz->obj_init = parent->obj_init; if ( clazz->obj_done == NULL ) clazz->obj_done = parent->obj_done; } /* find class initializer, if any */ { FT_Type ztype = ctype; FT_Object_InitFunc cinit = NULL; do { cinit = ztype->class_init; if ( cinit != NULL ) break; ztype = ztype->super; } while ( ztype != NULL ); /* then call it when needed */ if ( cinit != NULL ) error = cinit( (FT_Object) clazz, NULL ); } } if (error) { if ( clazz ) { /* we always call the class destructor when */ /* an error was detected in the constructor !! */ if ( clazz->class_done ) clazz->class_done( (FT_Object) clazz ); FT_FREE( clazz ); } FT_FREE( node ); } } Exit: return (FT_Class) clazz; }