Gondwana Game Engine Development (master) - 2.6.1
Gondwana is a cross-platform 2.5D game and rendering engine written in C#/.NET 8. It provides fine-grained control over rendering, timing, and scene composition, with built-in support for parallax, z-ordering, pixel overhang, collision detection, and particle effects. Gondwana targets desktop and web platforms using SkiaSharp for graphics and pluggable audio backends for desktop and browser targets.
Loading...
Searching...
No Matches
TypedValueBag.cs
1using Newtonsoft.Json;
2
3namespace Gondwana;
4
24public readonly record struct ValueKey<T>(string Name);
25
73public sealed class TypedValueBag : ICloneable
74{
89 [JsonIgnore]
90 private readonly Dictionary<string, object?> _data = new();
91
96 {
97 }
98
119 {
120 if (other is null)
121 throw new ArgumentNullException(nameof(other));
122
123 foreach (var (key, value) in other._data)
124 _data[key] = CloneValue(value);
125 }
126
145 public void Set<T>(ValueKey<T> key, T value)
146 {
147 ValidateKeyName(key.Name);
148 _data[key.Name] = value;
149 }
150
190 public bool TryGet<T>(ValueKey<T> key, out T? value)
191 {
192 ValidateKeyName(key.Name);
193
194 if (!_data.TryGetValue(key.Name, out var raw))
195 {
196 value = default;
197 return false;
198 }
199
200 if (raw is null)
201 {
202 value = default;
203 return true;
204 }
205
206 if (raw is T typed)
207 {
208 value = typed;
209 return true;
210 }
211
212 throw new InvalidCastException(
213 $"Value for key '{key.Name}' is of runtime type '{raw.GetType().FullName}', " +
214 $"which is not assignable to requested type '{typeof(T).FullName}'.");
215 }
216
240 public T Get<T>(ValueKey<T> key, T defaultValue = default!)
241 {
242 return TryGet(key, out var v) && v is not null
243 ? v
244 : defaultValue;
245 }
246
262 public bool Remove<T>(ValueKey<T> key)
263 {
264 ValidateKeyName(key.Name);
265 return _data.Remove(key.Name);
266 }
267
271 public void Clear()
272 {
273 _data.Clear();
274 }
275
293 public void MergeFrom(TypedValueBag? incoming, bool overwriteExisting = false)
294 {
295 if (incoming is null)
296 return;
297
298 foreach (var (key, value) in incoming._data)
299 {
300 if (!overwriteExisting && _data.ContainsKey(key))
301 continue;
302
303 _data[key] = CloneValue(value);
304 }
305 }
306
319 public bool Contains(string keyName)
320 {
321 ValidateKeyName(keyName);
322 return _data.ContainsKey(keyName);
323 }
324
340 public bool Contains<T>(ValueKey<T> key)
341 {
342 ValidateKeyName(key.Name);
343 return _data.ContainsKey(key.Name);
344 }
345
356 public TypedValueBag Clone() => new(this);
357
366 object ICloneable.Clone() => Clone();
367
378 public Dictionary<string, object?> ToDictionary()
379 {
380 return new Dictionary<string, object?>(_data);
381 }
382
415 private static object? CloneValue(object? value)
416 {
417 if (value is null)
418 return null;
419
420 if (value is Array array)
421 return array.Clone();
422
423 if (value is ICloneable cloneable)
424 return cloneable.Clone();
425
426 return value;
427 }
428
438 private static void ValidateKeyName(string keyName)
439 {
440 if (string.IsNullOrWhiteSpace(keyName))
441 throw new ArgumentException("Value bag keys may not be null, empty, or whitespace.", nameof(keyName));
442 }
443}
bool Contains(string keyName)
Determines whether the bag contains a value for the specified key name, regardless of type.
TypedValueBag()
Initializes a new instance of the TypedValueBag class.
TypedValueBag Clone()
Creates a copy of this TypedValueBag.
TypedValueBag(TypedValueBag other)
Initializes a new instance of the TypedValueBag class by performing a copy of another TypedValueBag.
Dictionary< string, object?> ToDictionary()
Produces a shallow snapshot of the bag's current contents.
void MergeFrom(TypedValueBag? incoming, bool overwriteExisting=false)
Merges values from another TypedValueBag into this instance.
void Clear()
Removes all values from the bag.