changeset 210:3fadd2f2742e

M4 macros to generate code for dynamic loading. - Introduce sprite. - Add mb_sprite_t and mb_sprite_lsym_t - mb_sprite_lsym_t is sprite with symbol that searched with linear search. - Add mb_sprite_lsym_t as first member variable of sprite. - Add symbol table to generated C code.
author Thinker K.F. Li <thinker@branda.to>
date Fri, 12 Dec 2008 00:33:54 +0800
parents 6f63aa67ed83
children 41eab0a10651
files include/mb_types.h tools/mb_c_header.m4 tools/mb_c_source.m4 tools/svg2code.py
diffstat 4 files changed, 133 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/include/mb_types.h	Wed Dec 10 17:15:26 2008 +0800
+++ b/include/mb_types.h	Fri Dec 12 00:33:54 2008 +0800
@@ -224,4 +224,27 @@
     mb_obj_t *(*get_obj_with_name)(mb_sprite_t *sprite, const char *id);
 };
 
+
+/*! \defgroup mb_sprite_lsym Sprite with linear symbol table.
+ * @{
+ */ 
+struct _mb_sprite_lsym_entry {
+    const char *sym;
+    const int offset;
+};
+typedef struct _mb_sprite_lsym_entry mb_sprite_lsym_entry_t;
+
+/*! \brief A sub-type of mb_sprite_t with linear symbol table.
+ *
+ * This type of sprite search symbols with linear/or binary searching.
+ */
+struct _mb_sprite_lsym {
+    mb_sprite_t sprite;
+    int num_entries;
+    mb_sprite_lsym_entry_t *entries;
+};
+typedef struct _mb_sprite_lsym mb_sprite_lsym_t;
+
+/* @} */
+
 #endif /* __MB_TYPES_H_ */
--- a/tools/mb_c_header.m4	Wed Dec 10 17:15:26 2008 +0800
+++ b/tools/mb_c_header.m4	Fri Dec 12 00:33:54 2008 +0800
@@ -40,6 +40,7 @@
 define([COORD_MATRIX],)
 define([SHAPE_TRANSLATE],)
 define([SHAPE_MATRIX],)
