summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--elementgen/elementgen.cs12
-rw-r--r--gstreamer-sharp/BindingHelper.cs50
-rw-r--r--gstreamer-sharp/DynamicSignal.cs108
-rw-r--r--gstreamer-sharp/Makefile.am1
-rw-r--r--gstreamer-sharp/Object.custom12
-rw-r--r--gstreamer-sharp/baseplugins/playbin.custom10
-rw-r--r--samples/DecodeBinTranscoder.cs13
-rw-r--r--samples/PlayBinPlayer.cs4
-rw-r--r--samples/TypeFind.cs14
9 files changed, 126 insertions, 98 deletions
diff --git a/elementgen/elementgen.cs b/elementgen/elementgen.cs
index d3e6139..c2e207b 100644
--- a/elementgen/elementgen.cs
+++ b/elementgen/elementgen.cs
@@ -255,7 +255,7 @@ public class ElementGen {
string class_name = (ei.class_name != null) ? ei.class_name : ei.gtype_name.StartsWith ("Gst") ? ei.gtype_name.Substring (3) : ei.gtype_name;
- writer.Write ("\tpublic class " + class_name + " : ");
+ writer.Write ("\tpublic sealed class " + class_name + " : ");
for (int i = 1; i < ei.hierarchy.Count; i++) {
string parent_type = (string) ei.hierarchy[i];
string parent_managed_type = CTypeToManagedType (parent_type, api_doc);
@@ -349,19 +349,13 @@ public class ElementGen {
}
writer.WriteLine ("\t\t}\n");
- writer.WriteLine ("\t\tprivate Delegate " + managed_name + "_delegate;\n");
-
- writer.WriteLine ("\t\tprotected virtual void On" + managed_name + " (object o, GLib.SignalArgs args) {");
- writer.WriteLine ("\t\t\tBindingHelper.InvokeProxySignalDelegate (" + managed_name + "_delegate, typeof (" + managed_name + "Args), o, args);");
- writer.WriteLine ("\t\t}\n");
-
writer.WriteLine ("\t\tpublic event " + managed_name + "Handler " + managed_name + " {");
writer.WriteLine ("\t\t\tadd {");
- writer.WriteLine ("\t\t\t\t" + managed_name + "_delegate = BindingHelper.AddProxySignalDelegate (this, \"" + si.name + "\", On" + managed_name + ", " + managed_name + "_delegate, value);");
+ writer.WriteLine ("\t\t\t\tDynamicSignal.Connect (this, \"" + si.name + "\", value);");
writer.WriteLine ("\t\t\t}\n");
writer.WriteLine ("\t\t\tremove {");
- writer.WriteLine ("\t\t\t\t" + managed_name + "_delegate = BindingHelper.RemoveProxySignalDelegate (this, \"" + si.name + "\", On" + managed_name + ", " + managed_name + "_delegate, value);");
+ writer.WriteLine ("\t\t\t\tDynamicSignal.Disconnect (this, \"" + si.name + "\", value);");
writer.WriteLine ("\t\t\t}");
writer.WriteLine ("\t\t}");
}
diff --git a/gstreamer-sharp/BindingHelper.cs b/gstreamer-sharp/BindingHelper.cs
deleted file mode 100644
index dc4b544..0000000
--- a/gstreamer-sharp/BindingHelper.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// BindingHelper.cs: Utility methods to make creating
-// element bindings by hand an easier task
-//
-// Authors:
-// Aaron Bockover (abockover@novell.com)
-//
-// Copyright (C) 2006 Novell, Inc.
-//
-
-using System;
-using GLib;
-
-namespace Gst {
- public static class BindingHelper {
- public static Delegate AddProxySignalDelegate (GLib.Object o, string signal,
- DynamicSignalHandler baseHandler, Delegate existingHandler, Delegate addHandler) {
- if (existingHandler == null) {
- DynamicSignal.Connect (o, signal, baseHandler);
- }
-
- return Delegate.Combine (existingHandler, addHandler);
- }
-
- public static Delegate RemoveProxySignalDelegate (GLib.Object o, string signal,
- DynamicSignalHandler baseHandler, Delegate existingHandler, Delegate removeHandler) {
- Delegate temp_delegate = Delegate.Remove (existingHandler, removeHandler);
- if (temp_delegate == null) {
- DynamicSignal.Disconnect (o, signal, baseHandler);
- }
-
- return temp_delegate;
- }
-
- public static void InvokeProxySignalDelegate (Delegate raiseDelegate, Type type,
- object o, GLib.SignalArgs args) {
- if (!type.IsSubclassOf (typeof (GLib.SignalArgs))) {
- throw new ArgumentException ("Args type must derive SignalArgs");
- }
-
- if (raiseDelegate != null) {
- GLib.SignalArgs new_args = (GLib.SignalArgs) Activator.CreateInstance (type);
- new_args.RetVal = args.RetVal;
- new_args.Args = args.Args;
-
- raiseDelegate.DynamicInvoke (new object [] { o, new_args });
- }
- }
- }
-}
diff --git a/gstreamer-sharp/DynamicSignal.cs b/gstreamer-sharp/DynamicSignal.cs
index 1acd2a0..4e82cee 100644
--- a/gstreamer-sharp/DynamicSignal.cs
+++ b/gstreamer-sharp/DynamicSignal.cs
@@ -10,16 +10,17 @@
using GLib;
using System;
+using System.Reflection;
using System.Runtime.InteropServices;
using System.Collections;
namespace Gst {
- public delegate void DynamicSignalHandler (object o, SignalArgs args);
-
delegate void GClosureMarshal (IntPtr closure, ref GLib.Value retval, uint argc, IntPtr argsPtr,
IntPtr invocation_hint, IntPtr data);
+ public delegate void SignalHandler (object o, SignalArgs args);
+
public static class DynamicSignal {
private static readonly int gvalue_struct_size = Marshal.SizeOf (typeof (GLib.Value));
@@ -50,6 +51,7 @@ namespace Gst {
uint handlerId;
IntPtr closure;
Delegate registeredHandler;
+ Type argsType;
public IntPtr Closure {
get {
@@ -78,10 +80,79 @@ namespace Gst {
}
}
+ public Type ArgsType {
+ get {
+ return argsType;
+ }
+ set {
+ argsType = value;
+ }
+ }
+
public SignalInfo (uint handlerId, IntPtr closure, Delegate registeredHandler) {
this.handlerId = handlerId;
this.closure = closure;
this.registeredHandler = registeredHandler;
+
+ if (!IsValidDelegate (registeredHandler))
+ throw new Exception ("Invalid delegate");
+
+ MethodInfo mi = registeredHandler.Method;
+ ParameterInfo[] parms = mi.GetParameters ();
+ this.argsType = parms[1].ParameterType;
+ }
+
+ public void UpdateArgsType (Delegate d) {
+ if (!IsCompatibleDelegate (d))
+ throw new Exception ("Incompatible delegate");
+
+ MethodInfo mi = d.Method;
+ ParameterInfo[] parms = mi.GetParameters ();
+
+ Type t1 = parms[1].ParameterType;
+ Type t2 = argsType;
+
+ if (t1 == t2)
+ return;
+
+ if (t1.IsSubclassOf (t2))
+ argsType = t1;
+ else if (t2.IsSubclassOf (t1))
+ argsType = t2;
+ else
+ throw new Exception ("Incompatible delegate");
+ }
+
+ public bool IsCompatibleDelegate (Delegate d) {
+ if (!IsValidDelegate (d))
+ return false;
+
+ MethodInfo mi = d.Method;
+ ParameterInfo[] parms = mi.GetParameters ();
+
+ if (parms[1].ParameterType != this.argsType &&
+ !parms[1].ParameterType.IsSubclassOf (this.argsType) &&
+ !this.argsType.IsSubclassOf (parms[1].ParameterType))
+ return false;
+
+ return true;
+ }
+
+ public static bool IsValidDelegate (Delegate d) {
+ MethodInfo mi = d.Method;
+
+ if (mi.ReturnType != typeof (void))
+ return false;
+
+ ParameterInfo[] parms = mi.GetParameters ();
+ if (parms.Length != 2)
+ return false;
+
+ if (parms[1].ParameterType != typeof (GLib.SignalArgs) &&
+ !parms[1].ParameterType.IsSubclassOf (typeof (GLib.SignalArgs)))
+ return false;
+
+ return true;
}
}
@@ -89,23 +160,42 @@ namespace Gst {
static GClosureMarshal marshalHandler = new GClosureMarshal (OnMarshal);
- public static void Connect (GLib.Object o, string name, DynamicSignalHandler handler) {
+ public static void Connect (GLib.Object o, string name, SignalHandler handler) {
+ Connect (o, name, false, (Delegate) handler);
+ }
+
+ public static void Connect (GLib.Object o, string name,
+ bool after, SignalHandler handler) {
+ Connect (o, name, after, (Delegate) handler);
+ }
+
+ public static void Connect (GLib.Object o, string name, Delegate handler) {
Connect (o, name, false, handler);
}
static int g_closure_sizeof = gstsharp_g_closure_sizeof ();
public static void Connect (GLib.Object o, string name,
- bool after, DynamicSignalHandler handler) {
+ bool after, Delegate handler) {
Delegate newHandler;
ObjectSignalKey k = new ObjectSignalKey (o, name);
+ if (!SignalInfo.IsValidDelegate (handler))
+ throw new Exception ("Invalid delegate");
+
if (SignalHandlers[k] != null) {
SignalInfo si = (SignalInfo) SignalHandlers[k];
+ if (!si.IsCompatibleDelegate (handler))
+ throw new Exception ("Incompatible delegate");
+
newHandler = Delegate.Combine (si.RegisteredHandler, handler);
+ si.UpdateArgsType (handler);
si.RegisteredHandler = newHandler;
} else {
+ if (!SignalInfo.IsValidDelegate (handler))
+ throw new Exception ("Invalid delegate");
+
IntPtr closure = g_closure_new_simple (g_closure_sizeof, IntPtr.Zero);
g_closure_set_meta_marshal (closure, (IntPtr) GCHandle.Alloc (k), marshalHandler);
uint signalId = g_signal_connect_closure (o.Handle, name, closure, after);
@@ -116,7 +206,7 @@ namespace Gst {
[DllImport ("gstreamersharpglue-0.10.dll") ]
static extern int gstsharp_g_closure_sizeof ();
- public static void Disconnect (GLib.Object o, string name, DynamicSignalHandler handler) {
+ public static void Disconnect (GLib.Object o, string name, Delegate handler) {
ObjectSignalKey k = new ObjectSignalKey (o, name);
if (SignalHandlers[k] != null) {
SignalInfo si = (SignalInfo) SignalHandlers[k];
@@ -143,15 +233,15 @@ namespace Gst {
if (data == IntPtr.Zero) {
Console.Error.WriteLine ("No available data");
+ return;
}
ObjectSignalKey k = (ObjectSignalKey) ( (GCHandle) data).Target;
if (k != null) {
- SignalArgs arg = new SignalArgs();
- arg.Args = args;
SignalInfo si = (SignalInfo) SignalHandlers[k];
- DynamicSignalHandler handler = (DynamicSignalHandler) si.RegisteredHandler;
- handler (o, arg);
+ GLib.SignalArgs arg = (GLib.SignalArgs) Activator.CreateInstance (si.ArgsType);
+ arg.Args = args;
+ si.RegisteredHandler.DynamicInvoke (new object[] {o, arg});
if (arg.RetVal != null) {
retval.Val = arg.RetVal;
}
diff --git a/gstreamer-sharp/Makefile.am b/gstreamer-sharp/Makefile.am
index d43b1b0..9a978a1 100644
--- a/gstreamer-sharp/Makefile.am
+++ b/gstreamer-sharp/Makefile.am
@@ -38,7 +38,6 @@ clean-local:
sources = \
DynamicSignal.cs \
- BindingHelper.cs \
Application.cs \
Version.cs \
AssemblyInfo.cs \
diff --git a/gstreamer-sharp/Object.custom b/gstreamer-sharp/Object.custom
index 6af7057..afc2763 100644
--- a/gstreamer-sharp/Object.custom
+++ b/gstreamer-sharp/Object.custom
@@ -49,11 +49,19 @@ public PropertyInfo[] Properties {
}
}
-public void Connect (string signal, DynamicSignalHandler handler) {
+public void Connect (string signal, SignalHandler handler) {
DynamicSignal.Connect (this, signal, handler);
}
-public void Disconnect (string signal, DynamicSignalHandler handler) {
+public void Disconnect (string signal, SignalHandler handler) {
+ DynamicSignal.Disconnect (this, signal, handler);
+}
+
+public void Connect (string signal, Delegate handler) {
+ DynamicSignal.Connect (this, signal, handler);
+}
+
+public void Disconnect (string signal, Delegate handler) {
DynamicSignal.Disconnect (this, signal, handler);
}
diff --git a/gstreamer-sharp/baseplugins/playbin.custom b/gstreamer-sharp/baseplugins/playbin.custom
index 073e043..b212821 100644
--- a/gstreamer-sharp/baseplugins/playbin.custom
+++ b/gstreamer-sharp/baseplugins/playbin.custom
@@ -103,19 +103,13 @@ public class StreamInfo : GLib.Object {
}
- private Delegate Muted_delegate;
-
- protected virtual void OnMuted (object o, GLib.SignalArgs args) {
- BindingHelper.InvokeProxySignalDelegate (Muted_delegate, typeof (MutedArgs), o, args);
- }
-
public event MutedHandler Muted {
add {
- Muted_delegate = BindingHelper.AddProxySignalDelegate (this, "muted", OnMuted, Muted_delegate, value);
+ DynamicSignal.Connect (this, "muted", value);
}
remove {
- Muted_delegate = BindingHelper.RemoveProxySignalDelegate (this, "muted", OnMuted, Muted_delegate, value);
+ DynamicSignal.Disconnect (this, "muted", value);
}
}
diff --git a/samples/DecodeBinTranscoder.cs b/samples/DecodeBinTranscoder.cs
index e9757c6..414cb36 100644
--- a/samples/DecodeBinTranscoder.cs
+++ b/samples/DecodeBinTranscoder.cs
@@ -9,6 +9,7 @@
using System;
using Gst;
+using Gst.CorePlugins;
using Gst.BasePlugins;
public delegate void ErrorHandler(object o, ErrorArgs args);
@@ -28,8 +29,8 @@ public class ProgressArgs : EventArgs
public class DecodeBinTranscoder : IDisposable
{
private Pipeline pipeline;
- private Element filesrc;
- private Element filesink;
+ private FileSrc filesrc;
+ private FileSink filesink;
private Element audioconvert;
private Element encoder;
private DecodeBin decodebin;
@@ -47,8 +48,8 @@ public class DecodeBinTranscoder : IDisposable
public void Transcode(string inputFile, string outputFile)
{
- filesrc["location"] = inputFile;
- filesink["location"] = outputFile;
+ filesrc.Location = inputFile;
+ filesink.Location = outputFile;
pipeline.SetState(State.Playing);
progress_timeout = GLib.Timeout.Add(250, OnProgressTimeout);
@@ -92,8 +93,8 @@ public class DecodeBinTranscoder : IDisposable
{
pipeline = new Pipeline("pipeline");
- filesrc = ElementFactory.Make("filesrc", "filesrc");
- filesink = ElementFactory.Make("filesink", "filesink");
+ filesrc = ElementFactory.Make("filesrc", "filesrc") as FileSrc;
+ filesink = ElementFactory.Make("filesink", "filesink") as FileSink;
audioconvert = ElementFactory.Make("audioconvert", "audioconvert");
encoder = ElementFactory.Make("wavenc", "wavenc");
decodebin = ElementFactory.Make("decodebin", "decodebin") as DecodeBin;
diff --git a/samples/PlayBinPlayer.cs b/samples/PlayBinPlayer.cs
index daff707..88110f4 100644
--- a/samples/PlayBinPlayer.cs
+++ b/samples/PlayBinPlayer.cs
@@ -1,12 +1,8 @@
-
using System;
-
using GLib;
-
using Gst;
using Gst.BasePlugins;
-
public class PlayBinPlayer
{
private static MainLoop loop;
diff --git a/samples/TypeFind.cs b/samples/TypeFind.cs
index 8915fe2..af34678 100644
--- a/samples/TypeFind.cs
+++ b/samples/TypeFind.cs
@@ -11,11 +11,11 @@ public static class GstTypefindTest
Application.Init();
Pipeline pipeline = new Pipeline("pipeline");
- Element source = ElementFactory.Make("filesrc", "source");
+ FileSrc source = FileSrc.Make("source");
typefind = TypeFindElement.Make("typefind");
- Element sink = ElementFactory.Make("fakesink", "sink");
+ FakeSink sink = FakeSink.Make("sink");
- source["location"] = args[0];
+ source.Location = args[0];
typefind.HaveType += OnHaveType;
@@ -26,16 +26,12 @@ public static class GstTypefindTest
pipeline.SetState(State.Paused);
pipeline.SetState(State.Null);
- source.Dispose();
- typefind.Dispose();
- sink.Dispose();
pipeline.Dispose();
}
- private static void OnHaveType(object o, GLib.SignalArgs args)
+ private static void OnHaveType(object o, TypeFindElement.HaveTypeArgs args)
{
- Caps caps = args.Args[1] as Caps;
- Console.WriteLine("MimeType: {0}", caps);
+ Console.WriteLine("MimeType: {0}", args.Caps);
}
}