当前位置: 代码迷 >> GIS >> 兑现类似GOBJECT类型注册功能(XXX_type_register)
  详细解决方案

兑现类似GOBJECT类型注册功能(XXX_type_register)

热度:222   发布时间:2016-05-05 06:29:23.0
实现类似GOBJECT类型注册功能(XXX_type_register)

代码摘自liferea

?

功能要求:

?

现在我们想自己定义一些类型,这些类型都是 nodeTypePtr 的子类型,这些类型包括:

feed
root
folder
vfolder
node
newsbin

以上都是一些类型(就像gvolume, gfile, gchar等等类型)具体的含义我们可以暂时不用管。然后,在一个init函数中通过调用类似XXX_type_register的函数来进行注册。注册好以后可以通过nodeTypePtr node_str_to_type(gchar *str)这样的函数来获得对应的子类型。

?

nodeTypePtr类型的数据结构:

?

node_type.h:

typedef struct nodeType {        gulong          capabilities;   /**< bitmask of node type capabilities */        gchar           *id;            /**< type id (used for type attribute in OPML export) */        gpointer        icon;           /**< default icon */                /* For method documentation see the wrappers defined below!            All methods are mandatory for each node type. */        void            (*import)               (nodePtr node, nodePtr parent, xmlNodePtr cur, gboolean trusted);        void            (*export)               (nodePtr node, xmlNodePtr cur, gboolean trusted);        itemSetPtr      (*load)                 (nodePtr node);        void            (*save)                 (nodePtr node);        void            (*update_counters)      (nodePtr node);        void            (*process_update_result)(nodePtr node, const struct updateResult * const result, updateFlags flags);        void            (*remove)               (nodePtr node);        gchar *         (*render)               (nodePtr node);        void            (*request_add)          (nodePtr parent);        void            (*request_properties)   (nodePtr node);                        /**         * Called to allow node type to clean up it's specific data.         * The node structure itself is destroyed after this call.         *         * @param node          the node         */        void            (*free)                 (nodePtr node);} *nodeTypePtr;         
?

?

我们先来实现定义feed类型:

feed.c:

nodeTypePtrfeed_get_node_type (void){        static struct nodeType nti = {                NODE_CAPABILITY_SHOW_UNREAD_COUNT |                NODE_CAPABILITY_UPDATE,                "feed",         /* not used, feed format ids are used instead */                NULL,                feed_import,                feed_export,                feed_load,                feed_save,                feed_update_unread_count,                feed_process_update_result,                feed_remove,                feed_render,                feed_add,                feed_properties,                feed_free        };        nti.icon = icons[ICON_DEFAULT];        return &nti;}// 函数实现static voidfeed_save (nodePtr node){        /* Nothing to do. Feeds do not have any UI states */}static voidfeed_update_unread_count (nodePtr node){        node->itemCount = db_itemset_get_item_count (node->id);        node->unreadCount = db_itemset_get_unread_count (node->id);}static voidfeed_remove (nodePtr node){        notification_node_removed (node);        ui_node_remove_node (node);        favicon_remove_from_cache (node->id);        db_subscription_remove (node->id);}...//数据结构中其余函数的实现

?

在集合类中进行类型注册:

feedlist.c

void feedlist_init(void) {        debug_enter("feedlist_init");        /* 1. Register standard node and source types */        node_type_register (feed_get_node_type ());        node_type_register (root_get_node_type ());        node_type_register (folder_get_node_type ());        node_type_register (vfolder_get_node_type ());        node_type_register (node_source_get_node_type ());        node_type_register (newsbin_get_node_type ());        node_source_type_register (default_source_get_type ());        node_source_type_register (dummy_source_get_type ());        node_source_type_register (opml_source_get_type ());        node_source_type_register (bloglines_source_get_type ());        node_source_type_register (google_source_get_type ());...// 省略}

?

类型注册实现函数:

node_type.c

static GSList *nodeTypes = NULL;void    node_type_register (nodeTypePtr nodeType){                       /* all attributes and methods are mandatory! */        g_assert (nodeType->id);        g_assert (nodeType->import);        g_assert (nodeType->export);        g_assert (nodeType->load);        g_assert (nodeType->save);        g_assert (nodeType->update_counters);        g_assert (nodeType->remove);        g_assert (nodeType->render);        g_assert (nodeType->request_add);        g_assert (nodeType->request_properties);                nodeTypes = g_slist_append (nodeTypes, (gpointer)nodeType);}voidnode_set_type (nodePtr node, nodeTypePtr type){        node->type = type;}const gchar *node_type_to_str (nodePtr node){        if (IS_FEED (node)) {                g_assert (NULL != node->data);                return feed_type_fhp_to_str (((feedPtr)(node->data))->fhp);        }        return NODE_TYPE (node)->id;}nodeTypePtrnode_str_to_type (const gchar *str){        GSList  *iter = nodeTypes;        g_assert (NULL != str);        if (g_str_equal (str, ""))      /* type maybe "" if initial download is not yet done */                return feed_get_node_type ();        if (NULL != feed_type_str_to_fhp (str))                return feed_get_node_type ();        /* check against all node types */        while (iter) {                if (g_str_equal (str, ((nodeTypePtr)iter->data)->id))                        return (nodeTypePtr)iter->data;                iter = g_slist_next (iter);        }        return NULL;}/* Interactive node adding (e.g. feed menu->new subscription) */voidnode_type_request_interactive_add (nodeTypePtr nodeType){        nodePtr         parent;        parent = feedlist_get_insertion_point ();        if (0 == (NODE_TYPE (parent->source->root)->capabilities & NODE_CAPABILITY_ADD_CHILDS))                return;        nodeType->request_add (parent);}                                                     

?

?

需要调用类型的时候,使用node_set_type(node, str)函数,比如:

?

nodeTypePtr node_type = node_str_to_type(“feed”);
?