+define([ADD_SYMBOL],)
 
 define([MADBUTTERFLY],[dnl
 [#ifndef __$1_H_
@@ -48,6 +49,7 @@
 typedef struct $1 $1_t;
 
 struct $1 {
+    mb_sprite_lsym_t lsym;
     redraw_man_t *rdman;
     coord_t *root_coord;]
 $2[]dnl
--- a/tools/mb_c_source.m4	Wed Dec 10 17:15:26 2008 +0800
+++ b/tools/mb_c_source.m4	Fri Dec 12 00:33:54 2008 +0800
@@ -50,6 +50,7 @@
 define([COORD_MATRIX],)
 define([SHAPE_TRANSLATE],)
 define([SHAPE_MATRIX],)
+define([ADD_SYMBOL],)
 divert[]])
 
 define([S_ADD_LINEAR_PAINT],[
@@ -205,6 +206,7 @@
 SIMPORT([COORD_MATRIX])
 SIMPORT([SHAPE_TRANSLATE])
 SIMPORT([SHAPE_MATRIX])
+define([ADD_SYMBOL],)
 divert[]])
 
 define([F_ADD_LINEAR_PAINT],[[
@@ -262,6 +264,7 @@
 define([COORD_MATRIX],)
 define([SHAPE_TRANSLATE],)
 define([SHAPE_MATRIX],)
+define([ADD_SYMBOL],)
 divert[]])
 
 define([REVERSE_VARS],[divert([-1])
@@ -297,6 +300,36 @@
 RIMPORT([COORD_MATRIX])
 RIMPORT([SHAPE_TRANSLATE])
 RIMPORT([SHAPE_MATRIX])
+define([ADD_SYMBOL],)
+divert[]dnl
+])
+
+define([Y_ADD_SYMBOL],[[{"$1", MB_SPRITE_OFFSET($1)},]])
+
+define([DECLARE_SYMS], [divert([-1])
+define([YIMPORT],[IMPORT(]QUOTE($[]1)[,[Y_])])
+define([ADD_LINEAR_PAINT])
+define([ADD_RADIAL_PAINT])
+define([COLOR_STOP])
+define([REF_STOPS_RADIAL])
+define([REF_STOPS_LINEAR])
+define([ADD_PATH])
+define([ADD_RECT])
+define([ADD_COORD])
+define([ADD_TEXT],)
+define([FILL_SHAPE])
+define([STROKE_SHAPE])
+define([FILL_SHAPE_WITH_PAINT])
+define([STROKE_SHAPE_WITH_PAINT])
+define([STROKE_WIDTH])
+define([GROUP_HIDE],)
+define([RECT_HIDE],)
+define([PATH_HIDE],)
+define([COORD_TRANSLATE],)
+define([COORD_MATRIX],)
+define([SHAPE_TRANSLATE],)
+define([SHAPE_MATRIX],)
+YIMPORT([ADD_SYMBOL])
 divert[]dnl
 ])
 
@@ -310,6 +343,33 @@
 #include <mb_paint.h>
 #include "$1.h"
 
+#ifdef MB_SPRITE_OFFSET
+#undef MB_SPRITE_OFFSET
+#endif
+#define MB_SPRITE_OFFSET(x) ((int)&((($1_t *)0)->x))
+
+static
+mb_sprite_lsym_entry_t $1_symbols[] = {]DECLARE_SYMS
+$2[
+};
+
+#ifndef MB_LSYM_GET_OBJ_WITH_NAME
+#define MB_LSYM_GET_OBJ_WITH_NAME
+static
+mb_obj_t *mb_lsym_get_obj_with_name(mb_sprite_lsym_t *lsym, const char *sym) {
+    int i;
+
+    for(i = 0; i < lsym->num_entries; i++) {
+	if(strcmp(lsym->entries[i].sym, sym) != 0)
+	    continue;
+	return (mb_obj_t *)(((void *)lsym) + lsym->entries[i].offset);
+    }
+    return NULL;
+}
+#endif /* MB_LSYM_GET_OBJ_WITH_NAME */
+
+void $1_free($1_t *);
+
 $1_t *$1_new(redraw_man_t *rdman, coord_t *parent_coord) {
     $1_t *obj;
     grad_stop_t *stops = NULL;]DECLARE_VARS
@@ -317,9 +377,17 @@
 [
     obj = ($1_t *)malloc(sizeof($1_t));
     if(obj == NULL) return NULL;
+
+    obj->lsym.sprite.free = (void (*)(mb_sprite_t))$1_free;
+    obj->lsym.sprite.get_obj_with_name =
+	(mb_obj_t *(*)(mb_sprite_t *, const char *))mb_lsym_get_obj_with_name;
+    obj->lsym.num_entries =
+	sizeof($1_symbols) / sizeof(mb_sprite_lsym_entry_t);
+    obj->lsym.entries = $1_symbols;
+
     obj->rdman = rdman;
-]SETUP_VARS
-    obj->root_coord = rdman_coord_new(rdman, parent_coord);
+]SETUP_VARS[
+    obj->root_coord = rdman_coord_new(rdman, parent_coord);]
 $2
 [    return obj;
 }
--- a/tools/svg2code.py	Wed Dec 10 17:15:26 2008 +0800
+++ b/tools/svg2code.py	Fri Dec 12 00:33:54 2008 +0800
@@ -52,7 +52,7 @@
     pass
 
 def translate_linearGradient(linear, codefo, doc):
-    linear_id = linear.getAttribute('id')
+    linear_id = _get_id(linear)
     if linear.hasAttribute('x1'):
         x1 = float(linear.getAttribute('x1'))
         y1 = float(linear.getAttribute('y1'))
@@ -74,7 +74,7 @@
     pass
 
 def translate_radialGradient(radial, codefo, doc):
-    radial_id = radial.getAttribute('id')
+    radial_id = _get_id(radial)
     try:
         cx = float(radial.getAttribute('cx'))
         cy = float(radial.getAttribute('cy'))
@@ -270,6 +270,36 @@
     pass
     return [commands,args,fix_args]
 
+_id_sn = 0
+
+def _get_id(obj):
+    global _id_sn
+
+    if obj.hasAttribute('id'):
+        oid = obj.getAttribute('id')
+    else:
+        oid = '_MB_RAND_%s_' % (_id_sn)
+        obj.setAttribute('id', oid)
+        _id_sn = _id_sn + 1
+        pass
+    return oid
+
+##
+# Decorator that check if objects have attribute 'mbname'.
+#
+def check_mbname(func):
+    def deco(obj, coord_id, codefo, doc):
+        if obj.hasAttribute('mbname'):
+            ## \note mbname declare that this node should be in the
+            # symbol table.
+            mbname = obj.getAttribute('mbname')
+            print >> codefo, 'ADD_SYMBOL([%s])dnl' % (mbname)
+            pass
+        func(obj, coord_id, codefo, doc)
+        pass
+    return deco
+
+@check_mbname
 def translate_path(path, coord_id, codefo, doc):
     coord_id = translate_shape_transform(path, coord_id, codefo)
 
@@ -290,10 +320,11 @@
     translate_style(path, coord_id, codefo, doc, 'PATH_')
     pass
 
+@check_mbname
 def translate_rect(rect, coord_id, codefo, doc):
     coord_id = translate_shape_transform(rect, coord_id, codefo)
 
-    rect_id = rect.getAttribute('id')
+    rect_id = _get_id(rect)
     x = float(rect.getAttribute('x'))
     y = float(rect.getAttribute('y'))
     rx = 0.0
@@ -313,7 +344,7 @@
     pass
 
 def translate_font_style(text, codefo):
-    text_id = text.getAttribute('id')
+    text_id = _get_id(text)
     style_str = text.getAttribute('style')
     style_map = get_style_map(style_str)
 
@@ -349,7 +380,7 @@
             pass
         pass
     if txt_strs:
-        text_id = text.getAttribute('id')
+        text_id = _get_id(text)
         x = float(text.getAttribute('x'))
         y = float(text.getAttribute('y'))
         print >> codefo, 'dnl'
@@ -392,8 +423,9 @@
         pass
     pass
 
+@check_mbname
 def translate_group(group, parent_id, codefo, doc):
-    group_id = group.getAttribute('id')
+    group_id = _get_id(group)
     print >> codefo, 'dnl'
     print >> codefo, 'ADD_COORD([%s], [%s])dnl' % (group_id, parent_id)