Most effective way of loading resources?

Started by
9 comments, last by ldeej 18 years, 10 months ago
Hello, I'm writing a game engine (heh who isn't?), and I'm thinking of rewriting my resource loading part. Currently, it's based on a set of Codec classes, which have a central function:
Resource *loadResource( std::string filename );
Where Resource is a memory-managed deriveable object that holds resource-specific data. My question is, is there a more effective way of loading resources? Right now loadResource() just creates a new Resource and returns it, relying on the memory management system to get rid of it once the engine's done with it. If you ask me this is slightly on the primitive side, but I can't think of any more advanced way to do it (effectively). Thanks in advance!
- fyhuang [ site ]
Advertisement
The most efficient way to load stuff (except for configuration files) is to save the the whole structure to the disk and load it when needed. However, this might backfire if:
1. A different compiler [version] is used.
2. Different compilation flags are used.
3. Different platform.
In practice though, there aren't many problems and a lot of people, includign me, use that.

The most elegant/platform independent way to do it is make a header with fixed lenghts for the header info, then put the data after the header. Something like, say, the BMP file format.
I was talking more about architectural stuff (like, different functions that return different things? pointer to Resource as an argument? that sorta stuff), but sure. I used to do that, but since my engine's supposed to compile under different platforms I think using that approach might not work. Also, Codecs handle not only engine-specific resources but also PNGs and sound files and stuff.

Cheers!
- fyhuang [ site ]
Quote:Original post by Raduprv
The most elegant/platform independent way to do it is make a header with fixed lenghts for the header info, then put the data after the header. Something like, say, the BMP file format.

To elaborate on this a little, you can use the popular IFF (Interchange File Format if memory serves me right) to represent your binary data. The format itself is very simple:
all data is divided into chunks, which consist of a chunk header followed by the actual data. Chunks can have sub-chunks, too so it's perfectly possible to represent hierachical data as well.

The chunk headers are typically 64 bits in size and use a four-character-code as identifier and an unsigned 32 bit integer that holds the size of the chunk (e.g. length of data to be read until next chunk header):
+--------+ --| FOURCC |    |+--------+     Chunk header| length |    /+--------+ --| data   ||        | --- length bytes of chunk data+--------+

Examples for IFF files are .WAV, .AVI and .3DS files.

HTH,
Pat

EDIT: Fixed the ASCII illustration [smile]
Yes, that's what I meant. I didn't know the proper name.

@fyhuang: It doesn't really matter what the function returns and stuff like that, as this is vastly insignificant compared to the time spent by the function that actually loads (and possibly process) your resources.
Quote:Original post by fyhuang
I was talking more about architectural stuff (like, different functions that return different things? pointer to Resource as an argument? that sorta stuff), but sure. I used to do that, but since my engine's supposed to compile under different platforms I think using that approach might not work. Also, Codecs handle not only engine-specific resources but also PNGs and sound files and stuff.

Cheers!

There's nothing wrong with a general resource interface. You could use smart pointers to take care of memory management. The only difficulty would be casting to the specialised interfaces. Codecs and filters are one way to cope with different resources. Another possibility is the transparent use of different resource loaders that are triggered by a resource type:
Resource * loadResource( std::string const & name, TypeId const & type );

This would allow the resource system to select a loader according to the requested type and let the loader take care of filtering and decoding the input.
I'd even separate resource access from actual resource loading as this might be two different processes. While accessing a resource might simply cause loading a byte stream from a media, loading it may trigger a specific sub-system (e.g. sound initialisation or texture uploading).

HTH,
Pat.


BTW, are you interested in the most effective or elegant way?
Well, now that I think about it, elegant. The performance and stuff doesn't matter quite as much (it still matters!) as long as the code you use to access the resource-loading API isn't a bunch of crap.

I like that IFF thing too...

Thanks!
- fyhuang [ site ]
Oh, then it's a whole different matter.
In my programs, resource loading stuff return either a pointer or, sometimes, depending on the case, an ID into a list (array) of that kind of objects.
Okay, thanks!
- fyhuang [ site ]

This topic is closed to new replies.

Advertisement