Content Manager

Started by
3 comments, last by frob 10 years, 1 month ago

Hi all,

A content manager is the place where all the engine use to get data.

Now the question is content manager should just be an array of path or load data ?

Another question is content manager should manage data from package or just store data ?

Thanks

Advertisement

Remember the Single Responsibility Principle (SRP). A class should have exactly one responsibility.

A very broad "content manager" typically severely violates SRP.

You will probably have several types of resource caches. You might have a mesh cache, a texture cache, a sound clip cache, gui image cache, and more. Assuming you don't want to pause the world while you want for data loads, perhaps you also get proxy objects. You might also have an asynchronous loader that streams in resources to the various caches and notifies them when the data transfer is complete. Then for graphics objects you will want some classes that coordinate with the rest of your rendering system to ensure the data is transferred to the video card and ready to use at the proper time.

You mentioned packaging your data, so you want to load data from a single package of compressed data. For that, consider PhysFS and similar systems. Their responsibility is to abstract away the file system so you can use any combination of compressed archives or basic disk directories that suits your development process.

In general, a content manager's primary responsibility is to prevent a resource from being loaded more than once if its unnecessary. If it receives a second request for a resource its already loaded, it just passes out a reference to the data it loaded the first time. Of coarse, this means that no one that shares a resource, or might, can modify it.

So parts if the game request a resource using some kind of unique ID -- that could be the path name of the file, a guid, some kind of hash, or maybe a byte offset in a Pak file. When its loaded the first time the content manager creates a record with that ID and a pointer to the loaded data. When another request comes in to load a file, it first checks those records to see if its already been loaded -- if it has, it hands out a reference to the data, otherwise it loads the file as usual, creates a record for that file, and passes out that data.

At some point, you need to be able to unload resources that are no longer in use. To know what's in use, you maintain a counter that says how many users are sharing the resource, and they can say they're done in some way so that you can decrement the counter. One way to unload the resources is to periodically sweep for resources whose counts are zero. Another way is to perform the check each time the counter is decremented and delete the resource (and its record) immediately when it reaches zero. Std::shared_ptr in c++ does all of this for you, except removing the record, but you can also supply your own deleted to shared_ptr that can remove the record and then finish deleting itself.

If you really want to get fancy, instead of deleting the data, you can remove it from the "hot" resource list and place it in a "cold" list. The idea of a cold list is to keep inactive resources in memory while its not a problem, but if you ever run out of memory you can dump everything in the cold list immediately.

throw table_exception("(? ???)? ? ???");

I saw PhysFS yesterday, it's funny you mentioned it, it looked to be a good lib.

About reference counter I have already a class RefCount who has release like that :


UInt32 Release()
{
  // Update the reference counter.
  const UInt32 NewRefCount = --m_RefCount;

  // Check if the counter is now 0.
  if( NewRefCount == 0 )
    delete this;

  // Return the new reference counter.
  return NewRefCount;
}

You mentioned a lot a notify, that mean resource need to register listener to content manager ?

I would have threading one day but it's a big part for me since I don't have experience on it, so I keep it outside for moment.

It's not clear about the fact that the content manager should load data in the same class or not, can you say more about that ?

But since threading will update the data of a resource inside content manager, I think you mean it should store data.

Okay, let's try a different direction.

What are the responsibilities of your 'content manager'?

* Coordinate with file system or archive file systems
* Load resources (asynchronously?)
* Cache resources to prevent duplication
* Parse data into useable textures
* Parse data into useable meshes
* Parse data into useable audio clips
* Parse data into useable animation clips
* Manage memory to keep memory pools small
* Coordinate data exchanges with rendering system
* Coordinate data exchanges with animation system
* Coordinate data exchanges with GUI
* Coordinate data exchanges with audio

Are there more tasks you need it to do?

Make a nice long list, breaking the tasks down into their smallest pieces of responsibility.

Then when you have your massive list, look it over. Each one of those little responsibilities should probably be its own class.

This topic is closed to new replies.

Advertisement