Iterating on words in a string list
While creating a game there are times that we need to step through a string list, one item at a time, and do some work on that item. An example could be a collection of object IDs produced by a volumetric search of the scene. We then want to do something with these found objects, such as possibly applying damage. In this recipe, we will learn a quick way to retrieve each item in a string list and do something with that item.
Getting ready
We will be adding some new TorqueScript functions to a project based on the Torque 3D Full
template and try it out using the Empty Terrain
level. If you haven't already, use the Torque Project Manager (Project Manager.exe
) to create a new project from the Full
template. It will be found under the My Projects
directory. Then start up your favorite script editor, such as Torsion, and let's get going!
How to do it...
We are going to write a TorqueScript function that will retrieve each item from a string list and do some work on it as follows:
Open the
game/scripts/server/game.cs
script file and add the following code to the bottom:function parseStringList1() { // Populate a variable with some sample object ID's. //This could have come from an axis aligned bounding box //search in the scene. %objects = "1121 1122 1438 1643 2025 1118 1564"; // Step through each object in the string list. // This string list could contain any valid // string characters and doesn't need to be // limited to object ID's. echo("-- Starting string list iteration"); foreach$ (%id in %objects) { // Perform some action on the object doSomething(%id); } echo("-- Finished string list iteration"); } function doSomething(%objID) { // Print out the object ID to the console. echo("Processing object ID: " @ %objID); }
Start up our game under the
My Projects
directory and load theEmpty Terrain
level. Open the console using the tilde (~) key and enter the following at the bottom of the screen:parseStringList1();
In the console we will see the following output:
==>parseStringList1(); -- Starting string list iteration Processing object ID: 1121 Processing object ID: 1122 Processing object ID: 1438 Processing object ID: 1643 Processing object ID: 2025 Processing object ID: 1118 Processing object ID: 1564 -- Finished string list iteration
How it works...
The previous code uses the foreach$()
function to retrieve each item in the string list and does some work on it. In this example, the item is passed on to another function.
The
foreach$()
function is different than most of the looping TorqueScript functions (such as for()
) in that it takes two parameters that are separated by the in
word rather than a semicolon. It is also unusual in that it creates a
new variable to hold a string of the item. The foreach$()
function has the following form:
foreach$( item in stringList) { ... Do something with item ... }
Here, the stringList
parameter is the list of items to be processed, and the item
parameter is a new variable that is created to hold a string of the item. It is the item
variable that we work on. In our previous example this is the %id
variable.
There's more...
There is another way to step through the items in a string by using the
getWordCount()
and getWord()
functions. For example, put the following function at the end of the game/scripts/server/game.cs
script file after the code we entered in the foreach$()
example:
function parseStringList2() { // Populate a variable with some sample object ID's. %objects = "1121 1122 1438 1643 2025 1118 1564"; // Get the number of items in the string list %count = getWordCount(%objects); // Step through each object in the string list. // This string list could contain any valid string // characters and doesn't need to be limited to // object ID's. echo("-- Starting string list processing"); for (%i=0; %i<%count; %i++) { // Get the object ID from the string list %id = getWord(%objects, %i); // Perform some action on the object doSomething(%id); } echo("-- Finished string list processing"); }
Start up our game under the My Projects
directory and load the Empty Terrain
level. Open the console using the tilde (~) key and enter the
following at the bottom of the screen:
parseStringList2();
In the console we will see the following output:
==>parseStringList2(); -- Starting string list processing Processing object ID: 1121 Processing object ID: 1122 Processing object ID: 1438 Processing object ID: 1643 Processing object ID: 2025 Processing object ID: 1118 Processing object ID: 1564 -- Finished string list processing
The results end up being the same as when we used the
foreach$()
function. So why would we use this method over the
foreach$()
method? Well, for one thing, we will see this pattern in a number of stock Torque 3D scripts that were written prior to foreach$()
being added to the TorqueScript language. We will also see this pattern in a lot of game developers' script code, just because they are not aware of the newer foreach$()
function (now you are one of the special ones that do know!).
One advantage of foreach$()
over using the getWordCount()
and getWord()
patterns to step through a list‑‑other than a lot less script code‑‑is that you don't have to perform two calls into the engine (getWordCount()
and getWord()
); every call we don't have to make back to the engine is a performance increase.
But then why would we actively use this alternative pattern at all? It is the only way to work with the other types of delimiters, such as tab and a new line. By replacing getWordCount()
and getWord()
with getFieldCount()
and getField()
respectively, not spaces but only tabs and new
lines are treated as delimiters, and by replacing them with getRecordCount()
and getRecord()
, neither spaces nor tabs, but only new lines are treated as delimiters. This allows us to work with different types of data.
See also
Accessing delimited fields within a string