/*
**	Working with LibV object model.
**	One should learn from this code only if want to extend LibV.
*/

#include <../source/TAL/objbase.h>
#include <stdio.h>

typedef struct obj_s
{
#define	magic		0x01020304
#define	name		"test object"
	libv_object_t	base;
	void			*mem;
}	obj_t, *obj_p;

u32_t	V_CALL
obj_destroy(vhandle_t handle)
{
	obj_p self=(obj_p)handle;
	printf("obj->destroy: ref_count is %u.\n",self->base.ref_count);
	if(--self->base.ref_count)
		return self->base.ref_count;	/* still references */
	/* no more references */
	memFree(self->mem);
	memFreeObject(self);
	puts("object destroyed");
	return 0;
}

vhandle_t
create_obj(void)
{
	obj_p obj;
	ALLOC_OBJECT(obj,obj_t,0,magic);
	obj->base.destroy=obj_destroy;
	obj->mem=memAlloc(1024);
	return obj;
}
	
vhandle_t
duplicate_obj(vhandle_t handle)
{
	obj_p self;
	self=(obj_p)libvIsHandle(handle,"duplicate_obj",name,magic);
	if(!self)
		return NULL;
	self->base.ref_count++;
	return self;
}	

static void	print_mem_stats(void)
{
	u32_t mc,pc,oc;
	memStats(&mc,&pc,&oc);
	printf("Memory stats: %u total,%u pointers,%u handles\n",mc,pc,oc);
}

int main()
{
	vhandle_t object, dupe;
	logStartConsoleLog();
	logUpperLevel(LOG_TRACE);
	print_mem_stats();				/* print memory info */
	object=create_obj();			/* create object */
	dupe=duplicate_obj(object);		/* increase ref_count */
	print_mem_stats();				/* print memory info */
	__libvCloseHandle(object);		/* decrease ref_count */
	__libvCloseHandle(dupe);		/* destroy object */
	print_mem_stats();				/* print memory info */
	logStopConsoleLog();
	print_mem_stats();				/* print memory info */
	return 0;
}
