资料

cocos2dx 里面有很多东西是直接从github上搞过来的,这个自然也是。
为了更好的理解Scheduler,我还是仔细看看uthash的实现吧!

http://troydhanson.github.io/uthash/
https://github.com/troydhanson/uthash

路径

1
2d/support/data-support/uthash.h

用法

现在的话,先是了解如何使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <stdio.h>   /* gets */
#include <stdlib.h> /* atoi, malloc */
#include <string.h> /* strcpy */
#include "uthash.h"

struct my_struct {
int id; /* 键值 */

char name[10];

UT_hash_handle hh; /* 关键结构体 */
};

struct my_struct *users = NULL;

void add_user(int user_id, char *name) {
struct my_struct *s;

HASH_FIND_INT(users, &user_id, s); /* id already in the hash? */
if (s==NULL) {
s = (struct my_struct*)malloc(sizeof(struct my_struct));
s->id = user_id;
HASH_ADD_INT( users, id, s ); /* id: name of key field */
}
strcpy(s->name, name);
}

struct my_struct *find_user(int user_id) {
struct my_struct *s;

HASH_FIND_INT( users, &user_id, s ); /* s: output pointer */
return s;
}

void delete_user(struct my_struct *user) {
HASH_DEL( users, user); /* user: pointer to deletee */
free(user);
}

void delete_all() {
struct my_struct *current_user, *tmp;

HASH_ITER(hh, users, current_user, tmp) {
HASH_DEL(users,current_user); /* delete it (users advances to next) */
free(current_user); /* free it */
}
}

void print_users() {
struct my_struct *s;

for(s=users; s != NULL; s=(struct my_struct*)(s->hh.next)) {
printf("user id %d: name %s\n", s->id, s->name);
}
}

int name_sort(struct my_struct *a, struct my_struct *b) {
return strcmp(a->name,b->name);
}

int id_sort(struct my_struct *a, struct my_struct *b) {
return (a->id - b->id);
}

void sort_by_name() {
HASH_SORT(users, name_sort);
}

void sort_by_id() {
HASH_SORT(users, id_sort);
}

int main(int argc, char *argv[]) {
char in[10];
int id=1, running=1;
struct my_struct *s;
unsigned num_users;

while (running) {
printf(" 1. add user\n");
printf(" 2. add/rename user by id\n");
printf(" 3. find user\n");
printf(" 4. delete user\n");
printf(" 5. delete all users\n");
printf(" 6. sort items by name\n");
printf(" 7. sort items by id\n");
printf(" 8. print users\n");
printf(" 9. count users\n");
printf("10. quit\n");
gets(in);
switch(atoi(in)) {
case 1:
printf("name?\n");
add_user(id++, gets(in));
break;
case 2:
printf("id?\n");
gets(in); id = atoi(in);
printf("name?\n");
add_user(id, gets(in));
break;
case 3:
printf("id?\n");
s = find_user(atoi(gets(in)));
printf("user: %s\n", s ? s->name : "unknown");
break;
case 4:
printf("id?\n");
s = find_user(atoi(gets(in)));
if (s) delete_user(s);
else printf("id unknown\n");
break;
case 5:
delete_all();
break;
case 6:
sort_by_name();
break;
case 7:
sort_by_id();
break;
case 8:
print_users();
break;
case 9:
num_users=HASH_COUNT(users);
printf("there are %u users\n", num_users);
break;
case 10:
running=0;
break;
}
}

delete_all(); /* free any structures */
return 0;
}

这个uthash User Guide的一个例子,说明了插入查找删除应该如何如何。

宏列表

便捷宏

这个便捷宏其实是对通用宏的再次封装。所以要求就来了:

  • UT_hash_handle在自定义结构体中的名字必须是hh
  • 键的类型只能是intchar[]void*(指针)
参数
HASH_ADD_INT (head, keyfield_name, item_ptr)
HASH_REPLACE_INT (head, keyfiled_name, item_ptr, replaced_item_ptr)
HASH_FIND_INT (head, key_ptr, item_ptr)
HASH_ADD_STR (head, keyfield_name, item_ptr)
HASH_REPLACE_STR (head, keyfield_name, item_ptr, replaced_item_ptr)
HASH_FIND_STR (head, key_ptr, item_ptr)
HASH_ADD_PTR (head, keyfield_name, item_ptr)
HASH_REPLACE_PTR (head, keyfield_name, item_ptr, replaced_item_ptr)
HASH_FIND_PTR (head, key_ptr, item_ptr)
HASH_DEL (head, item_ptr)
HASH_SORT (head, cmp)
HASH_COUNT (head)

通用宏

这些通用宏只建议在需要制定非intchar[]的键值的时候使用。

参数
HASH_ADD (hh_name, head, keyfield_name, key_len, item_ptr)
HASH_ADD_KEYPTR (hh_name, head, key_ptr, key_len, item_ptr)
HASH_REPLACE (hh_name, head, keyfield_name, key_len, item_ptr, replaced_item_ptr)
HASH_FIND (hh_name, head, key_ptr, key_len, item_ptr)
HASH_DELETE (hh_name, head, item_ptr)
HASH_SRT (hh_name, head, cmp)
HASH_CNT (hh_name, head)
HASH_CLEAR (hh_name, head)
HASH_SELECT (dst_hh_name, dst_head, src_hh_name, src_head, condition)
HASH_ITER (hh_name, head, item_ptr, tmp_item_ptr)
HASH_OVERHEAD (hh_name, head)

参数说明

hh_name

在结构体中UT_hash_handle的结构体成员名字。若使用便捷宏默认是hh

结构体头指针变量名

keyfield_name

在结构体中的键的实体名

key_len

键的长度,若键值是int,则为sizeof(int),若为str,则为strlen(str)

key_ptr

在HASH_FIND中,这是待查找的实体的一个指向结构体的键的类型的指针,
在HASH_ADD_KEYPTR中,需要这是一个结构体中键的类型的地址

item_ptr

指向那些待查找、添加、删除的结构体的指针。或者是当前迭代器的指针。
该参数作为HASH_ADDHASH_DELETE的输入,作为HASH_FINDHASH_ITER的输出。

replaced_item_ptr

在使用HASH_REPLACE的时候,作为一个输出参数,指向替换的内容的指针。

cmp

比较函数指针,其中是用到了mergesort排序

condition

传入一个宏或者函数指针,接受一个指向结构体的void*指针
这个宏或函数需要判断当前结构体是否符合select的条件,根据结果返回一个非零值。