Skip to content

Commit

Permalink
Implment managed object reference count
Browse files Browse the repository at this point in the history
  • Loading branch information
Delsin-Yu committed Aug 31, 2024
1 parent 61598c5 commit 4a8f918
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 2 deletions.
33 changes: 32 additions & 1 deletion modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public sealed class Array :

private WeakReference<IDisposable>? _weakReferenceToSelf;

internal int TypedWrapperReferenceCount;

/// <summary>
/// Constructs a new empty <see cref="Array"/>.
/// </summary>
Expand Down Expand Up @@ -1052,7 +1054,8 @@ public sealed class Array<[MustBeVariant] T> :
IReadOnlyList<T>,
ICollection<T>,
IEnumerable<T>,
IGenericGodotArray
IGenericGodotArray,
IDisposable
{
private static godot_variant ToVariantFunc(in Array<T> godotArray) =>
VariantUtils.CreateFromArray(godotArray);
Expand All @@ -1067,6 +1070,7 @@ static unsafe Array()
}

private readonly Array _underlyingArray;
private bool _disposed;

Array IGenericGodotArray.UnderlyingArray => _underlyingArray;

Expand All @@ -1083,6 +1087,7 @@ internal ref godot_array.movable NativeValue
public Array()
{
_underlyingArray = new Array();
_underlyingArray.TypedWrapperReferenceCount++;
}

/// <summary>
Expand All @@ -1099,6 +1104,7 @@ public Array(IEnumerable<T> collection)
throw new ArgumentNullException(nameof(collection));

_underlyingArray = new Array();
_underlyingArray.TypedWrapperReferenceCount++;

foreach (T element in collection)
Add(element);
Expand All @@ -1118,6 +1124,7 @@ public Array(T[] array)
throw new ArgumentNullException(nameof(array));

_underlyingArray = new Array();
_underlyingArray.TypedWrapperReferenceCount++;

foreach (T element in array)
Add(element);
Expand All @@ -1137,6 +1144,7 @@ public Array(Array array)
throw new ArgumentNullException(nameof(array));

_underlyingArray = array;
_underlyingArray.TypedWrapperReferenceCount++;
}

// Explicit name to make it very clear
Expand All @@ -1154,6 +1162,29 @@ internal static Array<T> CreateTakingOwnershipOfDisposableValue(godot_array nati
return from?._underlyingArray;
}

~Array()
{
Dispose(false);
}

/// <summary>
/// Disposes of this <see cref="Array"/>.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

public void Dispose(bool disposing)
{
if(_disposed) return;
_disposed = true;
_underlyingArray.TypedWrapperReferenceCount--;
if(_underlyingArray.TypedWrapperReferenceCount > 0) return;
_underlyingArray.Dispose(disposing);
}

/// <summary>
/// Duplicates this <see cref="Array{T}"/>.
/// </summary>
Expand Down
32 changes: 31 additions & 1 deletion modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public sealed class Dictionary :

private WeakReference<IDisposable>? _weakReferenceToSelf;

internal int TypedWrapperReferenceCount;

/// <summary>
/// Constructs a new empty <see cref="Dictionary"/>.
/// </summary>
Expand Down Expand Up @@ -488,7 +490,8 @@ internal interface IGenericGodotDictionary
public class Dictionary<[MustBeVariant] TKey, [MustBeVariant] TValue> :
IDictionary<TKey, TValue>,
IReadOnlyDictionary<TKey, TValue>,
IGenericGodotDictionary
IGenericGodotDictionary,
IDisposable
{
private static godot_variant ToVariantFunc(in Dictionary<TKey, TValue> godotDictionary) =>
VariantUtils.CreateFromDictionary(godotDictionary);
Expand All @@ -503,6 +506,7 @@ static unsafe Dictionary()
}

private readonly Dictionary _underlyingDict;
private bool _disposed;

Dictionary IGenericGodotDictionary.UnderlyingDictionary => _underlyingDict;

Expand All @@ -519,6 +523,7 @@ internal ref godot_dictionary.movable NativeValue
public Dictionary()
{
_underlyingDict = new Dictionary();
_underlyingDict.TypedWrapperReferenceCount++;
}

/// <summary>
Expand All @@ -535,6 +540,7 @@ public Dictionary(IDictionary<TKey, TValue> dictionary)
throw new ArgumentNullException(nameof(dictionary));

_underlyingDict = new Dictionary();
_underlyingDict.TypedWrapperReferenceCount++;

foreach (KeyValuePair<TKey, TValue> entry in dictionary)
Add(entry.Key, entry.Value);
Expand All @@ -554,6 +560,7 @@ public Dictionary(Dictionary dictionary)
throw new ArgumentNullException(nameof(dictionary));

_underlyingDict = dictionary;
_underlyingDict.TypedWrapperReferenceCount++;
}

// Explicit name to make it very clear
Expand All @@ -572,6 +579,29 @@ internal static Dictionary<TKey, TValue> CreateTakingOwnershipOfDisposableValue(
return from?._underlyingDict;
}

~Dictionary()
{
Dispose(false);
}

/// <summary>
/// Disposes of this <see cref="Array"/>.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

public void Dispose(bool disposing)
{
if(_disposed) return;
_disposed = true;
_underlyingDict.TypedWrapperReferenceCount--;
if(_underlyingDict.TypedWrapperReferenceCount > 0) return;
_underlyingDict.Dispose(disposing);
}

/// <summary>
/// Returns a copy of the <see cref="Dictionary{TKey, TValue}"/>.
/// If <paramref name="deep"/> is <see langword="true"/>, a deep copy is performed:
Expand Down

0 comments on commit 4a8f918

Please sign in to comment.