Modifying handle properties
Setting properties from Scilab
From Scilab to sci_set/sci_get
In scilab, a handle property is generally accessed with the handle.property syntaxes. However, before evaluation, it is converted into get(handle,"property"). Similarly, the syntaxe handle.property = newValue is converted into set(handle,"property",newValue).
Consequentely all the handle properties modifications is a call to either the set or get function. In C code, these are the sci_set and sci_get functions located in the sci_set.c and sci_get.c files.
From sciSet/sciGet to the modification functions
The purpose of the sci_get function is to find the property to modify of the input handle and return it. To retrieve the property, the function uses a big hash table. This hastable contains the mapping between all the properties name and a function which retrieve it. The hash table definition can be found in the GetHashTable.h file and the mapping in the GetHashTable.c file. The mapped functions are all the get_xxx_property where xxx is the name of the property. The mapped function all have the same protoptype and do the same job. They have one argument which is the handle given to set. Their job is to put the value of the property on the stack if the handle has a valid type.
For example if the property is figure_id property the function called will be get_figure_id_property. The argument of the function will be the specified handle which must be of type Figure. The function just put the figure id on the stack and returns.
The process for setting properties is similar. There is also a big hash table located in SetHashTable.h. The difference is that the called function as more parameters in order to be able to access the new value for the property. Informations on the new value are its position in the stack, its type and its size. Functions of this kind are called set_xxx_property. As get functions they check that the specified handle has the right type but also that the new value as a compatible type. The int value returned by the function is also important. It specified wether the set was successful or not. Their are three values such a function can return: SET_PROPERTY_SUCCEED, SET_PROPERTY_ERROR and SET_PROPERTY_UNCHANGED. The signification of the first two is obvious. When SET_PROPERTY_UNCHANGED is returned it meens that it was not needed to modify the property. In this case, a redraw of the handle is not requested and some precious CPU time is gain.
Improvement proposal : as specified above, each property only applies to a certain set of handle types and as a certain type. For example, the arc_drawing_method property only exists for Arc and Subwin objects and is a String. For now the checks about the compatibility between handle type, the property and the assigned value are done within each set and get functions.
However it is possible to factorize this checks. This would avoid missing checks and would improve maintaince and ease addition of new properties.
Practically, it should be possible to add such information inside the propertyTable array found in the SetHashTable.c and GetHashtable.c files. Besides the set or get function, the hash table would then also give the kinds of handle requested and the kind of value requested (for set functions). The tests would then be automatically done before the function call.
Setting properties from C code
As seen in Handle representation in Scilab, handle properties are stored in structures. Although it is possible to access and modify directly the structure fields, it is not recommended. There are two sets of functions dedicated in modifying handles properties. These are the sciSetxx and sciGetxxx functions located n SetProperty.h and GetProperty.h.
Theorically, there is one function to set and one to get each property. for example the sciSetBackground and sciGetBackground properties should eb used to set or get the background of an objects (sciPointObj).
Using these function, it is not requested to perform a cast to get the specific structure or even now the kind of handle dealt with. For example to set the visibility of an object obj whatever is type, it's just needed to call sciSetVisibility(obj, TRUE). To get it, just call sciGetVisibility(obj).
The return type of getters are generally the requested value. For setters, it's the same as the sciSet function. It can be either SET_PROPERTY_SUCCEED (=0), SET_PROPERTY_ERROR (=-1) or SET_PROPERTY_UNCHANGED (=1). However, for now the actual returned values are directly -1, 0 or 1, but should be gradually replaces by the enum values.
The advantage of geeters and setters is that they hide the casts (sciXXXX_FEATURES casts) from developpers. Actually, the casts are done inside the functions. Most of the function only contains a large swicth on all the object types and then performs cast depending on the actual object kind.
In addition to sciSetxxx, the sciInitxxx functions can be found. Normally, only the sciSetxxx functions needs to be used. The sciInitxxx functions should only be used when creating an object and setting its property for the first time. These functions were intriduced because most of the set function, first check if it is really needed to modify the value and return SET_PROPERTY_UNCHANGED if not.
The SetHashTable.c and GetHashtable.c are two very large files which both contains a lot of getters and setters. However, some getters and setters are still lacking and should be added, to ban all the ugly casts from Scilab code.