Configuration
Almost every aspect of SpeckSim is controlled by the Configuration system. At it's heart, the Configuration system simply provides a way to describe and alter the important variables of an object or system. The chief benefit of this is that a GUI can be generated from the code. This makes it much faster to add new features to SpeckSim.
Using the configurator system also makes it extremely easy to save and load the state of SpeckSim to and from a file.
Writing a Configurator
There are two routes to getting a Configurator:
- Manually building one by implementing the Configurator interface. This method allows the configurator to be dynamically built at run-time, but leads to some amount of tedious boiler-plate code.
- Using annotations to mark fields and methods that should be manipulated by the configurator. This methods avoids the boiler-plate code and duplication of object interface, at the expense of the dynamism as all variables must be defined at compile-time.
Manual Configurator
Looking at the can be a bit daunting, happily all of the non-specific functionality is already implemented for you in . All you need to concentrate on is:
- Defining the variables by giving them a name, and associating the name with a type flag, and optionally a description and range object
- Providing access to the values of the variables
- Enabling changes to the values of variables
Annotated Configuration
The alternative to manually building a Configurator is to have one built automatically by adding annotations to the configurable variables. The available annotations are:
- This must be applied to the class declaration, and specifies the name of the configurator
- This specifies the name of a Configurable variable, and can be applied to fields or methods. When applied to fields, the generated Configurator object will apply changes to the field via reflection. If applied to methods, it must be applied to exactly two methods and annotated with the same name value, one to set the value, and one to get the value. These methods must have the typical setter and getter signatures (i.e.: A setter has void return type and one argument of type x, a getter has no arguments and return type of x). The exception to these rule is that of the Action configurable type, where the annotated method must have no arguments and void return type.
- Specifies a legal range of values for integer, float, or vector variables
- Specifies a legal range of values in String and String list variables, and legal file suffixes in File variables.
- Applied to fields that are themselves Configurable, and should thus be accessible from this configurator
- Specifies the order in which the variables should appear in the resulting configurator. If this is not used, variables will appear in the order they are encountered in the configurable class
Using the annotations eliminates the tedious boilerplate code used in manual Configurators to get and set values, but at the cost of the configurator being fixed at compile time. Note that annotated fields and methods must be public in order to appear in the configurator.
You should have seen several examples of Configurators of both types by now, but in case you missed them, have a look at the ones contained by the examples in the Extending section.
Note that the Configuration system is very dynamic, you can add and remove variables, set range objects, even set the type of a variable at any time, and the GUI will keep up with the changes.
Default variable types
The configurator system can handle the following variable types by default:
- Boolean
- Integer - Range objects should be a two-element float array specifying the min and max values. Both, either, or none of the min and max may be Float.NaN to signify no bound.
- Float- Range objects are as in integer variables.
- String - Range objects should be a String array of possible values.
- Vector - Range objects should be a float array specifying the min and max values in { xmin, ymin, zmin, xmax, ymax, zmax } order.
- Colour - in rgba format
- File - Range objects are String arrays specifying acceptable file suffixes
- String list - Range objects should be an array of possible entries
- Action - Has no value, but is instead used to call a method in the configurable object
Adding new variable types
As it stands, there's nothing restricting you from setting any Class you like as the variable type, but you won't be able to take advantage of the GUI generation or serialisation capabilities.
To remedy this you must supply implementations of and .
ConfiguratorCodec simply translates between value objects and Strings, and is extremely easy to implement. You can add new codecs to SpeckSim by specifying the classname on the command line, or with the static call ConfigurationSerialiser.registerCodec( classname );
The Widget superclass is a bit more involved, and not entirely bulletproof. Once again, the best way to learn is probably to see how I've done it. are the widget classes for the default variable types.