Implemented signal name discovery if not setted on constructor.

Reviewer: Hugo Parente Lima <hugo.lima@openbossa.org>,
          Luciano Wolf <luciano.wolf@openbossa.org>
This commit is contained in:
Renato Filho 2010-05-14 17:14:49 -03:00
commit d8593de73a
3 changed files with 39 additions and 25 deletions

View file

@ -161,6 +161,7 @@ DynamicQMetaObject* DynamicQMetaObject::createBasedOn(PyObject *pyObj, PyTypeObj
while (PyDict_Next(type->tp_dict, &pos, &key, &value)) { while (PyDict_Next(type->tp_dict, &pos, &key, &value)) {
#if 0
//Register signals //Register signals
if (value->ob_type == &PySideSignal_Type) { if (value->ob_type == &PySideSignal_Type) {
SignalData *data = reinterpret_cast<SignalData*>(value); SignalData *data = reinterpret_cast<SignalData*>(value);
@ -171,6 +172,7 @@ DynamicQMetaObject* DynamicQMetaObject::createBasedOn(PyObject *pyObj, PyTypeObj
PyString_AS_STRING(PyObject_Str(key)), data->signatures[i]); PyString_AS_STRING(PyObject_Str(key)), data->signatures[i]);
} }
} }
#endif
if (!PyFunction_Check(value)) if (!PyFunction_Check(value))
continue; continue;

View file

