Evolution of string parameters

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:

  1. string comparisons are slow – much slower than comparing integers
  2. 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.
StringEvolution_values2
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]