// This file was generated by the Gtk# code generator.
// Any changes made will be lost if regenerated.

namespace GstSharp {

	using System;
	using System.Runtime.InteropServices;

#region Autogenerated code
	[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
	internal delegate void TaskThreadFuncNative(IntPtr task, out GLib.Thread thread, IntPtr user_data);

	internal class TaskThreadFuncInvoker {

		TaskThreadFuncNative native_cb;
		IntPtr __data;
		GLib.DestroyNotify __notify;

		~TaskThreadFuncInvoker ()
		{
			if (__notify == null)
				return;
			__notify (__data);
		}

		internal TaskThreadFuncInvoker (TaskThreadFuncNative native_cb) : this (native_cb, IntPtr.Zero, null) {}

		internal TaskThreadFuncInvoker (TaskThreadFuncNative native_cb, IntPtr data) : this (native_cb, data, null) {}

		internal TaskThreadFuncInvoker (TaskThreadFuncNative native_cb, IntPtr data, GLib.DestroyNotify notify)
		{
			this.native_cb = native_cb;
			__data = data;
			__notify = notify;
		}

		internal Gst.TaskThreadFunc Handler {
			get {
				return new Gst.TaskThreadFunc(InvokeNative);
			}
		}

		void InvokeNative (Gst.Task task, out GLib.Thread thread)
		{
			native_cb (task == null ? IntPtr.Zero : task.Handle, out thread, __data);
		}
	}

	internal class TaskThreadFuncWrapper {

		public void NativeCallback (IntPtr task, out GLib.Thread thread, IntPtr user_data)
		{
			try {
				managed (GLib.Object.GetObject(task) as Gst.Task, out thread);
				if (release_on_call)
					gch.Free ();
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: Above call does not return.
				throw e;
			}
		}

		bool release_on_call = false;
		GCHandle gch;

		public void PersistUntilCalled ()
		{
			release_on_call = true;
			gch = GCHandle.Alloc (this);
		}

		internal TaskThreadFuncNative NativeDelegate;
		Gst.TaskThreadFunc managed;

		public TaskThreadFuncWrapper (Gst.TaskThreadFunc managed)
		{
			this.managed = managed;
			if (managed != null)
				NativeDelegate = new TaskThreadFuncNative (NativeCallback);
		}

		public static Gst.TaskThreadFunc GetManagedDelegate (TaskThreadFuncNative native)
		{
			if (native == null)
				return null;
			TaskThreadFuncWrapper wrapper = (TaskThreadFuncWrapper) native.Target;
			if (wrapper == null)
				return null;
			return wrapper.managed;
		}
	}
#endregion
}
