1
#define __NR_OBJECT_C__
4
* RGBA display list system for inkscape
7
* Lauris Kaplinski <lauris@kaplinski.com>
8
* MenTaLguY <mental@rydia.net>
10
* This code is in public domain
16
#include <libnr/nr-macros.h>
18
#include "nr-object.h"
20
unsigned int nr_emit_fail_warning(const gchar *file, unsigned int line, const gchar *method, const gchar *expr)
22
fprintf (stderr, "File %s line %d (%s): Assertion %s failed\n", file, line, method, expr);
28
static NRObjectClass **classes = NULL;
29
static unsigned int classes_len = 0;
30
static unsigned int classes_size = 0;
32
NRType nr_type_is_a(NRType type, NRType test)
34
nr_return_val_if_fail(type < classes_len, FALSE);
35
nr_return_val_if_fail(test < classes_len, FALSE);
37
NRObjectClass *c = classes[type];
40
if (c->type == test) {
49
void const *nr_object_check_instance_cast(void const *ip, NRType tc)
51
nr_return_val_if_fail(ip != NULL, NULL);
52
nr_return_val_if_fail(nr_type_is_a(((NRObject const *) ip)->klass->type, tc), ip);
56
unsigned int nr_object_check_instance_type(void const *ip, NRType tc)
62
return nr_type_is_a(((NRObject const *) ip)->klass->type, tc);
65
NRType nr_object_register_type(NRType parent,
69
void (* cinit) (NRObjectClass *),
70
void (* iinit) (NRObject *))
72
if (classes_len >= classes_size) {
74
classes = nr_renew (classes, NRObjectClass *, classes_size);
75
if (classes_len == 0) {
81
NRType const type = classes_len;
84
classes[type] = (NRObjectClass*) new char[csize];
85
NRObjectClass *c = classes[type];
87
/* FIXME: is this necessary? */
90
if (classes[parent]) {
91
memcpy(c, classes[parent], classes[parent]->csize);
95
c->parent = classes[parent];
96
c->name = strdup(name);
107
static void nr_object_class_init (NRObjectClass *klass);
108
static void nr_object_init (NRObject *object);
109
static void nr_object_finalize (NRObject *object);
111
NRType nr_object_get_type()
113
static NRType type = 0;
116
type = nr_object_register_type (0,
118
sizeof (NRObjectClass),
120
(void (*) (NRObjectClass *)) nr_object_class_init,
121
(void (*) (NRObject *)) nr_object_init);
127
static void nr_object_class_init(NRObjectClass *c)
129
c->finalize = nr_object_finalize;
130
c->cpp_ctor = NRObject::invoke_ctor<NRObject>;
133
static void nr_object_init (NRObject *object)
137
static void nr_object_finalize (NRObject *object)
141
/* Dynamic lifecycle */
143
static void nr_class_tree_object_invoke_init(NRObjectClass *c, NRObject *object)
146
nr_class_tree_object_invoke_init(c->parent, object);
153
void finalize_object(void *base, void *)
155
NRObject *object = reinterpret_cast<NRObject *>(base);
156
object->klass->finalize(object);
162
NRObject *NRObject::alloc(NRType type)
164
nr_return_val_if_fail (type < classes_len, NULL);
166
NRObjectClass *c = classes[type];
168
if ( c->parent && c->cpp_ctor == c->parent->cpp_ctor ) {
169
g_error("Cannot instantiate NRObject class %s which has not registered a C++ constructor\n", c->name);
172
NRObject *object = reinterpret_cast<NRObject *>(
173
::operator new(c->isize, Inkscape::GC::SCANNED, Inkscape::GC::AUTO,
174
&finalize_object, NULL)
176
memset(object, 0xf0, c->isize);
180
nr_class_tree_object_invoke_init (c, object);
187
static void nr_active_object_class_init(NRActiveObjectClass *c);
188
static void nr_active_object_init(NRActiveObject *object);
189
static void nr_active_object_finalize(NRObject *object);
191
static NRObjectClass *parent_class;
193
NRType nr_active_object_get_type()
195
static NRType type = 0;
197
type = nr_object_register_type (NR_TYPE_OBJECT,
199
sizeof (NRActiveObjectClass),
200
sizeof (NRActiveObject),
201
(void (*) (NRObjectClass *)) nr_active_object_class_init,
202
(void (*) (NRObject *)) nr_active_object_init);
207
static void nr_active_object_class_init(NRActiveObjectClass *c)
209
NRObjectClass *object_class = (NRObjectClass *) c;
211
parent_class = object_class->parent;
213
object_class->finalize = nr_active_object_finalize;
214
object_class->cpp_ctor = NRObject::invoke_ctor<NRActiveObject>;
217
static void nr_active_object_init(NRActiveObject *object)
221
static void nr_active_object_finalize(NRObject *object)
223
NRActiveObject *aobject = (NRActiveObject *) object;
225
if (aobject->callbacks) {
226
for (unsigned int i = 0; i < aobject->callbacks->length; i++) {
227
NRObjectListener *listener = aobject->callbacks->listeners + i;
228
if ( listener->vector->dispose ) {
229
listener->vector->dispose(object, listener->data);
232
free (aobject->callbacks);
235
((NRObjectClass *) (parent_class))->finalize(object);
238
void nr_active_object_add_listener(NRActiveObject *object,
239
const NRObjectEventVector *vector,
243
if (!object->callbacks) {
244
object->callbacks = (NRObjectCallbackBlock*) malloc(sizeof(NRObjectCallbackBlock));
245
object->callbacks->size = 1;
246
object->callbacks->length = 0;
249
if (object->callbacks->length >= object->callbacks->size) {
250
int newsize = object->callbacks->size << 1;
251
object->callbacks = (NRObjectCallbackBlock *)
252
realloc(object->callbacks, sizeof(NRObjectCallbackBlock) + (newsize - 1) * sizeof (NRObjectListener));
253
object->callbacks->size = newsize;
256
NRObjectListener *listener = object->callbacks->listeners + object->callbacks->length;
257
listener->vector = vector;
258
listener->size = size;
259
listener->data = data;
260
object->callbacks->length += 1;
263
void nr_active_object_remove_listener_by_data(NRActiveObject *object, void *data)
265
if (object->callbacks == NULL) {
269
for (unsigned i = 0; i < object->callbacks->length; i++) {
270
NRObjectListener *listener = object->callbacks->listeners + i;
271
if ( listener->data == data ) {
272
object->callbacks->length -= 1;
273
if ( object->callbacks->length < 1 ) {
274
free(object->callbacks);
275
object->callbacks = NULL;
276
} else if ( object->callbacks->length != i ) {
277
*listener = object->callbacks->listeners[object->callbacks->length];
289
c-file-style:"stroustrup"
290
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
295
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :