rework typecheck

This commit is contained in:
xianjimli 2019-02-19 18:00:10 +08:00
parent 22674b0d6d
commit e0a92f07ab
8 changed files with 63 additions and 39 deletions

View File

@ -242,4 +242,20 @@ typedef struct _widget_vtable_t widget_vtable_t;
#define TK_LONG_PRESS_TIME 1000 #define TK_LONG_PRESS_TIME 1000
#ifdef WITH_SDL
#define WITH_WIDGET_TYPE_CHECK 1
#endif /*WITH_SDL*/
#ifdef WITH_WIDGET_TYPE_CHECK
#define TK_REF_VTABLE(vt) &(g_##vt##_vtable)
#define TK_PARENT_VTABLE(vt) TK_REF_VTABLE(vt)
#define TK_DECL_VTABLE(vt) const widget_vtable_t g_##vt##_vtable
#define TK_EXTERN_VTABLE(vt) extern const widget_vtable_t g_##vt##_vtable
#else
#define TK_REF_VTABLE(vt) &(s_##vt##_vtable)
#define TK_PARENT_VTABLE(vt) NULL
#define TK_DECL_VTABLE(vt) static const widget_vtable_t s_##vt##_vtable
#define TK_EXTERN_VTABLE(vt)
#endif /*WITH_WIDGET_TYPE_CHECK*/
#endif /*TK_TYPES_DEF_H*/ #endif /*TK_TYPES_DEF_H*/

View File

@ -1706,6 +1706,7 @@ ret_t widget_on_paint_end(widget_t* widget, canvas_t* c);
const char** widget_get_persistent_props(void); const char** widget_get_persistent_props(void);
bool_t widget_is_instance_of(widget_t* widget, const widget_vtable_t* vt); bool_t widget_is_instance_of(widget_t* widget, const widget_vtable_t* vt);
#define WIDGET_IS_INSTANCE_OF(widget, name) widget_is_instance_of(widget, TK_REF_VTABLE(app_bar))
END_C_DECLS END_C_DECLS

View File

@ -169,23 +169,23 @@ ret_t widget_on_paint_null(widget_t* widget, canvas_t* c) {
return RET_OK; return RET_OK;
} }
const widget_vtable_t g_widget_vtable = {.size = sizeof(widget_t), TK_DECL_VTABLE(widget) = {.size = sizeof(widget_t),
.type = WIDGET_TYPE_NONE, .type = WIDGET_TYPE_NONE,
.parent = NULL, .parent = NULL,
.invalidate = widget_invalidate_default, .invalidate = widget_invalidate_default,
.on_event = widget_on_event_default, .on_event = widget_on_event_default,
.on_paint_self = widget_on_paint_self_default, .on_paint_self = widget_on_paint_self_default,
.on_paint_children = widget_on_paint_children_default, .on_paint_children = widget_on_paint_children_default,
.on_keydown = widget_on_keydown_default, .on_keydown = widget_on_keydown_default,
.on_keyup = widget_on_keyup_default, .on_keyup = widget_on_keyup_default,
.on_pointer_down = widget_on_pointer_down_default, .on_pointer_down = widget_on_pointer_down_default,
.on_pointer_move = widget_on_pointer_move_default, .on_pointer_move = widget_on_pointer_move_default,
.on_pointer_up = widget_on_pointer_up_default, .on_pointer_up = widget_on_pointer_up_default,
.get_prop = widget_get_prop_default, .get_prop = widget_get_prop_default,
.set_prop = widget_set_prop_default, .set_prop = widget_set_prop_default,
.find_target = widget_find_target_default, .find_target = widget_find_target_default,
.on_destroy = widget_on_destroy_default}; .on_destroy = widget_on_destroy_default};
const widget_vtable_t* widget_vtable_default() { const widget_vtable_t* widget_vtable_default() {
return &g_widget_vtable; return TK_REF_VTABLE(widget);
} }

View File

@ -48,7 +48,7 @@ ret_t widget_destroy_default(widget_t* widget);
ret_t widget_on_paint_null(widget_t* widget, canvas_t* c); ret_t widget_on_paint_null(widget_t* widget, canvas_t* c);
/*public for subclass*/ /*public for subclass*/
extern const widget_vtable_t g_widget_vtable; TK_EXTERN_VTABLE(widget);
END_C_DECLS END_C_DECLS

