147 lines
3.7 KiB
C#
147 lines
3.7 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace CPF.Mac.ObjCRuntime
|
|
{
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public class Selector : IEquatable<Selector>
|
|
{
|
|
[MonoNativeFunctionWrapper]
|
|
private delegate int getFrameLengthDelegate(IntPtr @this, IntPtr sel);
|
|
|
|
public static readonly IntPtr Init = GetHandle("init");
|
|
|
|
public static readonly IntPtr InitWithCoder = GetHandle("initWithCoder:");
|
|
|
|
private static IntPtr MethodSignatureForSelector = GetHandle("methodSignatureForSelector:");
|
|
|
|
private static IntPtr FrameLength = GetHandle("frameLength");
|
|
|
|
internal static IntPtr RetainCount = GetHandle("retainCount");
|
|
|
|
internal const string Alloc = "alloc";
|
|
|
|
internal const string Release = "release";
|
|
|
|
internal const string Retain = "retain";
|
|
|
|
internal const string Autorelease = "autorelease";
|
|
|
|
internal const string DoesNotRecognizeSelector = "doesNotRecognizeSelector:";
|
|
|
|
internal const string PerformSelectorOnMainThreadWithObjectWaitUntilDone = "performSelectorOnMainThread:withObject:waitUntilDone:";
|
|
|
|
internal const string PerformSelectorWithObjectAfterDelay = "performSelector:withObject:afterDelay:";
|
|
|
|
internal static IntPtr AllocHandle = GetHandle("alloc");
|
|
|
|
internal static IntPtr ReleaseHandle = GetHandle("release");
|
|
|
|
internal static IntPtr RetainHandle = GetHandle("retain");
|
|
|
|
internal static IntPtr AutoreleaseHandle = GetHandle("autorelease");
|
|
|
|
internal static IntPtr DoesNotRecognizeSelectorHandle = GetHandle("doesNotRecognizeSelector:");
|
|
|
|
internal static IntPtr PerformSelectorOnMainThreadWithObjectWaitUntilDoneHandle = GetHandle("performSelectorOnMainThread:withObject:waitUntilDone:");
|
|
|
|
internal static IntPtr PerformSelectorWithObjectAfterDelayHandle = GetHandle("performSelector:withObject:afterDelay:");
|
|
|
|
internal IntPtr handle;
|
|
|
|
public IntPtr Handle => handle;
|
|
|
|
public string Name => Messaging.StringFromNativeUtf8(sel_getName(handle));
|
|
|
|
public Selector(IntPtr sel)
|
|
: this(sel, check: true)
|
|
{
|
|
}
|
|
|
|
internal Selector(IntPtr sel, bool check)
|
|
{
|
|
if (check && !sel_isMapped(sel))
|
|
{
|
|
throw new ArgumentException("sel is not a selector handle.");
|
|
}
|
|
handle = sel;
|
|
}
|
|
|
|
public Selector(string name, bool alloc)
|
|
{
|
|
handle = GetHandle(name);
|
|
}
|
|
|
|
public Selector(string name)
|
|
: this(name, alloc: false)
|
|
{
|
|
}
|
|
|
|
[MonoPInvokeCallback(typeof(getFrameLengthDelegate))]
|
|
public static int GetFrameLength(IntPtr @this, IntPtr sel)
|
|
{
|
|
return Messaging.int_objc_msgSend(Messaging.IntPtr_objc_msgSend_IntPtr(@this, MethodSignatureForSelector, sel), FrameLength);
|
|
}
|
|
|
|
public static Selector Register(IntPtr handle)
|
|
{
|
|
return new Selector(handle);
|
|
}
|
|
|
|
public static bool operator !=(Selector left, Selector right)
|
|
{
|
|
return !(left == right);
|
|
}
|
|
|
|
public static bool operator ==(Selector left, Selector right)
|
|
{
|
|
if ((object)left == null)
|
|
{
|
|
return (object)right == null;
|
|
}
|
|
if ((object)right == null)
|
|
{
|
|
return false;
|
|
}
|
|
return left.handle == right.handle;
|
|
}
|
|
|
|
public override bool Equals(object right)
|
|
{
|
|
return Equals(right as Selector);
|
|
}
|
|
|
|
public bool Equals(Selector right)
|
|
{
|
|
if (right == null)
|
|
{
|
|
return false;
|
|
}
|
|
return handle == right.handle;
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return (int)handle;
|
|
}
|
|
|
|
public static Selector FromHandle(IntPtr sel)
|
|
{
|
|
if (!sel_isMapped(sel))
|
|
{
|
|
return null;
|
|
}
|
|
return new Selector(sel, check: false);
|
|
}
|
|
|
|
[DllImport("/usr/lib/libobjc.dylib")]
|
|
private static extern IntPtr sel_getName(IntPtr sel);
|
|
|
|
[DllImport("/usr/lib/libobjc.dylib", EntryPoint = "sel_registerName")]
|
|
public static extern IntPtr GetHandle(string name);
|
|
|
|
[DllImport("/usr/lib/libobjc.dylib")]
|
|
private static extern bool sel_isMapped(IntPtr sel);
|
|
}
|
|
}
|