1 /*************************************************************************/
2 /*  array.cpp                                                            */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 
31 #include "gdnative/array.h"
32 
33 #include "core/array.h"
34 #include "core/os/memory.h"
35 
36 #include "core/color.h"
37 #include "core/pool_vector.h"
38 
39 #include "core/variant.h"
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 static_assert(sizeof(godot_array) == sizeof(Array), "Array size mismatch");
46 
godot_array_new(godot_array * r_dest)47 void GDAPI godot_array_new(godot_array *r_dest) {
48 	Array *dest = (Array *)r_dest;
49 	memnew_placement(dest, Array);
50 }
51 
godot_array_new_copy(godot_array * r_dest,const godot_array * p_src)52 void GDAPI godot_array_new_copy(godot_array *r_dest, const godot_array *p_src) {
53 	Array *dest = (Array *)r_dest;
54 	const Array *src = (const Array *)p_src;
55 	memnew_placement(dest, Array(*src));
56 }
57 
godot_array_new_pool_color_array(godot_array * r_dest,const godot_pool_color_array * p_pca)58 void GDAPI godot_array_new_pool_color_array(godot_array *r_dest, const godot_pool_color_array *p_pca) {
59 	Array *dest = (Array *)r_dest;
60 	PoolVector<Color> *pca = (PoolVector<Color> *)p_pca;
61 	memnew_placement(dest, Array);
62 	dest->resize(pca->size());
63 
64 	for (int i = 0; i < dest->size(); i++) {
65 		Variant v = pca->operator[](i);
66 		dest->operator[](i) = v;
67 	}
68 }
69 
godot_array_new_pool_vector3_array(godot_array * r_dest,const godot_pool_vector3_array * p_pv3a)70 void GDAPI godot_array_new_pool_vector3_array(godot_array *r_dest, const godot_pool_vector3_array *p_pv3a) {
71 	Array *dest = (Array *)r_dest;
72 	PoolVector<Vector3> *pca = (PoolVector<Vector3> *)p_pv3a;
73 	memnew_placement(dest, Array);
74 	dest->resize(pca->size());
75 
76 	for (int i = 0; i < dest->size(); i++) {
77 		Variant v = pca->operator[](i);
78 		dest->operator[](i) = v;
79 	}
80 }
81 
godot_array_new_pool_vector2_array(godot_array * r_dest,const godot_pool_vector2_array * p_pv2a)82 void GDAPI godot_array_new_pool_vector2_array(godot_array *r_dest, const godot_pool_vector2_array *p_pv2a) {
83 	Array *dest = (Array *)r_dest;
84 	PoolVector<Vector2> *pca = (PoolVector<Vector2> *)p_pv2a;
85 	memnew_placement(dest, Array);
86 	dest->resize(pca->size());
87 
88 	for (int i = 0; i < dest->size(); i++) {
89 		Variant v = pca->operator[](i);
90 		dest->operator[](i) = v;
91 	}
92 }
93 
godot_array_new_pool_string_array(godot_array * r_dest,const godot_pool_string_array * p_psa)94 void GDAPI godot_array_new_pool_string_array(godot_array *r_dest, const godot_pool_string_array *p_psa) {
95 	Array *dest = (Array *)r_dest;
96 	PoolVector<String> *pca = (PoolVector<String> *)p_psa;
97 	memnew_placement(dest, Array);
98 	dest->resize(pca->size());
99 
100 	for (int i = 0; i < dest->size(); i++) {
101 		Variant v = pca->operator[](i);
102 		dest->operator[](i) = v;
103 	}
104 }
105 
godot_array_new_pool_real_array(godot_array * r_dest,const godot_pool_real_array * p_pra)106 void GDAPI godot_array_new_pool_real_array(godot_array *r_dest, const godot_pool_real_array *p_pra) {
107 	Array *dest = (Array *)r_dest;
108 	PoolVector<godot_real> *pca = (PoolVector<godot_real> *)p_pra;
109 	memnew_placement(dest, Array);
110 	dest->resize(pca->size());
111 
112 	for (int i = 0; i < dest->size(); i++) {
113 		Variant v = pca->operator[](i);
114 		dest->operator[](i) = v;
115 	}
116 }
117 
godot_array_new_pool_int_array(godot_array * r_dest,const godot_pool_int_array * p_pia)118 void GDAPI godot_array_new_pool_int_array(godot_array *r_dest, const godot_pool_int_array *p_pia) {
119 	Array *dest = (Array *)r_dest;
120 	PoolVector<godot_int> *pca = (PoolVector<godot_int> *)p_pia;
121 	memnew_placement(dest, Array);
122 	dest->resize(pca->size());
123 
124 	for (int i = 0; i < dest->size(); i++) {
125 		Variant v = pca->operator[](i);
126 		dest->operator[](i) = v;
127 	}
128 }
129 
godot_array_new_pool_byte_array(godot_array * r_dest,const godot_pool_byte_array * p_pba)130 void GDAPI godot_array_new_pool_byte_array(godot_array *r_dest, const godot_pool_byte_array *p_pba) {
131 	Array *dest = (Array *)r_dest;
132 	PoolVector<uint8_t> *pca = (PoolVector<uint8_t> *)p_pba;
133 	memnew_placement(dest, Array);
134 	dest->resize(pca->size());
135 
136 	for (int i = 0; i < dest->size(); i++) {
137 		Variant v = pca->operator[](i);
138 		dest->operator[](i) = v;
139 	}
140 }
141 
godot_array_set(godot_array * p_self,const godot_int p_idx,const godot_variant * p_value)142 void GDAPI godot_array_set(godot_array *p_self, const godot_int p_idx, const godot_variant *p_value) {
143 	Array *self = (Array *)p_self;
144 	Variant *val = (Variant *)p_value;
145 	self->operator[](p_idx) = *val;
146 }
147 
godot_array_get(const godot_array * p_self,const godot_int p_idx)148 godot_variant GDAPI godot_array_get(const godot_array *p_self, const godot_int p_idx) {
149 	godot_variant raw_dest;
150 	Variant *dest = (Variant *)&raw_dest;
151 	const Array *self = (const Array *)p_self;
152 	memnew_placement(dest, Variant(self->operator[](p_idx)));
153 	return raw_dest;
154 }
155 
godot_array_operator_index(godot_array * p_self,const godot_int p_idx)156 godot_variant GDAPI *godot_array_operator_index(godot_array *p_self, const godot_int p_idx) {
157 	Array *self = (Array *)p_self;
158 	return (godot_variant *)&self->operator[](p_idx);
159 }
160 
godot_array_operator_index_const(const godot_array * p_self,const godot_int p_idx)161 const godot_variant GDAPI *godot_array_operator_index_const(const godot_array *p_self, const godot_int p_idx) {
162 	const Array *self = (const Array *)p_self;
163 	return (const godot_variant *)&self->operator[](p_idx);
164 }
165 
godot_array_append(godot_array * p_self,const godot_variant * p_value)166 void GDAPI godot_array_append(godot_array *p_self, const godot_variant *p_value) {
167 	Array *self = (Array *)p_self;
168 	Variant *val = (Variant *)p_value;
169 	self->append(*val);
170 }
171 
godot_array_clear(godot_array * p_self)172 void GDAPI godot_array_clear(godot_array *p_self) {
173 	Array *self = (Array *)p_self;
174 	self->clear();
175 }
176 
godot_array_count(const godot_array * p_self,const godot_variant * p_value)177 godot_int GDAPI godot_array_count(const godot_array *p_self, const godot_variant *p_value) {
178 	const Array *self = (const Array *)p_self;
179 	const Variant *val = (const Variant *)p_value;
180 	return self->count(*val);
181 }
182 
godot_array_empty(const godot_array * p_self)183 godot_bool GDAPI godot_array_empty(const godot_array *p_self) {
184 	const Array *self = (const Array *)p_self;
185 	return self->empty();
186 }
187 
godot_array_erase(godot_array * p_self,const godot_variant * p_value)188 void GDAPI godot_array_erase(godot_array *p_self, const godot_variant *p_value) {
189 	Array *self = (Array *)p_self;
190 	const Variant *val = (const Variant *)p_value;
191 	self->erase(*val);
192 }
193 
godot_array_front(const godot_array * p_self)194 godot_variant GDAPI godot_array_front(const godot_array *p_self) {
195 	const Array *self = (const Array *)p_self;
196 	godot_variant v;
197 	Variant *val = (Variant *)&v;
198 	memnew_placement(val, Variant);
199 	*val = self->front();
200 	return v;
201 }
202 
godot_array_back(const godot_array * p_self)203 godot_variant GDAPI godot_array_back(const godot_array *p_self) {
204 	const Array *self = (const Array *)p_self;
205 	godot_variant v;
206 	Variant *val = (Variant *)&v;
207 	memnew_placement(val, Variant);
208 	*val = self->back();
209 	return v;
210 }
211 
godot_array_find(const godot_array * p_self,const godot_variant * p_what,const godot_int p_from)212 godot_int GDAPI godot_array_find(const godot_array *p_self, const godot_variant *p_what, const godot_int p_from) {
213 	const Array *self = (const Array *)p_self;
214 	const Variant *val = (const Variant *)p_what;
215 	return self->find(*val, p_from);
216 }
217 
godot_array_find_last(const godot_array * p_self,const godot_variant * p_what)218 godot_int GDAPI godot_array_find_last(const godot_array *p_self, const godot_variant *p_what) {
219 	const Array *self = (const Array *)p_self;
220 	const Variant *val = (const Variant *)p_what;
221 	return self->find_last(*val);
222 }
223 
godot_array_has(const godot_array * p_self,const godot_variant * p_value)224 godot_bool GDAPI godot_array_has(const godot_array *p_self, const godot_variant *p_value) {
225 	const Array *self = (const Array *)p_self;
226 	const Variant *val = (const Variant *)p_value;
227 	return self->has(*val);
228 }
229 
godot_array_hash(const godot_array * p_self)230 godot_int GDAPI godot_array_hash(const godot_array *p_self) {
231 	const Array *self = (const Array *)p_self;
232 	return self->hash();
233 }
234 
godot_array_insert(godot_array * p_self,const godot_int p_pos,const godot_variant * p_value)235 void GDAPI godot_array_insert(godot_array *p_self, const godot_int p_pos, const godot_variant *p_value) {
236 	Array *self = (Array *)p_self;
237 	const Variant *val = (const Variant *)p_value;
238 	self->insert(p_pos, *val);
239 }
240 
godot_array_invert(godot_array * p_self)241 void GDAPI godot_array_invert(godot_array *p_self) {
242 	Array *self = (Array *)p_self;
243 	self->invert();
244 }
245 
godot_array_pop_back(godot_array * p_self)246 godot_variant GDAPI godot_array_pop_back(godot_array *p_self) {
247 	Array *self = (Array *)p_self;
248 	godot_variant v;
249 	Variant *val = (Variant *)&v;
250 	memnew_placement(val, Variant);
251 	*val = self->pop_back();
252 	return v;
253 }
254 
godot_array_pop_front(godot_array * p_self)255 godot_variant GDAPI godot_array_pop_front(godot_array *p_self) {
256 	Array *self = (Array *)p_self;
257 	godot_variant v;
258 	Variant *val = (Variant *)&v;
259 	memnew_placement(val, Variant);
260 	*val = self->pop_front();
261 	return v;
262 }
263 
godot_array_push_back(godot_array * p_self,const godot_variant * p_value)264 void GDAPI godot_array_push_back(godot_array *p_self, const godot_variant *p_value) {
265 	Array *self = (Array *)p_self;
266 	const Variant *val = (const Variant *)p_value;
267 	self->push_back(*val);
268 }
269 
godot_array_push_front(godot_array * p_self,const godot_variant * p_value)270 void GDAPI godot_array_push_front(godot_array *p_self, const godot_variant *p_value) {
271 	Array *self = (Array *)p_self;
272 	const Variant *val = (const Variant *)p_value;
273 	self->push_front(*val);
274 }
275 
godot_array_remove(godot_array * p_self,const godot_int p_idx)276 void GDAPI godot_array_remove(godot_array *p_self, const godot_int p_idx) {
277 	Array *self = (Array *)p_self;
278 	self->remove(p_idx);
279 }
280 
godot_array_resize(godot_array * p_self,const godot_int p_size)281 void GDAPI godot_array_resize(godot_array *p_self, const godot_int p_size) {
282 	Array *self = (Array *)p_self;
283 	self->resize(p_size);
284 }
285 
godot_array_rfind(const godot_array * p_self,const godot_variant * p_what,const godot_int p_from)286 godot_int GDAPI godot_array_rfind(const godot_array *p_self, const godot_variant *p_what, const godot_int p_from) {
287 	const Array *self = (const Array *)p_self;
288 	const Variant *val = (const Variant *)p_what;
289 	return self->rfind(*val, p_from);
290 }
291 
godot_array_size(const godot_array * p_self)292 godot_int GDAPI godot_array_size(const godot_array *p_self) {
293 	const Array *self = (const Array *)p_self;
294 	return self->size();
295 }
296 
godot_array_sort(godot_array * p_self)297 void GDAPI godot_array_sort(godot_array *p_self) {
298 	Array *self = (Array *)p_self;
299 	self->sort();
300 }
301 
godot_array_sort_custom(godot_array * p_self,godot_object * p_obj,const godot_string * p_func)302 void GDAPI godot_array_sort_custom(godot_array *p_self, godot_object *p_obj, const godot_string *p_func) {
303 	Array *self = (Array *)p_self;
304 	const String *func = (const String *)p_func;
305 	self->sort_custom((Object *)p_obj, *func);
306 }
307 
godot_array_bsearch(godot_array * p_self,const godot_variant * p_value,const godot_bool p_before)308 godot_int GDAPI godot_array_bsearch(godot_array *p_self, const godot_variant *p_value, const godot_bool p_before) {
309 	Array *self = (Array *)p_self;
310 	return self->bsearch(*(const Variant *)p_value, p_before);
311 }
312 
godot_array_bsearch_custom(godot_array * p_self,const godot_variant * p_value,godot_object * p_obj,const godot_string * p_func,const godot_bool p_before)313 godot_int GDAPI godot_array_bsearch_custom(godot_array *p_self, const godot_variant *p_value, godot_object *p_obj, const godot_string *p_func, const godot_bool p_before) {
314 	Array *self = (Array *)p_self;
315 	const String *func = (const String *)p_func;
316 	return self->bsearch_custom(*(const Variant *)p_value, (Object *)p_obj, *func, p_before);
317 }
318 
godot_array_destroy(godot_array * p_self)319 void GDAPI godot_array_destroy(godot_array *p_self) {
320 	((Array *)p_self)->~Array();
321 }
322 
godot_array_duplicate(const godot_array * p_self,const godot_bool p_deep)323 godot_array GDAPI godot_array_duplicate(const godot_array *p_self, const godot_bool p_deep) {
324 	const Array *self = (const Array *)p_self;
325 	godot_array res;
326 	Array *val = (Array *)&res;
327 	memnew_placement(val, Array);
328 	*val = self->duplicate(p_deep);
329 	return res;
330 }
331 
godot_array_slice(const godot_array * p_self,const godot_int p_begin,const godot_int p_end,const godot_int p_step,const godot_bool p_deep)332 godot_array GDAPI godot_array_slice(const godot_array *p_self, const godot_int p_begin, const godot_int p_end, const godot_int p_step, const godot_bool p_deep) {
333 	const Array *self = (const Array *)p_self;
334 	godot_array res;
335 	Array *val = (Array *)&res;
336 	memnew_placement(val, Array);
337 	*val = self->slice(p_begin, p_end, p_step, p_deep);
338 	return res;
339 }
340 
godot_array_max(const godot_array * p_self)341 godot_variant GDAPI godot_array_max(const godot_array *p_self) {
342 	const Array *self = (const Array *)p_self;
343 	godot_variant v;
344 	Variant *val = (Variant *)&v;
345 	memnew_placement(val, Variant);
346 	*val = self->max();
347 	return v;
348 }
349 
godot_array_min(const godot_array * p_self)350 godot_variant GDAPI godot_array_min(const godot_array *p_self) {
351 	const Array *self = (const Array *)p_self;
352 	godot_variant v;
353 	Variant *val = (Variant *)&v;
354 	memnew_placement(val, Variant);
355 	*val = self->min();
356 	return v;
357 }
358 
godot_array_shuffle(godot_array * p_self)359 void GDAPI godot_array_shuffle(godot_array *p_self) {
360 	Array *self = (Array *)p_self;
361 	self->shuffle();
362 }
363 
364 #ifdef __cplusplus
365 }
366 #endif
367