1 /** 2 Dynamic Variant array. 3 4 Copyright: 5 Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. 6 Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) 7 Copyright (c) 2017-2018 Godot-D contributors 8 9 License: $(LINK2 https://opensource.org/licenses/MIT, MIT License) 10 11 12 */ 13 module godot.core.array; 14 15 import godot.c; 16 import godot.core.variant; 17 import godot.core.poolarrays; 18 19 /** 20 Generic array, contains several elements of any type, accessible by numerical index starting at 0. Negative indices can be used to count from the right, like in Python. Arrays are always passed by reference. 21 */ 22 struct Array 23 { 24 int opApply(int delegate(size_t, ref Variant) dg) 25 { 26 foreach(i; 0..length) 27 { 28 Variant* v = cast(Variant*)&(this[i]); 29 int res = dg(cast(size_t)i, *v); 30 if(res) return res; 31 } 32 return 0; 33 } 34 35 int opApply(int delegate(size_t, const(Variant)) dg) const 36 { 37 foreach(i; 0..length) 38 { 39 int res = dg(cast(size_t)i, this[i]); 40 if(res) return res; 41 } 42 return 0; 43 } 44 45 int opApply(int delegate(ref Variant) dg) 46 { 47 foreach(i; 0..length) 48 { 49 Variant* v = cast(Variant*)&(this[i]); 50 int res = dg(*v); 51 if(res) return res; 52 } 53 return 0; 54 } 55 56 int opApply(int delegate(const(Variant)) dg) const 57 { 58 foreach(i; 0..length) 59 { 60 int res = dg(this[i]); 61 if(res) return res; 62 } 63 return 0; 64 } 65 66 67 @nogc nothrow: 68 69 package(godot) godot_array _godot_array; 70 71 @disable this(); 72 73 this(this) 74 { 75 const godot_array tmp = _godot_array; 76 _godot_api.godot_array_new_copy(&_godot_array, &tmp); 77 } 78 79 Array opAssign(in Array other) 80 { 81 _godot_api.godot_array_destroy(&_godot_array); 82 _godot_api.godot_array_new_copy(&_godot_array, &other._godot_array); 83 return this; 84 } 85 86 /++ 87 Assigning null empties the Array variable, but unlike `clear`, does not 88 destroy the original memory unless it was the only remaining reference. 89 90 Equivalent to assigning empty_array. 91 +/ 92 Array opAssign(in typeof(null) n) 93 { 94 return opAssign(empty_array); 95 } 96 97 static Array empty_array() 98 { 99 Array ret = void; 100 _godot_api.godot_array_new(&ret._godot_array); 101 return ret; 102 } 103 104 this(in typeof(null) n) 105 { 106 _godot_api.godot_array_new(&_godot_array); 107 } 108 109 this(in PoolByteArray a) 110 { 111 _godot_api.godot_array_new_pool_byte_array(&_godot_array, &a._godot_array); 112 } 113 114 this(in PoolIntArray a) 115 { 116 _godot_api.godot_array_new_pool_int_array(&_godot_array, &a._godot_array); 117 } 118 119 this(in PoolRealArray a) 120 { 121 _godot_api.godot_array_new_pool_real_array(&_godot_array, &a._godot_array); 122 } 123 124 this(in PoolStringArray a) 125 { 126 _godot_api.godot_array_new_pool_string_array(&_godot_array, &a._godot_array); 127 } 128 129 this(in PoolVector2Array a) 130 { 131 _godot_api.godot_array_new_pool_vector2_array(&_godot_array, &a._godot_array); 132 } 133 134 this(in PoolVector3Array a) 135 { 136 _godot_api.godot_array_new_pool_vector3_array(&_godot_array, &a._godot_array); 137 } 138 139 this(in PoolColorArray a) 140 { 141 _godot_api.godot_array_new_pool_color_array(&_godot_array, &a._godot_array); 142 } 143 144 auto ref inout(Variant) opIndex(size_t idx) inout 145 { 146 godot_variant* v = _godot_api.godot_array_operator_index(cast(godot_array*)&_godot_array, cast(int)idx); 147 return *cast(inout(Variant)*)v; 148 } 149 150 void opIndexAssign(T)(auto ref T value, in size_t idx) if(is(T : Variant) || Variant.compatibleToGodot!T) 151 { 152 Variant v = Variant(value); 153 _godot_api.godot_array_set(&_godot_array, cast(int)idx, &v._godot_variant); 154 } 155 156 void append(T)(auto ref T t) if(is(T : Variant) || Variant.compatibleToGodot!T) 157 { 158 Variant v = Variant(t); 159 _godot_api.godot_array_append(&_godot_array, &v._godot_variant); 160 } 161 alias opOpAssign(string op : "~") = append; 162 163 void clear() 164 { 165 _godot_api.godot_array_clear(&_godot_array); 166 } 167 168 size_t count(in Variant v) 169 { 170 return _godot_api.godot_array_count(&_godot_array, &v._godot_variant); 171 } 172 173 bool empty() const 174 { 175 return cast(bool)_godot_api.godot_array_empty(&_godot_array); 176 } 177 178 void erase(T)(T v) if(is(T : Variant) || Variant.compatibleToGodot!T) 179 { 180 Variant vv = v; 181 _godot_api.godot_array_erase(&_godot_array, &vv._godot_variant); 182 } 183 184 Variant front() const 185 { 186 godot_variant v = _godot_api.godot_array_front(&_godot_array); 187 return cast(Variant)v; 188 } 189 190 Variant back() const 191 { 192 godot_variant v = _godot_api.godot_array_back(&_godot_array); 193 return cast(Variant)v; 194 } 195 196 int find(T)(in T what, size_t from) const if(is(T : Variant) || Variant.compatibleToGodot!T) 197 { 198 const Variant vv = what; 199 return _godot_api.godot_array_find(&_godot_array, &vv._godot_variant, cast(int)from); 200 } 201 202 int findLast(T)(in T what) const if(is(T : Variant) || Variant.compatibleToGodot!T) 203 { 204 const Variant vv = what; 205 return _godot_api.godot_array_find_last(&_godot_array, &vv._godot_variant); 206 } 207 208 bool has(T)(in T what) const if(is(T : Variant) || Variant.compatibleToGodot!T) 209 { 210 const Variant vv = what; 211 return cast(bool)_godot_api.godot_array_has(&_godot_array, &vv._godot_variant); 212 } 213 214 uint hash() const 215 { 216 return _godot_api.godot_array_hash(&_godot_array); 217 } 218 219 void insert(T)(const size_t pos, T value) if(is(T : Variant) || Variant.compatibleToGodot!T) 220 { 221 Variant vv = value; 222 _godot_api.godot_array_insert(&_godot_array, cast(int)pos, &vv._godot_variant); 223 } 224 225 void invert() 226 { 227 _godot_api.godot_array_invert(&_godot_array); 228 } 229 230 Variant popBack() 231 { 232 godot_variant v = _godot_api.godot_array_pop_back(&_godot_array); 233 return cast(Variant)v; 234 } 235 236 Variant popFront() 237 { 238 godot_variant v = _godot_api.godot_array_pop_front(&_godot_array); 239 return cast(Variant)v; 240 } 241 242 void pushBack(T)(T v) if(is(T : Variant) || Variant.compatibleToGodot!T) 243 { 244 Variant vv = v; 245 _godot_api.godot_array_push_back(&_godot_array, &vv._godot_variant); 246 } 247 248 void pushFront(T)(T v) if(is(T : Variant) || Variant.compatibleToGodot!T) 249 { 250 Variant vv = v; 251 _godot_api.godot_array_push_front(&_godot_array, &vv._godot_variant); 252 } 253 254 void remove(size_t idx) 255 { 256 _godot_api.godot_array_remove(&_godot_array, cast(int)idx); 257 } 258 259 size_t size() const 260 { 261 return _godot_api.godot_array_size(&_godot_array); 262 } 263 alias length = size; // D-style `length` 264 265 void resize(size_t size) 266 { 267 _godot_api.godot_array_resize(&_godot_array, cast(int)size); 268 } 269 270 int rfind(T)(in T what, size_t from) const if(is(T : Variant) || Variant.compatibleToGodot!T) 271 { 272 const Variant vv = what; 273 return _godot_api.godot_array_rfind(&_godot_array, &vv._godot_variant, cast(int)from); 274 } 275 276 void sort() 277 { 278 _godot_api.godot_array_sort(&_godot_array); 279 } 280 281 /+void sort_custom(godot.Object obj, in ref String func) 282 { 283 _godot_api.godot_array_sort_custom(&_godot_array, obj, &func._godot_string); 284 }+/ 285 286 /// Allocate a new separate copy of the Array 287 Array dup() const 288 { 289 Array ret = empty_array; 290 size_t l = size(); 291 ret.resize(l); 292 foreach(vi; 0..l) 293 { 294 ret[vi] = this[vi]; 295 } 296 return ret; 297 } 298 299 ~this() 300 { 301 _godot_api.godot_array_destroy(&_godot_array); 302 } 303 } 304 305 306 307