10
src/widgets/app_bar.c Executable file → Normal file
View File

@ -22,15 +22,17 @@
#include "tkc/mem.h" #include "tkc/mem.h"
#include "widgets/app_bar.h" #include "widgets/app_bar.h"
static const widget_vtable_t s_app_bar_vtable = { TK_DECL_VTABLE(app_bar) = {.size = sizeof(app_bar_t),
.size = sizeof(app_bar_t), .type = WIDGET_TYPE_APP_BAR, .create = app_bar_create}; .type = WIDGET_TYPE_APP_BAR,
.parent = TK_PARENT_VTABLE(widget),
.create = app_bar_create};
widget_t* app_bar_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) { widget_t* app_bar_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
return widget_create(parent, &s_app_bar_vtable, x, y, w, h); return widget_create(parent, TK_REF_VTABLE(app_bar), x, y, w, h);
} }
widget_t* app_bar_cast(widget_t* widget) { widget_t* app_bar_cast(widget_t* widget) {
return_value_if_fail(widget != NULL && widget->vt == &s_app_bar_vtable, NULL); return_value_if_fail(WIDGET_IS_INSTANCE_OF(widget, app_bar), NULL);
return widget; return widget;
} }

View File

@ -91,6 +91,11 @@ widget_t* app_bar_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
*/ */
widget_t* app_bar_cast(widget_t* widget); widget_t* app_bar_cast(widget_t* widget);
#define APP_BAR(w) ((app_bar_t*)(app_bar_cast(w))
/*public for subclass and runtime type check*/
TK_EXTERN_VTABLE(app_bar);
END_C_DECLS END_C_DECLS
#endif /*TK_APP_BAR_H*/ #endif /*TK_APP_BAR_H*/

View File

@ -174,22 +174,22 @@ static ret_t button_on_destroy(widget_t* widget) {
static const char* s_button_properties[] = {WIDGET_PROP_REPEAT, NULL}; static const char* s_button_properties[] = {WIDGET_PROP_REPEAT, NULL};
const widget_vtable_t g_button_vtable = {.size = sizeof(button_t), TK_DECL_VTABLE(button) = {.size = sizeof(button_t),
.type = WIDGET_TYPE_BUTTON, .type = WIDGET_TYPE_BUTTON,
.enable_pool = TRUE, .enable_pool = TRUE,
.parent = &g_widget_vtable, .parent = TK_PARENT_VTABLE(widget),
.create = button_create, .create = button_create,
.clone_properties = s_button_properties, .clone_properties = s_button_properties,
.persistent_properties = s_button_properties, .persistent_properties = s_button_properties,
.on_event = button_on_event, .on_event = button_on_event,
.set_prop = button_set_prop, .set_prop = button_set_prop,
.get_prop = button_get_prop, .get_prop = button_get_prop,
.get_prop_default_value = button_get_prop_default_value, .get_prop_default_value = button_get_prop_default_value,
.on_destroy = button_on_destroy, .on_destroy = button_on_destroy,
.on_paint_self = widget_on_paint_self_default}; .on_paint_self = widget_on_paint_self_default};
widget_t* button_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) { widget_t* button_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
widget_t* widget = widget_create(parent, &g_button_vtable, x, y, w, h); widget_t* widget = widget_create(parent, TK_REF_VTABLE(button), x, y, w, h);
button_t* button = BUTTON(widget); button_t* button = BUTTON(widget);
return_value_if_fail(button != NULL, NULL); return_value_if_fail(button != NULL, NULL);
@ -202,7 +202,7 @@ widget_t* button_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
} }
widget_t* button_cast(widget_t* widget) { widget_t* button_cast(widget_t* widget) {
return_value_if_fail(widget_is_instance_of(widget, &g_button_vtable), NULL); return_value_if_fail(widget_is_instance_of(widget, TK_REF_VTABLE(button)), NULL);
return widget; return widget;
} }

View File

@ -138,8 +138,8 @@ ret_t button_set_repeat(widget_t* widget, int32_t repeat);
#define BUTTON(widget) ((button_t*)(button_cast(widget))) #define BUTTON(widget) ((button_t*)(button_cast(widget)))
/*public for subclass*/ /*public for subclass and runtime type check*/
extern const widget_vtable_t g_button_vtable; TK_EXTERN_VTABLE(button);
END_C_DECLS END_C_DECLS