D doesn't have weak references. So how can I make a associative array of objects without preventing their destruction?
Liam McGillivray
yoshi.pit.link.mario at gmail.com
Thu May 9 00:39:49 UTC 2024
A "weak reference" (in the sense that I'm referring to) is a
feature in some programming languages for a reference to an
object that doesn't prevent the GC from destroying that object.
My current understanding is that D doesn't have weak references,
though I've found some posts in this forum from many years back
that mention something called "weakref". So is weakref a real
thing, or just a concept that never got implemented?
The functionality that I'm going to describe would be easy with
weak references, but I don't know how I would implement it
without it. If there is a way to implement it without it, I would
like to know how. I am going to describe my specific example, but
it may apply to any class that's initialized using contents of a
file without any of that data being modified after.
In my particular case, the class I've created is a wrapper for
the `Texture2D` struct in Raylib. This class holds an image that
was loaded from a file.
```
Sprite[string] spritesByPath;
Sprite getSprite(string path) {
path = path.asAbsolutePath;
if (path !in spritesByPath) {
spritesByPath[path] = new Sprite(path);
}
return spritesByPath[path];
}
class Sprite
{
Texture2D texture;
alias this = texture;
string path;
this(string path) {
texture = LoadTexture(path.toStringz);
this.path = path;
}
~this() {
if (IsWindowReady) UnloadTexture(texture);
if (path in spritesByPath) spritesByName.remove(path);
}
}
```
Alternatively, `spritesByPath` and `getSprite` may be static
members of `Sprite`.
If D had weak references, than `spritesByPath` would be made of
weak references so that they don't prevent the destruction of
`Sprite` objects, which should be destroyed whenever they don't
have any references elsewhere.
I've considered making `Sprite` reference-counted, but I couldn't
manage to figure out how to do it properly. I tried doing
`SafeRefCounted!Sprite` but the compiler said it doesn't work on
`Object` types. I then tried making my own struct for reference
counting that would be placed in place of a direct reference to
the `Sprite` object, but there was some bug in which sometimes it
didn't increment the reference count, so it didn't work.
What's a good way I can achieve what I'm trying to do, using
either reference counting or a garbage-collected object?
More information about the Digitalmars-d-learn
mailing list