PDG Common: Configuration Class

This is one of those things that I wind up making for whatever game I happen to be working on, and when I’m smart, I make it once, put it into another assembly/package/other reusable unit, and make use of it evermore in whatever language/platform/ide I happen to be using.

It is a configuration class.

package com.pdg.common.managers;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.util.ResourceLoader;
import org.newdawn.slick.util.xml.XMLElement;
import org.newdawn.slick.util.xml.XMLElementList;
import org.newdawn.slick.util.xml.XMLParser;

import com.pdg.common.managers.names.TagNames;

public class Configuration {
	private Map managers = new HashMap();
	public Configuration(String ref) throws ConfigurationLoadException{
		if(!loadFromXml(ref)){
			throw new ConfigurationLoadException();
		}
	}
	@SuppressWarnings("unchecked")
	public  T get(String theName){
		try{
			return (T)managers.get(theName);//pesky unchecked warning... fix it one day
		} catch(ClassCastException e){
			return null;
		}
	}
	private boolean loadFromXml(String ref) {
		XMLParser parser = new XMLParser();
		try {
			InputStream stream = ResourceLoader.getResourceAsStream(ref);
			XMLElement root = parser.parse(ref,stream);
			XMLElementList children = root.getChildren();
			for(int index=0;index<children.size();++index){
				XMLElement child = children.get(index);
				String theType = child.getAttribute(TagNames.TYPE);
				LoadableFromXMLElement manager = (LoadableFromXMLElement)Class.forName(theType).newInstance();
				manager.loadFromXMLElement(child);
				managers.put(child.getName(), manager);
			}
			return true;
		} catch (SlickException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return false;
	}
}

And this works for however many managers I have to load.

For CTYR, I have the following managers:

<configuration>
	<image-manager type="com.pdg.common.managers.ImageManager">cfg/images.xml</image-manager>
	<sound-manager type="com.pdg.common.managers.SoundManager">cfg/sounds.xml</sound-manager>
	<widget-manager type="com.pdg.common.managers.WidgetManager">cfg/widgets.xml</widget-manager>
	<constant-manager type="com.pdg.common.managers.ConstantManager">cfg/constants.xml</constant-manager>
</configuration>

The “type” attribute conveniently tells me what class I need to load, and the contents of the tag tells me the file name.

I like to have different files for this, because things like images and sounds become rather large (as do constants), and so it gets quite hairy to have to manage the same file for everything.

When using an instance of Configuration, the line typically looks something like:

getConfiguration()<ConstantManager>get(ManagerNames.CONSTANT).<Integer>get(ConstantNames.DISPLAY_WIDTH);

Which gets rather lengthy, but this sort of flexibility comes at that cost.

I also wind up with a number of XXXXNames classes, for example ManagerNames and ConstantNames. These will have a number of string constants (or, in the case of Java, a bunch of public static final String lines). This is to centralize the use of magic strings.

Advertisements

Tags: , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: