Browse Source

Modify TR_INSTANCE to get variable argument list for the initialization values, effectively remove the need for this ugly stray closing curly bracket. Add TR_objectInit function which allows to call the constructor on an already existing object. Remove not used variable argument list on _TR_CALL and fix corresponding makros.

1.0.2
Georg Hopp 12 years ago
parent
commit
f68ee33914
  1. 78
      include/tr/class.h
  2. 10
      include/tr/interface/class.h
  3. 20
      src/i_class.c

78
include/tr/class.h

@ -118,23 +118,25 @@
/** /**
* NEW. Create a static instance of a class.
* Create a static instance of a class.
* This is new and currently it is only possible to create * This is new and currently it is only possible to create
* instances for class that does not need a constructor. * instances for class that does not need a constructor.
* *
* \todo
* This macro requires to close the initializer
* with an extra curly brancket. This is not nice...find a
* way to prevent this.
* \todo
* This does not call any constructor with any value...this * This does not call any constructor with any value...this
* has to be fixed.
* has to be fixed. // When this macro is used within a global
* (static) context this can't be fixed. No function can be
* called from there. Instead I add a TR_objectInit function which
* takes an object name (created on either the stack or the
* heap) and a variable argument list and calls its constructor
* with the arguments.
*/ */
#define TR_INSTANCE(class, name) \
struct c_##class##_object _##name; \
class name = &(_##name.data); \
struct c_##class##_object _##name = { \
&c_##class,
#define TR_INSTANCE(class, name, ...) \
struct c_##class##_object _##name; \
class name = &(_##name.data); \
struct c_##class##_object _##name = { \
&c_##class, \
{ ##__VA_ARGS__ } \
}
/** /**
* I initialize _ (the class's base or parent class) * I initialize _ (the class's base or parent class)
@ -185,7 +187,7 @@
* *
* /see TR_CLASS_MAGIC * /see TR_CLASS_MAGIC
*/ */
#define TR_IS_OBJECT(obj) \
#define TR_IS_OBJECT(obj) \
((TR_GET_CLASS((obj)))->magic == TR_CLASS_MAGIC) ((TR_GET_CLASS((obj)))->magic == TR_CLASS_MAGIC)
/** /**
@ -204,7 +206,7 @@
* *
* \cond PRIVATE * \cond PRIVATE
*/ */
#define _TR_CALL(_class,_iface,method,...) \
#define _TR_CALL(_class,_iface,method) \
do { \ do { \
TR_class_ptr class = _class; \ TR_class_ptr class = _class; \
iface = (struct i_##_iface *)TR_IFACE_GET(class, &i_##_iface); \ iface = (struct i_##_iface *)TR_IFACE_GET(class, &i_##_iface); \
@ -226,11 +228,11 @@
* \todo actually i use gcc feature ## for variadoc... think about * \todo actually i use gcc feature ## for variadoc... think about
* a way to make this standard. * a way to make this standard.
*/ */
#define TR_CALL(object,_iface,method,...) \
do { \
struct i_##_iface * iface; \
_TR_CALL(TR_GET_CLASS(object), _iface, method, ##__VA_ARGS__); \
iface->method(object, ##__VA_ARGS__); \
#define TR_CALL(object,_iface,method,...) \
do { \
struct i_##_iface * iface; \
_TR_CALL(TR_GET_CLASS(object), _iface, method); \
iface->method(object, ##__VA_ARGS__); \
} while(0) } while(0)
/** /**
@ -240,11 +242,11 @@
* *
* \see TR_CALL * \see TR_CALL
*/ */
#define TR_RETCALL(object,_iface,method,ret,...) \
do { \
struct i_##_iface * iface; \
_TR_CALL(TR_GET_CLASS(object), _iface, method, ##__VA_ARGS__); \
ret = iface->method(object, ##__VA_ARGS__); \
#define TR_RETCALL(object,_iface,method,ret,...) \
do { \
struct i_##_iface * iface; \
_TR_CALL(TR_GET_CLASS(object), _iface, method); \
ret = iface->method(object, ##__VA_ARGS__); \
} while(0) } while(0)
/** /**
@ -253,13 +255,13 @@
* *
* \see TR_CALL * \see TR_CALL
*/ */
#define TR_PARENTCALL(object,_iface,method,...) \
do { \
struct i_##_iface * iface; \
TR_class_ptr pc_class = TR_GET_CLASS((object)); \
assert(TR_HAS_PARENT(pc_class)); \
_TR_CALL(pc_class->parent, _iface, method, ##__VA_ARGS__); \
iface->method(object, ##__VA_ARGS__); \
#define TR_PARENTCALL(object,_iface,method,...) \
do { \
struct i_##_iface * iface; \
TR_class_ptr pc_class = TR_GET_CLASS((object)); \
assert(TR_HAS_PARENT(pc_class)); \
_TR_CALL(pc_class->parent, _iface, method); \
iface->method(object, ##__VA_ARGS__); \
} while(0) } while(0)
/* /*
@ -268,13 +270,13 @@
* *
* \see TR_RETCALL * \see TR_RETCALL
*/ */
#define TR_PARENTRETCALL(object,_iface,method,ret,...) \
do { \
struct i_##_iface * iface; \
TR_class_ptr pc_class = TR_GET_CLASS((object)); \
assert(TR_HAS_PARENT(pc_class)); \
_TR_CALL(pc_class->parent, _iface, method, ##__VA_ARGS__); \
ret = iface->method(object, ##__VA_ARGS__); \
#define TR_PARENTRETCALL(object,_iface,method,ret,...) \
do { \
struct i_##_iface * iface; \
TR_class_ptr pc_class = TR_GET_CLASS((object)); \
assert(TR_HAS_PARENT(pc_class)); \
_TR_CALL(pc_class->parent, _iface, method); \
ret = iface->method(object, ##__VA_ARGS__); \
} while(0) } while(0)

10
include/tr/interface/class.h

@ -71,6 +71,16 @@ void * TR_classNew(TR_class_ptr, ...);
*/ */
void * TR_classNewv(TR_class_ptr, va_list *); void * TR_classNewv(TR_class_ptr, va_list *);
/**
* Interface caller function for i_class::ctor.
* This is called when an instance of a class is created
* with TR_INSTANCE (created on the stack).
* Never called directly.
*
* \see TR_delete
*/
int TR_objectInit(void *, ...);
/** /**
* Interface caller function for i_class::dtor. * Interface caller function for i_class::dtor.
* Never called directly. * Never called directly.

20
src/i_class.c

@ -122,4 +122,24 @@ TR_classClone(void * _object)
} }
/** endcond */ /** endcond */
/**
* Interface caller function for i_class::ctor.
* Call the constructor on an existing object identified by name.
* In fact it calls first the destructor to ensure that all
* possibly previously acquired resource are cleaned.
*/
int
TR_objectInit(void * object, ...)
{
int ret;
va_list params;
va_start(params, object);
TR_CALL(object, TR_Class, dtor);
TR_RETCALL(object, TR_Class, ctor, ret, &params);
va_end(params);
return ret;
}
// vim: set ts=4 sw=4: // vim: set ts=4 sw=4:
Loading…
Cancel
Save