• Resource manager

    För ett tag sen, så läste jag en bloggpostning av en spelmakare som höll på och optimerade sitt spel, för att få snabbare laddningstider när han hade massor av texturer som dels behövde hanteras automatiskt, men också behövde användas av flera olika system i spelet.

    Det fick mig att tänka på resurshanterare i allmänhet, och på mina planer att byta ut den i min Pixie motor, till nånting mer robust, snabbare och mer generellt. Det slog mig också att det här är ett ämne som ganska ofta kommer upp, och jag tror att dom flesta utvecklare nån gång når en punkt där dom behöver lösa detta problem, eller något liknande. Så jag tänkte att jag kan lika gärna försöka mig på en lösning, och dela med mig av resultatet som public domain (som vanligt).

    Mina grundkrav på systemet är att det ska vara mycket enkelt att använda, men samtidigt väldigt effektivt, både när det gäller minneshantering och prestanda.

    I den lösning jag gjort, använder jag effektiva hash tabeller för att lagra resurserna, men jag wrappar upp dem i en lättanvänd resource class, som man kan använda så här enkelt:


    Kod:
    Resource<Texture> myTexture("myBitmap.tga");
    I det här exemplet, så är Texture den typ av object som vi vill att resurshanteraren ska hantera åt oss. Resource är en template-baseras wrapper klass, som vi använder för att få automatisk hantering av texturen. Men det behöver inte vara just en Texture man hanterar, det kan vara vilken som helst av dina egna klasser - enda kravet är att klassen i fråga har en konstruktor som tar ett filnamn som argument. Man behöver alltså inte ärva från nån speciell basklass eller nåt.

    Det är inga problem att ha många resurs-instanser som refererar samma fysisk resurs, så här:

    Kod:
    Resource<Texture> myTexture("myBitmap.tga");
    Resource<Texture> myOtherTexture("myBitmap.tga");
    Fast vi har två olika resurser, så eftersom dom skapas från samma filnamn, så innebär det att båda pekar på samma Texture instans. Den första av dessa rader, gör att Texture instansen skapas (minne allokeras, texturen laddas etc). Den andra raden lägger bara till en extra referens till samma Textureinstans (ingen allokering, inget laddande av textur).

    Resurser har automatisk reference count, så när en Resource tas bort, så minskar dess reference count, och när reference count når noll (vilket innebär att ingen Resource längre refererar instansen), så förstörs instansen (i detta fall texturen) automatiskt.

    En bra sak med den här implementationen, är att instanser av Resource tar väldigt lite minne - bara 4 bytes - då de bara lagrar en pekare till instansen som dom refererar till. Dom kan även kopieras och tilldelas fritt, och det ändrar bara reference count. Exempel:

    Kod:
    Resource<Texture> myTexture("myBitmap.tga"); // New instance created
    Resource<Texture> myTexture2("myBitmap2.tga"); // New instance created
    Resource<Texture> myTexture3(myTexture); // Ups ref count on "myBitmap.tga"
    myTexture2 = myTexture3; // Ups ref count on "myBitmap.tga" and also causes "myBitmap2.tga" instance to be destroyed
    Detta gör det möjligt att jobba väldigt fritt med Resources, man kan tilldela och kopiera till höger och vänster, trygg i vetskapen att allt hanteras väldigt effektivt bakom kulisserna, och att det stora mängden data (t.ex. pixlarna i texturen) delas mellan alla kopior.

    För övrigt så finns det med några hjälpfunktioner för att hämta filnamnet som en Resource skapades från, och att lista alla Resources av en viss typ - vilket kan vara praktiskt om man behöver loopa igeom alla för att göra nån operation, som t.ex. restorea surfaces i DirectX efter Alt+Tab.

    Koden är helt fri att använda - public domain. Den är helt fristående, och kompilerar utan externa beroenden, men den inkluderar flera datacontainers som jag ursprungligen utvecklade till Pixie, så det är ganska många filer i source packen, även fast själva resurshanteraren i sig bara består av fyra ganska små filer (men nyckeln till prestandan är i de effektiva containersarna - men för den som vill så kan de ju bytas ut mot t.ex. STL).

    http://mattiasgustavsson.com/Blog/Fi...ce_manager.zip

    Hoppas att koden kommer till användning för nån - om inte annat så som en startpunkt för ditt eget system
    This article was originally published in forum thread: Resource manager started by Mattias Gustavsson View original post