Destruction in D

via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat May 2 06:22:57 PDT 2015


On Friday, 1 May 2015 at 18:37:41 UTC, Idan Arye wrote:
> On Friday, 1 May 2015 at 17:45:02 UTC, bitwise wrote:
>> On Friday, 1 May 2015 at 02:35:52 UTC, Idan Arye wrote:
>>> On Thursday, 30 April 2015 at 23:27:49 UTC, bitwise wrote:
>>>> Well, the third thing was just my reasoning for asking in 
>>>> the first place. I need to be able to acquire/release shared 
>>>> resources reliably, like an OpenGL texture, for example.
>>>
>>> If you want to release resources, you are going to have to 
>>> call some functions that do that for you, so you can't escape 
>>> that "special stack frame"(what's so special about it?) - 
>>> though the compiler might inline it.
>>>
>>> When you use a GC the compiler don't need to invoke the 
>>> destructor in the end of the scope because the object is 
>>> destroyed in the background, but that also means you can't 
>>> rely on it to release your resources, so languages like Java 
>>> and C# use try-with-resources and using 
>>> statements(corresponding) to call something at the end of the 
>>> scope and end up using that stack frame anyways.
>>
>> I'm not sure I understand you 100%, but my plan was to have an 
>> asset management system give out ref counted textures/etc. 
>> Whenever the last one went out of scope, the asset would be 
>> destroyed. This only works if the destructor is called on the 
>> graphics thread due to limitations of graphics APIs. In a 
>> single threaded C++ app, this is fine, destructors are called 
>> at end of scope. I was confused though, because like C#, D has 
>> both reference and value types. But, while in C#, value types 
>> still do not have destructors(grrr...) D structs do have 
>> destructors, which apparently run when the struct goes out of 
>> scope. However, the D port of my code will most likely use 
>> multithreaded rendering, which removes the guarantee that the 
>> assets will go out of scope on the graphics thread, so this 
>> idea is a no-go anyways.
>
> Structs allow you to implement ref-counting smart pointers like 
> you can do in C++. There is an implementation in the standard 
> library: http://dlang.org/phobos/std_typecons.html#.RefCounted
>
> But for something as structured and as heavy as gaming 
> resources, I would go for a more manual approach like a 
> repository-style architecture, where you manually tell the 
> repository to load/release the the resources.

A very easy and simple solution is to have a queue of unused
textures in your asset manager, that any thread can push to, but
only one thread consumes from. Whenever the last ref is released
you push a texture into this queue, and at the end of each frame,
while the GPU is busy rendering or flipping, you go through this
queue on the appropriate thread and delete the textures.
This has the advantage of making your timings deterministic, i.e.
a function won't suddently take 200x longer because it happened
to release the last ref to a texture.

Also, remember that aquiring/releasing refs in a threaded
environment is quite expensive, and you don't want to be doing
this while passing a texture around in your graphics pipeline, so
you probably shouldn't be counting texture refs at the texture
level, but maybe when you load/destroy a material, for example.


More information about the Digitalmars-d-learn mailing list