I’ve been spending the past few weeks putting together a game project using XNA and ran into a brick wall in the functionality of the built in content manager. When I load in my game resources, internally they all get dumped into a single list. This causes me to have to dump all my resources from the content manager at one time. Normally, for small games this isn’t much of a problem, but start having games with multiple stages and VRAM gets filled awfully quick.
Doing some research, I came across a blog post by Shawn Hargreaves detailing how to extend the Content Manager and replace the default tracking implementation.
The content managers I’ve worked with in the past on Xbox360 and PS3 gave the ability to load resources in and track them in separate bins and I was looking for something similar for the XNA Framework. To this end I inherited a new class from ContentManager called BinContentManager.
class BinContentManager : ContentManager
{
// dictionary of contentBins
private Dictionary
// single bin active at one time
private ContentBin activeBin = null;
public BinContentManager(IServiceProvider services) : base(services)
{
}
public BinContentManager(IServiceProvider services, string rootDirectory)
: base(services, rootDirectory)
{
}
}
The BinContentManager class needs a few methods to make it usable:
// Add a new bin to the manager
public ContentBin AddBin(string name)
// remove an existing bin and free all internal resources
public void RemoveBin(string name)
// get a bin back to the caller
public ContentBin GetBinByName(string name)
// switch to another active bin for loading, using resources
public bool SwitchActiveBin(string name)
// overridden version of Load from the ContentManager
public override T Load
The main functionality of this class comes from the dictionary of ContentBin objects. Each time I load in a new resource, it gets loaded and dropped into the currently active ContentBin. By sectioning off resources into separate bins, I can load in menu UI resources into a separate list from my resources that I use in game. This allows me to dump the UI sepecifically when going into game and then dump game resources when going back to the main menu. As the game I’m creating has a lot of team specific resources, each time a new game is run, different resources will be necessary based on the user team selection. This extension to the content manager allows me the freedom to use and drop resources as I wish.
To make the system completely usable from a higher level, I did create another class on top of this called ResourceManager who has the job of abstracting away the content manager functionality from the main game code as it doesn’t really have to know how all this works. The ResourceManager also understands the concept of ResourceBundles, which are groups of resources compressed into a zip type format and can all be parsed and loaded in one go.
My next major step is to make the BinContentManager threaded to allow resources to be loaded on other threads, but at the moment this is working fine for me allowing me to get on with the game play I should be working on.
Leave a reply