1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 2000 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307, USA.
19 #ifndef __G_CLOSURE_H__
20 #define __G_CLOSURE_H__
23 #include <gobject/gtype.h>
28 #endif /* __cplusplus */
33 #define G_CLOSURE_NEEDS_MARSHAL(closure) (((GClosure*) (closure))->marshal == NULL)
34 #define G_CCLOSURE_SWAP_DATA(cclosure) (((GClosure*) (closure))->derivative_flag)
38 typedef struct _GClosure GClosure;
39 typedef struct _GClosureNotifyData GClosureNotifyData;
40 typedef gpointer GCallback;
41 typedef void (*GClosureNotify) (gpointer data,
43 typedef void (*GClosureMarshal) (GClosure *closure,
46 const GValue *param_values,
47 gpointer invocation_hint,
48 gpointer marshal_data);
49 typedef struct _GCClosure GCClosure;
52 /* --- structures --- */
53 struct _GClosureNotifyData
56 GClosureNotify notify;
60 /*< private >*/ guint ref_count : 15;
61 /*< private >*/ guint meta_marshal : 1;
62 /*< private >*/ guint n_guards : 1;
63 /*< private >*/ guint n_fnotifiers : 2; /* finalization notifiers */
64 /*< private >*/ guint n_inotifiers : 8; /* invalidation notifiers */
65 /*< private >*/ guint in_inotify : 1;
66 /*< private >*/ guint floating : 1;
67 /*< protected >*/ guint derivative_flag : 1;
68 /*< puplic >*/ guint in_marshal : 1;
69 /*< public >*/ guint is_invalid : 1;
71 /*< private >*/ void (*marshal) (GClosure *closure,
72 GValue /*out*/ *return_value,
74 const GValue *param_values,
75 gpointer invocation_hint,
76 gpointer marshal_data);
77 /*< protected >*/ gpointer data;
79 /*< private >*/ GClosureNotifyData *notifiers;
81 /* invariants/constrains:
82 * - ->marshal and ->data are _invalid_ as soon as ->is_invalid==TRUE
83 * - invocation of all inotifiers occours prior to fnotifiers
84 * - order of inotifiers is random
85 * inotifiers may _not_ free/invalidate parameter values (e.g. ->data)
86 * - order of fnotifiers is random
87 * - notifiers may only be removed before or during their invocation
88 * - reference counting may only happen prior to fnotify invocation
89 * (in that sense, fnotifiers are really finalization handlers)
92 /* closure for C function calls, callback() is the user function
101 /* --- prototypes --- */
102 GClosure* g_cclosure_new (GCallback callback_func,
104 GClosureNotify destroy_data);
105 GClosure* g_cclosure_new_swap (GCallback callback_func,
107 GClosureNotify destroy_data);
108 GClosure* g_signal_type_closure_new (GType itype,
109 guint struct_offset);
112 /* --- prototypes --- */
113 GClosure* g_closure_ref (GClosure *closure);
114 void g_closure_unref (GClosure *closure);
116 GClosure* g_closure_new_simple (guint sizeof_closure,
118 void g_closure_add_fnotify (GClosure *closure,
119 gpointer notify_data,
120 GClosureNotify notify_func);
121 void g_closure_remove_fnotify (GClosure *closure,
122 gpointer notify_data,
123 GClosureNotify notify_func);
124 void g_closure_add_inotify (GClosure *closure,
125 gpointer notify_data,
126 GClosureNotify notify_func);
127 void g_closure_remove_inotify (GClosure *closure,
128 gpointer notify_data,
129 GClosureNotify notify_func);
130 void g_closure_add_marshal_guards (GClosure *closure,
131 gpointer pre_marshal_data,
132 GClosureNotify pre_marshal_notify,
133 gpointer post_marshal_data,
134 GClosureNotify post_marshal_notify);
135 void g_closure_set_marshal (GClosure *closure,
136 GClosureMarshal marshal);
137 void g_closure_set_meta_marshal (GClosure *closure,
138 gpointer marshal_data,
139 GClosureMarshal meta_marshal);
140 void g_closure_invalidate (GClosure *closure);
141 void g_closure_invoke (GClosure *closure,
142 GValue /*out*/ *return_value,
143 guint n_param_values,
144 const GValue *param_values,
145 gpointer invocation_hint);
149 data_object::destroy -> closure_invalidate();
150 closure_invalidate() -> disconnect(closure);
151 disconnect(closure) -> (unlink) closure_unref();
152 closure_finalize() -> g_free (data_string);
154 1) need GObject and GType in glib
156 3) need to resolve dtor cycles
158 5) destroy on last caller ref or last data ref?
162 - don't mandate signals for GObject
163 - OTOH, don't mandate GObject for GSignal
164 - need marshaller repo with decent aliasing to base types
165 - provide marshaller collection, virtually covering anything out there
166 - at that point, still need GSignalCMarhsaller to g_signal_new() ?
167 - can we combine varargs collect mechanisms with marshaller stubs?
168 for out values (i.e. returntypes), that might get rid of the following
170 - char* return signals with connections ala:
171 connect({ return "static data that can't work"; }),
172 connect({ return g_strdup ("properly duplicated string"); })
173 won't work anymore. CRASH
176 - accumulator needs gboolean to indicate EMISSION_STOP
177 - accumulator needs data
183 #endif /* __cplusplus */
185 #endif /* __G_CLOSURE_H__ */