]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/client/sortlist.qc
handle an entity changing its type right (happend when both a remove and a spawn...
[divverent/nexuiz.git] / data / qcsrc / client / sortlist.qc
1 .float(entity,entity) sort_cmp;
2 .entity sort_next, sort_prev;
3
4 entity Sort_Spawn()
5 {
6         entity sort;
7         sort = spawn();
8         sort.sort_next = NULL;
9         sort.chain = sort;
10         return sort;
11 }
12
13 entity Sort_New(float(entity,entity) cmp)
14 {
15         entity sort;
16         sort = spawn();
17         sort.sort_cmp = cmp;
18         sort.sort_next = NULL;
19         sort.chain = sort;
20         return sort;
21 }
22
23 void Sort_Remove(entity sort)
24 {
25         entity next;
26         while(sort.sort_next)
27         {
28                 next = sort.sort_next;
29                 remove(sort);
30                 sort = next;
31         }
32         remove(sort);
33 }
34
35 void Sort_Add(entity sort, entity ent)
36 {
37         entity next, parent;
38         parent = sort;
39         next = sort.sort_next;
40         while(next)
41         {
42                 if(!sort.sort_cmp(next, ent))
43                         break;
44                 parent = next;
45                 next = next.sort_next;
46         }
47         ent.sort_next = next;
48         ent.sort_prev = parent;
49         parent.sort_next = ent;
50         if(next)
51                 next.sort_prev = ent;
52 }
53
54 void Sort_Reset(entity sort)
55 {
56         sort.chain = sort;
57 }
58
59 float Sort_HasNext(entity sort)
60 {
61         return (sort.chain.sort_next != NULL);
62 }
63
64 entity Sort_Next(entity sort)
65 {
66         entity next;
67         next = sort.chain.sort_next;
68         if(!next) {
69                 next = spawn();
70                 sort.chain.sort_next = next;
71                 next.sort_prev = sort.chain;
72                 next.sort_next = NULL;
73         }
74         sort.chain = next;
75         return next;
76 }
77
78 void Sort_Finish(entity sort)
79 {
80         entity next;
81         next = sort.chain;
82         if(!next)
83                 return;
84
85         while(next.sort_next)
86         {
87                 sort = next.sort_next;
88                 next.sort_next = sort.sort_next;
89                 remove(sort);
90         }
91 }
92
93 entity Sort_Get(entity sort, float i)
94 {
95         for(; sort.sort_next && i > 0; --i)
96                 sort = sort.sort_next;
97         return sort;
98 }
99
100 /**
101  * Swap two neighbours in a sortlist.
102  * @param a FIRST entity
103  * @param b entity after a
104  */
105 #define SORT_SWAP(a,b)                                                                  \
106         b.sort_prev = a.sort_prev;                                                      \
107         a.sort_next = b.sort_next;                                                      \
108         if(b.sort_next) b.sort_next.sort_prev = a;                      \
109         if(a.sort_prev) a.sort_prev.sort_next = b;                      \
110         a.sort_prev = b;                                                                        \
111         b.sort_next = a
112
113 void Sort_Erase(entity ent)
114 {
115         ent.sort_prev.sort_next = ent.sort_next;
116         if(ent.sort_next)
117                 ent.sort_next.sort_prev = ent.sort_prev;
118         remove(ent);
119 }
120
121 void Sort_RemoveOld(entity sort)
122 {
123         entity tmp;
124         for(tmp = sort.sort_next; tmp; tmp = tmp.sort_next)
125         {
126                 if(tmp.frame < time)
127                 {
128                         tmp = tmp.sort_prev;
129                         Sort_Erase(tmp.sort_next);
130                 }
131         }
132 }