July 08, 2007
Jarrett Billingsley wrote:
> "Samuel Winchenbach" <swinchen@eece.maine.edu> wrote in message news:f6o2k2$2gu6$1@digitalmars.com...
> 
>> class TextureHandle
>> {
>>     private Texture mTexture;
>>     private char[]  mName;
>>     this(texture aTexture, char[] aName)
>>     {
>>         mTexture = aTexture;
>>         mName = aName;
>>
>>     }
>>     ~this()
>>     {
>>         mTexture.mRef--;
>>         if (mTexture.mRef == 0)
>>         {
>>             mTexture.freeGPUtexture();
>>             textureList.remove(aName);
>>             delete mTexture;
>>         }
>>     }
>>
>> }
> 
> The only issue with this is that _technically_ what you're doing in the destructor is illegal.  Destructors of non-scope classes aren't guaranteed to be called (i.e. on program exit, they might not be, but the GC will definitely call them).  Furthermore, the order of destruction is undefined, meaning that on program exit, mTexture might be destroyed before this, causing a nasty access violation when you try to do "mTexture.ref--".
> 
> However, you can avoid this ugly nondeterministic-ness by always using scope references to TextureHandle (you can have scope references to non-scope classes, too), or by keeping all instances of TextureHandle in a static/global list which you clean up in a "static ~this()" -- when static dtors are called, the GC has not yet cleaned up, so it's still legal to access reference members in class dtors. 
> 
> 

Ok...  How do you learn these things?  I have been referencing the digitalmars docs and well.. it sort of seems incomplete.


Anyways here is my next attempt.  I have to change it around and get rid of the "loadTexture" function because that can not return scope classes, which makes sense I suppose.

btw, thanks for the help!  This is certainly and educational experience.



module texture;

import std.stdio;

scope class TextureHandle
{
    private Texture mTexture;
    private char[]  mName;

    this(char[] aName)
    {	
        mName = aName;

        if (auto t = (aName in textureList))
        {
            mTexture = *t;
        }
        else
        {
            mTexture = new Texture();
            textureList[aName] = mTexture;
        }

        mTexture.mRef++;

    }

    ~this()
    {
        mTexture.mRef--;
        if (mTexture.mRef == 0)
        {
            mTexture.freeGPUtexture();
            textureList.remove(mName);
            delete mTexture;
        }
    }
}

private
{
    Texture[char[]] textureList;

    class Texture
    {
        private uint mRef = 0;
        this()
        {
        }

        ~this()
        {
        }
        void freeGPUtexture()
        {
        }
    }
}


July 08, 2007
"Samuel Winchenbach" <swinchen@eece.maine.edu> wrote in message news:f6pdft$20g2$1@digitalmars.com...
>
> Ok...  How do you learn these things?  I have been referencing the digitalmars docs and well.. it sort of seems incomplete.
>

From using D and posting on the NGs for three years ;)

(God, it's been that long?!)

> Anyways here is my next attempt.  I have to change it around and get rid of the "loadTexture" function because that can not return scope classes, which makes sense I suppose.
>
> btw, thanks for the help!  This is certainly and educational experience.
>
>
>
> module texture;
>
> import std.stdio;
>
> scope class TextureHandle
> {
>     private Texture mTexture;
>     private char[]  mName;
>
>     this(char[] aName)
>     { mName = aName;
>
>         if (auto t = (aName in textureList))
>         {
>             mTexture = *t;
>         }
>         else
>         {
>             mTexture = new Texture();
>             textureList[aName] = mTexture;
>         }
>
>         mTexture.mRef++;
>
>     }
>
>     ~this()
>     {
>         mTexture.mRef--;
>         if (mTexture.mRef == 0)
>         {
>             mTexture.freeGPUtexture();
>             textureList.remove(mName);
>             delete mTexture;
>         }
>     }
> }
>
> private
> {
>     Texture[char[]] textureList;
>
>     class Texture
>     {
>         private uint mRef = 0;
>         this()
>         {
>         }
>
>         ~this()
>         {
>         }
>         void freeGPUtexture()
>         {
>         }
>     }
> }

Looks good to me.


July 09, 2007
Ok, I have come to a number of conclusions...

#1) Scope classes are cool, but in my situation their limitations are problematic (not being able to store them in an array for example)  So I need a method that doesn't rely on them.

#2) D can not really do not reference counting because lack of copy operator.   So maybe I should just ditch reference counting all together and try to make it slightly simpler.

auto h = resource.create();
resource.destroy(h);

something like that.  avoid reference counting and just rely on the developer using the resource manager to free the resource.

Opinions on this?


Also fonts have been bugging me.  Fonts can have the same file name, but different settings (italic, bold, underlined, pt. size, etc...)  so instead of having: FontList[char[]] I think I might have FontList[FontDescriptor[]].   This seems reasonable right?

So I think my resource manager will have both an AA and a descriptor for each type of resource.   Still working on how to make it somewhat generic.   I would really like there to only be one type of handle, one type of createResource and one type of freeResource.  I am not sure this is feasible though.   At this point I am just blabbing...

Thanks for the input,
Sam
July 09, 2007
"Samuel Winchenbach" <swinchen@eece.maine.edu> wrote in message news:f6tlr6$1je2$1@digitalmars.com...
>
> auto h = resource.create();
> resource.destroy(h);
>
> something like that.  avoid reference counting and just rely on the developer using the resource manager to free the resource.
>
> Opinions on this?

One thing you can do is forget about the "nondeterministic destruction" rule and free your resources in the dtor of your resource classes anyway (this would also remove the need for a "reference" class -- just use the Texture class directly).  Then run the GC periodically.  If you're tight with mem allocation in other areas, this could be pretty efficient.  The downside is that you still have the possibility of long GC cycles (though you have the possibility of long allocations without a GC too..), and the resources wouldn't be freed _immediately_ as with refcounting.  Though, if you called the GC once every 10 seconds or so, I doubt that would be too much of a problem, and if you called the GC right before you loaded a bunch of new resources, for example, it definitely wouldn't be a problem.

>
> Also fonts have been bugging me.  Fonts can have the same file name, but different settings (italic, bold, underlined, pt. size, etc...)  so instead of having: FontList[char[]] I think I might have FontList[FontDescriptor[]].   This seems reasonable right?

It'd probably be FontList[FontDescriptor], but yeah that sounds fine.  As long as two instances of FontDescriptor compared equal with the same members, and as long as they hashed to the same value as well.

> So I think my resource manager will have both an AA and a descriptor for each type of resource.   Still working on how to make it somewhat generic. I would really like there to only be one type of handle, one type of createResource and one type of freeResource.  I am not sure this is feasible though.   At this point I am just blabbing...

Is there any reason why you'd need one kind of resource handle?  I mean, you can't use a texture in place of some other resource; wouldn't this be breaking type safety?


1 2
Next ›   Last »