Skip to content

Commit 7279e03

Browse files
Merge pull request #7 from CoderGamester/develop
Release 0.6.0
2 parents 3c445ea + f0a6b70 commit 7279e03

11 files changed

+742
-262
lines changed

CHANGELOG.md

+27-2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,38 @@ All notable changes to this package will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## [0.6.0] - 2023-08-05
8+
9+
- Improved the *ObservableResolverList* and *ObservableResolverDictionary* data types to properly resolve lists and dictionaries with different data types from the original collection.
10+
11+
## [0.5.1] - 2023-09-04
12+
13+
- Added StructPair data type to support both object and struct type containers, improving memory usage performance.
14+
15+
**Fix**:
16+
- Fixed the dispose extension methods for GameObject and Object, removing pragma directives and adding null reference check in GetValid method to avoid unwanted exceptions
17+
18+
## [0.5.0] - 2023-08-05
19+
20+
- Added **floatP**, a deterministic floating-point number type, enhancing precision and predictability in mathematical operations. Including arithmetic and comparison operators for floatP to support complex calculations and conversion methods between floatP and float types.
21+
22+
## [0.4.0] - 2023-07-30
23+
24+
- Added utility methods and extensions for Unity's Object and GameObject types, enhancing the codebase's functionality.
25+
- Introduced a SerializableType struct for viewing, modifying, and saving types from the inspector, with serialization support and compatibility with filter attributes.
26+
27+
## [0.3.0] - 2023-07-28
28+
29+
- Added support for observing field updates with previous and current values in the ObservableField class.
30+
- Introduced a UnitySerializedDictionary class that allows serialization of dictionaries in Unity.
31+
732
## [0.2.0] - 2020-09-28
833

9-
- Removed *ObservableIdList* because it's behaviour was too confusing and the same result can be obtained with *ObservableList* or *ObservableDictionary*
1034
- Added new *ObservableResolverList*, *ObservableResolverDictionary* & *ObservableResolverField* to allow to create observable types without referencing the collection directly
11-
- Added Unit tests to all types
35+
- Added Unit tests to all data types in the project
1236

1337
**Changed**:
38+
- Removed *ObservableIdList* because it's behaviour was too confusing and the same result can be obtained with *ObservableList* or *ObservableDictionary*
1439
- Removed all Pair Data and moved them to new *Pair<Key,Value>* serialized type that can now be serializable on Unity 2020.1
1540
- Moved all Vector2, Vector3 & Vector4 extensions to the ValueData file
1641

Runtime/ObservableDictionary.cs

+179-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
using NUnit.Framework;
12
using System;
23
using System.Collections;
34
using System.Collections.Generic;
45
using System.Collections.ObjectModel;
6+
using UnityEngine.UIElements;
57

68
// ReSharper disable once CheckNamespace
79

@@ -19,6 +21,9 @@ public interface IObservableDictionary : IEnumerable
1921
}
2022

2123
/// <inheritdoc cref="IObservableDictionary"/>
24+
/// <remarks>
25+
/// This dictionary only allows to read the elements in it and not to modify it
26+
/// </remarks>
2227
public interface IObservableDictionaryReader<TKey, TValue> : IObservableDictionary, IEnumerable<KeyValuePair<TKey, TValue>>
2328
{
2429
/// <summary>
@@ -71,7 +76,7 @@ public interface IObservableDictionaryReader<TKey, TValue> : IObservableDictiona
7176
void StopObservingAll(object subscriber = null);
7277
}
7378

74-
/// <inheritdoc />
79+
/// <inheritdoc cref="IObservableDictionary"/>
7580
public interface IObservableDictionary<TKey, TValue> : IObservableDictionaryReader<TKey, TValue>
7681
{
7782
/// <summary>
@@ -86,12 +91,77 @@ public interface IObservableDictionary<TKey, TValue> : IObservableDictionaryRead
8691
/// <inheritdoc cref="Dictionary{TKey,TValue}.Remove" />
8792
bool Remove(TKey key);
8893

94+
/// <inheritdoc cref="Dictionary{TKey,TValue}.Clear"/>
95+
void Clear();
96+
8997
/// <remarks>
9098
/// It invokes any update method that is observing to the given <paramref name="key"/> on this dictionary
9199
/// </remarks>
92100
void InvokeUpdate(TKey key);
93101
}
94102

