public Struct grecmutex_type;
public Struct grwlock_type;
public Struct gcond_type;
+ public Class gsource_type;
public TypeSymbol type_module_type;
public TypeSymbol dbus_proxy_type;
gquark_type = new IntegerType ((Struct) glib_ns.scope.lookup ("Quark"));
gvalue_type = (Struct) glib_ns.scope.lookup ("Value");
gvariant_type = (Class) glib_ns.scope.lookup ("Variant");
+ gsource_type = (Class) glib_ns.scope.lookup ("Source");
mutex_type = (Struct) glib_ns.scope.lookup ("StaticRecMutex");
if (context.require_glib_version (2, 32)) {
type_param_index++;
}
}
+ } else if (current_class.base_class == gsource_type) {
+ // g_source_new
+
+ string class_prefix = CCodeBaseModule.get_ccode_lower_case_name (current_class);
+
+ var funcs = new CCodeDeclaration ("const GSourceFuncs");
+ funcs.modifiers = CCodeModifiers.STATIC;
+ funcs.add_declarator (new CCodeVariableDeclarator ("_source_funcs", new CCodeConstant ("{ %s_real_prepare, %s_real_check, %s_real_dispatch, %s_finalize}".printf (class_prefix, class_prefix, class_prefix, class_prefix))));
+ ccode.add_statement (funcs);
+
+ ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_source_funcs")));
+
+ var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
+ csizeof.add_argument (new CCodeIdentifier (get_ccode_name (current_class)));
+ ccall.add_argument (csizeof);
}
} else if (m is CreationMethod && m.parent_symbol is Struct) {
ccall.add_argument (get_this_cexpression ());
// assign new value
store_value (unary.inner.target_value, transform_value (unary.target_value, unary.inner.value_type, arg));
}
+
+ if (m is CreationMethod && m.parent_symbol is Class && current_class.base_class == gsource_type) {
+ var cinitcall = new CCodeFunctionCall (new CCodeIdentifier ("%s_instance_init".printf (get_ccode_lower_case_name (current_class, null))));
+ cinitcall.add_argument (get_this_cexpression ());
+ ccode.add_expression (cinitcall);
+ }
}
private string generate_enum_tostring_function (Enum en) {
bool is_gtypeinstance = !cl.is_compact;
bool is_fundamental = is_gtypeinstance && cl.base_class == null;
+ bool is_gsource = cl.base_class == gsource_type;
if (is_gtypeinstance) {
decl_space.add_type_declaration (new CCodeNewline ());
decl_space.add_type_declaration (new CCodeNewline ());
}
- if (cl.is_compact && cl.base_class != null) {
+ if (cl.is_compact && cl.base_class != null && !is_gsource) {
decl_space.add_type_declaration (new CCodeTypeDefinition (get_ccode_name (cl.base_class), new CCodeVariableDeclarator (get_ccode_name (cl))));
} else {
decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (get_ccode_name (cl)), new CCodeVariableDeclarator (get_ccode_name (cl))));
}
decl_space.add_function_declaration (function);
- } else if (!is_gtypeinstance) {
+ } else if (!is_gtypeinstance && !is_gsource) {
if (cl.base_class == null) {
var function = new CCodeFunction (get_ccode_lower_case_prefix (cl) + "free", "void");
if (cl.access == SymbolAccessibility.PRIVATE) {
bool is_gtypeinstance = !cl.is_compact;
bool is_fundamental = is_gtypeinstance && cl.base_class == null;
+ bool is_gsource = cl.base_class == gsource_type;
var instance_struct = new CCodeStruct ("_%s".printf (get_ccode_name (cl)));
var type_struct = new CCodeStruct ("_%sClass".printf (get_ccode_name (cl)));
}
}
- if (!cl.is_compact || cl.base_class == null) {
+ if (!cl.is_compact || cl.base_class == null || is_gsource) {
// derived compact classes do not have a struct
decl_space.add_type_definition (instance_struct);
}
begin_class_finalize_function (cl);
begin_finalize_function (cl);
} else {
- if (cl.base_class == null) {
+ if (cl.base_class == null || cl.base_class == gsource_type) {
begin_instance_init_function (cl);
begin_finalize_function (cl);
}
cfile.add_function (unref_fun);
}
} else {
- if (cl.base_class == null) {
+ if (cl.base_class == null || cl.base_class == gsource_type) {
// derived compact classes do not have fields
add_instance_init_function (cl);
add_finalize_function (cl);
private void begin_finalize_function (Class cl) {
push_context (instance_finalize_context);
- if (!cl.is_compact) {
+ bool is_gsource = cl.base_class == gsource_type;
+
+ if (!cl.is_compact || is_gsource) {
var fundamental_class = cl;
while (fundamental_class.base_class != null) {
fundamental_class = fundamental_class.base_class;
push_function (func);
- CCodeFunctionCall ccall = generate_instance_cast (new CCodeIdentifier ("obj"), cl);
+ if (is_gsource) {
+ cfile.add_function_declaration (func);
+ }
+
+ CCodeExpression ccast;
+ if (!cl.is_compact) {
+ ccast = generate_instance_cast (new CCodeIdentifier ("obj"), cl);
+ } else {
+ ccast = new CCodeCastExpression (new CCodeIdentifier ("obj"), get_ccode_name (cl) + "*");
+ }
ccode.add_declaration ("%s *".printf (get_ccode_name (cl)), new CCodeVariableDeclarator ("self"));
- ccode.add_assignment (new CCodeIdentifier ("self"), ccall);
+ ccode.add_assignment (new CCodeIdentifier ("self"), ccast);
} else {
var function = new CCodeFunction (get_ccode_lower_case_prefix (cl) + "free", "void");
if (cl.access == SymbolAccessibility.PRIVATE) {
}
cfile.add_function_declaration (instance_finalize_context.ccode);
- } else {
+ } else if (cl.base_class == null) {
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
ccall.add_argument (new CCodeIdentifier (get_ccode_name (cl)));
ccall.add_argument (new CCodeIdentifier ("self"));
}
}
- if (!external && !external_package && base_class != null) {
+ if (!external && !external_package && base_class != null && base_class != context.analyzer.gsource_type) {
foreach (Field f in fields) {
if (f.binding == MemberBinding.INSTANCE) {
error = true;
if (parent_symbol is Class) {
var cl = (Class) parent_symbol;
- if (cl.is_compact) {
+ if (cl.is_compact && cl != context.analyzer.gsource_type) {
Report.error (source_reference, "Virtual methods may not be declared in compact classes");
return false;
}
public DataType list_type;
public DataType tuple_type;
public DataType error_type;
+ public Class gsource_type;
public int next_lambda_id = 0;
gerror_type = (Class) glib_ns.scope.lookup ("Error");
regex_type = new ObjectType ((Class) root_symbol.scope.lookup ("GLib").scope.lookup ("Regex"));
+ gsource_type = (Class) glib_ns.scope.lookup ("Source");
+
current_symbol = root_symbol;
context.root.check (context);
context.accept (this);
[Compact]
[CCode (ref_function = "g_source_ref", unref_function = "g_source_unref")]
- public class Source {
- public Source (SourceFuncs source_funcs, uint struct_size /* = sizeof (Source) */);
+ public abstract class Source {
+ protected Source ();
public void set_funcs (SourceFuncs funcs);
public uint attach (MainContext? context);
public void destroy ();
public static bool remove (uint id);
public static bool remove_by_funcs_user_data (void* user_data);
public static bool remove_by_user_data (void* user_data);
+
+ protected abstract bool prepare (out int timeout_);
+ protected abstract bool check ();
+ protected abstract bool dispatch (SourceFunc _callback);
}
[CCode (has_target = false)]