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