Filtering the “find” functions in Halion Scripting

Filtering the “find” functions in Halion Scripting

Halion scripting has very efficient find functions such as findZones() and findLayers(), that will quickly return an array containing the desired results. There is however a way of refining the search, by means of a filter function, to give a more targeted outcome. This can make the resulting array easier to work with, avoid excessive memory usage and increase performance in the case of large programs.

findZones(recursive, nameOrFilterFunction)

The Steinberg Halion online reference says this about the function:

Function to find zones in the specified layer. For example, this.parent defines the parent layer of the script module as the layer to be searched in. If recursive is set to true, sublayers will also be searched. The function returns an array with the Zone objects of the found zones. Particular zones can be searched by name or through a filter function. If searching by name, findZones accepts only the Zone objects that match the specified name. The filter function uses the Zone object of each zone as argument. Only those Zone objects that return true for the search criteria defined in the filter function will be accepted by findZones. Without a name or filter function the Zone objects of all zones in the searched layers will be returned.Steinberg Halion Reference

In its simplest form the function will be implemented as: zones = this.parent:findZones()
In case you want to search sub layers too: zones = this.parent:findZones(true)

The Filter Function

What wasn’t apparent to me when starting with Halion scripting, was that the filter function needs to be an anonymous inline functionwhich can then accept the zone object as its argument. It’s easy to lose track of your bracketing, so prepare your layout before you start writing the function. The bracket after “end” in line 6 for example, closes the bracket after “findZones” in line 1. For the findZones() function to recognise your filter function, it needs to be the 2nd argument so the recursive boolean must always be included.

(In an empty program, randomly add a few synth and sample zones, and one Lua script module (the sample zones can be empty). These will help with the example code below. Copy and past the code as needed.)

The disadvantage of including your entire filter function in the findZones() function, is that the code can’t be reused. The solution is to use the anonymous function to call an external, named function (similar to when declaring the change function after creating parameter). This will make the filter conditions available for all findZones() functions in your script.

As can be seen in the findByType() declared function, there is a zone and zone_Type argument. The filter function can now be reused and search for whatever zone type you want by adding the type index as a second argument when calling the filter from the find function (line 8). The thing to remember here is that you need the return function in both the filter and the find function, otherwise the boolean condition won’t reach the findZones() function to prompt the adding of zone objects to the array.

Alternatively, you can use a named callback function, but then only the object can be passed as an argument to the filter function.

Filter functions can be as complex as you want, especially with the addition of Lua’s string, math and table libraries. The ~= operator can also be used instead of == for exclusion, if you want to remove one zone type from the results and include all others. These same principles obviously count for all other find functions, and any parameter can be a criterion.

I’ve become more proficient with Halion Scripting over the past year. Although I’m by no means an expert, I’ve come to learn a few things about the language’s capabilities and Halion’s idiosyncrasies, so I’ll likely write a few more of these.

That’s all for now though.

Leave a Reply