@ -28,7 +28,7 @@ static PyObject* qsignal_instance_emit(PyObject *self, PyObject *args);
static char* qsignal_build_signature(const char *name, const char *signature); static char* qsignal_build_signature(const char *name, const char *signature);
static const char* qsignal_get_type_name(PyObject *type); static const char* qsignal_get_type_name(PyObject *type);
static void qsignal_append_signature(SignalData *self, PyObject *args); static void qsignal_append_signature(SignalData *self, PyObject *args);
static void qsignal_instance_initialize(PyObject *instance, SignalData *data, PyObject *source); static void qsignal_instance_initialize(PyObject *instance, PyObject *name, SignalData *data, PyObject *source);
PyTypeObject PySideSignal_Type = { PyTypeObject PySideSignal_Type = {
PyObject_HEAD_INIT(0) PyObject_HEAD_INIT(0)
@ -166,7 +166,7 @@ void signal_update_source(PyObject *source)
if (value->ob_type == &PySideSignal_Type) { if (value->ob_type == &PySideSignal_Type) {
PyObject *signal_instance = (PyObject*)PyObject_New(SignalData, &PySideSignalInstance_Type); PyObject *signal_instance = (PyObject*)PyObject_New(SignalData, &PySideSignalInstance_Type);
qsignal_instance_initialize(signal_instance, reinterpret_cast<SignalData*>(value), source); qsignal_instance_initialize(signal_instance, key, reinterpret_cast<SignalData*>(value), source);
PyObject_SetAttr(source, key, signal_instance); PyObject_SetAttr(source, key, signal_instance);
Py_DECREF(signal_instance); Py_DECREF(signal_instance);
@ -198,6 +198,7 @@ char* qsignal_build_signature(const char *name, const char *signature)
void qsignal_append_signature(SignalData *self, PyObject *args) void qsignal_append_signature(SignalData *self, PyObject *args)
{ {
char *signature = 0; char *signature = 0;
for(Py_ssize_t i=0, i_max=PySequence_Size(args); i < i_max; i++) { for(Py_ssize_t i=0, i_max=PySequence_Size(args); i < i_max; i++) {
Shiboken::AutoDecRef arg(PySequence_ITEM(args, i)); Shiboken::AutoDecRef arg(PySequence_ITEM(args, i));
const char *type_name = qsignal_get_type_name(arg); const char *type_name = qsignal_get_type_name(arg);
@ -212,14 +213,13 @@ void qsignal_append_signature(SignalData *self, PyObject *args)
} }
self->signatures_size++; self->signatures_size++;
if (self->signatures_size > 1) { if (self->signatures_size > 1) {
self->signatures = (char**) realloc(self->signatures, sizeof(char**) * self->signatures_size); self->signatures = (char**) realloc(self->signatures, sizeof(char**) * self->signatures_size);
} else { } else {
self->signatures = (char**) malloc(sizeof(char**)); self->signatures = (char**) malloc(sizeof(char**));
} }
self->signatures[self->signatures_size -1] = qsignal_build_signature(self->signal_name, signature); self->signatures[self->signatures_size-1] = signature;
printf("registred signature:[%d][%s]\n", self->signatures_size -1, self->signatures[self->signatures_size -1]);
free(signature);
} }
int qsignal_init(PyObject *self, PyObject *args, PyObject *kwds) int qsignal_init(PyObject *self, PyObject *args, PyObject *kwds)
@ -237,8 +237,9 @@ int qsignal_init(PyObject *self, PyObject *args, PyObject *kwds)
bool tupled_args = false; bool tupled_args = false;
SignalData *data = reinterpret_cast<SignalData*>(self); SignalData *data = reinterpret_cast<SignalData*>(self);
if (arg_name) if (arg_name) {
data->signal_name = strdup(arg_name); data->signal_name = strdup(arg_name);
}
for(Py_ssize_t i=0, i_max=PyTuple_Size(args); i < i_max; i++) { for(Py_ssize_t i=0, i_max=PyTuple_Size(args); i < i_max; i++) {
PyObject *arg = PyTuple_GET_ITEM(args, i); PyObject *arg = PyTuple_GET_ITEM(args, i);
@ -260,9 +261,15 @@ void qsignal_free(void *self)
PyObject *pySelf = reinterpret_cast<PyObject*>(self); PyObject *pySelf = reinterpret_cast<PyObject*>(self);
SignalData *data = reinterpret_cast<SignalData*>(self); SignalData *data = reinterpret_cast<SignalData*>(self);
//keep the data to instance for(int i=0, i_max=data->signatures_size; i < i_max; i++) {
if (!data->initialized) if (data->signatures[i])
qsignal_instance_free(self); free(data->signatures[i]);
}
free(data->signatures);
free(data->signal_name);
data->initialized = false;
data->signatures_size = 0;
pySelf->ob_type->tp_free (self); pySelf->ob_type->tp_free (self);
} }
@ -270,27 +277,27 @@ void qsignal_free(void *self)
void qsignal_instance_free(void *self) void qsignal_instance_free(void *self)
{ {
PyObject *pySelf = reinterpret_cast<PyObject*>(self); PyObject *pySelf = reinterpret_cast<PyObject*>(self);
SignalData *data = reinterpret_cast<SignalData*>(self); qsignal_free(self);
free(data->signatures[0]); pySelf->ob_type->tp_free(self);
for(int i=1, i_max=data->signatures_size; i < i_max; i++) {
free(data->signatures[i]);
}
free(data->signatures);
free(data->signal_name);
data->initialized = false;
pySelf->ob_type->tp_free (self);
} }
void qsignal_instance_initialize(PyObject *instance, SignalData *data, PyObject *source) void qsignal_instance_initialize(PyObject *instance, PyObject *name, SignalData *data, PyObject *source)
{ {
SignalData *self = reinterpret_cast<SignalData*>(instance); SignalData *self = reinterpret_cast<SignalData*>(instance);
self->signal_name = data->signal_name; if (data->signal_name)
self->signal_name = strdup(data->signal_name);
else
self->signal_name = strdup(PyString_AsString(name));
self->signatures_size = data->signatures_size; self->signatures_size = data->signatures_size;
self->signatures = data->signatures;
self->initialized = true; self->initialized = true;
self->source = source; self->source = source;
data->initialized = true; data->initialized = true;
self->signatures = (char**) malloc(sizeof(char**) * self->signatures_size);
///build signature
for(int i=0, i_max=self->signatures_size; i < i_max; i++)
self->signatures[i] = qsignal_build_signature(self->signal_name, data->signatures[i]);
} }
PyObject* qsignal_instance_connect(PyObject *self, PyObject *args, PyObject *kwds) PyObject* qsignal_instance_connect(PyObject *self, PyObject *args, PyObject *kwds)

View file

@ -9,31 +9,36 @@ from PySide.QtCore import *
class MyObject(QObject): class MyObject(QObject):
sig1 = Signal() sig1 = Signal()
sig2 = Signal(int, name='rangeChanged') sig2 = Signal(int, name='rangeChanged')
sig3 = Signal(int)
@Slot(int) @Slot(int)
def myRange(self, r): def myRange(self, r):
print "Range changed:", r print "Range changed:", r
self._range = r
def slot1(self): def slot1(self):
self._called = True self._called = True
class SignalObjectTest(unittest.TestCase): class SignalObjectTest(unittest.TestCase):
def testsingleConnect(self): def testsingleConnect(self):
o = MyObject() o = MyObject()
o.sig1.connect(o.slot1) o.sig1.connect(o.slot1)
o.sig1.emit() o.sig1.emit()
self.assert_(o._called) self.assert_(o._called)
def testSignalWithArgs(self):
o = MyObject()
o.sig3.connect(o.myRange)
o.sig3.emit(10)
self.assertEqual(o._range, 10)
def testSignatureParse(self): def testSignatureParse(self):
o = MyObject() o = MyObject()
o.sig2.connect(o.myRange) o.sig2.connect(o.myRange)
o.sig2.emit(10) o.sig2.emit(10)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()