diff --git a/ChangeLog b/ChangeLog index a03ed2ac4..832c11966 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2001-11-25 Mike Kestner + + * codegen/defs-parse.pl (get_sighandler): gen the helper class. arg + passing and return value handling need beefing up still. + * glib/SignalArgs.cs : New arg passing/ return value handling class. + * glib/SignalCallback.cs (dtor): kill, this will be gen'd in the + subclasses. (ctor): prune down to two params. + 2001-11-24 Mike Kestner * codegen/defs-parse.pl : mkdir the glib/generated dir. diff --git a/codegen/defs-parse.pl b/codegen/defs-parse.pl index 3ce4f0f69..63bb7330b 100755 --- a/codegen/defs-parse.pl +++ b/codegen/defs-parse.pl @@ -525,7 +525,7 @@ sub gen_param_strings sub get_sighandler { my ($def) = @_; - my ($key, $name, $sname, $dname, $dir, $ns, $nspace, $tok); + my ($key, $name, $dir, $ns, $nspace, $tok); $def =~ /return-type \"(\w+)\"/; my $ret = $1; @@ -566,8 +566,9 @@ sub get_sighandler die "Whassup with $tok?"; } } - $sname = $name . "Signal"; - $dname = $name . "Delegate"; + my $sname = $name . "Signal"; + my $dname = $name . "Delegate"; + my $cbname = $name . "Callback"; $sighandlers{$key} = $name; @@ -578,9 +579,38 @@ sub get_sighandler foreach $ns (split (/,/, $usings{$nspace})) { print SIGFILE "\tusing $ns;\n"; } - print SIGFILE "\tpublic delegate $marshaltypes{$ret} "; + print SIGFILE "\n\tpublic delegate $marshaltypes{$ret} "; print SIGFILE "$dname($pinv, int key);\n\n"; - print SIGFILE "}\n"; + print SIGFILE "\tpublic class $sname : SignalCallback {\n\n"; + print SIGFILE "\t\tprivate static $dname _Delegate;\n\n"; + print SIGFILE "\t\tprivate static $maptypes{$ret} "; + print SIGFILE "$cbname($pinv, int key)\n\t\t{\n"; + print SIGFILE "\t\t\tif (!_Instances.Contains(key))\n"; + print SIGFILE "\t\t\t\tthrow new Exception(\"Unexpected signal key\");"; + print SIGFILE "\n\n\t\t\t$sname inst = ($sname) _Instances[key];\n"; + print SIGFILE "\t\t\tSignalArgs args = new SignalArgs ();\n"; + print SIGFILE "\t\t\tinst._handler (inst._obj, args);\n"; + if ($ret ne "none") { + print SIGFILE "\t\t\treturn ($maptypes{$ret}) args.RetVal;\n"; + } + print SIGFILE "\t\t}\n\n"; + print SIGFILE "\t\t[DllImport(\"gobject-1.3.dll\", "; + print SIGFILE "CharSet=CharSet.Ansi, "; + print SIGFILE "CallingConvention=CallingConvention.Cdecl)]\n"; + print SIGFILE "\t\tstatic extern void g_signal_connect_data("; + print SIGFILE "IntPtr obj, IntPtr name, $dname cb, int key, IntPtr p,"; + print SIGFILE " int flags);\n\n"; + print SIGFILE "\t\tpublic $sname(GLib.Object obj, IntPtr raw, "; + print SIGFILE "String name, EventHandler eh) : base(obj, eh)"; + print SIGFILE "\n\t\t{\n\t\t\tif (_Delegate == null) {\n"; + print SIGFILE "\t\t\t\t_Delegate = new $dname($cbname);\n\t\t\t}\n"; + print SIGFILE "\t\t\tg_signal_connect_data(raw, "; + print SIGFILE "Marshal.StringToHGlobalAnsi(name), _Delegate, _key, "; + print SIGFILE "new IntPtr(0), 0);\n\t\t}\n\n"; + print SIGFILE "\t\t~$sname()\n{\t\t\t_Instances.Remove(_key);\n"; + print SIGFILE "\t\t\tif(_Instances.Count == 0) {\n"; + print SIGFILE "\t\t\t\t_Delegate = null;\n\t\t\t}\n\t\t}\n"; + print SIGFILE "\t}\n}\n"; close (SIGFILE); return $sighandlers{$key}; diff --git a/glib/SignalArgs.cs b/glib/SignalArgs.cs new file mode 100644 index 000000000..eeed49445 --- /dev/null +++ b/glib/SignalArgs.cs @@ -0,0 +1,103 @@ +// GtkSharp.SignalArgs.cs - Signal argument class implementation +// +// Author: Mike Kestner +// +// (c) 2001 Mike Kestner + +namespace GtkSharp { + using System; + using System.Collections; + + /// + /// SignalArgs Class + /// + /// + /// + /// Arguments and return value for signals. + /// + + public class SignalArgs : EventArgs { + + private object _ret; + private object[] _args; + + /// + /// SignalArgs Constructor + /// + /// + /// + /// Creates a SignalArgs object with no return value and + /// no arguments. + /// + + public SignalArgs() + { + _ret = null; + _args = null; + } + + /// + /// SignalArgs Constructor + /// + /// + /// + /// Creates a SignalArgs object with a return value and + /// no arguments. + /// + + public SignalArgs(object retval) + { + _ret = retval; + _args = null; + } + + /// + /// SignalArgs Constructor + /// + /// + /// + /// Creates a SignalArgs object with a return value and + /// a list of arguments. + /// + + public SignalArgs(object retval, object[] args) + { + _ret = retval; + _args = args; + } + + /// + /// Args Property + /// + /// + /// + /// A list of arguments. + /// + + public object[] Args { + get { + return _args; + } + set { + _args = value; + } + } + + /// + /// RetVal Property + /// + /// + /// + /// The return value. + /// + + public object RetVal { + get { + return _ret; + } + set { + _ret = value; + } + } + } +} diff --git a/glib/SignalCallback.cs b/glib/SignalCallback.cs index 26beabbc9..8dce633a2 100644 --- a/glib/SignalCallback.cs +++ b/glib/SignalCallback.cs @@ -39,8 +39,7 @@ namespace GtkSharp { /// Initializes instance data. /// - public SignalCallback (GLib.Object obj, IntPtr raw, - String name, EventHandler eh) + public SignalCallback (GLib.Object obj, EventHandler eh) { _key = _NextKey++; _obj = obj; @@ -48,11 +47,5 @@ namespace GtkSharp { _Instances [_key] = this; } - // Destructor needed to release references from the instance - // table and unpin the delegate if no refs remain. - ~SignalCallback () - { - _Instances.Remove (_key); - } } }