1
\$\begingroup\$

I am trying to write an engine for a game, in particular a component-based one (in my approach components contain both data and logic). So basically I have entities, and each entity has a list of components (each component extends the Component class). Now, I want to be able to define templates for my entities in xml files, and load them at runtime. The template would look something like this:

<Entity>
   <Component name="MovementComponent">
      <...Variables to be initialized...>
   </Component>
   <Component name="RenderComponent">
      <...Animations...>
   </Component>
</Entity>

The "name" attribute is the name of the corresponding component class. Now, of course the components are game-specific so I need a way to create an instance of the component and add it to the entity's list without actually knowing the specific class. I thought about Class.forName("...the "name" attribute...").newInstance(), but this way I can't add the components to the list, since it is an ArrayList of Component and the program cannot know that the object returned by the method newInstance is actually a subclass of Component. Is there any simple way to do this?

\$\endgroup\$
1
\$\begingroup\$

Generally I would advise the use of reflection and serialization to load component data like this. This allows you to find a class by name at runtime and to also enumerate all the fields of the class, mapping them to XML. Most existin serialization libraries use reflection already or you can roll your own if you have a very particular format in mind.

See the Java reflection docs and something like JAXB or XStream for serialization.

The simple approach you mention using Class.forName("...the 'name' attribute...").newInstance() is flawed, but more complete reflection usage fixes this. You can look up the class and ensure it derives from Component before you instantiate it and then just cast it afterwards since you know the cast will always work. You could require some specific set of annotations if you think it'll in some way help, too.

\$\endgroup\$
0
\$\begingroup\$

You're not likely to have too many components in your game. I suggest you set up something simple like a switch statement:

switch(componentName) {
     case "Movement":
        entity.AddComponent(new MovementComponent.ParseXML(componentXML));
        break;
     case "Render":
        entity.AddComponent(new RenderComponent.ParseXML(componentXML));
        break;
     ...

}

Each component has a function called ParseFile that reads all the XML contained within the <Component> element. This way, each component knows how to parse itself from the XML file, and parsing code is kept with the components. I set up something similar for a game of mine and it works great. I've also posted some details about it here: How smartly implement scripting in game and here Storing items in external data files

\$\endgroup\$
  • \$\begingroup\$ Thank you for your reply and the nice examples. Using a switch statement would probably be the simplest way, however my current objective is mainly to develop the engine itself and to make it as generic as possible. Searching a bit on google I found the XStream library, which seems pretty good for instantiating unknown objects. I didn't consider the idea of using an existing library, but maybe it is a good idea, you know, the "not reinventing the wheel" thing hehe! \$\endgroup\$ – Bricco Dec 15 '13 at 17:10
  • \$\begingroup\$ Honestly it'll be hard to be more generic. Unless you're allowing users to create their own components (it seems like you just want them to create their own entities), this strategy will save you a significant amount of trouble. \$\endgroup\$ – MichaelHouse Dec 15 '13 at 17:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.