[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-bindings
Subject:    Re: [Kde-bindings] more work on the TODO
From:       "Paolo Capriotti" <p.capriotti () gmail ! com>
Date:       2006-05-29 12:14:55
Message-ID: 87b37d60605290514l4d088984l355483e2764a96e1 () mail ! gmail ! com
[Download RAW message or body]

On 5/29/06, Richard Dale <Richard_Dale@tipitina.demon.co.uk> wrote:
>
> baldhead duke 505% patch --dry-run < signalslot.diff
> can't find file to patch at input line 5
> Perhaps you should have used the -p or --strip option?

Try adding -p0 to the patch arguments.
Attached is an updated patch.

Paolo Capriotti

["signalslot.diff" (text/x-patch)]

Index: qyoto.cpp
===================================================================
--- qyoto.cpp	(revision 545029)
+++ qyoto.cpp	(working copy)
@@ -415,15 +415,6 @@
     }
 };
 
-// class UnencapsulatedQObject : public QObject {
-// public:
-//     int public_receivers(int signal) const { return receivers(signal); }
-// //    void public_activate_signal(QConnectionList *clist, QUObject *o) { \
                activate_signal(clist, o); }
-//     void public_activate_signal(void* one, void* two) {
-//       QMetaObject::activate(1,23,4,5);
-//     }
-// };
-
 class EmitSignal : public Marshall {
     QObject *_qobj;
     int _id;
@@ -962,110 +953,33 @@
 
 	return true;
 }
