Messages : 389
Date d'inscription : 2009-07-20
Localisation : A coté de Paris
|Subject: New feature: controller system Sun Oct 13, 2013 4:16 pm|| |
I just commited a major feature of SPARK: the controller system, that will enable you to automate your effects.
For those who know the signal & slot mechanism of Qt (or the one of boost), this system is very similar, in the sense that it is a signal/slot mechanism where signals are fired every frame (to be simplistic).
There also other parts of this system: automatic de/serialization, reflection, etc...Controllers
At the object level, a 'description' is added, which is a type that describe the object in which it is:
class MyObject : public Parent
spark_description( MyObject, Parent ) // Start the description by specifying the class and its parent in the hierarchy
spk_attribute(int, value, setValue, getValue); // An attribute, format is: type, name, setter, getter(s)
spk_attribute(Pair<float>, radius, setRadius, getRadiusMin, getRadiusMax); // Same as before, but here it is a pair, so we need two getters
spk_control(int, magic); // A control, the format is: type, name.
spk_control(float, phase); // Another control
Then, you can make connections between controls and attributes (1 control can be connected to any attribute of the same type, but an attribute can be connected to only one control). With a connection, the value of the control is propagated to its connected attributes each frame.
Ref<MyObject> obj1 = ...;
Ref<MyObject> obj2 = ...;
SPK::connect(obj1, "magic", obj2, "value"); // here, "magic" and "value" have the same type
SPK::connect(obj1, "magic", obj2, "radius"); // error: here "magic" is an int, but "radius" is a pair of floats
// If the connection fails, the return value of connect() is an error code indicating the error
With that, you can automate some changes in the effect. For example, you can make the position (or direction) of an emitter change over time, without having to do it manually. What's more, connections are serialized - so artists can make these connections.
There are 3 types of attributes:
- standard: created using 'spk_attribute', this attribute is always accessed as a whole, with a setter and one or more getter(s).
- array: created using 'spk_array', it is an array that is not accessed as a whole, but is handled as an unordered set. For example, the groups of a system are in an array. The type internally is 'std::vector<T>', where 'T' is a 'BaseType' (see the enumeration in SPK_Types.h). The individual values are not controlled, the control is on the number and the presence of values. Note that there are no differences between array attributes and standard attributes when it comes to de/serialization.
- structured: created using 'spk_structure', these are like arrays, but with custom types. Also, it is possible to control a specific field of a specific item:
spark_description( MyObject, Parent )
spk_structure(graph, createEntry, removeEntry, clearEntries, getNbEntries) // Format is: name, create_function, remove_function, remove_all_entries_function, get_number_of_entries_function
spk_field(float, x, setX, getX); // A field, format is: type, name, setter, getter. This field can be controlled specifically
spk_field(float, y, setY, getY); // Another field
Here, the structure 'graph' will be equivalent to:
Each field in each item in this 'graph' can be controlled independently, via a connection:
SPK::connect(obj1, "phase", obj2, "graph", 3, "x"); // 3 is the index of the item, and "x" is the field.
It is possible to retrieve a runtime version of the description of an object, via
Then you can:
- retrieve the name of the class
- retrieve the number of attributes, and the type / name of each one
- retrieve the number of controls, and the type / name of each one
- retrieve the number of fields per a specified attribute, and the type / name of each one
- retrieve whether the object inherits from a class specified by a name
- de/serialize the object
All this is possible also by using the compile-time version of the description.
Don't hesitate to ask question in comments, or browse the doxygen documentation for more information (and also, please see the Irrlicht_Controller demo) !