Managing custom properties in script



Script can be used to achieve all the custom property manipulation of the Scene settings dialog, and more. Here are the main (global) script functions related to property creation and modifying.
    bool addCustomProperty(string class, string name, string displayName, string type);
    bool removeCustomProperty(string class, string type);
    bool setCustomPropertyNames(string class, string oldName, string newName, string newDisplayName);
You can investigate the existence of custom properties in individual items with these functions ('item' will actually be one of: world, body, fixture, joint, image):
    string[] item::getCustomProperties();
    string   item::getCustomPropertyType(string name);
    bool     item::hasCustomProperty(string name);
You can set/get/clear the property values of individual items with these functions ('item' will actually be one of: world, body, fixture, joint, image):
    void item::setCustomInt(string name, int val);
    void item::clearCustomProperty(string name);
    int  item::getCustomInt(string name);
(Note that only the int version of these is shown here. You can replace the 'Int' in the function names above with 'Float', 'String', 'Vec2', or 'Bool' for the other property types.)


Properties as direct class members
When a custom property is added, it is registered in the script engine as a direct property of the class it belongs to, so you can use a more straightforward method to access it. For example if the world class has been given a property of type float called 'myfloat', you could access it like this:
    world w;
    w.myfloat = 12.34;
This is usually easier than using the set/get functions above, but there are two things to be aware of when using this notation.

The first is that this property is not really a genuine member of the class, and when the script is parsed, this 'member' gets automatically translated to an underlying function which will actually be executed. In this case the function would be called 'set_myfloat'. If we were only reading the value, the function would be 'get_myfloat'.

The point is, this notation only allows us to either get or set, but not both. So we cannot write code which attempts to get and set in the same statement, like these (they will run without errors but the result will not be as expected):
    w.myfloat++;
    w.myfloat -= 2;
The other thing to be aware of is that you cannot add a property and use it in the same script run, because the property must first exist in order for the script to compile. Suppose we have this script which adds a property to the world class and then sets a value in it:
    addCustomProperty("world", "float", "myfloat", "My float");
    world w;
    w.myfloat = 12.34;
This will fail to compile with the message "'myfloat' is not a member of 'world'" because the property will not be added until the script has executed. If you need to both add and use properties in a single script execution, you can use the longer form functions as above. For this example, you could do:
    addCustomProperty("world", "float", "myfloat", "My float");
    world w;
    w.setCustomFloat("myfloat", 12.34);