-/*
-static QUParameter *
-make_QUParameter(char * name, char * type, int inout)
-{
-    QUParameter *p = new QUParameter;
-    p->name = new char[strlen(name) + 1];
-    strcpy((char*)p->name, name);
-    if(strcmp(type, "bool") == 0)
-	p->type = &static_QUType_bool;
-    else if(strcmp(type, "int") == 0)
-	p->type = &static_QUType_int;
-    else if(strcmp(type, "double") == 0)
-	p->type = &static_QUType_double;
-    else if(strcmp(type, "char*") == 0 || strcmp(type, "const char*") == 0)
-	p->type = &static_QUType_charstar;
-    else if(strcmp(type, "QString") == 0 || strcmp(type, "QString&") == 0 ||
-	    strcmp(type, "const QString") == 0 || strcmp(type, "const QString&") == 0)
-	p->type = &static_QUType_QString;
-    else
-	p->type = &static_QUType_ptr;
-    // Lacking support for several types. Evil.
-    p->inOut = inout;
-    p->typeExtra = 0;
-//    return Data_Wrap_Struct(rb_cObject, 0, 0, p);
-    return p;
-}
 
-static QMetaData *
-make_QMetaData(char * name, void * method)
-{
-    QMetaData *m = new QMetaData;		// will be deleted
-    m->name = new char[strlen(name) + 1];
-    strcpy((char*)m->name, name);
-//    Data_Get_Struct(method, QUMethod, m->method);
-    m->access = QMetaData::Public;
-//    return Data_Wrap_Struct(rb_cObject, 0, 0, m);
-    return m;
-}
 
-static QUMethod *
-make_QUMethod(char * name, int count, QUParameter * p)
-{
-	QUMethod *m = new QUMethod;			// permanent memory allocation
-	m->name = new char[strlen(name) + 1];	// this too
-	strcpy((char*)m->name, name);
-	m->parameters = 0;
-	m->count = count;
-
-	if (m->count > 0) {
-		m->parameters = new QUParameter[m->count];
-		for (long i = 0; i < m->count; i++) {
-//	    VALUE param = rb_ary_entry(params, i);
-//	    QUParameter *p = 0;
-//	    Data_Get_Struct(param, QUParameter, p);
-			((QUParameter *) m->parameters)[i] = *p;
-			delete p;
-			p++;
-		}
-	}
-//    return Data_Wrap_Struct(rb_cObject, 0, 0, m);
-	return m;
+void* make_metaObject(QMetaObject* parent, const char* stringdata, const uint* data) \
{ +  printf("parent = %x\n", parent);
+  printf("stringdata = %s\n", stringdata);
+  printf("data = %x\n", data);
+  // create a QMetaObject on the stack
+  QMetaObject tmp = {{
+    parent,
+    stringdata,
+    data,
+    0
+  }};
+  
+  // copy it to the heap
+  QMetaObject* meta = new QMetaObject;
+  *meta = tmp;
+  
+  // create smoke object
+  smokeqyoto_object* m = (smokeqyoto_object*)malloc(sizeof(smokeqyoto_object));
+  m->smoke = qt_Smoke;
+  m->classId = qt_Smoke->idClass("QMetaObject");
+  m->ptr = meta;
+  
+  return m;
 }
 
-static QMetaData *
-make_QMetaData_tbl(long count, QMetaData * old)
-{
-//    long count = RARRAY(list)->len;
-	QMetaData *m = new QMetaData[count];
-
-	for (long i = 0; i < count; i++) {
-//	VALUE item = rb_ary_entry(list, i);
-
-//	QMetaData *old = 0;
-//	Data_Get_Struct(item, QMetaData, old);
-		m[i] = *old;
-		delete old;
-		old++;
-	}
-
-//    return Data_Wrap_Struct(rb_cObject, 0, 0, m);
-    return m;
-}
-
-static void *
-make_metaObject(char * className, QMetaObject* parent, QMetaData * slot_tbl, int \
                slot_count, QMetaData * signal_tbl, int signal_count)
-{
-	QMetaObject *meta = QMetaObject::new_metaobject(
-	className, parent,
-	(const QMetaData*)slot_tbl, slot_count,	// slots
-	(const QMetaData*)signal_tbl, signal_count,	// signals
-	0, 0,	// properties
-	0, 0,	// enums
-	0, 0);
-
-    smokeqyoto_object * o = (smokeqyoto_object *) malloc(sizeof(smokeqyoto_object));
-    o->smoke = qt_Smoke;
-    o->classId = qt_Smoke->idClass("QMetaObject");
-    o->ptr = meta;
-    o->allocated = true;
-
-//    return Data_Wrap_Struct(qt_qmetaobject_class, smokeruby_mark, smokeruby_free, \
                o);
-	return set_obj_info("QMetaObject", o);
-}*/
-
 void
 Init_qyoto()
 {
Index: qyoto/QObject.cs
===================================================================
--- qyoto/QObject.cs	(revision 545029)
+++ qyoto/QObject.cs	(working copy)
@@ -5,6 +5,7 @@
 using System.Reflection;
 	using System.Collections;
 	using System.Text;
+  using System.Reflection; 
 
 	/// See <see cref="IQObjectSignals"></see> for signals emitted by QObject
 	[SmokeClass("QObject")]
@@ -12,20 +13,18 @@
 		protected Object _interceptor = null;
  
 		private IntPtr _smokeObject;
+
 		protected QObject(Type dummy) {
-			Type t = GetType();
-#if DEBUG
-			Console.WriteLine("ENTER: dummy constructor for {0}", t);
-#endif
-			MethodInfo m = t.GetMethod("Emit", BindingFlags.NonPublic | \
                BindingFlags.Instance);
-			if (m != null) {
-				Type proxyInterface = m.ReturnType;
-				SignalInvocation realProxy = new SignalInvocation(proxyInterface, this);
-				Q_EMIT = realProxy.GetTransparentProxy();
-			} else {
-				Console.WriteLine("Could not find Emit");
+      try {
+        Type proxyInterface = Qyoto.GetSignalsInterface(GetType());
+        SignalInvocation realProxy = new SignalInvocation(proxyInterface, this);
+        Q_EMIT = realProxy.GetTransparentProxy();
+      }
+      catch {
+				Console.WriteLine("Could not retrieve signal interface");
 			}
 		}
+    
 		interface IQObjectProxy {
 			string Tr(string s, string c);
 			string Tr(string s);
@@ -207,7 +206,7 @@
 		}
 		[SmokeMethod("connect(const QObject*, const char*, const QObject*, const char*)")]
 		public static bool Connect(QObject sender, string signal, QObject receiver, string \
                member) {
-			return StaticQObject().Connect(sender,signal,receiver,member);
+			 return StaticQObject().Connect(sender,signal,receiver,member);
 		}
 		[SmokeMethod("disconnect(const QObject*, const char*, const QObject*, const \
char*)")]  public static bool Disconnect(QObject sender, string signal, QObject \
                receiver, string member) {
Index: qyoto/Qyoto.cs
===================================================================
--- qyoto/Qyoto.cs	(revision 545029)
+++ qyoto/Qyoto.cs	(working copy)
@@ -3,15 +3,23 @@
 	using System;
 	using System.Collections;
 	using System.Reflection;
+  using System.Text;
+  using System.Text.RegularExpressions;
 	using System.Runtime.InteropServices;
 	
 	public class Qyoto : System.Object
 	{
 		[DllImport("libqyoto", CharSet=CharSet.Ansi)]
 		public static extern void Init_qyoto();
-		
+    
+    [DllImport("libqyoto", CharSet=CharSet.Ansi)]
+    static extern IntPtr make_metaObject(IntPtr parent, IntPtr stringdata, IntPtr \
data); +      
 		/// This Hashtable contains a list of classes with their Hashtables for slots. The \
class name is the key, the slot-hashtable the value.  public static Hashtable classes \
= new Hashtable(); +    
+    /// This hashtable has classe names as keys, and QMetaObjects as values
+    static Hashtable metaObjects = new Hashtable();
 		
 		public static void GetSlotSignatures(Type t) {
 			
@@ -21,7 +29,7 @@
 			/// This Hashtable contains the slots of a class. The C++ type signature is the \
key, the appropriate C# MethodInfo the value.  Hashtable slots = new Hashtable();
 			
-			MethodInfo[] mis = t.GetMethods( BindingFlags.Instance | BindingFlags.Static | \
BindingFlags.Public | BindingFlags.NonPublic ); +			MethodInfo[] mis = t.GetMethods( \
BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | \
BindingFlags.NonPublic);  
 			foreach (MethodInfo mi in mis) {
 				object[] attributes = mi.GetCustomAttributes(typeof(Q_SLOT), false);
@@ -34,10 +42,10 @@
 			classes.Add(t.Name, slots);
 		}
 		
-		public static string[] GetSignalSignatures(QObject o) {
+		public static string[] GetSignalSignatures(Type t) {
 			Type iface;
 			try {
-				iface = GetSignalsInterface(o);
+				iface = GetSignalsInterface(t);
 			}
 			catch {
 				return null;
@@ -62,11 +70,160 @@
 			return signatures;
 		}
 		
-		public static Type GetSignalsInterface(QObject o) {
-			Type t = o.GetType();
+		public static Type GetSignalsInterface(Type t) {
 			MethodInfo mi = t.GetMethod("Emit", BindingFlags.Instance | \
BindingFlags.NonPublic);  return mi.ReturnType;
 		}
+    
+    class QyotoMetaData {
+      // Keeps a hash of strings against their corresponding offsets
+      // within the qt_meta_stringdata sequence of null terminated
+      // strings.
+      class StringTableHandler {
+        Hashtable hash;
+        int offset;
+        ArrayList data;
+        
+        public StringTableHandler() {
+          hash = new Hashtable();
+          offset = 0;
+          data = new ArrayList();
+        }
+
+        public int this[string str] {
+          get {
+            if (!hash.ContainsKey(str)) {
+              Console.WriteLine("adding {0} in hash at offset {1}", str, offset);
+              hash[str] = offset;
+              data.Add(str);
+              offset += str.Length + 1;
+            }
+            return (int)hash[str];
+          }
+        }
+        
+        public byte[] GetStringData() {
+          ArrayList result = new ArrayList();
+          foreach(string x in data) {
+            result.AddRange(Encoding.ASCII.GetBytes(x));
+            result.Add((byte)0);
+          }
+          byte[] res = new byte[result.Count];
+          result.CopyTo(res);
+          return res;
+        }
+      }
+    
+      byte[] stringdata;
+      int[] data;
+      StringTableHandler handler;
+      
+      // from qt-copy/src/tools/moc/generator.cpp
+      enum MethodFlags {
+        AccessPrivate = 0x00,
+        AccessProtected = 0x01,
+        AccessPublic = 0x02,
+        MethodMethod = 0x00,
+        MethodSignal = 0x04,
+        MethodSlot = 0x08,
+        MethodCompatibility = 0x10,
+        MethodCloned = 0x20,
+        MethodScriptable = 0x40
+      }
+      
+      void AddMethod(ArrayList array, string method, MethodFlags flags) {
+        array.Add(handler[method]);                            // signature
+        array.Add(handler[Regex.Replace(method, "[^,]", "")]); // parameters
+        array.Add(handler[""]);                                // type
+        array.Add(handler[""]);                                // tag
+        array.Add((int)flags);                                 // flags
+      }
+      
+      public QyotoMetaData(string className, ICollection signals, ICollection slots) \
{ +        handler = new StringTableHandler();
+        ArrayList tmp = new ArrayList(new int[] { 
+            1,                                  // revision
+            handler[className],                 // classname
+            0, 0,                               // classinfo
+            signals.Count + slots.Count, 10,  // methods
+            0, 0,                               // properties
+            0, 0
+        });
+        
+        foreach (string entry in signals)
+          AddMethod(tmp, entry, MethodFlags.MethodSignal | \
MethodFlags.AccessProtected); +        
+        foreach (string entry in signals)
+          AddMethod(tmp, entry, MethodFlags.MethodSlot | MethodFlags.AccessPublic);
+          
+        tmp.Add(0);
+        
+        stringdata = handler.GetStringData();
+        data = new int[tmp.Count];
+        tmp.CopyTo(data);
+      }
+      
+      public byte[] StringData {
+        get { return stringdata; }
+      }
+      
+      public int[] Data {
+        get { return data; }
+      }
+    }
+    
+    public static QMetaObject MakeMetaObject(Type t) {
+      Console.WriteLine("ENTER: MakeMetaObject.  t => {0}", t);
+      
+      if (t == null || typeof(QObject).IsAssignableFrom(t)) return null;
+      
+      string className = t.ToString();
+      Hashtable slotTable = (Hashtable)classes[className];
+      
+      ICollection slots;
+      if (slotTable != null)
+        slots = slotTable.Values;
+      else {
+        // build slot table
+        GetSlotSignatures(t);
+        slotTable = (Hashtable)classes[className];
+        slots = slotTable.Values;
+      }
+      
+      string[] signals = GetSignalSignatures(t);
+      QyotoMetaData metaData = new QyotoMetaData(className, signals, slots);
+      GCHandle parentMetaObject = GCHandle.Alloc(GetMetaObject(t.BaseType));
+      IntPtr metaSmokeObject;
+      
+      unsafe {
+        fixed (byte* stringdata = metaData.StringData)
+        fixed (int* data = metaData.Data) {
+          metaSmokeObject = make_metaObject((IntPtr)parentMetaObject, \
(IntPtr)stringdata, (IntPtr)data); +        }
+      }
+      
+      // create a new C# QMetaObject and replace its
+      // inner _smokeObject with that returned from make_metaObject
+      QMetaObject res = new QMetaObject();
+      FieldInfo fieldInfo = typeof(QMetaObject).GetField(  "_smokeObject", 
+                              BindingFlags.NonPublic 
+                              | BindingFlags.GetField
+                              | BindingFlags.Instance );
+      ((GCHandle)fieldInfo.GetValue(res)).Free();
+      fieldInfo.SetValue(res, metaSmokeObject);
+
+      Console.WriteLine("LEAVE MakeMetaObject");
+      return res;
+    }
+    
+    public static QMetaObject GetMetaObject(Type t) {
+      QMetaObject res = (QMetaObject)metaObjects[t.ToString()];
+      if (res == null) {
+        res = MakeMetaObject(t);
+        metaObjects[t.ToString()] = res;
+      }
+      return res;
+    }
 	}
 	
 	[AttributeUsage( AttributeTargets.Class )]
@@ -108,7 +265,7 @@
 	}
 
 	[AttributeUsage( AttributeTargets.Method )]
-	class Q_SIGNAL : Attribute
+	public class Q_SIGNAL : Attribute
 	{
 		public string signature;
 	
@@ -127,7 +284,7 @@
 	}
 
 	[AttributeUsage( AttributeTargets.Method )]
-	class Q_SLOT : Attribute
+	public class Q_SLOT : Attribute
 	{
 		public string signature;
 	



_______________________________________________
Kde-bindings mailing list
Kde-bindings@kde.org
https://mail.kde.org/mailman/listinfo/kde-bindings


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic