static void EnumGen(Type t) { //TODO: we needn't split out each enum into its own file string gname = CsTypeToG(t); Hdecls.WriteLine("typedef enum"); Hdecls.WriteLine("{"); C.WriteLine("GType " + cur_type + "_get_type (void)", H, ";"); C.WriteLine("{"); C.WriteLine("static GType etype = 0;"); C.WriteLine("if (etype == 0) {"); C.WriteLine("static const GEnumValue values[] = {"); foreach (FieldInfo fi in t.GetFields(BindingFlags.Static | BindingFlags.Public)) { string finame = (cur_type + "_" + CamelToC(fi.Name)).ToUpper(); Hdecls.WriteLine(finame + ","); C.WriteLine("{ " + finame + ", \"" + finame + "\", \"" + CamelToC(fi.Name).Replace("_", "-") + "\" },"); } Hdecls.WriteLine("} " + gname + ";"); Hdecls.WriteLine(); C.WriteLine("{ 0, NULL, NULL }"); C.WriteLine("};"); C.WriteLine("etype = g_enum_register_static (\"" + gname + "\", values);"); C.WriteLine("}"); C.WriteLine("return etype;"); C.WriteLine("}"); }
static void ClassGen(Type t) { //TODO: what flags do we want for GetEvents and GetConstructors? //events as signals EventInfo[] events; events = t.GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); //events as signals MethodInfo[] methods; methods = t.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); Type[] ifaces; ifaces = t.GetInterfaces(); H.WriteLine("G_BEGIN_DECLS"); H.WriteLine(); { string NS = NsToC(ns).ToUpper(); string T = CamelToC(t.Name).ToUpper(); string NST = NS + "_" + T; string NSTT = NS + "_TYPE_" + T; H.WriteLine("#define " + NSTT + " (" + cur_type + "_get_type ())"); H.WriteLine("#define " + NST + "(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), " + NSTT + ", " + CurType + "))"); if (!t.IsInterface) { H.WriteLine("#define " + NST + "_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), " + NSTT + ", " + CurTypeClass + "))"); } H.WriteLine("#define " + NS + "_IS_" + T + "(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), " + NSTT + "))"); if (!t.IsInterface) { H.WriteLine("#define " + NS + "_IS_" + T + "_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), " + NSTT + "))"); } if (t.IsInterface) { H.WriteLine("#define " + NST + "_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), " + NSTT + ", " + CurTypeClass + "))"); } else { H.WriteLine("#define " + NST + "_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), " + NSTT + ", " + CurTypeClass + "))"); } } if (!C.IsDuplicate) { Hdecls.WriteLine("typedef struct _" + CurType + " " + CurType + ";"); Hdecls.WriteLine("typedef struct _" + CurTypeClass + " " + CurTypeClass + ";"); Hdecls.WriteLine(); } H.WriteLine(); string ParentName; string ParentNameClass; if (t.BaseType != null) { ParentName = CsTypeToG(t.BaseType); ParentNameClass = GToGC(ParentName); } else { ParentName = "GType"; if (t.IsInterface) { ParentNameClass = ParentName + "Interface"; } else { ParentNameClass = ParentName + "Class"; } } //H.WriteLine ("typedef struct _" + CurType + " " + CurType + ";"); //H.WriteLine (); //H.WriteLine ("typedef struct _" + CurType + "Class " + CurType + "Class;"); if (!t.IsInterface) { H.WriteLine("typedef struct _" + CurType + "Private " + CurType + "Private;"); H.WriteLine(); H.WriteLine("struct _" + CurType); H.WriteLine("{"); H.WriteLine(ParentName + " parent_instance;"); H.WriteLine(CurType + "Private *priv;"); H.WriteLine("};"); H.WriteLine(); } H.WriteLine("struct _" + CurTypeClass); H.WriteLine("{"); //H.WriteLine (ParentNameClass + " parent_class;"); H.WriteLine(ParentNameClass + " parent;"); if (t.BaseType != null) { H.WriteLine("/* inherits " + t.BaseType.Namespace + " " + t.BaseType.Name + " */"); } if (events.Length != 0) { H.WriteLine(); H.WriteLine("/* signals */"); //FIXME: event arguments foreach (EventInfo ei in events) { H.WriteLine("void (* " + CamelToC(ei.Name) + ") (" + CurType + " *thiz" + ");"); } } if (t.IsInterface) { if (methods.Length != 0) { H.WriteLine(); H.WriteLine("/* vtable */"); //FIXME: method arguments //string funcname = ToValidFuncName (CamelToC (imi.Name)); foreach (MethodInfo mi in methods) { H.WriteLine("void (* " + CamelToC(mi.Name) + ") (" + CurType + " *thiz" + ");"); } } } H.WriteLine("};"); H.WriteLine(); //generate c file //private struct C.WriteLine("struct _" + CurType + "Private"); C.WriteLine("{"); C.WriteLine("MonoObject *mono_object;"); C.WriteLine("};"); C.WriteLine(); //events if (events.Length != 0) { C.WriteLine("enum {"); foreach (EventInfo ei in events) { C.WriteLine(CamelToC(ei.Name).ToUpper() + ","); } C.WriteLine("LAST_SIGNAL"); C.WriteLine("};"); C.WriteLine(); } C.WriteLine("static gpointer parent_class;"); if (events.Length == 0) { C.WriteLine("static guint signals[0];"); } else { C.WriteLine("static guint signals[LAST_SIGNAL] = { 0 };"); } C.WriteLine(); C.WriteLine("static MonoClass *" + cur_type + "_get_mono_class (void)"); C.WriteLine("{"); C.WriteLine("MonoAssembly *assembly;"); C.WriteLine("static MonoClass *class = NULL;"); C.WriteLine("if (class != NULL) return class;"); C.WriteLine("assembly = (MonoAssembly*) " + NsToC(ns) + "_get_mono_assembly ();"); C.WriteLine("class = (MonoClass*) mono_class_from_name ((MonoImage*) mono_assembly_get_image (assembly)" + ", \"" + ns + "\", \"" + t.Name + "\");"); C.WriteLine("mono_class_init (class);"); C.WriteLine(); C.WriteLine("return class;"); C.WriteLine("}"); C.WriteLine(); wrap_gobject = TypeIsGObject(t); //TODO: generate thin wrappers for interfaces //generate constructors ConstructorInfo[] constructors; constructors = t.GetConstructors(); foreach (ConstructorInfo c in constructors) { ConstructorGen(c, t); } //generate static methods //MethodInfo[] methods; methods = t.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly); foreach (MethodInfo m in methods) { MethodGen(m, t); } //generate instance methods methods = t.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); foreach (MethodInfo m in methods) { MethodGen(m, t); } C.WriteLine(); if (t.IsClass) { //generate the GObject init function C.WriteLine("static void " + cur_type + "_init (" + CurType + " *thiz" + ")"); C.WriteLine("{"); C.WriteLine("thiz->priv = g_new0 (" + CurType + "Private, 1);"); C.WriteLine("}"); C.WriteLine(); //generate the GObject class init function C.WriteLine("static void " + cur_type + "_class_init (" + CurTypeClass + " *klass" + ")"); C.WriteLine("{"); C.WriteLine("GObjectClass *object_class = G_OBJECT_CLASS (klass);"); C.WriteLine("parent_class = g_type_class_peek_parent (klass);"); //C.WriteLine ("object_class->finalize = _finalize;"); foreach (EventInfo ei in events) { EventGen(ei, t); } C.WriteLine("}"); C.WriteLine(); } if (ifaces.Length != 0) { foreach (Type iface in ifaces) { if (!IsRegistered(iface)) { continue; } C.WriteLine("static void " + NsToC(iface.Namespace) + "_" + CamelToC(iface.Name) + "_interface_init (" + GToGI(CsTypeToG(iface)) + " *iface" + ")"); C.WriteLine("{"); foreach (MethodInfo imi in iface.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { string funcname = ToValidFuncName(CamelToC(imi.Name)); C.WriteLine("iface->" + funcname + " = " + cur_type + "_" + funcname + ";"); } //TODO: properties etc. C.WriteLine("}"); C.WriteLine(); } } //generate the GObject get_type function C.WriteLine("GType " + cur_type + "_get_type (void)", H, ";"); C.WriteLine("{"); C.WriteLine("static GType object_type = 0;"); C.WriteLine("g_type_init ();"); C.WriteLine(); C.WriteLine("if (object_type) return object_type;"); C.WriteLine(); C.WriteLine("static const GTypeInfo object_info ="); C.WriteLine("{"); C.WriteLine("sizeof (" + CurTypeClass + "),"); C.WriteLine("(GBaseInitFunc) NULL, /* base_init */"); C.WriteLine("(GBaseFinalizeFunc) NULL, /* base_finalize */"); if (t.IsClass) { C.WriteLine("(GClassInitFunc) " + cur_type + "_class_init, /* class_init */"); } else { C.WriteLine("NULL, /* class_init */"); } C.WriteLine("NULL, /* class_finalize */"); C.WriteLine("NULL, /* class_data */"); if (t.IsClass) { C.WriteLine("sizeof (" + CurType + "),"); } else { C.WriteLine("0,"); } C.WriteLine("0, /* n_preallocs */"); if (t.IsClass) { C.WriteLine("(GInstanceInitFunc) " + cur_type + "_init, /* instance_init */"); } else { C.WriteLine("NULL, /* instance_init */"); } C.WriteLine("};"); C.WriteLine(); foreach (Type iface in ifaces) { if (!IsRegistered(iface)) { continue; } C.WriteLine("static const GInterfaceInfo " + CamelToC(iface.Namespace) + "_" + CamelToC(iface.Name) + "_info" + " ="); C.WriteLine("{"); C.WriteLine("(GInterfaceInitFunc) " + NsToC(iface.Namespace) + "_" + CamelToC(iface.Name) + "_interface_init, /* interface_init */"); C.WriteLine("(GInterfaceFinalizeFunc) NULL, /* interface_finalize */"); C.WriteLine("NULL, /* interface_data */"); C.WriteLine("};"); C.WriteLine(); } if (t.BaseType != null) { string parent_type = "G_TYPE_OBJECT"; if (IsRegistered(t.BaseType)) { parent_type = NsToC(t.BaseType.Namespace).ToUpper() + "_TYPE_" + CamelToC(t.BaseType.Name).ToUpper(); } C.WriteLine("object_type = g_type_register_static (" + parent_type + ", \"" + CurType + "\", &object_info, 0);"); } foreach (Type iface in ifaces) { if (!IsRegistered(iface)) { continue; } C.WriteLine("g_type_add_interface_static (object_type, " + NsToC(iface.Namespace).ToUpper() + "_TYPE_" + CamelToC(iface.Name).ToUpper() + ", &" + NsToC(iface.Namespace) + "_" + CamelToC(iface.Name) + "_info" + ");"); } C.WriteLine(); C.WriteLine("return object_type;"); C.WriteLine("}"); H.WriteLine(); H.WriteLine("G_END_DECLS"); }