Dictionary.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections;
  4. using System.Runtime.CompilerServices;
  5. using System.Runtime.InteropServices;
  6. namespace Godot.Collections
  7. {
  8. class DictionarySafeHandle : SafeHandle
  9. {
  10. public DictionarySafeHandle(IntPtr handle) : base(IntPtr.Zero, true)
  11. {
  12. this.handle = handle;
  13. }
  14. public override bool IsInvalid
  15. {
  16. get
  17. {
  18. return handle == IntPtr.Zero;
  19. }
  20. }
  21. protected override bool ReleaseHandle()
  22. {
  23. Dictionary.godot_icall_Dictionary_Dtor(handle);
  24. return true;
  25. }
  26. }
  27. public class Dictionary :
  28. IDictionary<object, object>,
  29. ICollection<KeyValuePair<object, object>>,
  30. IEnumerable<KeyValuePair<object, object>>,
  31. IDisposable
  32. {
  33. DictionarySafeHandle safeHandle;
  34. bool disposed = false;
  35. public Dictionary()
  36. {
  37. safeHandle = new DictionarySafeHandle(godot_icall_Dictionary_Ctor());
  38. }
  39. internal Dictionary(DictionarySafeHandle handle)
  40. {
  41. safeHandle = handle;
  42. }
  43. internal Dictionary(IntPtr handle)
  44. {
  45. safeHandle = new DictionarySafeHandle(handle);
  46. }
  47. internal IntPtr GetPtr()
  48. {
  49. if (disposed)
  50. throw new ObjectDisposedException(GetType().FullName);
  51. return safeHandle.DangerousGetHandle();
  52. }
  53. public void Dispose()
  54. {
  55. if (disposed)
  56. return;
  57. if (safeHandle != null)
  58. {
  59. safeHandle.Dispose();
  60. safeHandle = null;
  61. }
  62. disposed = true;
  63. }
  64. public object this[object key]
  65. {
  66. get
  67. {
  68. return godot_icall_Dictionary_GetValue(GetPtr(), key);
  69. }
  70. set
  71. {
  72. godot_icall_Dictionary_SetValue(GetPtr(), key, value);
  73. }
  74. }
  75. public ICollection<object> Keys
  76. {
  77. get
  78. {
  79. IntPtr handle = godot_icall_Dictionary_Keys(GetPtr());
  80. return new Array(new ArraySafeHandle(handle));
  81. }
  82. }
  83. public ICollection<object> Values
  84. {
  85. get
  86. {
  87. IntPtr handle = godot_icall_Dictionary_Values(GetPtr());
  88. return new Array(new ArraySafeHandle(handle));
  89. }
  90. }
  91. public int Count
  92. {
  93. get
  94. {
  95. return godot_icall_Dictionary_Count(GetPtr());
  96. }
  97. }
  98. public bool IsReadOnly
  99. {
  100. get
  101. {
  102. return false;
  103. }
  104. }
  105. public void Add(object key, object value)
  106. {
  107. godot_icall_Dictionary_Add(GetPtr(), key, value);
  108. }
  109. public void Add(KeyValuePair<object, object> item)
  110. {
  111. Add(item.Key, item.Value);
  112. }
  113. public void Clear()
  114. {
  115. godot_icall_Dictionary_Clear(GetPtr());
  116. }
  117. public bool Contains(KeyValuePair<object, object> item)
  118. {
  119. return godot_icall_Dictionary_Contains(GetPtr(), item.Key, item.Value);
  120. }
  121. public bool ContainsKey(object key)
  122. {
  123. return godot_icall_Dictionary_ContainsKey(GetPtr(), key);
  124. }
  125. public void CopyTo(KeyValuePair<object, object>[] array, int arrayIndex)
  126. {
  127. // TODO 3 internal calls, can reduce to 1
  128. Array keys = (Array)Keys;
  129. Array values = (Array)Values;
  130. int count = Count;
  131. for (int i = 0; i < count; i++)
  132. {
  133. // TODO 2 internal calls, can reduce to 1
  134. array[arrayIndex] = new KeyValuePair<object, object>(keys[i], values[i]);
  135. arrayIndex++;
  136. }
  137. }
  138. public IEnumerator<KeyValuePair<object, object>> GetEnumerator()
  139. {
  140. // TODO 3 internal calls, can reduce to 1
  141. Array keys = (Array)Keys;
  142. Array values = (Array)Values;
  143. int count = Count;
  144. for (int i = 0; i < count; i++)
  145. {
  146. // TODO 2 internal calls, can reduce to 1
  147. yield return new KeyValuePair<object, object>(keys[i], values[i]);
  148. }
  149. }
  150. public bool Remove(object key)
  151. {
  152. return godot_icall_Dictionary_RemoveKey(GetPtr(), key);
  153. }
  154. public bool Remove(KeyValuePair<object, object> item)
  155. {
  156. return godot_icall_Dictionary_Remove(GetPtr(), item.Key, item.Value);
  157. }
  158. public bool TryGetValue(object key, out object value)
  159. {
  160. object retValue;
  161. bool found = godot_icall_Dictionary_TryGetValue(GetPtr(), key, out retValue);
  162. value = found ? retValue : default(object);
  163. return found;
  164. }
  165. IEnumerator IEnumerable.GetEnumerator()
  166. {
  167. return GetEnumerator();
  168. }
  169. [MethodImpl(MethodImplOptions.InternalCall)]
  170. internal extern static IntPtr godot_icall_Dictionary_Ctor();
  171. [MethodImpl(MethodImplOptions.InternalCall)]
  172. internal extern static void godot_icall_Dictionary_Dtor(IntPtr ptr);
  173. [MethodImpl(MethodImplOptions.InternalCall)]
  174. internal extern static object godot_icall_Dictionary_GetValue(IntPtr ptr, object key);
  175. [MethodImpl(MethodImplOptions.InternalCall)]
  176. internal extern static object godot_icall_Dictionary_GetValue_Generic(IntPtr ptr, object key, int valTypeEncoding, IntPtr valTypeClass);
  177. [MethodImpl(MethodImplOptions.InternalCall)]
  178. internal extern static void godot_icall_Dictionary_SetValue(IntPtr ptr, object key, object value);
  179. [MethodImpl(MethodImplOptions.InternalCall)]
  180. internal extern static IntPtr godot_icall_Dictionary_Keys(IntPtr ptr);
  181. [MethodImpl(MethodImplOptions.InternalCall)]
  182. internal extern static IntPtr godot_icall_Dictionary_Values(IntPtr ptr);
  183. [MethodImpl(MethodImplOptions.InternalCall)]
  184. internal extern static int godot_icall_Dictionary_Count(IntPtr ptr);
  185. [MethodImpl(MethodImplOptions.InternalCall)]
  186. internal extern static void godot_icall_Dictionary_Add(IntPtr ptr, object key, object value);
  187. [MethodImpl(MethodImplOptions.InternalCall)]
  188. internal extern static void godot_icall_Dictionary_Clear(IntPtr ptr);
  189. [MethodImpl(MethodImplOptions.InternalCall)]
  190. internal extern static bool godot_icall_Dictionary_Contains(IntPtr ptr, object key, object value);
  191. [MethodImpl(MethodImplOptions.InternalCall)]
  192. internal extern static bool godot_icall_Dictionary_ContainsKey(IntPtr ptr, object key);
  193. [MethodImpl(MethodImplOptions.InternalCall)]
  194. internal extern static bool godot_icall_Dictionary_RemoveKey(IntPtr ptr, object key);
  195. [MethodImpl(MethodImplOptions.InternalCall)]
  196. internal extern static bool godot_icall_Dictionary_Remove(IntPtr ptr, object key, object value);
  197. [MethodImpl(MethodImplOptions.InternalCall)]
  198. internal extern static bool godot_icall_Dictionary_TryGetValue(IntPtr ptr, object key, out object value);
  199. [MethodImpl(MethodImplOptions.InternalCall)]
  200. internal extern static bool godot_icall_Dictionary_TryGetValue_Generic(IntPtr ptr, object key, out object value, int valTypeEncoding, IntPtr valTypeClass);
  201. [MethodImpl(MethodImplOptions.InternalCall)]
  202. internal extern static void godot_icall_Dictionary_Generic_GetValueTypeInfo(Type valueType, out int valTypeEncoding, out IntPtr valTypeClass);
  203. }
  204. public class Dictionary<TKey, TValue> :
  205. IDictionary<TKey, TValue>,
  206. ICollection<KeyValuePair<TKey, TValue>>,
  207. IEnumerable<KeyValuePair<TKey, TValue>>
  208. {
  209. Dictionary objectDict;
  210. internal static int valTypeEncoding;
  211. internal static IntPtr valTypeClass;
  212. static Dictionary()
  213. {
  214. Dictionary.godot_icall_Dictionary_Generic_GetValueTypeInfo(typeof(TValue), out valTypeEncoding, out valTypeClass);
  215. }
  216. public Dictionary()
  217. {
  218. objectDict = new Dictionary();
  219. }
  220. public Dictionary(Dictionary dictionary)
  221. {
  222. objectDict = dictionary;
  223. }
  224. internal Dictionary(IntPtr handle)
  225. {
  226. objectDict = new Dictionary(handle);
  227. }
  228. internal Dictionary(DictionarySafeHandle handle)
  229. {
  230. objectDict = new Dictionary(handle);
  231. }
  232. public static explicit operator Dictionary(Dictionary<TKey, TValue> from)
  233. {
  234. return from.objectDict;
  235. }
  236. public TValue this[TKey key]
  237. {
  238. get
  239. {
  240. return (TValue)Dictionary.godot_icall_Dictionary_GetValue_Generic(objectDict.GetPtr(), key, valTypeEncoding, valTypeClass);
  241. }
  242. set
  243. {
  244. objectDict[key] = value;
  245. }
  246. }
  247. public ICollection<TKey> Keys
  248. {
  249. get
  250. {
  251. IntPtr handle = Dictionary.godot_icall_Dictionary_Keys(objectDict.GetPtr());
  252. return new Array<TKey>(new ArraySafeHandle(handle));
  253. }
  254. }
  255. public ICollection<TValue> Values
  256. {
  257. get
  258. {
  259. IntPtr handle = Dictionary.godot_icall_Dictionary_Values(objectDict.GetPtr());
  260. return new Array<TValue>(new ArraySafeHandle(handle));
  261. }
  262. }
  263. public int Count
  264. {
  265. get
  266. {
  267. return objectDict.Count;
  268. }
  269. }
  270. public bool IsReadOnly
  271. {
  272. get
  273. {
  274. return objectDict.IsReadOnly;
  275. }
  276. }
  277. public void Add(TKey key, TValue value)
  278. {
  279. objectDict.Add(key, value);
  280. }
  281. public void Add(KeyValuePair<TKey, TValue> item)
  282. {
  283. objectDict.Add(item.Key, item.Value);
  284. }
  285. public void Clear()
  286. {
  287. objectDict.Clear();
  288. }
  289. public bool Contains(KeyValuePair<TKey, TValue> item)
  290. {
  291. return objectDict.Contains(new KeyValuePair<object, object>(item.Key, item.Value));
  292. }
  293. public bool ContainsKey(TKey key)
  294. {
  295. return objectDict.ContainsKey(key);
  296. }
  297. public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
  298. {
  299. // TODO 3 internal calls, can reduce to 1
  300. Array<TKey> keys = (Array<TKey>)Keys;
  301. Array<TValue> values = (Array<TValue>)Values;
  302. int count = Count;
  303. for (int i = 0; i < count; i++)
  304. {
  305. // TODO 2 internal calls, can reduce to 1
  306. array[arrayIndex] = new KeyValuePair<TKey, TValue>(keys[i], values[i]);
  307. arrayIndex++;
  308. }
  309. }
  310. public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
  311. {
  312. // TODO 3 internal calls, can reduce to 1
  313. Array<TKey> keys = (Array<TKey>)Keys;
  314. Array<TValue> values = (Array<TValue>)Values;
  315. int count = Count;
  316. for (int i = 0; i < count; i++)
  317. {
  318. // TODO 2 internal calls, can reduce to 1
  319. yield return new KeyValuePair<TKey, TValue>(keys[i], values[i]);
  320. }
  321. }
  322. public bool Remove(TKey key)
  323. {
  324. return objectDict.Remove(key);
  325. }
  326. public bool Remove(KeyValuePair<TKey, TValue> item)
  327. {
  328. return objectDict.Remove(new KeyValuePair<object, object>(item.Key, item.Value));
  329. }
  330. public bool TryGetValue(TKey key, out TValue value)
  331. {
  332. object retValue;
  333. bool found = Dictionary.godot_icall_Dictionary_TryGetValue_Generic(GetPtr(), key, out retValue, valTypeEncoding, valTypeClass);
  334. value = found ? (TValue)retValue : default(TValue);
  335. return found;
  336. }
  337. IEnumerator IEnumerable.GetEnumerator()
  338. {
  339. return GetEnumerator();
  340. }
  341. internal IntPtr GetPtr()
  342. {
  343. return objectDict.GetPtr();
  344. }
  345. }
  346. }