103+
/// <inheritdoc />
104+
/// <remarks>
105+
/// This interface resolves between 2 dictionaries with different types of keys and values
106+
/// </remarks>
107+
public interface IObservableResolverDictionaryReader<TKey, TValue, TKeyOrigin, TValueOrigin> :
108+
IObservableDictionaryReader<TKey, TValue>
109+
{
110+
/// <summary>
111+
/// The Original Dictionary that is being resolved across the entire interface
112+
/// </summary>
113+
ReadOnlyDictionary<TKeyOrigin, TValueOrigin> OriginDictionary { get; }
114+
115+
/// <summary>
116+
/// Gets the value from the origin dictionary corresponding to the specified key.
117+
/// </summary>
118+
/// <param name="key">The key to locate in the origin dictionary.</param>
119+
/// <returns>The value from the origin dictionary corresponding to the specified key.</returns>
120+
TValueOrigin GetOriginValue(TKey key);
121+
122+
/// <summary>
123+
/// Attempts to get the value from the origin dictionary corresponding to the specified key.
124+
/// </summary>
125+
/// <param name="key">The key to locate in the origin dictionary.</param>
126+
/// <param name="value">When this method returns, contains the value from the origin dictionary corresponding to the specified key, if the key is found; otherwise, the default value for the type of the value parameter. This parameter is passed uninitialized.</param>
127+
/// <returns>true if the origin dictionary contains an element with the specified key; otherwise, false.</returns>
128+
bool TryGetOriginValue(TKey key, out TValueOrigin value);
129+
}
130+
131+
/// <inheritdoc cref="IObservableDictionary{TKey,TValue}"/>
132+
/// <remarks>
133+
/// This interface resolves between 2 dictionaries with different types of keys and values
134+
/// </remarks>
135+
public interface IObservableResolverDictionary<TKey, TValue, TKeyOrigin, TValueOrigin> :
136+
IObservableResolverDictionaryReader<TKey, TValue, TKeyOrigin, TValueOrigin>,
137+
IObservableDictionary<TKey, TValue>
138+
{
139+
/// <summary>
140+
/// Updates the value in the origin dictionary corresponding to the specified origin key.
141+
/// </summary>
142+
/// <param name="key">The key of the value to update in the origin dictionary.</param>
143+
/// <param name="value">The new value to set in the origin dictionary.</param>
144+
void UpdateOrigin(TKeyOrigin key, TValueOrigin value);
145+
146+
/// <inheritdoc cref="Dictionary{TKey,TValue}.Add" />
147+
/// <remarks>
148+
/// Add's to the origin dictionary
149+
/// </remarks>
150+
void AddOrigin(TKeyOrigin key, TValueOrigin value);
151+
152+
/// <inheritdoc cref="Dictionary{TKey,TValue}.Remove" />
153+
/// <remarks>
154+
/// Remove's to the origin dictionary
155+
/// </remarks>
156+
bool RemoveOrigin(TKeyOrigin key);
157+
158+
/// <inheritdoc cref="Dictionary{TKey,TValue}.Clear" />
159+
/// <remarks>
160+
/// Clear's to the origin dictionary
161+
/// </remarks>
162+
void ClearOrigin();
163+
}
164+
95165
/// <inheritdoc />
96166
public class ObservableDictionary<TKey, TValue> : IObservableDictionary<TKey, TValue>
97167
{
@@ -153,7 +223,7 @@ public bool ContainsKey(TKey key)
153223
}
154224

155225
/// <inheritdoc />
156-
public void Add(TKey key, TValue value)
226+
public virtual void Add(TKey key, TValue value)
157227
{
158228
Dictionary.Add(key, value);
159229

@@ -172,7 +242,7 @@ public void Add(TKey key, TValue value)
172242
}
173243

