From 05c1d5a0ed07b2f1e5069c8a4a03e674d151129c Mon Sep 17 00:00:00 2001 From: dwk Date: Thu, 22 May 2008 02:40:59 -0600 Subject: [PATCH] Expanded on same-loop-handler-signature code, added staticgen.pl. Eliminated set_panel_callbacks(), the function which took as parameters many, many function pointers. Now, set_panel_data() is called followed by several calls to set_panel_callback(). Added staticgen.pl to automatically generate xuni_loadso_load_function() functions to allow LOADSO_STATIC_VERSION. Make the xuni test programs not display anything upon successful execution. Added Doxygen documentation to functions in resource.c, dump.c, and widget.c. --- TODO | 2 +- src/editor/editor.c | 20 +++++-- src/loop.c | 70 ++++++++++++------------- src/loop.h | 7 +-- src/memory.c | 6 +-- src/resource/libexpat.c | 6 +-- src/resource/resource.c | 27 ++++++++++ src/staticgen.pl | 137 ++++++++++++++++++++++++++++++++++++++++++++++++ src/test/main.c | 32 +++++------ src/widget/checkbox.c | 9 ++++ src/widget/dump.c | 8 +++ src/widget/panel.c | 24 +++++++-- src/widget/panel.h | 4 ++ 13 files changed, 281 insertions(+), 71 deletions(-) create mode 100755 src/staticgen.pl diff --git a/TODO b/TODO index 1df66f4..93659d9 100644 --- a/TODO +++ b/TODO @@ -338,4 +338,4 @@ Make the images for the glowbox theme smaller. Need to test call_blit_surface(). -Test STATIC_LOADSO_FUNC, because some functions were renamed. +[done] Test STATIC_LOADSO_FUNC, because some functions were renamed. diff --git a/src/editor/editor.c b/src/editor/editor.c index d5c7630..35fb500 100644 --- a/src/editor/editor.c +++ b/src/editor/editor.c @@ -101,15 +101,28 @@ enum wid_t { }; static void init_loop_data(struct gui_t *gui) { + struct widget_t *panel; void *data; init_wid(gui->widget, gui->widget, PANEL_EDITOR, "editor"); + panel = widget_nameid_access(gui->widget, PANEL_EDITOR); + data = xuni_memory_allocate(sizeof(struct editor_data_t)); - set_panel_callbacks(widget_nameid_access(gui->widget, PANEL_EDITOR), + set_panel_data(panel, data, 0); + set_panel_callback(panel, PANEL_EVENT_INIT, editor_init); + set_panel_callback(panel, PANEL_EVENT_START, editor_start); + set_panel_callback(panel, PANEL_EVENT_EVENT, editor_event); + set_panel_callback(panel, PANEL_EVENT_SEL, default_panel_sel); + set_panel_callback(panel, PANEL_EVENT_CLICK, editor_click); + set_panel_callback(panel, PANEL_EVENT_DEACTIVATE, editor_deactivate); + set_panel_callback(panel, PANEL_EVENT_PAINT, editor_paint); + set_panel_callback(panel, PANEL_EVENT_FREE, editor_free); + + /*set_panel_callbacks(widget_nameid_access(gui->widget, PANEL_EDITOR), data, 0, editor_init, editor_start, editor_event, default_panel_sel, editor_click, editor_deactivate, - editor_paint, editor_free); + editor_paint, editor_free);*/ } static const char *get_mode_name(enum editor_mode_t mode) { @@ -159,9 +172,6 @@ static int editor_start(struct xuni_t *xuni, struct panel_data_t *data) { } static int editor_event(struct xuni_t *xuni, struct panel_data_t *data) { -/*static int editor_event(void *vdata, struct xuni_t *xuni, panel_type_t *mode, - SDL_Event *event) {*/ - struct editor_data_t *edata = data->data; struct widget_t *cbox; int repaint = 0; diff --git a/src/loop.c b/src/loop.c index 63ef624..11d45ce 100644 --- a/src/loop.c +++ b/src/loop.c @@ -18,7 +18,6 @@ static int call_perform_click_func(struct xuni_t *xuni, struct panel_data_t *panel, struct widget_t *widget, panel_type_t *mode); -static void call_free_funcs(struct widget_t *widget, struct xuni_t *xuni); static SDL_Cursor *sdl_cursor_from_xpm(const char *image[]); static void set_widget_cursor(struct xuni_t *xuni); @@ -73,7 +72,29 @@ void call_init_funcs(struct xuni_t *xuni, struct widget_t *widget, } } -int panel_event_recursive(struct xuni_t *xuni, struct panel_event_t *data, +void call_free_funcs(struct xuni_t *xuni, struct widget_t *widget) { + size_t x; + + if(!widget) return; + + if(widget->type == WIDGET_PANEL + && widget->p.panel->event[PANEL_EVENT_FREE].handler) { + + (*widget->p.panel->event[PANEL_EVENT_FREE].handler) + (xuni, widget->p.panel); + } + + if(widget->compose) { + for(x = 0; x < widget->compose->widgets; x ++) { + call_free_funcs(xuni, widget->compose->widget[x]); + } + } +} + +/* !!! Note that because of this function, the handler member of the structure + passed to panel event handlers is not defined. +*/ +int panel_event_recursive(struct xuni_t *xuni, struct panel_data_t *data, enum panel_event_type_t type, struct widget_t *widget) { int r = 0; @@ -81,8 +102,10 @@ int panel_event_recursive(struct xuni_t *xuni, struct panel_event_t *data, if(!widget) return 0; - if(widget->type == WIDGET_PANEL && data->handler) { - (*data->handler)(xuni, widget->p.panel); + if(widget->type == WIDGET_PANEL + && widget->p.panel->event[type].handler) { + + (*widget->p.panel->event[type].handler)(xuni, data); } if(widget->compose) { @@ -132,28 +155,6 @@ void call_deactivate_func(struct xuni_t *xuni, struct widget_t *widget) { } } -static void call_free_funcs(struct widget_t *widget, struct xuni_t *xuni) { - size_t x; - - if(!widget) return; - - if(widget->type == WIDGET_PANEL) { - if(widget->p.panel->event[PANEL_EVENT_FREE].handler) { - (*widget->p.panel->event[PANEL_EVENT_FREE].handler) - (xuni, widget->p.panel); - } - - /* this is handled by free_widget() */ - /*xuni_memory_free(widget->p.panel->data);*/ - } - - if(widget->compose) { - for(x = 0; x < widget->compose->widgets; x ++) { - call_free_funcs(widget->compose->widget[x], xuni); - } - } -} - /*#define HIDE_COMBOBOX_POPUPS*/ int default_panel_sel(struct xuni_t *xuni, struct panel_data_t *data) { @@ -218,6 +219,7 @@ int set_default_widget_sel(struct xuni_t *xuni, panel_type_t mode, return r; } +#if !1 void set_panel_callbacks(struct widget_t *widget, void *vdata, int frameupdate, panel_event_func_t init_func, @@ -231,14 +233,7 @@ void set_panel_callbacks(struct widget_t *widget, void *vdata, widget->p.panel->data = vdata; widget->p.panel->frameupdate = frameupdate; - /*widget->p.panel->init_func = init_func; - widget->p.panel->start_func = start_func; - widget->p.panel->event_func = event_func; - widget->p.panel->set_widget_sel_func = set_widget_sel_func; - widget->p.panel->perform_click_func = perform_click_func; - widget->p.panel->deactivate_func = deactivate_func; - widget->p.panel->paint_func = paint_func; - widget->p.panel->free_func = free_func;*/ + widget->p.panel->event[PANEL_EVENT_INIT].handler = init_func; widget->p.panel->event[PANEL_EVENT_START].handler = start_func; widget->p.panel->event[PANEL_EVENT_EVENT].handler = event_func; @@ -252,6 +247,7 @@ void set_panel_callbacks(struct widget_t *widget, void *vdata, widget->p.panel->accel = 0; } +#endif void execute_callback(struct xuni_t *xuni, struct xuni_callback_t *callback) { if(callback && callback->func) { @@ -337,7 +333,8 @@ void main_loop(struct xuni_t *xuni, struct xuni_callback_t *always, set_caption("Quitting . . ."); - call_free_funcs(xuni->gui->widget, xuni); + /*panel_event_recursive(xuni, 0, PANEL_EVENT_FREE, xuni->gui->widget);*/ + call_free_funcs(xuni, xuni->gui->widget); } /* An XPM image of a CURSOR_TEXT, used when the mouse is inside textboxes. */ @@ -547,8 +544,7 @@ static int process_event(SDL_Event *event, panel_type_t *mode, xuni->gui->widget->p.panel ->event[PANEL_EVENT_EVENT].p.event.event = event; - panel_event_recursive(xuni, - &xuni->gui->widget->p.panel->event[PANEL_EVENT_EVENT], + panel_event_recursive(xuni, xuni->gui->widget->p.panel, PANEL_EVENT_EVENT, xuni->gui->widget); } diff --git a/src/loop.h b/src/loop.h index 6b6c2b9..861fa87 100644 --- a/src/loop.h +++ b/src/loop.h @@ -11,7 +11,8 @@ void call_init_funcs(struct xuni_t *xuni, struct widget_t *widget, struct resource_t *settings); -int panel_event_recursive(struct xuni_t *xuni, struct panel_event_t *data, +void call_free_funcs(struct xuni_t *xuni, struct widget_t *widget); +int panel_event_recursive(struct xuni_t *xuni, struct panel_data_t *data, enum panel_event_type_t type, struct widget_t *widget); void call_deactivate_func(struct xuni_t *xuni, struct widget_t *widget); @@ -19,7 +20,7 @@ int default_panel_sel(struct xuni_t *xuni, struct panel_data_t *data); int set_default_widget_sel(struct xuni_t *xuni, panel_type_t mode, int xp, int yp, int click, void *vdata); -void set_panel_callbacks(struct widget_t *widget, void *vdata, +/*void set_panel_callbacks(struct widget_t *widget, void *vdata, int frameupdate, panel_event_func_t init_func, panel_event_func_t start_func, @@ -28,7 +29,7 @@ void set_panel_callbacks(struct widget_t *widget, void *vdata, panel_event_func_t perform_click_func, panel_event_func_t deactivate_func, panel_event_func_t paint_func, - panel_event_func_t free_func); + panel_event_func_t free_func);*/ void execute_callback(struct xuni_t *xuni, struct xuni_callback_t *callback); void main_loop(struct xuni_t *xuni, struct xuni_callback_t *always, diff --git a/src/memory.c b/src/memory.c index 7a9b408..2b179a8 100644 --- a/src/memory.c +++ b/src/memory.c @@ -92,7 +92,7 @@ void xuni_memory_free_all(void) { #else #define GARBAGE_COLLECT_ALL -#define RECORD_MAXIMUMS +/*#define RECORD_MAXIMUMS*/ #define DEBUG_UNALLOCATED_DECREMENT #define DUMP_EXTRA_MEMORY @@ -710,14 +710,14 @@ void xuni_memory_free_all(void) { #endif #ifdef DUMP_EXTRA_MEMORY - printf("Freeing all extra memory:\n"); + /*printf("Freeing all extra memory:\n");*/ #endif for(x = 0; x < memory.n; x ++) { if(!memory.data[x].count) continue; #ifdef DUMP_EXTRA_MEMORY - printf(" Freeing "); + printf("Freeing "); print_block(x); if(!strcmp(memory.data[x].func, "xuni_memory_duplicate_string")) { diff --git a/src/resource/libexpat.c b/src/resource/libexpat.c index 46b4fbd..575bf14 100644 --- a/src/resource/libexpat.c +++ b/src/resource/libexpat.c @@ -42,8 +42,6 @@ static void add_new_string(struct resource_data_t *element, const char *text, size_t len); static void resize_existing_string(char **str, const char *text, size_t len); -static void XMLCALL default_handler(void *vdata, const XML_Char *text, - int len); static void XMLCALL start_element(void *vdata, const XML_Char *name, const XML_Char **attribute); static void process_attribute(struct resource_stack_t *data, const char *name, @@ -62,7 +60,7 @@ void parse_resource_file(struct resource_data_t *resource, stack->parser = XML_ParserCreate(NULL); XML_SetUserData(stack->parser, stack); - XML_SetDefaultHandler(stack->parser, default_handler); + /*XML_SetDefaultHandler(stack->parser, default_handler);*/ XML_SetElementHandler(stack->parser, start_element, end_element); XML_SetCharacterDataHandler(stack->parser, handle_text); @@ -179,11 +177,13 @@ static void resize_existing_string(char **str, const char *text, size_t len) { (*str)[slen + len] = 0; } +#if 0 static void XMLCALL default_handler(void *vdata, const XML_Char *text, int len) { /*printf("default_handler(): \"%.*s\" [%i]\n", len, text, len);*/ } +#endif static void XMLCALL start_element(void *vdata, const XML_Char *name, const XML_Char **attribute) { diff --git a/src/resource/resource.c b/src/resource/resource.c index d112a21..c4a0edc 100644 --- a/src/resource/resource.c +++ b/src/resource/resource.c @@ -29,10 +29,21 @@ void init_resource(struct resource_t *resource) { resource->data->data.tag->list = 0; } +/*! Writes the resource tree \a resource into the file \a filename. At the + moment, this file will always be in semi-readable XML. (Information about + which resource file a resource element came from is not saved, so only one + file is generated with the entire tree.) + + \param resource The resource tree to recursively write to the file. + \param filename The file to save the resource tree to. +*/ void write_resource(struct resource_data_t *resource, const char *filename) { xmlwrite_write_resource(resource, filename); } +/*! Allocates and initializes an empty struct resource_list_t. + \return The newly allocated resource_list_t. +*/ struct resource_list_t *new_resource_list(void) { struct resource_list_t *list = xuni_memory_allocate(sizeof(*list)); @@ -162,6 +173,14 @@ int parse_resource_filename(struct resource_data_t *resource, if(filename) parse_resource(data, filename); }*/ +/*! Recursively examines the resource tree \a data, looking for "path" and + "include" tags. Path tags are modified so that their path is relative to + the xuni executable instead of to the original resource file, and include + tags are used to recursively specify other resource files. + + \param data The existing resource tree to add to or modify. + \param path The file path thus far, to the current resource file. +*/ void make_paths_relative_to_xuni(struct resource_data_t *data, char **path) { struct resource_list_t *list; const char *filename; @@ -206,6 +225,14 @@ void make_paths_relative_to_xuni(struct resource_data_t *data, char **path) { return; } +/*! Calculates how much of \a filename is the path to the file. + + \param filename The filename to examine, which could include a relative or + absolute path. + \return The position in the string \a filename that the path ends and the + filename begins. (The trailing directory separator is included in the + path, if found.) +*/ static size_t filename_path_length(const char *filename) { size_t x; for(x = strlen(filename); x; x --) { diff --git a/src/staticgen.pl b/src/staticgen.pl new file mode 100755 index 0000000..57c5811 --- /dev/null +++ b/src/staticgen.pl @@ -0,0 +1,137 @@ +#!/usr/bin/perl + +my $firstfunc = 1; +my $path = ''; +my @funclist = (); + +print_header(); + +foreach my $file (@ARGV) { + $path = ''; + get_list(get_path($file), read_file($file)); +} + +print_funclist(); + +print_footer(); + +sub get_path { + my $file = shift; + $file =~ /(.*)\// && return $1; + + return ''; +} + +sub get_filename { + my $file = shift; + $file =~ /\/([^\/]+)/; + + return $1; +} + +sub read_file { + my $file = shift; + + #print "--- $file\n"; + + open(FILE, "$file"); + my @data = ; + close FILE; + + return @data; +} + +sub get_list { + my $path = shift; + my @data = @_; + my $in = 0; + my @list = (); + + foreach my $line (@data) { + if($in) { + if($line =~ /<\/handler/) { + $in = 0; + } + else { + if($line =~ /<[\w\d_]+>([\w\d_]+)<\/[\w\d_]+>/) { + push(@funclist, $1); + } + } + } + else { + if($line =~ /(.*)<\/include>/) { + my $file = $1; + my $addpath = get_path($file); + my $temppath = $path; + + if($addpath ne '') { + $temppath .= "/$addpath"; + } + + get_list($temppath, + read_file("$temppath/" . get_filename($file))); + } + + if($line =~ /compose->widget[0]->compose->widget[0]->p.box->style; @@ -131,6 +136,10 @@ void toggle_checkbox(struct widget_t *widget) { else *style = BOX_STYLE_NORMAL; } +/*! Sets the selected state of the checkbox \a widget. + \param widget The checkbox to set the state of. + \param checked The state to set the checkbox to, either true or false. +*/ void set_checkbox(struct widget_t *widget, int checked) { if(checked) { widget->compose->widget[WID_CHECKBOX_BUTTON]->compose diff --git a/src/widget/dump.c b/src/widget/dump.c index eab6e04..87c018e 100644 --- a/src/widget/dump.c +++ b/src/widget/dump.c @@ -38,6 +38,14 @@ void print_widget_backtrace(struct xuni_t *xuni, struct widget_t *widget) { putchar('\n'); } +/*! Returns the name of the widget type \a type. This name is determined with + the xuni_t::wtype structure. + + \param xuni A pointer to the xuni structure. (Only the wtype member is + used.) + \param type The type of widget to return the name of. + \return A string that is the name of the widget type \a type. +*/ const char *get_widget_type_name(struct xuni_t *xuni, enum widget_type_t type) { diff --git a/src/widget/panel.c b/src/widget/panel.c index fac442e..2a858ff 100644 --- a/src/widget/panel.c +++ b/src/widget/panel.c @@ -33,11 +33,17 @@ void panel_widget_event(struct xuni_t *xuni, struct widget_t *widget, } void init_panel(struct widget_t *widget) { - enum panel_event_type_t x; - widget->type = WIDGET_PANEL; widget->p.panel = xuni_memory_allocate(sizeof(*widget->p.panel)); + init_panel_data(widget); + + /*widget->compose = allocate_panel(widget);*/ +} + +void init_panel_data(struct widget_t *widget) { + enum panel_event_type_t x; + widget->p.panel->data = 0; widget->p.panel->frameupdate = 0; @@ -49,8 +55,20 @@ void init_panel(struct widget_t *widget) { widget->p.panel->nameid = 0; widget->p.panel->accel = 0; +} + +void set_panel_data(struct widget_t *widget, void *vdata, int frameupdate) { + widget->p.panel->data = vdata; + widget->p.panel->frameupdate = frameupdate; - /*widget->compose = allocate_panel(widget);*/ + widget->p.panel->nameid = 0; + widget->p.panel->accel = 0; +} + +void set_panel_callback(struct widget_t *widget, enum panel_event_type_t type, + panel_event_func_t func) { + + widget->p.panel->event[type].handler = func; } static func_point_t panel_load_handler(void *object, diff --git a/src/widget/panel.h b/src/widget/panel.h index 5c8c715..2f7c45d 100644 --- a/src/widget/panel.h +++ b/src/widget/panel.h @@ -18,6 +18,10 @@ void panel_widget_event(struct xuni_t *xuni, struct widget_t *widget, enum widget_event_t event); void init_panel(struct widget_t *widget); +void init_panel_data(struct widget_t *widget); +void set_panel_data(struct widget_t *widget, void *vdata, int frameupdate); +void set_panel_callback(struct widget_t *widget, enum panel_event_type_t type, + panel_event_func_t func); void init_panel_from_resource(struct xuni_t *xuni, struct widget_t *widget, struct resource_list_t *list); void free_panel(struct xuni_t *xuni, struct panel_t *panel); -- 2.11.4.GIT