DynamicSignal: Reformat to match conventions

This commit is contained in:
Stephan Sundermann 2014-11-25 11:13:44 +01:00
parent 5b386f21fb
commit db3ffc2a70

View file

@ -29,40 +29,47 @@ using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Collections; using System.Collections;
namespace Gst { namespace Gst
{
delegate void GClosureMarshal (IntPtr closure, ref GLib.Value retval, uint argc, IntPtr argsPtr, delegate void GClosureMarshal (IntPtr closure, ref GLib.Value retval, uint argc, IntPtr argsPtr,
IntPtr invocation_hint, IntPtr data); IntPtr invocation_hint, IntPtr data);
public delegate void SignalHandler (object o, SignalArgs args); public delegate void SignalHandler (object o, SignalArgs args);
public static class DynamicSignal { public static class DynamicSignal
{
private static readonly int gvalue_struct_size = Marshal.SizeOf (typeof (GLib.Value)); private static readonly int gvalue_struct_size = Marshal.SizeOf (typeof(GLib.Value));
class ObjectSignalKey { class ObjectSignalKey
{
object o; object o;
string signal_name; string signal_name;
public ObjectSignalKey (object o, string name) { public ObjectSignalKey (object o, string name)
{
this.o = o; this.o = o;
signal_name = name; signal_name = name;
} }
public override bool Equals (object o) { public override bool Equals (object o)
{
if (o is ObjectSignalKey) { if (o is ObjectSignalKey) {
ObjectSignalKey k = (ObjectSignalKey) o; ObjectSignalKey k = (ObjectSignalKey)o;
return k.o.Equals (this.o) && signal_name.Equals (k.signal_name); return k.o.Equals (this.o) && signal_name.Equals (k.signal_name);
} }
return base.Equals (o); return base.Equals (o);
} }
public override int GetHashCode() { public override int GetHashCode ()
return o.GetHashCode() ^ signal_name.GetHashCode(); {
return o.GetHashCode () ^ signal_name.GetHashCode ();
} }
} }
class SignalInfo { class SignalInfo
{
uint handlerId; uint handlerId;
IntPtr closure; IntPtr closure;
Delegate registeredHandler; Delegate registeredHandler;
@ -71,7 +78,8 @@ namespace Gst {
public IntPtr Closure { public IntPtr Closure {
get { get {
return closure; return closure;
} set { }
set {
closure = value; closure = value;
} }
} }
@ -79,7 +87,8 @@ namespace Gst {
public uint HandlerId { public uint HandlerId {
get { get {
return handlerId; return handlerId;
} set { }
set {
handlerId = value; handlerId = value;
} }
} }
@ -87,7 +96,8 @@ namespace Gst {
public Delegate RegisteredHandler { public Delegate RegisteredHandler {
get { get {
return registeredHandler; return registeredHandler;
} set { }
set {
registeredHandler = value; registeredHandler = value;
} }
} }
@ -95,12 +105,14 @@ namespace Gst {
public Type ArgsType { public Type ArgsType {
get { get {
return argsType; return argsType;
} set { }
set {
argsType = value; argsType = value;
} }
} }
public SignalInfo (uint handlerId, IntPtr closure, Delegate registeredHandler) { public SignalInfo (uint handlerId, IntPtr closure, Delegate registeredHandler)
{
this.handlerId = handlerId; this.handlerId = handlerId;
this.closure = closure; this.closure = closure;
this.registeredHandler = registeredHandler; this.registeredHandler = registeredHandler;
@ -110,17 +122,18 @@ namespace Gst {
MethodInfo mi = registeredHandler.Method; MethodInfo mi = registeredHandler.Method;
ParameterInfo[] parms = mi.GetParameters (); ParameterInfo[] parms = mi.GetParameters ();
this.argsType = parms[1].ParameterType; this.argsType = parms [1].ParameterType;
} }
public void UpdateArgsType (Delegate d) { public void UpdateArgsType (Delegate d)
{
if (!IsCompatibleDelegate (d)) if (!IsCompatibleDelegate (d))
throw new Exception ("Incompatible delegate"); throw new Exception ("Incompatible delegate");
MethodInfo mi = d.Method; MethodInfo mi = d.Method;
ParameterInfo[] parms = mi.GetParameters (); ParameterInfo[] parms = mi.GetParameters ();
Type t1 = parms[1].ParameterType; Type t1 = parms [1].ParameterType;
Type t2 = argsType; Type t2 = argsType;
if (t1 == t2) if (t1 == t2)
@ -134,60 +147,66 @@ namespace Gst {
throw new Exception ("Incompatible delegate"); throw new Exception ("Incompatible delegate");
} }
public bool IsCompatibleDelegate (Delegate d) { public bool IsCompatibleDelegate (Delegate d)
{
if (!IsValidDelegate (d)) if (!IsValidDelegate (d))
return false; return false;
MethodInfo mi = d.Method; MethodInfo mi = d.Method;
ParameterInfo[] parms = mi.GetParameters (); ParameterInfo[] parms = mi.GetParameters ();
if (parms[1].ParameterType != this.argsType && if (parms [1].ParameterType != this.argsType &&
!parms[1].ParameterType.IsSubclassOf (this.argsType) && !parms [1].ParameterType.IsSubclassOf (this.argsType) &&
!this.argsType.IsSubclassOf (parms[1].ParameterType)) !this.argsType.IsSubclassOf (parms [1].ParameterType))
return false; return false;
return true; return true;
} }
public static bool IsValidDelegate (Delegate d) { public static bool IsValidDelegate (Delegate d)
{
MethodInfo mi = d.Method; MethodInfo mi = d.Method;
if (mi.ReturnType != typeof (void)) if (mi.ReturnType != typeof(void))
return false; return false;
ParameterInfo[] parms = mi.GetParameters (); ParameterInfo[] parms = mi.GetParameters ();
if (parms.Length != 2) if (parms.Length != 2)
return false; return false;
if (parms[1].ParameterType != typeof (GLib.SignalArgs) && if (parms [1].ParameterType != typeof(GLib.SignalArgs) &&
!parms[1].ParameterType.IsSubclassOf (typeof (GLib.SignalArgs))) !parms [1].ParameterType.IsSubclassOf (typeof(GLib.SignalArgs)))
return false; return false;
return true; return true;
} }
} }
static Hashtable SignalHandlers = new Hashtable(); static Hashtable SignalHandlers = new Hashtable ();
static GClosureMarshal marshalHandler = new GClosureMarshal (OnMarshal); static GClosureMarshal marshalHandler = new GClosureMarshal (OnMarshal);
public static void Connect (GLib.Object o, string name, SignalHandler handler) { public static void Connect (GLib.Object o, string name, SignalHandler handler)
Connect (o, name, false, (Delegate) handler); {
Connect (o, name, false, (Delegate)handler);
} }
public static void Connect (GLib.Object o, string name, public static void Connect (GLib.Object o, string name,
bool after, SignalHandler handler) { bool after, SignalHandler handler)
Connect (o, name, after, (Delegate) handler); {
Connect (o, name, after, (Delegate)handler);
} }
public static void Connect (GLib.Object o, string name, Delegate handler) { public static void Connect (GLib.Object o, string name, Delegate handler)
{
Connect (o, name, false, handler); Connect (o, name, false, handler);
} }
static int g_closure_sizeof = gstsharp_g_closure_sizeof (); static int g_closure_sizeof = gstsharp_g_closure_sizeof ();
public static void Connect (GLib.Object o, string name, public static void Connect (GLib.Object o, string name,
bool after, Delegate handler) { bool after, Delegate handler)
{
Delegate newHandler; Delegate newHandler;
ObjectSignalKey k = new ObjectSignalKey (o, name); ObjectSignalKey k = new ObjectSignalKey (o, name);
@ -195,8 +214,8 @@ namespace Gst {
if (!SignalInfo.IsValidDelegate (handler)) if (!SignalInfo.IsValidDelegate (handler))
throw new Exception ("Invalid delegate"); throw new Exception ("Invalid delegate");
if (SignalHandlers[k] != null) { if (SignalHandlers [k] != null) {
SignalInfo si = (SignalInfo) SignalHandlers[k]; SignalInfo si = (SignalInfo)SignalHandlers [k];
if (!si.IsCompatibleDelegate (handler)) if (!si.IsCompatibleDelegate (handler))
throw new Exception ("Incompatible delegate"); throw new Exception ("Incompatible delegate");
@ -208,19 +227,20 @@ namespace Gst {
throw new Exception ("Invalid delegate"); throw new Exception ("Invalid delegate");
IntPtr closure = g_closure_new_simple (g_closure_sizeof, IntPtr.Zero); IntPtr closure = g_closure_new_simple (g_closure_sizeof, IntPtr.Zero);
g_closure_set_meta_marshal (closure, (IntPtr) GCHandle.Alloc (k), marshalHandler); g_closure_set_meta_marshal (closure, (IntPtr)GCHandle.Alloc (k), marshalHandler);
uint signalId = g_signal_connect_closure (o.Handle, name, closure, after); uint signalId = g_signal_connect_closure (o.Handle, name, closure, after);
SignalHandlers.Add (k, new SignalInfo (signalId, closure, handler)); SignalHandlers.Add (k, new SignalInfo (signalId, closure, handler));
} }
} }
[DllImport ("libgstreamersharpglue-1.0.0.dll") ] [DllImport ("libgstreamersharpglue-1.0.0.dll")]
static extern int gstsharp_g_closure_sizeof (); static extern int gstsharp_g_closure_sizeof ();
public static void Disconnect (GLib.Object o, string name, Delegate handler) { public static void Disconnect (GLib.Object o, string name, Delegate handler)
{
ObjectSignalKey k = new ObjectSignalKey (o, name); ObjectSignalKey k = new ObjectSignalKey (o, name);
if (SignalHandlers[k] != null) { if (SignalHandlers [k] != null) {
SignalInfo si = (SignalInfo) SignalHandlers[k]; SignalInfo si = (SignalInfo)SignalHandlers [k];
Delegate newHandler = Delegate.Remove (si.RegisteredHandler, handler); Delegate newHandler = Delegate.Remove (si.RegisteredHandler, handler);
if (newHandler == null || handler == null) { if (newHandler == null || handler == null) {
g_signal_handler_disconnect (o.Handle, si.HandlerId); g_signal_handler_disconnect (o.Handle, si.HandlerId);
@ -232,14 +252,15 @@ namespace Gst {
} }
static void OnMarshal (IntPtr closure, ref GLib.Value retval, uint argc, IntPtr argsPtr, static void OnMarshal (IntPtr closure, ref GLib.Value retval, uint argc, IntPtr argsPtr,
IntPtr ihint, IntPtr data) { IntPtr ihint, IntPtr data)
object [] args = new object[argc - 1]; {
object o = ( (GLib.Value) Marshal.PtrToStructure (argsPtr, typeof (GLib.Value))).Val; object[] args = new object[argc - 1];
object o = ((GLib.Value)Marshal.PtrToStructure (argsPtr, typeof(GLib.Value))).Val;
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
IntPtr struct_ptr = (IntPtr) ( (long) argsPtr + (i * gvalue_struct_size)); IntPtr struct_ptr = (IntPtr)((long)argsPtr + (i * gvalue_struct_size));
GLib.Value argument = (GLib.Value) Marshal.PtrToStructure (struct_ptr, typeof (GLib.Value)); GLib.Value argument = (GLib.Value)Marshal.PtrToStructure (struct_ptr, typeof(GLib.Value));
args[i - 1] = argument.Val; args [i - 1] = argument.Val;
} }
if (data == IntPtr.Zero) { if (data == IntPtr.Zero) {
@ -247,12 +268,12 @@ namespace Gst {
return; return;
} }
ObjectSignalKey k = (ObjectSignalKey) ( (GCHandle) data).Target; ObjectSignalKey k = (ObjectSignalKey)((GCHandle)data).Target;
if (k != null) { if (k != null) {
SignalInfo si = (SignalInfo) SignalHandlers[k]; SignalInfo si = (SignalInfo)SignalHandlers [k];
GLib.SignalArgs arg = (GLib.SignalArgs) Activator.CreateInstance (si.ArgsType); GLib.SignalArgs arg = (GLib.SignalArgs)Activator.CreateInstance (si.ArgsType);
arg.Args = args; arg.Args = args;
si.RegisteredHandler.DynamicInvoke (new object[] {o, arg}); si.RegisteredHandler.DynamicInvoke (new object[] { o, arg });
if (arg.RetVal != null) { if (arg.RetVal != null) {
retval.Val = arg.RetVal; retval.Val = arg.RetVal;
} }
@ -260,39 +281,44 @@ namespace Gst {
} }
[DllImport ("libgobject-2.0-0.dll") ] [DllImport ("libgobject-2.0-0.dll")]
static extern IntPtr g_closure_new_simple (int size, IntPtr data); static extern IntPtr g_closure_new_simple (int size, IntPtr data);
[DllImport ("libgobject-2.0-0.dll") ] [DllImport ("libgobject-2.0-0.dll")]
static extern uint g_signal_connect_closure (IntPtr instance, static extern uint g_signal_connect_closure (IntPtr instance,
string name, IntPtr closure, bool after); string name, IntPtr closure, bool after);
[DllImport ("libgobject-2.0-0.dll") ] [DllImport ("libgobject-2.0-0.dll")]
static extern void g_closure_set_meta_marshal (IntPtr closure, IntPtr data, GClosureMarshal marshal); static extern void g_closure_set_meta_marshal (IntPtr closure, IntPtr data, GClosureMarshal marshal);
class GTypeSignalKey { class GTypeSignalKey
{
GType type; GType type;
string signal_name; string signal_name;
public GTypeSignalKey (GType type, string name) { public GTypeSignalKey (GType type, string name)
{
this.type = type; this.type = type;
signal_name = name; signal_name = name;
} }
public override bool Equals (object o) { public override bool Equals (object o)
{
if (o is GTypeSignalKey) { if (o is GTypeSignalKey) {
GTypeSignalKey k = (GTypeSignalKey) o; GTypeSignalKey k = (GTypeSignalKey)o;
return k.type.Equals (this.type) && signal_name.Equals (k.signal_name); return k.type.Equals (this.type) && signal_name.Equals (k.signal_name);
} }
return base.Equals (o); return base.Equals (o);
} }
public override int GetHashCode() { public override int GetHashCode ()
return type.GetHashCode() ^ signal_name.GetHashCode(); {
return type.GetHashCode () ^ signal_name.GetHashCode ();
} }
} }
struct SignalQuery { struct SignalQuery
{
public uint signal_id; public uint signal_id;
public string signal_name; public string signal_name;
public GType itype; public GType itype;
@ -304,7 +330,8 @@ namespace Gst {
static Hashtable SignalEmitInfo = new Hashtable (); static Hashtable SignalEmitInfo = new Hashtable ();
public static object Emit (GLib.Object o, string name, params object[] parameters) { public static object Emit (GLib.Object o, string name, params object[] parameters)
{
SignalQuery query; SignalQuery query;
IntPtr type = gstsharp_g_type_from_instance (o.Handle); IntPtr type = gstsharp_g_type_from_instance (o.Handle);
GType gtype = new GType (type); GType gtype = new GType (type);
@ -324,7 +351,7 @@ namespace Gst {
GTypeSignalKey key = new GTypeSignalKey (gtype, signal_name); GTypeSignalKey key = new GTypeSignalKey (gtype, signal_name);
if (SignalEmitInfo[key] == null) { if (SignalEmitInfo [key] == null) {
IntPtr native_string = GLib.Marshaller.StringToPtrGStrdup (signal_name); IntPtr native_string = GLib.Marshaller.StringToPtrGStrdup (signal_name);
uint signal_id = g_signal_lookup (native_string, type); uint signal_id = g_signal_lookup (native_string, type);
GLib.Marshaller.Free (native_string); GLib.Marshaller.Free (native_string);
@ -351,27 +378,27 @@ namespace Gst {
IntPtr t = Marshal.ReadIntPtr (q.param_types, i); IntPtr t = Marshal.ReadIntPtr (q.param_types, i);
GType g = new GType (t); GType g = new GType (t);
query.param_types[i] = (Type) g; query.param_types [i] = (Type)g;
} }
SignalEmitInfo.Add (key, query); SignalEmitInfo.Add (key, query);
} }
query = (SignalQuery) SignalEmitInfo[key]; query = (SignalQuery)SignalEmitInfo [key];
GLib.Value[] signal_parameters = new GLib.Value[query.n_params + 1]; GLib.Value[] signal_parameters = new GLib.Value[query.n_params + 1];
signal_parameters[0] = new GLib.Value (o); signal_parameters [0] = new GLib.Value (o);
if (parameters.Length != query.n_params) if (parameters.Length != query.n_params)
throw new ApplicationException (String.Format ("Invalid number of parameters: expected {0}, got {1}", query.n_params, parameters.Length)); throw new ApplicationException (String.Format ("Invalid number of parameters: expected {0}, got {1}", query.n_params, parameters.Length));
for (int i = 0; i < query.n_params; i++) { for (int i = 0; i < query.n_params; i++) {
Type expected_type = (Type) query.param_types[i]; Type expected_type = (Type)query.param_types [i];
Type given_type = parameters[i].GetType (); Type given_type = parameters [i].GetType ();
if (expected_type != given_type && ! given_type.IsSubclassOf (given_type)) if (expected_type != given_type && !given_type.IsSubclassOf (given_type))
throw new ApplicationException (String.Format ("Invalid parameter type: expected {0}, got {1}", expected_type, given_type)); throw new ApplicationException (String.Format ("Invalid parameter type: expected {0}, got {1}", expected_type, given_type));
signal_parameters[i + 1] = new GLib.Value (parameters[i]); signal_parameters [i + 1] = new GLib.Value (parameters [i]);
} }
GLib.Value return_value = new GLib.Value (); GLib.Value return_value = new GLib.Value ();
@ -397,23 +424,24 @@ namespace Gst {
return ret; return ret;
} }
[DllImport ("libgstreamersharpglue-1.0.0.dll") ] [DllImport ("libgstreamersharpglue-1.0.0.dll")]
static extern IntPtr gstsharp_g_type_from_instance (IntPtr o); static extern IntPtr gstsharp_g_type_from_instance (IntPtr o);
[DllImport ("libgobject-2.0-0.dll") ] [DllImport ("libgobject-2.0-0.dll")]
static extern int g_signal_handler_disconnect (IntPtr o, uint handler_id); static extern int g_signal_handler_disconnect (IntPtr o, uint handler_id);
[DllImport ("libgobject-2.0-0.dll") ] [DllImport ("libgobject-2.0-0.dll")]
static extern uint g_signal_lookup (IntPtr name, IntPtr itype); static extern uint g_signal_lookup (IntPtr name, IntPtr itype);
[DllImport ("libglib-2.0-0.dll") ] [DllImport ("libglib-2.0-0.dll")]
static extern uint g_quark_from_string (IntPtr str); static extern uint g_quark_from_string (IntPtr str);
[DllImport ("libgobject-2.0-0.dll") ] [DllImport ("libgobject-2.0-0.dll")]
static extern void g_signal_emitv (GLib.Value[] parameters, uint signal_id, uint detail, ref GLib.Value return_value); static extern void g_signal_emitv (GLib.Value[] parameters, uint signal_id, uint detail, ref GLib.Value return_value);
[StructLayout (LayoutKind.Sequential) ] [StructLayout (LayoutKind.Sequential)]
struct GSignalQuery { struct GSignalQuery
{
public uint signal_id; public uint signal_id;
public IntPtr signal_name; public IntPtr signal_name;
public IntPtr itype; public IntPtr itype;
@ -423,7 +451,7 @@ namespace Gst {
public IntPtr param_types; public IntPtr param_types;
} }
[DllImport ("libgobject-2.0-0.dll") ] [DllImport ("libgobject-2.0-0.dll")]
static extern void g_signal_query (uint signal_id, ref GSignalQuery query); static extern void g_signal_query (uint signal_id, ref GSignalQuery query);
} }
} }