六. 全部代码
/***********************************************************************
object.h文件
************************************************************************/
#ifndef _H_OBJECT_H_
#define _H_OBJECT_H_
#define TOP_OBJECT_TYPE 0
#define BASE_OBJECT_TYPE GetObjectType()
#define IS_OBJECT_TYPE(obj) IsObjectType(obj,BASE_OBJECT_TYPE)
#define BASE_OBJECT_CLASS(obj) ((CObjectClass*)GetObjectClass(obj))
typedef void (*pInitObjectCallback)(void*);
typedef void (*pInitClassCallback)(void*);
typedef struct _CObject CObject;
typedef struct _CObjectClass CObjectClass;
typedef struct _ClassInfo ClassInfo;
struct _CObject
{
CObjectClass *vclass;
short ref_counter;
};
struct _CObjectClass
{
int class_type;
void (*destory)(CObject *object);
};
struct _ClassInfo
{
char *name;
int object_size;
int class_size;
void (*InitObjectCallback)(void*);
void (*InitClassCallback)(void *);
};
#ifdef __cplusplus
extern "C" {
#endif
int
GetObjectType(void);
void*
GetObjectClass(void *);
CObject *
NewObject(void);
void
DestoryObject(CObject *object);
void
AttachObject(CObject *object);
void
ReleaseObject(CObject *object);
void
InitObjectLib(void);
int
RegisterClassType(ClassInfo *classinfo, int parent_type);
void*
NewClassType(int class_type);
int
IsObjectType(void *obj, int type);
int
CheckClassType(int type);
#ifdef __cplusplus
}
#endif
#endif
/***********************************************************************
object.c文件
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "object.h"
#include "tvstring.h"
#include "debug.h"
#define MAX_CLASS_NUM 128
#define lock()
#define unlock()
typedef struct _ClassType
{
char* name;
int class_size;
int object_size;
CObjectClass* vclass;
void (*InitClassCallback)(void*);
void (*InitObjectCallback)(void*);
struct _ClassType* parent;
struct _ClassType* next;
}ClassType;
static ClassType classes[MAX_CLASS_NUM];
static ClassType *used_classes = NULL;
static ClassType *free_classes = NULL;
/****************************************************************/
static void
InitObjectClass(CObjectClass *vclass)
{
if(vclass==NULL)
return;
vclass->destory = DestoryObject;
}
static void
InitObject(CObject *object)
{
if(object==NULL)
return;
object->ref_counter = 1;
}
int
GetObjectType(void)
{
static int type = 0;
if( type==0 )
{
static ClassInfo classinfo =
{
"OBJECT",
sizeof(CObject),
sizeof(CObjectClass),
(pInitObjectCallback)InitObject,
(pInitClassCallback)InitObjectClass,
};
type = RegisterClassType(&classinfo, TOP_OBJECT_TYPE);
}
return type;
}
void*
GetObjectClass(void *obj)
{
CObject *object;
if(obj==NULL)
return NULL;
object = (CObject *)obj;
return (void*)object->vclass;
}
CObject *
NewObject(void)
{
return NewClassType(BASE_OBJECT_TYPE);
}
void
DestoryObject(CObject *object)
{
if(object==NULL)
return;
free(object);
}
void
AttachObject(CObject *object)
{
if(object==NULL)
return;
object->ref_counter++;
}
void
ReleaseObject(CObject *object)
{
if(object==NULL)
return;
if( --object->ref_counter==0 )
DestoryObject(object);
}
/****************************************************************/
void
InitObjectLib(void)
{
int i;
memset(classes, 0, sizeof(ClassType)*MAX_CLASS_NUM);
for( i=0;i<MAX_CLASS_NUM-1;i++ )
{
classes[i].next = &(classes[i+1]);
}
free_classes = &(classes[0]);
}
int
RegisterClassType(ClassInfo *classinfo, int parent_type)
{
int type = 0;
ClassType *current, *parent;
{
parent = (ClassType *)parent_type;
#ifdef __DEBUG
if( parent &&parent->vclass==NULL )
{
TRACE("RegisterClassType(): parent_type is invalid/n");
return type;
}
#endif
if( classinfo->name==NULL )
{
TRACE("RegisterClassType(): class name is NULL/n");
return type;
}
lock();
current = used_classes;
while(current)
{
if(strcmp(current->name, classinfo->name)==0 )
{
TRACE("RegisterClassType(): class name is redefined/n");
unlock();
return type;
}
current = current->next;
}
current = free_classes;
if(current)
{
free_classes = free_classes->next;
current->name = classinfo->name;
current->parent = parent;
current->class_size = classinfo->class_size;
current->InitClassCallback = classinfo->InitClassCallback;
current->InitObjectCallback = classinfo->InitObjectCallback;
current->vclass = malloc(current->class_size);
if( current->vclass==NULL )
{
TRACE("RegisterClassType(): malloc vclass failed/n");
}
memset( current->vclass, 0, current->class_size);
current->vclass->class_type = (int)current;
if( parent )
{
memcpy(current->vclass, parent->vclass, parent->class_size);
}
if( current->InitClassCallback )
current->InitClassCallback(current->vclass);
current->next = used_classes;
used_classes = current;
}
else
{
TRACE("RegisterClassType(): ERROR, no class in class pool/n");
}
unlock();
type = (int)current;
}
return type;
}
static void
InitParentObject(ClassType *current, void *object)
{
if( current )
{
if( current->parent )
InitParentObject(current->parent, object);
if( current->InitObjectCallback )
current->InitObjectCallback(object);
}
}
void *
NewClassType(int class_type)
{
ClassType *pclass = NULL;
void *object = NULL;
if( pclass==0 )
return NULL;
#ifdef __DEBUG
if( CheckClassType(class_type)==0 )
{
TRACE("NewObjectType(): invalid class_type/n");
return NULL;
}
#endif
pclass = (ClassType*)class_type;
object = (CObject*)malloc(pclass->object_size);
if( object )
{
((CObject*)object)->vclass = pclass->vclass;
InitParentObject(pclass, object);
}
return object;
}
int
IsObjectType(void *obj, int type)
{
ClassType *pclass, *objtype;
CObject *object;
if( obj==NULL || type==0 )
return 0;
pclass = (ClassType*)type;
object = (CObject*)obj;
if( object->vclass==NULL )
return 0;
objtype = (ClassType*)object->vclass->class_type;
while(objtype)
{
if( objtype==pclass )
return 1;
objtype = objtype->parent;
}
return 0;
}
int
CheckClassType(int type)
{
ClassType *objtype;
objtype = used_classes;
while(objtype)
{
if( (int)objtype==type )
return 1;
objtype = objtype->next;
}
return 0;
}