A library part usually has lots of string parameters, so it’s time to take a look at the coding possibilities, and to get a historical overview of programming techniques of string handling.
This post starts with the oldest method and closes with the most up-to-date technology.
Using string parameters only
The most simple solution with 2 significant problems at least:
- string comparisons are slow – much slower than comparing integers
- it is quite difficult to change/localize the possible values list without migration
A simple example with an imagined situation – a table with a leg type parameter, called stLegType
:
! Parameter script values "stLegType" `Rectangular`, `Cylindrical`
! 3D script if stLegType = `Rectangular` then add2 -0.02, -0.02 block 0.04, 0.04, 0.66 del 1 else ! Cylinder cylind 0.66, 0.02 endif
! UI script ui_infield "stLegType" x, y, infieldWidth, infieldHeight
The example contains 2 types of quotation marks: "
and `
. We use these to mark the strings in the scripts: there are `translatable`
and "non-translatable"
strings in GRAPHISOFT’s library parts, our localization tools are built on this difference.
String-integer pairs
The first improvement was adding a new integer parameter, and using it in most of the script types. This gives faster comparisons, and the string value list can be changed without the need of migration (if the string and integer parameters are properly linked in parameter script).
On the “dark side” there is the bigger number of parameters, the need to link the string and integer parameters in paramscript and reduced readability of scripts.
The simple example now has two parameters, the previous string parameter stLegType
and its integer pair iLegType
.
In the parameter script, the 2 params need to be linked correctly:
! Parameter script values "stLegType" `Rectangular`, `Cylindrical` values "iLegType" 1, 2 if GLOB_MODPAR_NAME = "stLegType" then iLegType = 1 if stLegType = `Cylindrical` then iLegType = 2 parameters iLegType = iLegType else stLegType = `Rectangular` if iLegType = 2 then stLegType = `Cylindrical` parameters stLegType = stLegType endif
These lines make sure the 2 parameters will always change their values in a synchronized way, and the string values can be modified at any time: its value will be set by the integer at the moment you open the settings dialog.
! 3D script if iLegType = 1 then ! Rectangular add2 -0.02, -0.02 block 0.04, 0.04, 0.66 del 1 else ! Cylinder cylind 0.66, 0.02 endif
In the 3D script we use the faster integer comparison, but without the comments it can be difficult to read the script: it doesn’t tell you much about the actual meaning behind iLegType = 1
.
! UI script ui_infield{3} "iLegType", 50, 100, 100, 20, 8, "", ! method, picname 0, 0, ! images_number, rows_number, 0, 0, ! cell_x, cell_y, 0, 0, ! image_x, image_y, "", `Rectangular`, 1, !expression_image1, text1, value_definition1 "", `Cylindrical`, 2 !expression_image2, text2, value_definition2
With the integer parameter we use improved interface items, such as a pop-up list in this example.
Adding “constants” for a better overview
To improve the scripts’ readability, we use so called “constants” in our scripts, and put the strings to arrays.
This solution provides more readable and stable code, and it is much faster to modify the strings or integer values – if the number of possible values doesn’t change you just need to modify the master script.
The modified examples will look like the following:
! Master script LEG_RECT = 1 LEG_CYLIND = 2 if GLOB_SCRIPT_TYPE <> 2 and GLOB_SCRIPT_TYPE <> 3 then dim stLegTypeValues[2] stLegTypeValues[1] = `Rectangular` stLegTypeValues[2] = `Cylindrical` endif
! Parameter script values "stLegType" stLegTypeValues values "iLegType" LEG_RECT, LEG_CYLIND if GLOB_MODPAR_NAME = "stLegType" then iLegType = LEG_RECT if stLegType = stLegTypeValues[LEG_CYLIND] then iLegType = LEG_CYLIND parameters iLegType = iLegType else stLegType = stLegTypeValues[max(1, min(iLegType, vardim1(stLegTypeValues)] parameters stLegType = stLegType endif
! 3D script if iLegType = LEG_RECT then add2 -0.02, -0.02 block 0.04, 0.04, 0.66 del 1 else ! Cylinder cylind 0.66, 0.02 endif
! UI script ui_infield{3} "iLegType", 50, 100, 100, 20, 8, "", 0, 0 0, 0, 0, 0, "", stLegTypeValues[LEG_RECT], LEG_RECT, "", stLegTypeValues[LEG_CYLIND], LEG_CYLIND
Using integers with VALUES{2}
As we created more and more complicated library parts it was a continuously growing overhead to add an integer pair to all string parameters and create the GLOB_MODPAR_NAME linking for them.
We needed a more simple technology, to solve the problems:
- we want to use integers in the scripts where they are working as integers
- we want these parameters to be presented as text parameters for the user
As a solution to both problems, the new VALUES{2} command was introduced in ARCHICAD 18.
All the updated scripts are similar to the ones with constants, except the parameter script, which gets much shorter:
! Parameter script values{2} "iLegType" LEG_RECT, stLegTypeValues[LEG_RECT], LEG_CYLIND, stLegTypeValues[LEG_CYLIND]