Readline()
by Teromous · in Torque Game Builder · 04/06/2008 (11:57 am) · 5 replies
Hey guys I've been looking in the TGB documentation for the arguments on readline() but there are none listed. I'm wanting to store certain lines from a text file, similar to:
%line1 = %file.readLine(1);
%line3 = %file.readLine(3);
%line20 = %file.readLine(20);
I don't want to store every line, just specific ones. Those numbers are arbitrary, I just wanted to show the idea that I'm not wanting sequential lines to be stored or anything. Can anyone help me figure this out?
%line1 = %file.readLine(1);
%line3 = %file.readLine(3);
%line20 = %file.readLine(20);
I don't want to store every line, just specific ones. Those numbers are arbitrary, I just wanted to show the idea that I'm not wanting sequential lines to be stored or anything. Can anyone help me figure this out?
About the author
#2
Having said that, there is no need to store any lines that you don't want (or any lines at all, for that matter). Instead, use a counter variable to track which line you are on and store only those lines corresponding to those you hope to capture from the file.
For example (as I know nothing about what you are actually doing), lets pretend that each line in the file contains a player's name. We'll presume that the file has five (5) lines and appears like so (the line numbers are purely for purposes of reference):
[1] Joan
[2] Archibald
[3] Ronald
[4] Mickey
[5] Lucian
Lets assume you only wanted the names from line 2 and 4. Those names you want to store in the variables $player1_name and $player2_name (again, hypothetical). Pseudo-code would go something like:
This will result in only storing the most recent line read from the file in the LINE variable, and only those lines from the file of interest are further relayed to other variables of interest (i.e., the player name variables).
Additionally, the DONE variable is used so you can denote when you have all that you need from the file. Doing that permits you to avoid reading remaining (re: unwanted) lines from the file.
In any case, you shouldn't worry so much that you are required to step through the file unless the file(s) you are dealing with are very large and take inordinate amount of time to process. If that is the case, it is very likely that a new design consideration is presenting itself. That is a little beyond the ability for us to discuss without knowing more from you and what you are trying to accomplish.
Maybe, if you could provide more information, someone here could highlight a better method or design that you could use to accomplish what you want?
04/06/2008 (1:17 pm)
There are no arguments for readLine() -- it simply reads a line from the file.Having said that, there is no need to store any lines that you don't want (or any lines at all, for that matter). Instead, use a counter variable to track which line you are on and store only those lines corresponding to those you hope to capture from the file.
For example (as I know nothing about what you are actually doing), lets pretend that each line in the file contains a player's name. We'll presume that the file has five (5) lines and appears like so (the line numbers are purely for purposes of reference):
[1] Joan
[2] Archibald
[3] Ronald
[4] Mickey
[5] Lucian
Lets assume you only wanted the names from line 2 and 4. Those names you want to store in the variables $player1_name and $player2_name (again, hypothetical). Pseudo-code would go something like:
create a boolean variable DONE
create a counter variable COUNT
set DONE to false
set COUNT to zero (0)
create a file object
open/load a file for reading with the file object
while(not EOF and DONE equals false)
increment COUNT
read a line from the file and store in variable LINE
inspect the value of counter
IF counter is equal to 2
Add the data from LINE to $player1_name
IF counter is equal to 4
Add the data from LINE to $player2_name
set DONE to true
close the file
delete the file objectThis will result in only storing the most recent line read from the file in the LINE variable, and only those lines from the file of interest are further relayed to other variables of interest (i.e., the player name variables).
Additionally, the DONE variable is used so you can denote when you have all that you need from the file. Doing that permits you to avoid reading remaining (re: unwanted) lines from the file.
In any case, you shouldn't worry so much that you are required to step through the file unless the file(s) you are dealing with are very large and take inordinate amount of time to process. If that is the case, it is very likely that a new design consideration is presenting itself. That is a little beyond the ability for us to discuss without knowing more from you and what you are trying to accomplish.
Maybe, if you could provide more information, someone here could highlight a better method or design that you could use to accomplish what you want?
#3
function ReadCharacterSheet()
{
%file = new FileObject();
if(%file.openForRead("~/data/files/Character.chs"))
{
%Life = %file.readLine();
$LifeValue = %file.readLine();
%Spirit = %file.readLine();
$SpiritValue = %file.readLine();
%Accuracy = %file.readLine();
$AccuracyValue = %file.readLine();
%Deflection = %file.readLine();
$DeflectionValue = %file.readLine();
%DamageMod = %file.readLine();
$DamageModValue = %file.readLine();
%Absorption = %file.readLine();
$AbsorptionValue = %file.readLine();
}
else
{
error("cannot open file for read");
}
%file.close();
}
This would be paired with:
Life
100
Spirit
100
Accuracy
30
Deflection
40
Damage Mod
50
Absorption
60
...I only need every other line because those are the numbers I'm pulling, but I keep in the "Life" words etc to make it easier for me to modify character sheets.
04/06/2008 (3:25 pm)
What I'm doing isn't very complicated. The code I posted above is pretty much the whole code I'm using, but because you asked:function ReadCharacterSheet()
{
%file = new FileObject();
if(%file.openForRead("~/data/files/Character.chs"))
{
%Life = %file.readLine();
$LifeValue = %file.readLine();
%Spirit = %file.readLine();
$SpiritValue = %file.readLine();
%Accuracy = %file.readLine();
$AccuracyValue = %file.readLine();
%Deflection = %file.readLine();
$DeflectionValue = %file.readLine();
%DamageMod = %file.readLine();
$DamageModValue = %file.readLine();
%Absorption = %file.readLine();
$AbsorptionValue = %file.readLine();
}
else
{
error("cannot open file for read");
}
%file.close();
}
This would be paired with:
Life
100
Spirit
100
Accuracy
30
Deflection
40
Damage Mod
50
Absorption
60
...I only need every other line because those are the numbers I'm pulling, but I keep in the "Life" words etc to make it easier for me to modify character sheets.
#4
I can see two things that I'd offer for your consideration: 1) a new format for storing your character data in file (via a tab delimited file format), and 2) a new format for storing your character data in code (via character class objects).
Under the presumption that you may have multiple characters for whom you store data in a file, changing your file format a little could be more efficient and easier for you to deal with. A simple, tabular (i.e., flat file) format would allow each line to hold the data for a single character. The file might look something like this:
The new column is the ID of a specific character (or character/unit type, for example). The first line read would obviously just contain the header information, which you would ignore. Each line thereafter holds all of the information for a single character or unit type.
So, in this example, after four line reads you would have all of the data for three characters slurped from the file. Your existing format would require roughly 36 to 42 line reads to accomplish the same thing (and potentially much more code behind it to both read and parse the data).
Naturally, the format I suggest also implies that you would have to parse each line read but this is a fairly simple process using [url=[http://tdn.garagegames.com/wiki/TorqueScript_Commands#getWord"]getWord(x, y)[/url]. If you want or need, I can provide some example code to show you how you might accomplish that as well.
Beyond that, it may be useful (and promote a better internal design) if you create a character class to store, reference, and manipulate your character data. This, opposed to using general, global variables.
Even if you have only a single character it is probably a better way to go. For example, you could add a "load" function to your character class that contains the code that will open and read a file, slurping out only the character data related to the ID you provide. Your code might appear as such:
04/07/2008 (12:05 pm)
Hi again Teromous,I can see two things that I'd offer for your consideration: 1) a new format for storing your character data in file (via a tab delimited file format), and 2) a new format for storing your character data in code (via character class objects).
Under the presumption that you may have multiple characters for whom you store data in a file, changing your file format a little could be more efficient and easier for you to deal with. A simple, tabular (i.e., flat file) format would allow each line to hold the data for a single character. The file might look something like this:
ID LIFE SPIRIT ACC DEFL DMG ABS 1 100 100 30 40 50 60 2 80 120 40 40 40 60 3 115 85 30 40 45 65
The new column is the ID of a specific character (or character/unit type, for example). The first line read would obviously just contain the header information, which you would ignore. Each line thereafter holds all of the information for a single character or unit type.
So, in this example, after four line reads you would have all of the data for three characters slurped from the file. Your existing format would require roughly 36 to 42 line reads to accomplish the same thing (and potentially much more code behind it to both read and parse the data).
Naturally, the format I suggest also implies that you would have to parse each line read but this is a fairly simple process using [url=[http://tdn.garagegames.com/wiki/TorqueScript_Commands#getWord"]getWord(x, y)[/url]. If you want or need, I can provide some example code to show you how you might accomplish that as well.
Beyond that, it may be useful (and promote a better internal design) if you create a character class to store, reference, and manipulate your character data. This, opposed to using general, global variables.
Even if you have only a single character it is probably a better way to go. For example, you could add a "load" function to your character class that contains the code that will open and read a file, slurping out only the character data related to the ID you provide. Your code might appear as such:
function character::load(%this, %id)
{
// all of your file reading and parsing is done here
// after this function is called, you would have all your character data
// loaded into the character object that called this function.
<< ... code ... >>
// parsed data is placed into your character object like this:
// (the %line variable is the string read from the file corresponding to the ID of this character)
// (the "2" in getWord() indicates that you want the second "Word" from the %line variable,
// which contains the value of "life")
%this.life = getWord(%line, 2);
}
// an example of an accessor function--see below for more
function character::getLife(%this)
{
return %this.life;
}
// This function is an example of how you might instantiate a character
// in the code using the functionality from above related to the class you've created
// Note that this function is not part of the character class--just a general function to call
function createCharacter(%ID)
{
// I'm presuming that a character is a scene visible object here, so
// this example uses a static sprite. It could be an invisible sceneobject
// or just a scriptobject, however.
%char = new t2dStaticSprite() { class = "character"; };
// this is how easy it would be for you to load a character thanks to your "load()" function
// if %ID was equal to three, the data stored in the file with an ID of 3 would load into this character object
%char.load(%ID);
// you could use accessor functions to get and set data in your character object thereafter
// or simply access the variables directly, like so:
echo("Life: " @ %char.life);
// or via access function(s) that you would create
echo("Life: " @ %char.getLife());
}
#5
04/11/2008 (7:46 pm)
Thanks for the insight! This is closer to what I was wanting to do, which is make the character sheet look like a small database file. Could you show me a small example of how I could script to read this format? I looked for information on getWord() but all I could find out was information on vectors.
Torque Owner Teromous
%line1 = %file.readLine();
%line2 = %file.readLine();
%line3 = %file.readLine();
...
%line20 = %file.readLine();
...Will work because it actually goes through a new line whenever "readline" is called. I just wish there was a way to call a specific line without having to go through ALL of them to just pull out a few of them.