1 /** 2 Variant hashmap/dictionary type. 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.dictionary; 14 15 import godot.c; 16 import godot.core; 17 18 import std.meta; 19 20 /** 21 Associative container which contains values referenced by unique keys. Dictionaries are always passed by reference. 22 */ 23 struct Dictionary 24 { 25 int opApply(int delegate(const(Variant), ref Variant) dg) 26 { 27 const(godot_variant)* k = _godot_api.godot_dictionary_next(&_godot_dictionary, null); 28 while(k) 29 { 30 Variant* v = cast(Variant*)_godot_api.godot_dictionary_operator_index( 31 &_godot_dictionary, k); 32 int res = dg(*cast(const(Variant*))k, *v); 33 if(res) return res; 34 k = _godot_api.godot_dictionary_next(&_godot_dictionary, k); 35 } 36 return 0; 37 } 38 39 int opApply(int delegate(const(Variant), ref const(Variant)) dg) const 40 { 41 const(godot_variant)* k = _godot_api.godot_dictionary_next(&_godot_dictionary, null); 42 while(k) 43 { 44 Variant* v = cast(Variant*)_godot_api.godot_dictionary_operator_index( 45 cast(godot_dictionary*)&_godot_dictionary, k); 46 int res = dg(*cast(const(Variant*))k, *v); 47 if(res) return res; 48 k = _godot_api.godot_dictionary_next(&_godot_dictionary, k); 49 } 50 return 0; 51 } 52 53 54 @nogc nothrow: 55 56 package(godot) godot_dictionary _godot_dictionary; 57 58 @disable this(); 59 60 this(this) 61 { 62 const godot_dictionary tmp = _godot_dictionary; 63 _godot_api.godot_dictionary_new_copy(&_godot_dictionary, &tmp); 64 } 65 66 Dictionary opAssign(in Dictionary other) 67 { 68 _godot_api.godot_dictionary_destroy(&_godot_dictionary); 69 _godot_api.godot_dictionary_new_copy(&_godot_dictionary, &other._godot_dictionary); 70 return this; 71 } 72 73 /++ 74 Create a Dictionary and add the key-value pairs $(PARAM args) to it. 75 76 Example: 77 --- 78 Dictionary emptyDictionary = Dictionary.make(); 79 Dictionary status = Dictionary.make(gs!"health", 100, gs!"shields", 75); 80 --- 81 +/ 82 static Dictionary make(Args...)(Args args) 83 if(Args.length % 2 == 0 && allSatisfy!(Variant.compatibleToGodot, Args)) 84 { 85 Dictionary ret = void; 86 _godot_api.godot_dictionary_new(&ret._godot_dictionary); 87 /+ 88 BUG: wtf? when using static foreach(i; 0..Args.length/2): 89 Error: cannot use operator ~= in @nogc delegate godot.core.dictionary.Dictionary.make!(GodotStringLiteral!"name", String, GodotStringLiteral!"type", int).make.__lambda6 90 +/ 91 static foreach(i, Arg; Args) 92 { 93 static if(i % 2 == 0) 94 { 95 ret[args[i]] = args[i+1]; 96 } 97 } 98 return ret; 99 } 100 101 /// FIXME: naming convention fail again 102 deprecated("Use Dictionary.make() with 0 args instead.") 103 static Dictionary empty_dictionary() 104 { 105 Dictionary d = void; 106 _godot_api.godot_dictionary_new(&d._godot_dictionary); 107 return d; 108 } 109 110 void clear() 111 { 112 _godot_api.godot_dictionary_clear(&_godot_dictionary); 113 } 114 115 bool empty() const 116 { 117 return cast(bool)_godot_api.godot_dictionary_empty(&_godot_dictionary); 118 } 119 120 void erase(K)(in K key) if(is(K : Variant) || Variant.compatibleToGodot!K) 121 { 122 const Variant k = key; 123 _godot_api.godot_dictionary_erase(&_godot_dictionary, &k._godot_variant); 124 } 125 126 bool has(K)(in K key) const if(is(K : Variant) || Variant.compatibleToGodot!K) 127 { 128 const Variant k = key; 129 return cast(bool)_godot_api.godot_dictionary_has(&_godot_dictionary, &k._godot_variant); 130 } 131 132 bool hasAll(in Array keys) const 133 { 134 return cast(bool)_godot_api.godot_dictionary_has_all(&_godot_dictionary, &keys._godot_array); 135 } 136 137 uint hash() const 138 { 139 return _godot_api.godot_dictionary_hash(&_godot_dictionary); 140 } 141 142 Array keys() const 143 { 144 Array a = void; 145 a._godot_array = _godot_api.godot_dictionary_keys(&_godot_dictionary); 146 return a; 147 } 148 149 Variant opIndex(K)(in K key) const if(is(K : Variant) || Variant.compatibleToGodot!K) 150 { 151 const Variant k = key; 152 Variant ret = void; 153 ret._godot_variant = _godot_api.godot_dictionary_get(&_godot_dictionary, &k._godot_variant); 154 return ret; 155 } 156 157 void opIndexAssign(K, V)(in auto ref V value, in auto ref K key) if( 158 (is(K : Variant) || Variant.compatibleToGodot!K) && 159 (is(V : Variant) || Variant.compatibleToGodot!V) ) 160 { 161 const Variant k = key; 162 const Variant v = value; 163 _godot_api.godot_dictionary_set(&_godot_dictionary, &k._godot_variant, &v._godot_variant); 164 } 165 166 int size() const 167 { 168 return _godot_api.godot_dictionary_size(&_godot_dictionary); 169 } 170 171 String toJson() const 172 { 173 godot_string s = _godot_api.godot_dictionary_to_json(&_godot_dictionary); 174 return cast(String)s; 175 } 176 177 Array values() const 178 { 179 godot_array a = _godot_api.godot_dictionary_values(&_godot_dictionary); 180 return cast(Array)a; 181 } 182 183 ~this() 184 { 185 _godot_api.godot_dictionary_destroy(&_godot_dictionary); 186 } 187 } 188