"); would return "tag" just some examples on how to disect strings :) use these in my Torque DB to"> Here are a three string utility functions | Torque Game Builder | Forums | Community | GarageGames.com

Game Development Community

Here are a three string utility functions

by Matthew Langley · in Torque Game Builder · 04/22/2005 (5:01 pm) · 15 replies

ReturnStringBefore("string-test", "-");

would return "string"

returnStringAfter("string-test", "-");

would return "test"

getTagName("");

would return "tag"

just some examples on how to disect strings :) use these in my Torque DB to parse and ran accross another need for them so figured I'd post them as reference

function returnStringAfter(%string, %char)
{
	%endChar = strLen(%string);

	for(%i=0;%i<%endChar;%i++)
	{
		%charToCheck = getSubStr(%string, %i, 1);

		if(%charToCheck $= %char)
		{
			%startChar = %i + 1;
		}
	}	

	
	%totalChar = %endChar - %startChar;
	%stringToReturn = getSubStr(%string, %startChar, %totalChar); 

	return %stringToReturn;
}

function returnStringBefore(%string, %char)
{
	%endChar = strLen(%string);

	for(%i=0;%i<%endChar;%i++)
	{
		%charToCheck = getSubStr(%string, %i, 1);
		if(%charToCheck $= %char)
		{
			%startChar = %i;
		}

	}	

	%totalChar = %startChar;
	%stringToReturn = getSubStr(%string, 0, %totalChar); 
	
	return %stringToReturn;
}

function getTagName(%string)
{
	%endChar = strLen(%string);
	%firstChar = getSubStr(%string, 0, 1);
	if(%firstChar $= "<")
	{
		%totalChar = %endChar - 2;
	} else
	{
		%totalChar = %endChar - 1;
	}
	%stringToReturn = getSubStr(%string, 1, %totalChar); 
	
	return %stringToReturn;
}

About the author

Was a GG Associate and then joined GG in 2005. Lead tool dev for T2D and T3D. In 2011 joined mobile company ngmoco/DeNA and spent about 4 years working game and server tech. 2014 joined startup Merigo Games developing server technology.


#1
04/23/2005 (3:55 pm)
IIRC, the 'getTagName is implemented in TAP as "detag", and there is also a "getTag". Not sure if you are using "Tag" as the same definition TAP does however!
#2
04/23/2005 (4:02 pm)
Someday I want to implement the PHP string functons into TAP. PHP has some of the best string hsandling i've ever seen.

Things like explode are so convenient.
#3
04/23/2005 (4:22 pm)
Thx for the heads up Stephen... I think your right... though it might be much more complex than mine, might handle the MLText tags... I need to look that up...

I agree John
explode is great... my favorite is

Quote:
$bad_chars= array("\\", "'", "\"");
$good_chars = array("\\\\", "''", "\"\"");
return str_replace($bad_chars, $good_chars, $strTemp);

amazingly easy to replace things in a whole document quick
#4
04/23/2005 (4:27 pm)
TCL has some very nifty techniques for handling generic formats that have consistent separators as well. There is a data format in healthcare IT called "HL7", which utilizes a "relative-positional index" concept, where a particular data field is valued based on it's position within a particular block of similar data, and fields are separated by a consistent "field separator" character. For example:

%PlayerAcccountInfo = "PAI|Active|||Stephen Zepp|3333-4444-5555-6666|";

The "PAI" means that this would be the "Player Account Info" data set, and the sender and receiver agree on a consistent positional index for various fields: the first field in this example would be the account status, the fourth "field" in this example is "Player Name", the 5th is "Credit Card Number".

What's neat is that TCL allows you to split a string into a list, and then you have an entire set of functions that can be performed on lists, including search, indexing, replacement, etc.

(psuedo code follows, using TAPScript instead of TCL syntax):
%PlayerAccountInfoFields = listSplit(%PlayerAccountInfo, "|");

%PlayerName = listIndex(%playerAccountInfoFields, 4);
%playerCCNumber = listIndex(%playerAccountInfoFields, 5);

%playerAccountStatus = "Disabled"; // disabled account

%PlayerAccountInfoFields = listReplace(%PlayerAccountInfoFields, %playerAccountStatus, 1);
%playerAccountInfo = listJoin(%PlayerAccountInfoFields, "|");

It makes for an extremely efficient data protocol for bandwidth purposes, and once you become familiar with the field associations, relatively human-readible as well.
#5
04/23/2005 (4:40 pm)
Hmm very cool...

looks like almost identical functions as php... I like that
#6
04/23/2005 (5:05 pm)
The big disadvantage with this type of system is that it is "static", in that the sender and receiver both need to be exactly aware of all the fields in the datasets, and what they are used for. XML for example is "run time decodable", since you actually have tags.

