diff options
author | Kai Huuhko <kai.huuhko@gmail.com> | 2015-03-13 19:21:36 +0200 |
---|---|---|
committer | Kai Huuhko <kai.huuhko@gmail.com> | 2015-03-13 19:22:01 +0200 |
commit | 4ccea0f35d1a920aeb1b30451c58dab53909664b (patch) | |
tree | f528b7dbb31b6b8c0694e0f3fe31637a118b3175 | |
parent | ea2d5bd689226dc2a8c5cb2d0ca28ec0913bffa7 (diff) |
Evas.SmartObject: Add smart callback introspection
-rw-r--r-- | efl/evas/efl.evas_object_smart.pxi | 234 | ||||
-rw-r--r-- | examples/elementary/test_core_evas_smart.py | 26 | ||||
-rw-r--r-- | include/efl.evas.pxd | 22 |
3 files changed, 262 insertions, 20 deletions
diff --git a/efl/evas/efl.evas_object_smart.pxi b/efl/evas/efl.evas_object_smart.pxi index 460f3b7..b8bc667 100644 --- a/efl/evas/efl.evas_object_smart.pxi +++ b/efl/evas/efl.evas_object_smart.pxi | |||
@@ -21,10 +21,78 @@ from efl.eo cimport Eo, EoIterator | |||
21 | 21 | ||
22 | from cpython cimport Py_INCREF, Py_DECREF, PyObject_Call, \ | 22 | from cpython cimport Py_INCREF, Py_DECREF, PyObject_Call, \ |
23 | PyMem_Malloc, PyMem_Free | 23 | PyMem_Malloc, PyMem_Free |
24 | from libc.stdlib cimport malloc | ||
25 | from libc.string cimport strdup | ||
24 | 26 | ||
25 | #cdef object _smart_classes | 27 | #cdef object _smart_classes |
26 | #_smart_classes = list() | 28 | #_smart_classes = list() |
27 | 29 | ||
30 | cdef list _descriptions_to_list(const Evas_Smart_Cb_Description **arr, unsigned int arr_len): | ||
31 | cdef: | ||
32 | unsigned int i | ||
33 | list ret = list() | ||
34 | |||
35 | if arr == NULL: | ||
36 | return ret | ||
37 | |||
38 | for i in range(arr_len): | ||
39 | ret.append(SmartCbDescription.create(arr[i])) | ||
40 | |||
41 | if arr[i+1] != NULL: | ||
42 | EINA_LOG_DOM_WARN(PY_EFL_EVAS_LOG_DOMAIN, "array was not NULL terminated!", NULL) | ||
43 | |||
44 | return ret | ||
45 | |||
46 | cdef Evas_Smart_Cb_Description *_descriptions_to_array(descs): | ||
47 | cdef: | ||
48 | unsigned int arr_len = len(descs) | ||
49 | Evas_Smart_Cb_Description *arr | ||
50 | SmartCbDescription desc | ||
51 | |||
52 | if arr_len == 0: | ||
53 | return NULL | ||
54 | |||
55 | # allocate arr_len + 1 so it's NULL terminated | ||
56 | arr = <Evas_Smart_Cb_Description *>malloc(arr_len + 1 * sizeof(Evas_Smart_Cb_Description)) | ||
57 | |||
58 | for i, desc in enumerate(descs): | ||
59 | arr[i] = desc.desc[0] | ||
60 | |||
61 | return arr | ||
62 | |||
63 | |||
64 | cdef class SmartCbDescription: | ||
65 | """Introspection description for a smart callback""" | ||
66 | cdef const Evas_Smart_Cb_Description *desc | ||
67 | |||
68 | def __init__(self, name, types): | ||
69 | cdef Evas_Smart_Cb_Description *tmp | ||
70 | tmp = <Evas_Smart_Cb_Description *>malloc(sizeof(Evas_Smart_Cb_Description*)) | ||
71 | if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name) | ||
72 | tmp.name = strdup(name) | ||
73 | if isinstance(types, unicode): types = PyUnicode_AsUTF8String(types) | ||
74 | tmp.type = strdup(types) | ||
75 | self.desc = <const Evas_Smart_Cb_Description *>tmp | ||
76 | |||
77 | @staticmethod | ||
78 | cdef create(const Evas_Smart_Cb_Description *desc): | ||
79 | cdef SmartCbDescription ret = SmartCbDescription.__new__(SmartCbDescription) | ||
80 | ret.desc = desc | ||
81 | return ret | ||
82 | |||
83 | def __repr__(self): | ||
84 | return "%s(%r, %r)" % (self.__class__.__name__, self.name, self.type) | ||
85 | |||
86 | property name: | ||
87 | """:type: string""" | ||
88 | def __get__(self): | ||
89 | return _ctouni(self.desc.name) | ||
90 | |||
91 | property type: | ||
92 | """:type: string""" | ||
93 | def __get__(self): | ||
94 | return _ctouni(self.desc.type) | ||
95 | |||
28 | 96 | ||
29 | cdef void _smart_object_delete(Evas_Object *o) with gil: | 97 | cdef void _smart_object_delete(Evas_Object *o) with gil: |
30 | cdef: | 98 | cdef: |
@@ -416,8 +484,9 @@ cdef class Smart(object): | |||
416 | .. versionadded:: 1.14 | 484 | .. versionadded:: 1.14 |
417 | """ | 485 | """ |
418 | 486 | ||
419 | def __cinit__(self, bint clipped=False): | 487 | def __cinit__(self, Smart parent=None, bint clipped=False, callback_descriptions=[], *args, **kwargs): |
420 | cdef Evas_Smart_Class *cls_def | 488 | cdef: |
489 | Evas_Smart_Class *cls_def | ||
421 | 490 | ||
422 | cls_def = <Evas_Smart_Class*>PyMem_Malloc(sizeof(Evas_Smart_Class)) | 491 | cls_def = <Evas_Smart_Class*>PyMem_Malloc(sizeof(Evas_Smart_Class)) |
423 | if cls_def == NULL: | 492 | if cls_def == NULL: |
@@ -445,20 +514,55 @@ cdef class Smart(object): | |||
445 | cls_def.member_add = _smart_object_member_add | 514 | cls_def.member_add = _smart_object_member_add |
446 | cls_def.member_del = _smart_object_member_del | 515 | cls_def.member_del = _smart_object_member_del |
447 | 516 | ||
448 | cls_def.parent = NULL | 517 | cls_def.parent = parent.cls_def if parent is not None else NULL |
449 | cls_def.callbacks = NULL | 518 | |
519 | cls_def.callbacks = _descriptions_to_array(callback_descriptions) | ||
520 | |||
521 | # TODO: interfaces? | ||
450 | cls_def.interfaces = NULL | 522 | cls_def.interfaces = NULL |
523 | |||
451 | cls_def.data = <void *>self | 524 | cls_def.data = <void *>self |
452 | 525 | ||
453 | self.cls = evas_smart_class_new(cls_def) | 526 | self.cls_def = <const Evas_Smart_Class *>cls_def |
527 | self.cls = evas_smart_class_new(self.cls_def) | ||
454 | 528 | ||
455 | def __dealloc__(self): | 529 | def __dealloc__(self): |
456 | cdef const Evas_Smart_Class *cls_def | 530 | cdef const Evas_Smart_Class *cls_def |
457 | cls_def = evas_smart_class_get(self.cls) | 531 | cls_def = evas_smart_class_get(self.cls) |
458 | PyMem_Free(<void*>cls_def) | 532 | PyMem_Free(<void*>cls_def) |
459 | evas_smart_free(self.cls) | 533 | evas_smart_free(self.cls) # FIXME: Check that all resources (cb descriptions etc.) are truly freed |
460 | self.cls = NULL | 534 | self.cls = NULL |
461 | 535 | ||
536 | property callback_descriptions: | ||
537 | def __get__(self): | ||
538 | cdef: | ||
539 | const Evas_Smart_Cb_Description **descriptions | ||
540 | unsigned int count | ||
541 | |||
542 | descriptions = evas_smart_callbacks_descriptions_get(self.cls, &count) | ||
543 | |||
544 | return _descriptions_to_list(descriptions, count) | ||
545 | |||
546 | def callback_descriptions_get(self): | ||
547 | cdef: | ||
548 | const Evas_Smart_Cb_Description **descriptions | ||
549 | unsigned int count | ||
550 | |||
551 | descriptions = evas_smart_callbacks_descriptions_get(self.cls, &count) | ||
552 | |||
553 | return _descriptions_to_list(descriptions, count) | ||
554 | |||
555 | def callback_description_find(self, name): | ||
556 | cdef: | ||
557 | const Evas_Smart_Cb_Description *desc | ||
558 | |||
559 | if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name) | ||
560 | desc = evas_smart_callback_description_find(self.cls, name) | ||
561 | if desc == NULL: | ||
562 | return None | ||
563 | |||
564 | return SmartCbDescription.create(desc) | ||
565 | |||
462 | @staticmethod | 566 | @staticmethod |
463 | def delete(obj): | 567 | def delete(obj): |
464 | """ | 568 | """ |
@@ -638,7 +742,7 @@ cdef class SmartObject(Object): | |||
638 | #_smart_classes.append(<uintptr_t>cls_def) | 742 | #_smart_classes.append(<uintptr_t>cls_def) |
639 | self._set_obj(evas_object_smart_add(canvas.obj, smart.cls)) | 743 | self._set_obj(evas_object_smart_add(canvas.obj, smart.cls)) |
640 | self._set_properties_from_keyword_args(kwargs) | 744 | self._set_properties_from_keyword_args(kwargs) |
641 | self.smart = smart | 745 | self._smart = smart |
642 | 746 | ||
643 | cdef int _set_obj(self, cEo *obj) except 0: | 747 | cdef int _set_obj(self, cEo *obj) except 0: |
644 | assert self.obj == NULL, "Object must be clean" | 748 | assert self.obj == NULL, "Object must be clean" |
@@ -699,6 +803,13 @@ cdef class SmartObject(Object): | |||
699 | eina_list_free(lst) | 803 | eina_list_free(lst) |
700 | return tuple(ret) | 804 | return tuple(ret) |
701 | 805 | ||
806 | property smart: | ||
807 | def __get__(self): | ||
808 | if self._smart is not None: | ||
809 | return self._smart | ||
810 | else: | ||
811 | return Smart.create(evas_object_smart_smart_get(self.obj)) | ||
812 | |||
702 | def smart_get(self): | 813 | def smart_get(self): |
703 | return self.smart | 814 | return self.smart |
704 | 815 | ||
@@ -947,5 +1058,114 @@ cdef class SmartObject(Object): | |||
947 | <void*>event_info if event_info is not None else NULL | 1058 | <void*>event_info if event_info is not None else NULL |
948 | ) | 1059 | ) |
949 | 1060 | ||
1061 | def callback_descriptions_set(self, descriptions): | ||
1062 | """Set an smart object **instance's** smart callbacks descriptions. | ||
1063 | |||
1064 | :return: ``True`` on success, ``False`` on failure. | ||
1065 | |||
1066 | These descriptions are hints to be used by introspection and are | ||
1067 | not enforced in any way. | ||
1068 | |||
1069 | It will not be checked if instance callbacks descriptions have the same | ||
1070 | name as respective possibly registered in the smart object **class**. | ||
1071 | Both are kept in different arrays and users of | ||
1072 | :meth:`callbacks_descriptions_get` should handle this case as they | ||
1073 | wish. | ||
1074 | |||
1075 | .. note:: | ||
1076 | |||
1077 | While instance callbacks descriptions are possible, they are | ||
1078 | **not** recommended. Use **class** callbacks descriptions | ||
1079 | instead as they make you smart object user's life simpler and | ||
1080 | will use less memory, as descriptions and arrays will be | ||
1081 | shared among all instances. | ||
1082 | |||
1083 | |||
1084 | :param descriptions: A list with :class:`SmartCbDescription` | ||
1085 | descriptions. List elements won't be modified at run time, but | ||
1086 | references to them and their contents will be made, so this array | ||
1087 | should be kept alive during the whole object's lifetime. | ||
1088 | |||
1089 | """ | ||
1090 | |||
1091 | if not evas_object_smart_callbacks_descriptions_set( | ||
1092 | self.obj, | ||
1093 | <const Evas_Smart_Cb_Description *>_descriptions_to_array(descriptions) | ||
1094 | ): | ||
1095 | raise ValueError("Could not set callback descriptions") | ||
1096 | |||
1097 | def callback_descriptions_get(self, get_class=True, get_instance=True): | ||
1098 | """Retrieve a smart object's known smart callback descriptions | ||
1099 | |||
1100 | This call searches for registered callback descriptions for both | ||
1101 | instance and class of the given smart object. These lists will be | ||
1102 | sorted by name. | ||
1103 | |||
1104 | .. note:: | ||
1105 | |||
1106 | If just class descriptions are of interest, try | ||
1107 | :meth:`Smart.callbacks_descriptions_get` instead. | ||
1108 | |||
1109 | :param bool get_class: Get class descriptions | ||
1110 | :param bool get_instance: Get instance descriptions | ||
1111 | :return: A tuple with two lists, for both class and instance | ||
1112 | descriptions. | ||
1113 | :rtype: tuple | ||
1114 | """ | ||
1115 | cdef: | ||
1116 | const Evas_Smart_Cb_Description **class_descriptions | ||
1117 | const Evas_Smart_Cb_Description **instance_descriptions | ||
1118 | unsigned int class_count, instance_count | ||
1119 | |||
1120 | evas_object_smart_callbacks_descriptions_get( | ||
1121 | self.obj, | ||
1122 | &class_descriptions if get_class is True else NULL, | ||
1123 | &class_count, | ||
1124 | &instance_descriptions if get_instance is True else NULL, | ||
1125 | &instance_count | ||
1126 | ) | ||
1127 | return ( | ||
1128 | _descriptions_to_list(class_descriptions, class_count), | ||
1129 | _descriptions_to_list(instance_descriptions, instance_count) | ||
1130 | ) | ||
1131 | |||
1132 | def callback_description_find(self, name, search_class=True, search_instance=True): | ||
1133 | """Find callback description for callback given in ``name``. | ||
1134 | |||
1135 | or ``None`` if not found. | ||
1136 | |||
1137 | :param string name: name of desired callback, must **not** be ``None``. | ||
1138 | :param bool search_class: whether to search in class descriptions | ||
1139 | :param bool search_instance: whether to search in instance descriptions | ||
1140 | :return: reference to description if found, ``None`` if not found. | ||
1141 | |||
1142 | .. | ||
1143 | The | ||
1144 | search have a special case for ``name`` being the same | ||
1145 | pointer as registered with Evas_Smart_Cb_Description, one | ||
1146 | can use it to avoid excessive use of strcmp(). | ||
1147 | """ | ||
1148 | cdef: | ||
1149 | const Evas_Smart_Cb_Description *class_description | ||
1150 | const Evas_Smart_Cb_Description *instance_description | ||
1151 | list ret = list() | ||
1152 | |||
1153 | if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name) | ||
1154 | |||
1155 | evas_object_smart_callback_description_find( | ||
1156 | self.obj, name, | ||
1157 | &class_description if search_class is True else NULL, | ||
1158 | &instance_description if search_instance is True else NULL | ||
1159 | ) | ||
1160 | |||
1161 | if class_description != NULL: | ||
1162 | ret.append(SmartCbDescription.create(class_description)) | ||
1163 | else: | ||
1164 | ret.append(None) | ||
1165 | if instance_description != NULL: | ||
1166 | ret.append(SmartCbDescription.create(instance_description)) | ||
1167 | else: | ||
1168 | ret.append(None) | ||
1169 | return ret | ||
950 | 1170 | ||
951 | _object_mapping_register("Evas_Smart", SmartObject) | 1171 | _object_mapping_register("Evas_Smart", SmartObject) |
diff --git a/examples/elementary/test_core_evas_smart.py b/examples/elementary/test_core_evas_smart.py index e1bb7cf..adb73fc 100644 --- a/examples/elementary/test_core_evas_smart.py +++ b/examples/elementary/test_core_evas_smart.py | |||
@@ -4,9 +4,8 @@ | |||
4 | import os | 4 | import os |
5 | from random import randint | 5 | from random import randint |
6 | 6 | ||
7 | from efl.eo import Eo | ||
8 | from efl.evas import SmartObject, Smart, EXPAND_BOTH, FILL_BOTH, Rectangle, \ | 7 | from efl.evas import SmartObject, Smart, EXPAND_BOTH, FILL_BOTH, Rectangle, \ |
9 | Line, FilledImage, Polygon, Text | 8 | Line, FilledImage, Polygon, Text, SmartCbDescription |
10 | from efl import elementary | 9 | from efl import elementary |
11 | from efl.elementary.window import StandardWindow | 10 | from efl.elementary.window import StandardWindow |
12 | from efl.elementary.box import Box | 11 | from efl.elementary.box import Box |
@@ -23,6 +22,7 @@ def random_color(): | |||
23 | 22 | ||
24 | 23 | ||
25 | class MySmart(Smart): | 24 | class MySmart(Smart): |
25 | |||
26 | @staticmethod | 26 | @staticmethod |
27 | def resize(smart_object, w, h): | 27 | def resize(smart_object, w, h): |
28 | print("RESIZE", w, h) | 28 | print("RESIZE", w, h) |
@@ -72,10 +72,15 @@ class MySmart(Smart): | |||
72 | def clip_unset(smart_object): | 72 | def clip_unset(smart_object): |
73 | pass | 73 | pass |
74 | 74 | ||
75 | descriptions = ( | ||
76 | SmartCbDescription("mycb", "i"), | ||
77 | ) | ||
78 | |||
79 | |||
75 | class MySmartObj(SmartObject): | 80 | class MySmartObj(SmartObject): |
76 | 81 | ||
77 | def __init__(self, canvas): | 82 | def __init__(self, canvas, smart): |
78 | SmartObject.__init__(self, canvas, MySmart()) | 83 | SmartObject.__init__(self, canvas, smart) |
79 | 84 | ||
80 | # gray background | 85 | # gray background |
81 | self.bg = Rectangle(canvas, color=(128, 128, 128, 128)) | 86 | self.bg = Rectangle(canvas, color=(128, 128, 128, 128)) |
@@ -131,11 +136,13 @@ class MySmartObj(SmartObject): | |||
131 | 136 | ||
132 | 137 | ||
133 | def btn_add_cb(b): | 138 | def btn_add_cb(b): |
134 | sm = MySmartObj(b.evas) | 139 | sm = MySmart(callback_descriptions=descriptions) |
135 | sm.size = 100, 100 | 140 | print(sm.callback_descriptions) |
136 | sm.pos = 100, 100 | 141 | so = MySmartObj(b.evas, sm) |
137 | sm.show() | 142 | so.size = 100, 100 |
138 | objects.append(sm) | 143 | so.pos = 100, 100 |
144 | so.show() | ||
145 | objects.append(so) | ||
139 | 146 | ||
140 | 147 | ||
141 | def btn_del_cb(b): | 148 | def btn_del_cb(b): |
@@ -154,6 +161,7 @@ def btn_show_cb(b): | |||
154 | 161 | ||
155 | def core_evas_smart_clicked(obj, item=None): | 162 | def core_evas_smart_clicked(obj, item=None): |
156 | win = StandardWindow("evassmart", "Evas Smart Object Test", autodel=True) | 163 | win = StandardWindow("evassmart", "Evas Smart Object Test", autodel=True) |
164 | print(win.callback_descriptions_get()) | ||
157 | if obj is None: | 165 | if obj is None: |
158 | win.callback_delete_request_add(lambda o: elementary.exit()) | 166 | win.callback_delete_request_add(lambda o: elementary.exit()) |
159 | 167 | ||
diff --git a/include/efl.evas.pxd b/include/efl.evas.pxd index 1ca573f..15ccc57 100644 --- a/include/efl.evas.pxd +++ b/include/efl.evas.pxd | |||
@@ -387,7 +387,7 @@ cdef extern from "Evas.h": | |||
387 | void (*member_add)(Evas_Object *o, Evas_Object *child) | 387 | void (*member_add)(Evas_Object *o, Evas_Object *child) |
388 | void (*member_del)(Evas_Object *o, Evas_Object *child) | 388 | void (*member_del)(Evas_Object *o, Evas_Object *child) |
389 | const Evas_Smart_Class *parent | 389 | const Evas_Smart_Class *parent |
390 | Evas_Smart_Cb_Description *callbacks | 390 | const Evas_Smart_Cb_Description *callbacks |
391 | const Evas_Smart_Interface **interfaces | 391 | const Evas_Smart_Interface **interfaces |
392 | const void *data | 392 | const void *data |
393 | 393 | ||
@@ -781,12 +781,14 @@ cdef extern from "Evas.h": | |||
781 | 781 | ||
782 | 782 | ||
783 | #################################################################### | 783 | #################################################################### |
784 | # Smart Object (py3:TODO) | 784 | # Smart Object |
785 | # | 785 | # |
786 | void evas_smart_free(Evas_Smart *s) | 786 | void evas_smart_free(Evas_Smart *s) |
787 | Evas_Smart *evas_smart_class_new(Evas_Smart_Class *sc) | 787 | Evas_Smart *evas_smart_class_new(Evas_Smart_Class *sc) |
788 | Evas_Smart_Class *evas_smart_class_get(Evas_Smart *s) | 788 | Evas_Smart_Class *evas_smart_class_get(Evas_Smart *s) |
789 | const Eo_Class *evas_object_smart_class_get() | 789 | const Eo_Class *evas_object_smart_class_get() |
790 | const Evas_Smart_Cb_Description **evas_smart_callbacks_descriptions_get(const Evas_Smart *s, unsigned int *count) | ||
791 | const Evas_Smart_Cb_Description *evas_smart_callback_description_find(const Evas_Smart *s, const char *name) | ||
790 | 792 | ||
791 | void *evas_smart_data_get(Evas_Smart *s) | 793 | void *evas_smart_data_get(Evas_Smart *s) |
792 | 794 | ||
@@ -809,6 +811,9 @@ cdef extern from "Evas.h": | |||
809 | void evas_object_smart_move_children_relative(Evas_Object *obj, int dx, int dy) | 811 | void evas_object_smart_move_children_relative(Evas_Object *obj, int dx, int dy) |
810 | Eina_Iterator *evas_object_smart_iterator_new(const Evas_Object_Smart *obj) | 812 | Eina_Iterator *evas_object_smart_iterator_new(const Evas_Object_Smart *obj) |
811 | void evas_object_smart_clipped_smart_set(Evas_Smart_Class *sc) | 813 | void evas_object_smart_clipped_smart_set(Evas_Smart_Class *sc) |
814 | Eina_Bool evas_object_smart_callbacks_descriptions_set(Evas_Object_Smart *obj, const Evas_Smart_Cb_Description *descriptions) | ||
815 | void evas_object_smart_callbacks_descriptions_get(const Evas_Object_Smart *obj, const Evas_Smart_Cb_Description ***class_descriptions, unsigned int *class_count, const Evas_Smart_Cb_Description ***instance_descriptions, unsigned int *instance_count) | ||
816 | void evas_object_smart_callback_description_find(const Evas_Object_Smart *obj, const char *name, const Evas_Smart_Cb_Description **class_description, const Evas_Smart_Cb_Description **instance_description) | ||
812 | 817 | ||
813 | 818 | ||
814 | #################################################################### | 819 | #################################################################### |
@@ -1210,11 +1215,20 @@ cdef class Textblock(Object): | |||
1210 | # ctypedef object(*Smart_Conv_Func)(void *) | 1215 | # ctypedef object(*Smart_Conv_Func)(void *) |
1211 | 1216 | ||
1212 | cdef class Smart: | 1217 | cdef class Smart: |
1213 | cdef Evas_Smart *cls | 1218 | cdef: |
1219 | Evas_Smart *cls | ||
1220 | const Evas_Smart_Class *cls_def | ||
1221 | |||
1222 | @staticmethod | ||
1223 | cdef inline create(Evas_Smart *cls): | ||
1224 | cdef Smart ret = Smart.__new__(Smart) | ||
1225 | ret.cls = cls | ||
1226 | ret.cls_def = evas_smart_class_get(cls) | ||
1227 | return ret | ||
1214 | 1228 | ||
1215 | cdef class SmartObject(Object): | 1229 | cdef class SmartObject(Object): |
1216 | cdef: | 1230 | cdef: |
1217 | public Smart smart | 1231 | Smart _smart |
1218 | dict _smart_callback_specs | 1232 | dict _smart_callback_specs |
1219 | int _set_obj(self, cEo *obj) except 0 | 1233 | int _set_obj(self, cEo *obj) except 0 |
1220 | int _callback_add_full(self, event, object(*)(void*), func, tuple args, dict kargs) except 0 | 1234 | int _callback_add_full(self, event, object(*)(void*), func, tuple args, dict kargs) except 0 |