Monday, April 1, 2013

Stupid Reflection Tricks

The game that I'm currently working on (based on parts of Box2D, Artemis, libGDX and a dash of RUBE for level design) employs reflection.  I've got custom properties defined for various bodies, fixtures, and joints in RUBE.  Some of these custom properties are strings that are interpreted as classes for instantiation at run-time via Java reflection.  For example, I have eggs in the game that have a custom property "PreSolverScript".  This field is defined with EggImpact.  EggImpact is a Java class that defines what happens when the related fixture is detected for the Box2D presolver.  This class checks the velocity of the egg object just before impact.  If the velocity is great enough, the egg receives damage and potentially breaks.

The script references are resolved at run-time through the use of Java reflection.  Doing reflection with simple Java constructors is fairly simple.  It gets somewhat tricky when you have to worry about parameters.  Here's an example of my code that does reflection with parameterized script strings.  If parameters for a script exist, they appear as comma-separated values following the script name.

In the example below, preSolverProperty is a string containing the custom property for the string.

            String [] parms = preSolverProperty.split(",");
            IPreSolverScript preSolverScript;
            if (parms.length > 1)
               preSolverScript = (IPreSolverScript)Class.forName(ScriptConstants.SCRIPT_PACKAGE_NAME + parms[0]).getConstructor(String[].class).newInstance((Object)parms);
               preSolverScript = (IPreSolverScript)Class.forName(ScriptConstants.SCRIPT_PACKAGE_NAME + preSolverProperty).newInstance();

The sticking part for me was casting parms to (Object).  Without this I got a invalid number of parameters error at run-time.