The big advantage however is that it's damned fast, and extremely minimal data is sent for changing just a few fields, all the way up to changing a ton of fields--tags and /tags can get really expensive bandwidth wise if they are fully human readable.
#7
04/28/2005 (9:34 am)
Well I found the need for a simple explode like function...

www.razedskyz.com/games/torque/tutorials/T2D/explode/explode1.JPG
figured I'd share


you call it like this

%val = explode("blah1|blah2|blah3", "|");

then it ruturns a script object like this

%val.contents[0] = blah1
%val.contents[2] = blah2
%val.contents[3] = blah3
%val.count = 3

function explode(%string, %char)
{
	if(!isObject(explode))
		new ScriptObject(explode);

	%explodeCount = 0;
	%lastFound = 0;

	%endChar = strLen(%string);	

	for(%i=0;%i<%endChar;%i++)
	{
		%charToCheck = getSubStr(%string, %i, 1);
		if(%charToCheck $= %char)
		{
			
			explode.contents[%explodeCount] = getSubStr(%string, %lastFound, (%i-%lastFound)); 
			%lastFound = %i + 1;
			%explodeCount++;
		}
		
	}
	
	explode.contents[%explodeCount] = getSubStr(%string, %lastFound, (%i-%lastFound)); 
	explode.count = %explodeCount + 1;	

	return explode;
}
#8
04/28/2005 (9:41 am)
I think getField might have worked also...
#9
04/28/2005 (9:55 am)
Hmm thanks, seems like that will do it

echo(getField("blah\tblah2\tblah3", "0"));
returns blah.... "1" returns blah2... it seperates it by \t\n


maybe if I exposed the getUnit(s) command I could have more control

through right now a script function works for more control
#10
07/08/2005 (11:58 am)
(Might as well add any other useful script functions here :)

Heres a function you can add in script to add a "getObjectByName" function to SimSets

function SimSet::getObjectByName(%this, %name)
{
   %count = %this.getCount();

   for(%i=0;%i<%count;%i++)
   {
      %obj = %this.getObject(%i);
      if(%obj.getName() $= %name)
         return %obj;
   }

   return -1;
}

heres how I tested it

new ScriptObject(SO);
new SimSet(SS);
SS.add(SO);
echo(SS.getObjectByName("SO"));

it echoed the ScriptObject's ID :)
#11
07/08/2005 (4:31 pm)
@Matt:
This also seems to work and no (script-side) iteration... Do you have any serious code to test this on?

function SimSet::getObjectByName(%this, %name)
{
	if( isObject( %name ) )
	{
		%id = %name.getId();
		return %this.isMember( %id ) ? %id : -1;
	}

	return -1;
}


new ScriptObject(SO);
new ScriptObject(GO);
new ScriptObject(YAO);

new SimSet(SS);
SS.add(SO);
SS.add(GO);
SS.add(YAO);

// Find the objects by name
echo(SS.getObjectByName("SO"));
echo(SS.getObjectByName("GO"));
echo(SS.getObjectByName("YAO"));

// And if it's not in there
echo(SS.getObjectByName("NO"));
#12
07/15/2005 (7:32 am)
Thank you! these are going into my permanent functions block!
#13
07/15/2005 (7:34 am)
Newbie question for

@Matthew

When dealing with arrays within Scriptobjects, do you need to delete the object explicity, or if it's assigned to a local would it be deleted when it's out of scope? ( I remember reading something on the other forums about arrays and script/simobjects needed to be specifically deleted...)

thanks!
#14
07/15/2005 (8:23 am)
@Brian: Completely correct. In fact I originally created that in using a sub value instead of the actual name, like %obj.type since in my scripting I usually run off of sub values like that, but for the example I did that for (in another Torque forum) I used the name... you are definately correct though, that would be a much more efficient way of .getObjectByName().

@Colleen: "ScriptObject arrays" (thats what I always call them) is a bit of a misconception. ScriptObjects really are objects, like a sprite, or sceneobject. They have a unique "ID."... now when I create a scripobject like this

%obj = new ScriptObject();

all it really is doing is putting the reference ID of the scriptObject into %obj. So when the %obj variable leaves "scope" and is destroyed the script object still exists but now can only be referenced by its "ID" number which is lost since I never stored it in anything else...

In short you must delete them

%obj.delete();

hope that explains why :)
#15
07/30/2005 (11:50 am)
As a follow up, it occurred to me that the version of "getObjectByName ()" I suggested fails if names are not globally unique :-(
e.g.
new SimSet(SS);
new ScriptObject(YO);
SS.add(YO);
new ScriptObject(YO){ msg = "I'm not YO, I just look like him!";};

echo(SS.getObjectByName("YO"));

This would definitely be a problem for those using named objects for the namespace they create.

Be warned, use Matt's version instead!