Monday, January 12, 2009

Gtk+上使用stack

Gtk+是在linux上面使用十分頻繁的GUI library,許許多多的project都以它為front-end的介面程式,最近使用Gtk+的時候,產生了一個簡單的需求:Stack,但找了一下glib裡面發現卻沒有stack的支援,看來要自己去寫。

不過~~我真的很懶,於是我看了一下,恩~~用linked-list來幫我完成這項工作吧。

首先,當然你必須宣告一個glib的linked-list,你可以宣告成全域變數或是在每一個push與pop的參數列將它傳入,當然用參數比較具有彈性,這個stack可以到處使用,我這邊的stack只有一個地方需要使用,於是~~我簡單的把他宣告成全域變數

GList *MyStackList = NULL;

一個stack的資料結構其實很簡單,就是資料後進先出,它擁有兩個簡單的介面:push與pop,我們用GList來幫我們簡化這些程式碼。首先,push的實做:

void _my_stack_puch(struct _my_own_data *data)
{
struct _my_own_data *ptr = (struct _my_own_data *)g_malloc(sizeof(struct _my_own_data));
ptr->data1 = data->data1;
.....其他你的資料需要複製的部份,當然~~最簡單就是memcpy.......

MyStackList = g_list_prepend(MyStackList, (gpointer)ptr);
}

每一次插入一個元素我就宣告一個然後放置在linked-list的前端。簡單吧,再來就是pop的實做了:

gboolean _my_stack_pop(struct _my_own_data *data)
{
struct _my_own_data *ptr;

if (MyStackList == NULL)
return FALSE;

ptr = (struct _my_own_data *)g_list_nth_data(MyStackList, 0);
if (ptr == NULL)
return FALSE;

data->data1 = ptr->data1;
.....其他你的資料需要複製的部份.......

g_free(ptr);
MyStackList = g_list_delete_link(MyStackList, MyStackList);

return TRUE;
}

只是GList的刪除link的動作,不過要記得這個我們在pop分配的記憶體要記得刪除這個link前先釋放掉。

這樣就簡單的完成一個用GList實做出來的stack可以使用,你當然可以再寫一個清除所有stack裡面元素的function,這很簡單我就不寫了。簡單的利用別人寫好的程式,我想這才是使用open source最好的方式吧。

3 comments:

Anonymous said...

不能用STL?

Anonymous said...

不能用STL?

sam said...

C的環境,沒有C++