internal unsafe static void RegisterMethod (MethodInfo minfo, ExportAttribute ea, Type type, IntPtr handle) { NativeMethodBuilder builder = new NativeMethodBuilder (minfo, type, ea); class_addMethod (minfo.IsStatic ? ((objc_class *) handle)->isa : handle, builder.Selector, builder.Delegate, builder.Signature); method_wrappers.Add (builder.Delegate); #if DEBUG Console.WriteLine ("[METHOD] Registering {0}[0x{1:x}|{2}] on {3} -> ({4})", ea.Selector, (int) builder.Selector, builder.Signature, type, minfo); #endif }
internal unsafe static IntPtr Register (Type type, string name) { IntPtr parent = IntPtr.Zero; IntPtr handle = IntPtr.Zero; objc_class *k; handle = objc_getClass (name); if (handle != IntPtr.Zero) { if (!type_map.ContainsKey (handle)) { type_map [handle] = type; } return handle; } Type parent_type = type.BaseType; string parent_name = null; while (Attribute.IsDefined (parent_type, typeof (ModelAttribute), false)) parent_type = parent_type.BaseType; RegisterAttribute parent_attr = (RegisterAttribute) Attribute.GetCustomAttribute (parent_type, typeof (RegisterAttribute), false); parent_name = parent_attr == null ? parent_type.FullName : parent_attr.Name ?? parent_type.FullName; parent = objc_getClass (parent_name); if (parent == IntPtr.Zero && parent_type.Assembly != NSObject.MonoMacAssembly) { // Its possible as we scan that we might be derived from a type that isn't reigstered yet. Class.Register (parent_type, parent_name); parent = objc_getClass (parent_name); } if (parent == IntPtr.Zero) { // This spams mtouch, we need a way to differentiate from mtouch's (ab)use // Console.WriteLine ("CRITICAL WARNING: Falling back to NSObject for type {0} reported as {1}", type, parent_type); parent = objc_getClass ("NSObject"); } handle = objc_allocateClassPair (parent, name, IntPtr.Zero); k = (objc_class *) handle; class_addIvar (handle, "__monoObjectGCHandle", (IntPtr) Marshal.SizeOf (typeof (Int32)), (ushort) 4, "i"); foreach (PropertyInfo prop in type.GetProperties (BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { ConnectAttribute cattr = (ConnectAttribute) Attribute.GetCustomAttribute (prop, typeof (ConnectAttribute)); if (cattr != null) { string ivar_name = cattr.Name ?? prop.Name; class_addIvar (handle, ivar_name, (IntPtr) Marshal.SizeOf (typeof (IntPtr)), (ushort) Math.Log (Marshal.SizeOf (typeof (IntPtr)), 2), "@"); } } #if OBJECT_REF_TRACKING class_addMethod (handle, release_builder.Selector, release_builder.Delegate, release_builder.Signature); class_addMethod (handle, retain_builder.Selector, retain_builder.Delegate, retain_builder.Signature); #endif foreach (MethodInfo minfo in type.GetMethods (BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { ExportAttribute ea = (ExportAttribute) Attribute.GetCustomAttribute (minfo.GetBaseDefinition (), typeof (ExportAttribute)); if (ea == null || (minfo.IsVirtual && minfo.DeclaringType != type && minfo.DeclaringType.Assembly == NSObject.MonoMacAssembly)) continue; NativeMethodBuilder builder = new NativeMethodBuilder (minfo); class_addMethod (minfo.IsStatic ? k->isa : handle, builder.Selector, builder.Delegate, builder.Signature); method_wrappers.Add (builder.Delegate); #if DEBUG Console.WriteLine ("[METHOD] Registering {0}[0x{1:x}|{2}] on {3} -> ({4})", ea.Selector, (int) builder.Selector, builder.Signature, type, minfo); #endif } ConstructorInfo default_ctor = type.GetConstructor (Type.EmptyTypes); if (default_ctor != null) { NativeConstructorBuilder builder = new NativeConstructorBuilder (default_ctor); class_addMethod (handle, builder.Selector, builder.Delegate, builder.Signature); method_wrappers.Add (builder.Delegate); #if DEBUG Console.WriteLine ("[CTOR] Registering {0}[0x{1:x}|{2}] on {3} -> ({4})", "init", (int) builder.Selector, builder.Signature, type, default_ctor); #endif } foreach (ConstructorInfo cinfo in type.GetConstructors (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) { ExportAttribute ea = (ExportAttribute) Attribute.GetCustomAttribute (cinfo, typeof (ExportAttribute)); if (ea == null) continue; NativeConstructorBuilder builder = new NativeConstructorBuilder (cinfo); class_addMethod (handle, builder.Selector, builder.Delegate, builder.Signature); method_wrappers.Add (builder.Delegate); #if DEBUG Console.WriteLine ("[CTOR] Registering {0}[0x{1:x}|{2}] on {3} -> ({4})", ea.Selector, (int) builder.Selector, builder.Signature, type, cinfo); #endif } objc_registerClassPair (handle); type_map [handle] = type; return handle; }