[Kde-bindings] playground/bindings/kimono
Arno Rehn
kde at arnorehn.de
Wed Feb 28 14:17:01 UTC 2007
SVN commit 637998 by arnorehn:
* Don't include inherited signals/slots when building up the metaobject
* Added seperate methods for getting all the signals/slots of a class, including
inherited ones. This is needed for InvokeCustomSlot() and SignalInvocation.Invoke()
* Changed qt_metacall to be more like the one genereted by moc:
* First call qt_metacall of the base class
* If the return value is postive, it was a C++ slot/signal/property, return
* If the return value is negative, look for C# slots/signals/properties
and call them
CCMAIL: kde-bindings at kde.org
M +11 -0 ChangeLog
M +92 -5 Qyoto.cs
M +2 -2 SmokeInvocation.cs
M +25 -30 qyoto.cpp
--- trunk/playground/bindings/kimono/ChangeLog #637997:637998
@@ -1,3 +1,14 @@
+2007-02-28 Arno Rehn <arno at arnorehn.de>
+
+ * Don't include inherited signals/slots when building up the metaobject
+ * Added seperate methods for getting all the signals/slots of a class, including
+ inherited ones. This is needed for InvokeCustomSlot() and SignalInvocation.Invoke()
+ * Changed qt_metacall to be more like the one genereted by moc:
+ * First call qt_metacall of the base class
+ * If the return value is postive, it was a C++ slot/signal/property, return
+ * If the return value is negative, look for C# slots/signals/properties
+ and call them
+
2007-02-27 Richard Dale <rdale at foton.es>
* Made the QMetaObject creation work correctly with nested subclasses
--- trunk/playground/bindings/kimono/Qyoto.cs #637997:637998
@@ -209,18 +209,56 @@
type = return_type;
}
+ // this method is only used when we build up our meta object.
+ // it only returns declared slots
public static Dictionary<string, CPPMethod> GetSlotSignatures(Type t) {
+ /// This Hashtable contains the slots of a class. The C++ type signature is the key, the appropriate array with the MethodInfo, signature and return type the value.
+ Dictionary<string, CPPMethod> slots = new Dictionary<string, CPPMethod>();
+
+ // only declared members
+ MethodInfo[] mis = t.GetMethods( BindingFlags.Instance
+ | BindingFlags.Static
+ | BindingFlags.Public
+ | BindingFlags.NonPublic
+ | BindingFlags.DeclaredOnly);
+
+ foreach (MethodInfo mi in mis) {
+ if (IsSmokeClass(mi.DeclaringType)) continue;
+ object[] attributes = mi.GetCustomAttributes(typeof(Q_SLOT), false);
+ foreach (Q_SLOT attr in attributes) {
+ CPPMethod cppinfo = new CPPMethod();
+
+ string sig = attr.Signature;
+ if (sig == "")
+ sig = SignatureFromMethodInfo(mi);
+ GetCPPMethodInfo(sig, out cppinfo.signature, out cppinfo.type);
+
+ cppinfo.mi = mi;
+
+ if (mi.GetCustomAttributes(typeof(Q_SCRIPTABLE), false).Length > 0)
+ cppinfo.scriptable = true;
+
+ slots.Add(cppinfo.signature, cppinfo);
+ break;
+ }
+ }
+ return slots;
+ }
+
+ // this method is used to get _all_ the slots of a class
+ // this is needed by SmokeInvocation.InvokeCustomSlot()
+ public static Dictionary<string, CPPMethod> GetAllSlotSignatures(Type t) {
/// Remove the old object if it already exists
classes.Remove(t.ToString());
/// This Hashtable contains the slots of a class. The C++ type signature is the key, the appropriate array with the MethodInfo, signature and return type the value.
Dictionary<string, CPPMethod> slots = new Dictionary<string, CPPMethod>();
+ // also include inherited members
MethodInfo[] mis = t.GetMethods( BindingFlags.Instance
| BindingFlags.Static
| BindingFlags.Public
- | BindingFlags.NonPublic
- /*| BindingFlags.DeclaredOnly */);
+ | BindingFlags.NonPublic);
foreach (MethodInfo mi in mis) {
if (IsSmokeClass(mi.DeclaringType)) continue;
@@ -247,8 +285,8 @@
return slots;
}
-
- /// returns a Hastable with the MethodInfo as a key and the array with the MethodInfo, signature and return type the value.
+ // this method is again only used when we build up our meta object.
+ // it only returns declared signals
public static Dictionary<MethodInfo, CPPMethod> GetSignalSignatures(Type t) {
Dictionary<MethodInfo, CPPMethod> signals = new Dictionary<MethodInfo, CPPMethod>();
if (IsSmokeClass(t)) {
@@ -264,8 +302,14 @@
}
Type iface = propertyInfo.PropertyType;
- MethodInfo[] mis = iface.GetMethods();
+ // don't get inherited methods
+ MethodInfo[] mis = iface.GetMethods(BindingFlags.Instance
+ | BindingFlags.Static
+ | BindingFlags.DeclaredOnly
+ | BindingFlags.Public
+ | BindingFlags.NonPublic);
+
/// the interface has no signals...
if (mis.Length == 0)
return signals;
@@ -290,6 +334,49 @@
return signals;
}
+ // this method returns _all_ the signals of a class, including inherited ones
+ // used by SignalInvocation.Invoke()
+ public static Dictionary<MethodInfo, CPPMethod> GetAllSignalSignatures(Type t) {
+ Dictionary<MethodInfo, CPPMethod> signals = new Dictionary<MethodInfo, CPPMethod>();
+ if (IsSmokeClass(t))
+ return signals;
+
+ Type currentType = t;
+ while (!IsSmokeClass(currentType)) {
+ PropertyInfo propertyInfo = currentType.GetProperty( "Emit",
+ BindingFlags.Instance
+ | BindingFlags.NonPublic
+ | BindingFlags.DeclaredOnly );
+ if (propertyInfo == null) {
+ currentType = currentType.BaseType;
+ continue;
+ }
+
+ Type iface = propertyInfo.PropertyType;
+ MethodInfo[] mis = iface.GetMethods();
+
+ foreach (MethodInfo mi in mis) {
+ object[] attributes = mi.GetCustomAttributes(typeof(Q_SIGNAL), false);
+ foreach (Q_SIGNAL attr in attributes) {
+ CPPMethod cppinfo = new CPPMethod();
+ string sig = attr.Signature;
+ if (sig == "")
+ sig = SignatureFromMethodInfo(mi).Trim();
+ GetCPPMethodInfo(sig, out cppinfo.signature, out cppinfo.type);
+ cppinfo.mi = mi;
+
+ if (mi.GetCustomAttributes(typeof(Q_SCRIPTABLE), false).Length > 0)
+ cppinfo.scriptable = true;
+
+ signals.Add(cppinfo.mi, cppinfo);
+ }
+ }
+
+ currentType = currentType.BaseType;
+ }
+
+ return signals;
+ }
public static Type GetSignalsInterface(Type t) {
PropertyInfo pi = t.GetProperty("Emit", BindingFlags.Instance | BindingFlags.NonPublic);
return pi.PropertyType;
--- trunk/playground/bindings/kimono/SmokeInvocation.cs #637997:637998
@@ -247,7 +247,7 @@
#endif
Dictionary<string, Qyoto.CPPMethod> slotTable;
if (!Qyoto.classes.TryGetValue(className, out slotTable)) {
- slotTable = Qyoto.GetSlotSignatures(qobj.GetType());
+ slotTable = Qyoto.GetAllSlotSignatures(qobj.GetType());
}
MethodInfo slot;
try {
@@ -554,7 +554,7 @@
IMethodReturnMessage returnMessage = (IMethodReturnMessage) message;
MethodReturnMessageWrapper returnValue = new MethodReturnMessageWrapper((IMethodReturnMessage) returnMessage);
GCHandle instanceHandle = GCHandle.Alloc(_instance);
- Dictionary<MethodInfo, Qyoto.CPPMethod> signals = Qyoto.GetSignalSignatures(_instance.GetType());
+ Dictionary<MethodInfo, Qyoto.CPPMethod> signals = Qyoto.GetAllSignalSignatures(_instance.GetType());
/// should not happen
if (signals == null) {
--- trunk/playground/bindings/kimono/qyoto.cpp #637997:637998
@@ -1630,45 +1630,40 @@
int qt_metacall(void* obj, int _c, int _id, void* _o) {
- // get obj metaobject with a virtual call
smokeqyoto_object* o = value_obj_info(obj);
- QObject *qobj = (QObject*)o->ptr;
+
+ Smoke::Index nameId = o->smoke->idMethodName("qt_metacall$$?");
+ Smoke::Index meth = o->smoke->findMethod(o->classId, nameId);
+ if(meth > 0) {
+ Smoke::Method &m = o->smoke->methods[o->smoke->methodMaps[meth].method];
+ Smoke::ClassFn fn = o->smoke->classes[m.classId].classFn;
+ Smoke::StackItem i[4];
+ i[1].s_enum = _c;
+ i[2].s_int = _id;
+ i[3].s_voidp = _o;
+ (*fn)(m.method, o->ptr, i);
+
+ int ret = i[0].s_int;
+ if (ret < 0)
+ return ret;
+ } else {
+ // Should never happen..
+ qFatal("Cannot find %s::qt_metacall() method\n",
+ o->smoke->classes[o->classId].className );
+ }
+
+ QObject *qobj = (QObject*)o->ptr;
+ // get obj metaobject with a virtual call
const QMetaObject *metaobject = qobj->metaObject();
- // get method count and offset
+ // get method/property count
int count = 0;
- int offset = 0;
if (_c == QMetaObject::InvokeMetaMethod) {
count = metaobject->methodCount();
- offset = metaobject->methodOffset();
} else {
count = metaobject->propertyCount();
- offset = metaobject->propertyOffset();
}
-
- // if id < offset call base version
- if (_id < offset || (*IsSmokeClass)(obj)) {
- // Assume the target slot is a C++ one
- Smoke::Index nameId = o->smoke->idMethodName("qt_metacall$$?");
- Smoke::Index meth = o->smoke->findMethod(o->classId, nameId);
- if(meth > 0) {
- Smoke::Method &m = o->smoke->methods[o->smoke->methodMaps[meth].method];
- Smoke::ClassFn fn = o->smoke->classes[m.classId].classFn;
- Smoke::StackItem i[4];
- i[1].s_enum = _c;
- i[2].s_int = _id;
- i[3].s_voidp = _o;
- (*fn)(m.method, o->ptr, i);
-
- return i[0].s_int;
- }
-
- // Should never happen..
- qFatal("Cannot find %s::qt_metacall() method\n",
- o->smoke->classes[o->classId].className );
- }
-
if (_c == QMetaObject::InvokeMetaMethod) {
// retrieve method signature from id
QMetaMethod method = metaobject->method(_id);
@@ -1677,7 +1672,7 @@
if (method.methodType() == QMetaMethod::Signal) {
metaobject->activate(qobj, _id, (void**) _o);
- return _id - (count - offset);
+ return _id - count;
}
int items;
More information about the Kde-bindings
mailing list