diff --git a/include/tr/class.h b/include/tr/class.h index 647d2ab..58f4954 100644 --- a/include/tr/class.h +++ b/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 * 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 - * 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) @@ -185,7 +187,7 @@ * * /see TR_CLASS_MAGIC */ -#define TR_IS_OBJECT(obj) \ +#define TR_IS_OBJECT(obj) \ ((TR_GET_CLASS((obj)))->magic == TR_CLASS_MAGIC) /** @@ -204,7 +206,7 @@ * * \cond PRIVATE */ -#define _TR_CALL(_class,_iface,method,...) \ +#define _TR_CALL(_class,_iface,method) \ do { \ TR_class_ptr class = _class; \ iface = (struct i_##_iface *)TR_IFACE_GET(class, &i_##_iface); \ @@ -226,11 +228,11 @@ * \todo actually i use gcc feature ## for variadoc... think about * 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) /** @@ -240,11 +242,11 @@ * * \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) /** @@ -253,13 +255,13 @@ * * \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) /* @@ -268,13 +270,13 @@ * * \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) diff --git a/include/tr/interface/class.h b/include/tr/interface/class.h index 1947553..0a740b7 100644 --- a/include/tr/interface/class.h +++ b/include/tr/interface/class.h @@ -71,6 +71,16 @@ void * TR_classNew(TR_class_ptr, ...); */ 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. * Never called directly. diff --git a/src/i_class.c b/src/i_class.c index bd41f11..b5fb4b0 100644 --- a/src/i_class.c +++ b/src/i_class.c @@ -122,4 +122,24 @@ TR_classClone(void * _object) } /** 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, ¶ms); + va_end(params); + + return ret; +} + // vim: set ts=4 sw=4: