Commit | Line | Data |
---|---|---|
e38f8ec4 TC |
1 | #include "EXTERN.h" |
2 | #include "perl.h" | |
3 | #include "XSUB.h" | |
4 | #include <string.h> /* for memmove() mostly */ | |
5 | #include <errno.h> /* errno values */ | |
a0e4f61f | 6 | #include "queue.h" |
e38f8ec4 TC |
7 | |
8 | /* this typedef lets the standard T_PTROBJ typemap handle the | |
9 | conversion between perl class and C type and back again */ | |
10 | typedef poe_queue *POE__XS__Queue__Array; | |
11 | ||
12 | /* This gives us our new method and correct destruction */ | |
13 | #define pq_new(class) pq_create() | |
14 | #define pq_DESTROY(pq) pq_delete(pq) | |
15 | ||
16 | MODULE = POE::XS::Queue::Array PACKAGE = POE::XS::Queue::Array PREFIX = pq_ | |
17 | ||
18 | PROTOTYPES: DISABLE | |
19 | ||
20 | POE::XS::Queue::Array | |
21 | pq_new(class) | |
22 | ||
23 | void | |
24 | pq_DESTROY(pq) | |
25 | POE::XS::Queue::Array pq | |
26 | ||
27 | int | |
28 | pq_enqueue(pq, priority, payload) | |
29 | POE::XS::Queue::Array pq | |
30 | double priority | |
31 | SV *payload | |
32 | ||
33 | void | |
34 | pq_dequeue_next(pq) | |
35 | POE::XS::Queue::Array pq | |
36 | PREINIT: | |
37 | pq_priority_t priority; | |
38 | pq_id_t id; | |
39 | SV *payload; | |
40 | PPCODE: | |
41 | if (pq_dequeue_next(pq, &priority, &id, &payload)) { | |
42 | EXTEND(SP, 3); | |
43 | PUSHs(sv_2mortal(newSVnv(priority))); | |
44 | PUSHs(sv_2mortal(newSViv(id))); | |
45 | PUSHs(sv_2mortal(payload)); | |
46 | } | |
47 | ||
48 | SV * | |
49 | pq_get_next_priority(pq) | |
50 | POE::XS::Queue::Array pq | |
51 | PREINIT: | |
52 | pq_priority_t priority; | |
53 | CODE: | |
54 | if (pq_get_next_priority(pq, &priority)) { | |
55 | RETVAL = newSVnv(priority); /* XS will mortalize this for us */ | |
56 | } | |
57 | else { | |
58 | RETVAL = &PL_sv_undef; | |
59 | } | |
60 | OUTPUT: | |
61 | RETVAL | |
62 | ||
63 | int | |
64 | pq_get_item_count(pq) | |
65 | POE::XS::Queue::Array pq | |
66 | ||
67 | void | |
68 | pq_remove_item(pq, id, filter) | |
69 | POE::XS::Queue::Array pq | |
70 | int id | |
71 | SV *filter | |
72 | PREINIT: | |
73 | pq_entry removed; | |
74 | PPCODE: | |
75 | if (pq_remove_item(pq, id, filter, &removed)) { | |
76 | EXTEND(SP, 3); | |
77 | PUSHs(sv_2mortal(newSVnv(removed.priority))); | |
78 | PUSHs(sv_2mortal(newSViv(removed.id))); | |
79 | PUSHs(sv_2mortal(removed.payload)); | |
80 | } | |
81 | ||
82 | void | |
83 | pq_remove_items(pq, filter, ...) | |
84 | POE::XS::Queue::Array pq | |
85 | SV *filter | |
86 | PREINIT: | |
87 | int max_count; | |
88 | pq_entry *removed_entries = NULL; | |
89 | int removed_count; | |
90 | int i; | |
91 | PPCODE: | |
92 | if (items > 2) | |
93 | max_count = SvIV(ST(2)); | |
94 | else | |
95 | max_count = pq_get_item_count(pq); | |
96 | removed_count = pq_remove_items(pq, filter, max_count, | |
97 | &removed_entries); | |
98 | if (removed_count) { | |
99 | EXTEND(SP, removed_count); | |
100 | for (i = 0; i < removed_count; ++i) { | |
101 | pq_entry *entry = removed_entries + i; | |
102 | AV *av = newAV(); | |
103 | SV *rv; | |
104 | av_extend(av, 2); | |
105 | av_store(av, 0, newSVnv(entry->priority)); | |
106 | av_store(av, 1, newSViv(entry->id)); | |
107 | av_store(av, 2, entry->payload); | |
108 | rv = newRV_noinc((SV *)av); | |
109 | PUSHs(sv_2mortal(rv)); | |
110 | } | |
111 | } | |
112 | if (removed_entries) | |
113 | free(removed_entries); | |
114 | ||
115 | void | |
116 | pq_adjust_priority(pq, id, filter, delta) | |
117 | POE::XS::Queue::Array pq | |
118 | int id | |
119 | SV *filter | |
120 | double delta | |
121 | PREINIT: | |
122 | pq_priority_t new_priority; | |
123 | PPCODE: | |
124 | if (pq_adjust_priority(pq, id, filter, delta, &new_priority)) { | |
125 | EXTEND(SP, 1); | |
126 | PUSHs(sv_2mortal(newSVnv(new_priority))); | |
127 | } | |
128 | ||
129 | void | |
130 | pq_set_priority(pq, id, filter, new_priority) | |
131 | POE::XS::Queue::Array pq | |
132 | int id | |
133 | SV *filter | |
134 | double new_priority | |
135 | PPCODE: | |
136 | if (pq_set_priority(pq, id, filter, new_priority)) { | |
137 | EXTEND(SP, 1); | |
138 | PUSHs(sv_2mortal(newSVnv(new_priority))); | |
139 | } | |
140 | ||
141 | void | |
142 | pq_peek_items(pq, filter, ...) | |
143 | POE::XS::Queue::Array pq | |
144 | SV *filter | |
145 | PREINIT: | |
146 | pq_entry *ret_items; | |
147 | int count, i; | |
148 | int max_count; | |
149 | PPCODE: | |
150 | if (items == 3) | |
151 | max_count = SvIV(ST(2)); | |
152 | else | |
153 | max_count = pq_get_item_count(pq); | |
154 | count = pq_peek_items(pq, filter, max_count, &ret_items); | |
155 | if (count) { | |
156 | EXTEND(SP, count); | |
157 | for (i = 0; i < count; ++i) { | |
158 | pq_entry *entry = ret_items + i; | |
159 | AV *av = newAV(); | |
160 | SV *rv; | |
161 | av_extend(av, 2); | |
162 | av_store(av, 0, newSVnv(entry->priority)); | |
163 | av_store(av, 1, newSViv(entry->id)); | |
164 | av_store(av, 2, newSVsv(entry->payload)); | |
165 | rv = newRV_noinc((SV *)av); | |
166 | PUSHs(sv_2mortal(rv)); | |
167 | } | |
168 | free(ret_items); | |
169 | } | |
170 | ||
171 | void | |
172 | pq_dump(pq) | |
173 | POE::XS::Queue::Array pq |