174244
/// <inheritdoc />
175-
public bool Remove(TKey key)
245+
public virtual bool Remove(TKey key)
176246
{
177247
if (!Dictionary.TryGetValue(key, out var value))
178248
{
@@ -197,6 +267,22 @@ public bool Remove(TKey key)
197267
return true;
198268
}
199269

270+
/// <inheritdoc />
271+
public virtual void Clear()
272+
{
273+
var dictionary = new Dictionary<TKey, TValue>(Dictionary);
274+
275+
Dictionary.Clear();
276+
277+
for (var i = 0; i < _updateActions.Count; i++)
278+
{
279+
foreach (var data in dictionary)
280+
{
281+
_updateActions[i](data.Key, data.Value, default, ObservableUpdateType.Removed);
282+
}
283+
}
284+
}
285+
200286
/// <inheritdoc />
201287
public void InvokeUpdate(TKey key)
202288
{
@@ -310,16 +396,100 @@ protected void InvokeUpdate(TKey key, TValue previousValue)
310396
}
311397

312398
/// <inheritdoc />
313-
public class ObservableResolverDictionary<TKey, TValue> : ObservableDictionary<TKey, TValue>
314-
where TValue : struct
399+
public class ObservableResolverDictionary<TKey, TValue, TKeyOrigin, TValueOrigin> :
400+
ObservableDictionary<TKey, TValue>,
401+
IObservableResolverDictionary<TKey, TValue, TKeyOrigin, TValueOrigin>
315402
{
316-
private readonly Func<IDictionary<TKey, TValue>> _dictionaryResolver;
403+
private readonly IDictionary<TKeyOrigin, TValueOrigin> _dictionary;
404+
private readonly Func<TKey, TValue, KeyValuePair<TKeyOrigin, TValueOrigin>> _toOrignResolver;
405+
private readonly Func<KeyValuePair<TKeyOrigin, TValueOrigin>, KeyValuePair<TKey, TValue>> _fromOrignResolver;
317406

318-
protected override IDictionary<TKey, TValue> Dictionary => _dictionaryResolver();
407+
/// <inheritdoc />
408+
public ReadOnlyDictionary<TKeyOrigin, TValueOrigin> OriginDictionary => new ReadOnlyDictionary<TKeyOrigin, TValueOrigin>(_dictionary);
319409

320-
public ObservableResolverDictionary(Func<IDictionary<TKey, TValue>> dictionaryResolver)
410+
public ObservableResolverDictionary(IDictionary<TKeyOrigin, TValueOrigin> dictionary,
411+
Func<KeyValuePair<TKeyOrigin, TValueOrigin>, KeyValuePair<TKey, TValue>> fromOrignResolver,
412+
Func<TKey, TValue, KeyValuePair<TKeyOrigin, TValueOrigin>> toOrignResolver)
413+
: base(new Dictionary<TKey, TValue>(dictionary.Count))
414+
{
415+
_dictionary = dictionary;
416+
_toOrignResolver = toOrignResolver;
417+
_fromOrignResolver = fromOrignResolver;
418+
419+
foreach (var pair in dictionary)
420+
{
421+
Dictionary.Add(fromOrignResolver(pair));
422+
}
423+
}
424+
425+
/// <inheritdoc />
426+
public TValueOrigin GetOriginValue(TKey key)
427+
{
428+
return _dictionary[_toOrignResolver(key, default).Key];
429+
}
430+
431+
/// <inheritdoc />
432+
public bool TryGetOriginValue(TKey key, out TValueOrigin value)
433+
{
434+
return _dictionary.TryGetValue(_toOrignResolver(key, default).Key, out value);
435+
}
436+
437+
/// <inheritdoc />
438+
public void UpdateOrigin(TKeyOrigin key, TValueOrigin value)
439+
{
440+
var convertPair = _fromOrignResolver(new KeyValuePair<TKeyOrigin, TValueOrigin>(key, value));
441+
442+
_dictionary[key] = value;
443+
this[convertPair.Key] = convertPair.Value;
444+
}
445+
446+
/// <inheritdoc />
447+
public override void Add(TKey key, TValue value)
448+
{
449+
_dictionary.Add(_toOrignResolver(key, value));
450+
base.Add(key, value);
451+
}
452+
453+
/// <inheritdoc />
454+
public override bool Remove(TKey key)
455+
{
456+
var pair = _toOrignResolver(key, Dictionary[key]);
457+
458+
_dictionary.Remove(pair.Key);
459+
460+
return base.Remove(key);
461+
}
462+
463+
/// <inheritdoc />
464+
public override void Clear()
465+
{
466+
_dictionary.Clear();
467+
base.Clear(); ;
468+
}
469+
470+
/// <inheritdoc />
471+
public void AddOrigin(TKeyOrigin key, TValueOrigin value)
472+
{
473+
var convertPair = _fromOrignResolver(new KeyValuePair<TKeyOrigin, TValueOrigin>(key, value));
474+
475+
_dictionary.Add(key, value);
476+
base.Add(convertPair.Key, convertPair.Value);
477+
}
478+
479+
/// <inheritdoc />
480+
public bool RemoveOrigin(TKeyOrigin key)
481+
{
482+
var convertPair = _fromOrignResolver(new KeyValuePair<TKeyOrigin, TValueOrigin>(key, OriginDictionary[key]));
483+
484+
_dictionary.Remove(key);
485+
return base.Remove(convertPair.Key);
486+
}
487+
488+
/// <inheritdoc />
489+
public void ClearOrigin()
321490
{
322-
_dictionaryResolver = dictionaryResolver;
491+
_dictionary.Clear();
492+
base.Clear();
323493
}
324494
}
325495
}

0 commit comments

Comments
 (0)