trueSpace7: activeX FileSystemObject

About Truespace Archives

These pages are a copy of the official truespace forums prior to their removal somewhere around 2011.

They are retained here for archive purposes only.

trueSpace7: activeX FileSystemObject // Interactive Artwork

1  |  

Post by Norm // Feb 15, 2006, 6:57pm

Norm
Total Posts: 862
pic
From April.05:

You have to look at the code in script and change the file path for hard drive, currently shows as "e:". Change the code to agree with your hard drive/path to file. Put the text file in the rar, into the Scripts directory.


There is a second path to write a file, where if you change the hard drive in that line of code, you will see that a file is created and written to.

The script itself was not meant to do anything except show how activeX file system object is utilized. There is an array involved, which makes the script useful in that you can use the array's data if you wish.


I guess these functions are worth using in your own scripts for various reasons. Power to read write and append is interesting.

Post by Norm // Feb 18, 2006, 5:13pm

Norm
Total Posts: 862
pic
Well, how about we try this a different way?

Anyone want to see a tut on using this feature. Very simple but would show one possible scenario.

I would have to build from scratch, but I have a simple idea, which would help show the usefulness.

Post by b_scotty // Feb 18, 2006, 5:26pm

b_scotty
Total Posts: 176
pic
That would be nice, Norm. I'm just starting to delve into scripting and such,
so any information is useful to me at this point. :)

Post by trueBlue // Feb 18, 2006, 6:06pm

trueBlue
Total Posts: 1761
pic
Norm,
Yes I would be very interested as well. Would it be possible to attach the file anything other that a RAR file?
Thanks

Post by Norm // Feb 18, 2006, 6:30pm

Norm
Total Posts: 862
pic
Ok here goes.

I provided a text file, but you are able to create your own.

Basic reason for text file is because it is easy enough to work with and understand.

As you realize potential here, you would naturally create what ever type of text file you require. It may be a single row or multiple rows. It may have one or many columns/fields. The important point to remember is that you can move data between text file and an array in memory and from an array in memory to a text file (not necessarily the same text file, however you could read and write(append) the same text file if desired).


ActiveX file system gives us a mechanizm to open an existing text file, to read it, create a text file for writing, or append an existing text file. We should look closer at the code, so you can get a feel for what is happening.


Blow'byblow'mode:




function RosettaReads()

{

var forReading = 1, forWriting = 2, forAppending = 8;

rline = new Array();

fs = new ActiveXObject("Scripting.FileSystemObject");

f = fs.GetFile("e:\\trueSpace7\\ts\\Scripts\\ts7Scriptfile.txt");

connToFile = f.OpenAsTextStream( forReading, 0);





Variable "forReading" is created to be user readable. The numbers are all that will matter to the fso (FileSystemObject). We send a value of 1 to read an existing file, 2 if we wish to create a file for writing, or 8 if we wish to open an existing file and append, meaning write another row/line to the file.


Variable "rline" represents the creation of an empty array in memory. The plan is to populate the array with the data in the text file.


Variable "fs" represents a call to the FileSystemObject (wakes it up and we get a fresh object to use as we see fit.


Variable "f" represents a call to the FileSystemObject to GetFile The value within the () is actual path/location of the file. My specific location is shown. Yours could be different. You have to set this value yourself. It is specific to everyone's machine. No big deal really.


Variable "connToFile" represents the heart of this FileSystemObject scenario. Here we tell the system to open the file as a stream of data, which we wish to read.

Here is an explanation of what the two values we pass represent:


File Mode: (1, 2, 8)


forReading (1) Opens text file for read only. This non-desctuctive to the existing data. It only reads.

forWriting (2) Opens the file for writing. If the file exists the size is set to zero before writing. This is destructive to any existing data. By setting the size to zero, you effectively erase all data. This can be useful in some situations, however if you make the wrong call to this file, ... well you loose data. Be safe in this regard.

forAppending (8) Opens the file for appending. Add data to end of the file only.


File Format: (-2, -1, 0) respectively.



TristateUseDefault (-2) Opens the file using the system default.

TristateTrue (-1) Open the file as Unicode.

TristateFalse (0) Open the file as ASCII.



So in this case we are setting the FileSystemObject, to open an existing text file (ASCII) for read only, non-destructive data access :)




connToFile = f.OpenAsTextStream( forReading, 0);

var count = 0;

while( !connToFile.AtEndOfStream )

{

rline[count] = connToFile.ReadLine();

count++;

}

connToFile.Close();




Ok so we opened the text file. What happens next in the scipt is a few lines of code to count how many rows of data exist.

Variable "count" represents, or will represent the number of rows in the file.

The next 5 lines of code perform a loop. The loop has rules to follow:



While, meaning as long as,

the symbol ! = NOT.

So while not end of stream or file, read a line. I use the rline array, which we created a little earlier, to help count the rows of data, by transfering the data to the array. It comes in as a stream, meaning one shot from start to finish in one chunk. Each line is identified in the file, so the array ends up with the same number of rows as the original text file. Pretty slick actually. :)

Count++ is javascript increment by 1. So everytime a line is read, the value of "count" increases by 1.


Finally the while loop reaches the end of the file, drops out of the loop and is told to close the file. Always close your files. Is best practice.


Now the way we populated the array was with "strings" of data. A string would represent an entire row of data.

Post by Norm // Feb 18, 2006, 6:32pm

Norm
Total Posts: 862
pic
Norm,

Yes I would be very interested as well. Would it be possible to attach the file anything other that a RAR file?

Thanks

Sure, here is contents of rar.

Post by SiRender // Feb 18, 2006, 6:55pm

SiRender
Total Posts: 38
This is great. Thanks Norm!

Post by Norm // Feb 18, 2006, 7:22pm

Norm
Total Posts: 862
pic
connToFile.Close();

var aIndex = rline.length;

var msgA = rline[0];

var msgB = msgA.split(",");

var aElements = msgB.length;



Ok so far we have opened the file and populated an array with the data. We divided the data from the text file into rows of raw data or strings.

This next bit of scripting further refines the data, so to speak.


Variable "aIndex" represents a value for length of the array or number of rows.


Variable "msgA" represents a single row of data. We set it to 0 here, to ensure we read the first row of the array. We are passing the entire row of data into the msgA value as a string. Remember this is how we passed the contents of the text file into this array.


Variable "msgB" is now declared and used to help us refine the data.

msgA.split(",") is an interesting item, which splits the contents of msgA wherever it finds the comma character ","


Variable "aElements" represents the length of msgB, or number of fields/columns in the row.


ok I have to be careful I do not get ahead of myself here :)


Once the mechanizm to refine this data exists (we just covered that in part3), we can begin to build a second array, that will structure the data into a usable format for us.



dataArray = "";

dataArray = new Array(aIndex, aElements);

var msg = "";

for(i = 0; i < rline.length; i++)

{

msg = rline[i]; // scoop one line from msg array.

SubMsg = msg.split(","); // split the line into elements.

for (a = 0; a < SubMsg.length; a++)

{

if (SubMsg[a] == " ") // test for emptyness

{

break;

}

dataArray[i] = SubMsg;



}

}




I declare an empty array in code: dataArray = "";


I change the array and define it with rows and columns: dataArray = new Array(aIndex, aElements);

Remember we worked out the details earlier for value of aIndex and aElements by counting them.


Variable "msg" will be used to read in the raw rows of data from our original array. I set its value to empty: var msg = "";


Once I have set those items in place, it is time to introduce a loop of sorts. The "for" loop indicates that an action must take place for each iteration of the loop. We are going to count sequentially through the rows in the array called rline and process the data in each row.


for(i = 0; i < rline.length; i++)


The loop begins here. The "i" variable is used as a counter of sorts. It begins as 0. It is compared to the value we determined for the length of the rline array. It then increments the value of "i" by 1. That is what the "i++" does in javascript. As long as the value of "i" is less than the length of the array, the following lines of code are processed ...


msg = rline[i];

The variable "msg" is passed the referenced row of the rline array. As "i" is incremented each pass through this loop, the next line of the rline array is passed into "msg".


SubMsg = msg.split(",");


Split that row into elements. Where ever a comma is found, new element follows.


for (a = 0; a < SubMsg.length; a++)


Here we begin a second inner loop. Our first loop is handling each "row" of the array. Here, we must process each element in the row. We have to cycle through all the elements of this row, before we can move on to the next row. So we create an inner loop to do this. Just as the "i" was used in our first loop, we will use the "a" for our inner loop.


If you think about it, SubMsg is actually an array as well. Once we split the msg, the result is an array of "a" length. This is where the value for length in that condition is found. We did this earlier when we were working with the "split" action.


{

if (SubMsg[a] == " ") // test for emptyness

{

break;



Here we have to run a test. We much check to see if there is anything to process in the SubMsg. If it is empty (for whatever reason), we should break out of this inner loop and proceed to the next row in the rline array. That is what the "break" does for us. If the message is not "empty",


dataArray[i] = SubMsg;


We write the data to the first row of the new array. Now I take a moment here to exlain.

rline array is single dimension. It has rows only. Each row has a single string of characters.

Our "dataArray" array, has elements associated with each row. This is where we have refined the data into a multi-dimensional array (simple). Where in our rline array, all you could call was a row, here in new array we can reference each row element. Pretty cool if you understand how we broke the data down.


As each SubMsg is processed, we return to the main loop and hit the next row of rline array. Once we have finished processing the last row in rline and the last SubMsg is processed into the dataArray, ....


The function ends with some curly braces on last few lines.


So now we can have a reprise at this point in time.

What we have so far:

1. Ability to call the FileSystemObject

2. Ability to read from an existing text file of data.

3. Ability to refine the raw data into a multi-dimensional(2) array.

4. Ability to access the data in the array by row and element.


The question remains what can I do with the data?


If you understand where we are so far, I suggest next thing to do is create our own script object in trueSpace7 to utilize this function. There are still a few missing peices, but this next little example will help to clarify.


First order of business is to drag a jScript object into the link editor. Here we see where to find the "System Components" library if it is not currently showing for you. Once you have the System library, you can see the jScript object. Just lclick drag it into the Link Editor.


http://forums1.caligari.com/truespace/images/tuts/fso/fso1.jpg


Here I show a rename of the default jScript to something more meaningful; AccTextFile:


http://forums1.caligari.com/truespace/images/tuts/fso/fso2.jpg


Once you have renamed the object, enter the script object by clicking on the Orange "Enter" button: righthand side of the AccTextFile title bar.


http://forums1.caligari.com/truespace/images/tuts/fso/fso3.jpg


Here are 5 images depicting creation of attributes for our new AccTextFile script object. Add these attributes to your script object. Do this before you do anything else. Adding these items before you enter the script editor itself, will automatically insert code for them. If you enter the Script Editor's "Method" tab are first, then go back to the attributes tab, to enter new attributes, automatic code insertion will not occur. You may have to delete this jScript object and start a new one in order to see what I am saying.


http://forums1.caligari.com/truespace/images/tuts/fso/fsoScriptObj1.jpg

Add inFrame attribute as shown here. We will use this as a trigger in our script. Notice the direction is "in".


http://forums1.caligari.com/truespace/images/tuts/fso/fsoScriptObj2.jpg

First of three output values we will export for use in our scene. These three attributes have an "out" direction.


http://forums1.caligari.com/truespace/images/tuts/fso/fsoScriptObj3.jpg

Second of three output values.


http://forums1.caligari.com/truespace/images/tuts/fso/fsoScriptObj4.jpg

Last of three output values.


http://forums1.caligari.com/truespace/images/tuts/fso/fsoScriptObj5.jpg

Here is what your Attributes tab of the Script Editor should look like.

Post by Délé // Feb 19, 2006, 12:32am

Délé
Total Posts: 1374
pic
Looks like I've got some analyzing to do. :) Thanks for taking the time to share some of your knowledge here Norm. :)

Post by b_scotty // Feb 19, 2006, 2:39am

b_scotty
Total Posts: 176
pic
Thanks Norm!
Now I've got some readin' and 'sperimentin' to do :)

Post by Norm // Feb 19, 2006, 7:51am

Norm
Total Posts: 862
pic
Once you have created these basic input and output connectors, it is safe to change the Script Editor from Attributes tab, to Methods tab. When you switch, the following is what you should see:


http://forums1.caligari.com/truespace/images/tuts/fso/fsoScriptObj6.jpg


This becomes the simple state of our jScript object. By default, we are presented with a single function called OnComputeOutputs. This default function is used to compute the values for the output connectors we just created. We will require more scripting to turn this into something useful.


The main question at this point is what will we do. What data do we want to use. For sake of the tut, lets consider using a text file that has more than one row and each row will contain three numbers, separated by commas. We can take those values and send them to the output connectors outA, outB and outC.


Our script will presume a text file exists. First order of business is to decide what data we need and to create it. I suggest creating a new text file. Keeping things simple, create a text file with the following rows/values.


1,1,1

2,1,1

2,2,1

2,2,2


You could copy and paste the above four lines into a notepad file and save it to the ts/Scripts directory with name of "location.txt".


So we know this predefined data exists in the location.txt file. We know how to grab data from a text file and populate an array with this data. Question at this point is how do we implement this in our script object to suit our needs. One way to accomplish this is to use one of the Advanced Handlers provided in the Script Editor toolbar:


http://forums1.caligari.com/truespace/images/tuts/fso/advHandler1.jpg


I admit this is a bit awkward but it places all the following code into our script, just below the existing OnComputeOutputs function:


// ---------------------------------

// Advanced handlers

// ---------------------------------


// OnDefaultValue

// Called to set default value for specific connector

function OnDefaultValue(params)

{

conName = params.Param('conName');

switch (conName)

{

// set default value for particular connectors like this, if desired :

}

}


function OnSetValue(params)

{

conName = params.Param('conName');

dataBlock = params.Param('dataBlock');


switch (conName)

{

// TODO: handle particular connectors here

}

}


function OnCreate(params)

{

connectors = params.Param('connectors');


// remove following code line to set dependencies manually,

// e.g. connectors.SetDepend(inConName, outConName)


connectors.SetDefaultDependency();

}


function OnInvalidate(params)

{

conName = params.Param('conName');

}


function OnCustomEvent(params)

{

eventData = params.Param('vtEventData');

}


function OnSharedSpace_NodeStatusChanged(params)

{

ntNodeStat = params.Param('NtNodeStat');

numLocSS = params.Param('NumLocSS');

}


function OnSharedSpace_SpaceStatusChanged(params)

{

SpaceNode = params.Param('SpaceNode');

NtController = params.Param('NtController');

bActivated = params.Param('bActivated');

}


function OnPostLoad(params)

{

}



All we really want is: OnDefaultValue function


// OnDefaultValue

// Called to set default value for specific connector

function OnDefaultValue(params)

{

conName = params.Param('conName');

switch (conName)

{

// set default value for particular connectors like this, if desired :

}

}



You should edit the remaining functions out of the script. It should look like this at this point:


http://forums1.caligari.com/truespace/images/tuts/fso/fsoScriptObj7.jpg


Notice I did some extra editing in the image above. I set the inFrame input connector as a "case" scenario:


case 'inFrame' :

params.Param('vtData') = 0;

break;


What this does for us, is provide a "moment in time" , when the script object is first loaded into the Link Editor, where an action is performed. It is not much quite yet. All it is programmed to do is set value for inFrame to 0 when script is dragged into the Link Editor. Once the value is set for inFrame, the next line breaks out of the function. So we will add some lines of script code, just before the params.Param('vtData') = 0; line of code. Since that is where the action begins in this function, we have to do our work just before this action happens.

Post by stan // Feb 19, 2006, 9:11am

stan
Total Posts: 1240
pic
thanks Norm..very informative..:banana:

Post by Norm // Feb 19, 2006, 7:49pm

Norm
Total Posts: 862
pic
Perhaps best way to approach this is to do the fso scenario in a few different steps. I was hum'n'ho how to approach this and came up with this. Image below shows the initial scenario for fso:


declare variable "forReading" (you should be familiar with this)

declare variable "fs", an ActiveX FileSystemObject (you are familiar with this)

declare variable "f" and use GetFile to point the ActiveX object to our text file: location.txt.

open the text file forReading.

declare varable "count" and set its value to 0.

construct the "while" loop scenario, which parses our text file, row by row (single dimension), counting all the rows.

close the connection/textstream.

set the value for "inFrame" at 0.

break out of the "case" statement.

exit the function.



http://forums1.caligari.com/truespace/images/tuts/fso/fsoScriptObj8.jpg


In order to help you understand the flow of data, I have inserted some script code to call an "Alert" box and fill it with some info. These alerts can become a pain, but are helpful. You can easily "comment" them out using two forward slashes like so: //


The first alert statement, is located inside the "while" loop:

System.Alert("rline[count]: " + " = " + count + '\n' + rline[count] + " ");


This line is stategically placed in the "while" loop and structured to give us some info.


System.Alert places a call to alert system for windows. The information or construction following and within the ( ... ) is sent as a parameter for printing.

within the " ... " quotes will litterally be printed. The double quotes signify a "string" of characters is enclosed within. First line of the alert will be: rline[count]:

we use the + sign to concantenate or "string-together" elements of information, on the same line.

we can break the alert into separate lines using the '\n' character combination. The single quotes indicate a command is enclosed, rather than a string of characters. In this particular case, the \n represents a new line feed.

rline[count] without the double quotes, represents the data contained on the respective row.



The second System.Alert is located stategically at a point in the function, where the connection to file has just been closed. It is just outside the "while" loop. It indicates the script has finished with the while loop and closed the connection to the file/textstream. If you notice in the image, it is commented out. This means that it will not print. To make this System.Alert print to screen, I would remove the leading forward slashes //. You have to "commit" your script changes for this to work.



http://forums1.caligari.com/truespace/images/tuts/fso/commit1.jpg


//System.Alert("Connection to file is now closed");



This alert is easy to understand what it will print. It is just one string of text.

When playing around with this little script, you have to have a method to change the code enough, to trigger the fso-scenario. This alert is best for me. If I remove the slashes to run it one time, I must add the slashes in order to change the script enough to refresh and run the fso again. This is a "test-bed", so these types of items are handy. Placing alerts strategically in your script code, helps you understand the flow of the code and where any problems may be happening.


I am attaching AccTextFile.RsObj file. It is as shown in the earlier image. It has the code set up except for the path to file. You have to edit it to point to your own location.txt file, assuming you created it.


When you load the script, the alerts should begin showing up and look like this: you have to click "OK" on each alert, to show next alert. The system actually stops the script until you click ok. Is kindof neat to learn how to use this.



http://forums1.caligari.com/truespace/images/tuts/fso/sysAlert1.jpg http://forums1.caligari.com/truespace/images/tuts/fso/sysAlert2.jpg http://forums1.caligari.com/truespace/images/tuts/fso/sysAlert3.jpg http://forums1.caligari.com/truespace/images/tuts/fso/sysAlert4.jpg

http://forums1.caligari.com/truespace/images/tuts/fso/sysAlert5.jpg



So you can see that the first row is numbered 0, with data that matches the first row in your location.txt file. Four alert boxes for four rows. The fifth alert is the second alert statement and tells us that the connection was closed and we exited the while loop.


Load the script into your Objects/Script objects library.

Make sure you have your own location.txt file to use with this.

Remember to edit the path script line to agree with location of your text file.


For the brave, if you get this scenario to work, go edit your text file and add more rows. Run the script again (remember to add and then remove the // slashes so the script will run. You must "commit" these little script changes to trigger the fso-scenario).


If you were really brave and created your own script, got all the code right without using the attached file, congrats.

If you are unable to get the scenario to work, ask some questions and we can get your script running. You can use the attached file to check your own script or to copy paste if you wish.


I will add some more parts to the scenario. So far, if you can get the code to run ok, you have successfully created an important script scenario. You see flow of data and you see a counting mechanizm happening. If you remember from the previous part, we also talked about further refining the data into a multidimensional array. That will be in part 5 :)


This is so cool. Wait till you see where we can go with this!

Post by Johny // Feb 19, 2006, 8:53pm

Johny
Total Posts: 672
pic
Norm, thanks for this topic :)

Post by b_scotty // Feb 20, 2006, 6:18am

b_scotty
Total Posts: 176
pic
Yes, this is most informative. :)

Post by Norm // Feb 20, 2006, 8:49am

Norm
Total Posts: 862
pic
I would suggest that we continue with the fso scenario after first saving this particular script object in a new library. Sort of a history if you will of these items. They can prove useful over time and are relatively small. So save this script object:


first making a copy by control+lclick+drag of the AccTextFile titlebar and drag the copy somewhere close in the Link Editor.

Change the new copy's name to something like AccTextFileCounts.

Insert this script object into a new library that I will assume you can figure out how to do.

Then delete this new script from the Link Editor.



This should leave you with the original AccTextFile script object in the Link Editor.


Now we can add some more code to the script. We have to incorporate the further refining of data, into a second array, which becomes a multi-dimensional array. I call it a simple one because it only has rows and columns/fields. It is 2 dimensional. You could have more dimensions but that is beyond the scope of this tut. We still have to deal with the refinement of data. Question is where do we wish to do this? Where strategically in our code, do we "have to" refine the data to move forward? To answer this we decide what we want the script to eventually do. Eventually, triggered by a frame value, data from this new multidimensional array will be sent to our three output connectors.


For this tut, I plan to do nothing more than export data to these connectors and hook these connectors to the tx, ty and tz input connectors for matrix of any object. That would complete the circuit and provide a functionality that although limited, is beneficial in the making and subsequent use elsewhere.


Blow'by'blow again we wish to add:



var aIndex = rline.length;

var msgA = rline[0];

var msgB = msgA.split(",");

var aElements = msgB.length;

dataArray = "";

dataArray = new Array(aIndex, aElements);

var msg = "";

for(i = 0; i < rline.length; i++)

{

msg = rline[i]; // scoop one line from msg array.

SubMsg = msg.split(","); // split the line into elements.

for (a = 0; a < SubMsg.length; a++)

{

if (SubMsg[a] == " ") // test for emptyness

{

break;

}

dataArray[i,a] = SubMsg[a];

System.Alert("This data is now sitting in the array: " + '\n' + SubMsg[a]);

System.Alert("Location [i,a]: " + dataArray[i,a]);

}




}



At this point, rline is the first array we created with data harvested from the text file location.txt. This array exists in memory. We can reference this array by its name. This array has some properties, one of which is its length or number of rows in this case. With this in mind, our first varable decalaration is for a value called aIndex. We pass the length value of the rline array to aIndex.

var aIndex = rline.length;

We have the length of rline, it provides us with one element for size of new array. Our new array will have same number of rows as rline. What we need to know next is how may elements in each row of the array. For our purposes, each row is assumed to be same size. In our case each row has 3 elements or fields/columns. Use an array that does not follow these rules and your outcome will be unpredicable :) With this system, you can vary the "size" of your original text file and it will do the figuring for you. We end up with a utility type script.


Ok next line of code accesses the rline array and transfers the data into next declared variable "msgA". You see it address the first row in array: row 0

var msgA = rline[0];

This next line of code does a neat javascript function called split: best I can figure is a separate array is created by the split. It refines the data, separating individual elements by the comma character. Heck you could write a text file that used any character to "delimit", but comma is most common. Here an array is created to host the split and passed to this new variable: msgB.

var msgB = msgA.split(",");

Once this initial split is performed, we use another neat line of code to pass the length of msgB to another variable: aElements

var aElements = msgB.length;


With the length of the rows now known, this script has the important values to use as "size" for a multidimensional array. Remember we are just working out the math for required size. Not transferring data yet.


This next line of code is used to ensure that we destroy any existing array with the name dataArray. The very next line of code constructs an array named dataArray, which is why we first must ensure no data exists in the array. Why? Just for safe measure. I believe I was running into problems with existing data while constructing this. Research presented the concept of rendering the array dataless first. So I did :)

dataArray = "";


As mentioned, this next line of code creates a new array. Check it out though. We create the new array using values for size. This is where the counting comes down to showing its usefulness. :)

dataArray = new Array(aIndex, aElements);



So the code has now created a new multidimensional array in memory.


Now this next section of code is semi-familiar to those who followed all the parts so far:



for(i = 0; i < rline.length; i++)

{

msg = rline[i]; // scoop one line from msg array.

SubMsg = msg.split(","); // split the line into elements.

for (a = 0; a < SubMsg.length; a++)

{

if (SubMsg[a] == " ") // test for emptyness

{

break;

}

dataArray[i,a] = SubMsg[a];

System.Alert("This data is now sitting in the array: " + '\n' + SubMsg[a]);

System.Alert("Location [i,a]: " + dataArray[i,a]);

}




}


I cleaned up the code in this section a little. I added a couple of system alerts to pass along information to you. In short, this section has a couple of loops. The outer loop is looping through each row sequentially. The second loop is looping through elements on each row and assigning them to a specific location in our array. You will get an alert for each element in a row along with each row. Quite a few alerts but again, if you can understand how the code is working, you get a good idea for what is sitting in your array and why it is there. You set it.


It is important that you look at the code in the script object. Quoting the code as I do above, does not show the code as it is intended to be. The actual code in the script object is what is import. How it is formated, indented and such. It makes more sense in script editor than in my method above. :)


I attach the code again. What is happening with the alerts? Can you tell when the alerts arrive, where the code is executing in the script?


What happens if you substitute this System Alert:


System.Alert("Location [" + i + "," + a + "]: " + dataArray[i,a]);


for the System Alert:


System.Alert("Location [i,a]: " + dataArray[i,a]);

Post by stan // Feb 20, 2006, 12:47pm

stan
Total Posts: 1240
pic
Norm..when I load RosettaRW my norton doesn't like it..once it's open, there is no problem or norton warning when ts7 autoloads the scene ..just thought it was worth mentioning..

Post by Norm // Feb 20, 2006, 6:14pm

Norm
Total Posts: 862
pic
Norm..when I load RosettaRW my norton doesn't like it..once it's open, there is no problem or norton warning when ts7 autoloads the scene ..just thought it was worth mentioning..


It is possible that using the fso could do this Stan. Depends on how high you have restrictions set. It would appear it gives you the opportunity to take "action". I explained what we were doing and ran through the code for folks. The decision is yours to make. I suggest it is safe to check first. If you do not know what a script will do, you would be better off not letting it run. If you can understand the code enough to feel confident it would cause no harm then you could decide if it is safe to run or not.


I should point out that at this stage of the game, the RosettaRW script is old news. It is what I originally offered as a curiousity. I got no nibbles so decided to show it in a practical scenario. The last two attachment scripts I made available are reworkings of that original RosettaRW. It still holds some value for code sample. Let me know if the other two scripts throw the same error Stan. I am assuming they will. Might be best to deny first time, in order that you can examine the code itself, to make sure it has no malicious purpose.


Hope this is helpful.

Post by trueBlue // Feb 20, 2006, 6:37pm

trueBlue
Total Posts: 1761
pic
This is so cool. Wait till you see where we can go with this!

Norm:
Thank you very much for this in depth tutorial. I am really enjoying and learning from the details of your script. I am really looking forward to where this is going as well. Oh and ... God Bless!

Post by stan // Feb 21, 2006, 4:33am

stan
Total Posts: 1240
pic
Norm..the other scripts you posted open fine..it was just that one..I know you are not malicious..:D

Post by stan // Feb 21, 2006, 7:18am

stan
Total Posts: 1240
pic
http://www.microsoft.com/downloads/details.aspx?FamilyID=01592C48-207D-4BE1-8A76-1C4099D7BBB9&displaylang=en&Hash=W7YJ6M8


you can download the jscript help file here..;)

Post by Norm // Feb 21, 2006, 6:00pm

Norm
Total Posts: 862
pic
Well to be honest, it looks like I am falling down in the multidimension array area. Not sure I am populating or declaring correctly. Hopefully I will be able to figure out what the scoop is, or perhaps someone who reads can help to clarify. I am getting very unpredictable results so far. It is like it is almost working ... :)


Hunting across the net and so far found this which I may try: http://www.devx.com/tips/Tip/5280

Post by Norm // Feb 24, 2006, 8:09am

Norm
Total Posts: 862
pic
I ran into some success folks.


:banana:


You have to edit the path line of code like before. I supply my location.txt but you may have your own.


It is rough but it does the job. It has not much purpose at this point except to show this can be done. I wish to go one step further. It requires method to check if frame value is higher than the total number of lines in original text file. Then some action would happen perhaps.


My head hurts on this one :)


10.05.06 new MDarrayExample uploaded; thanks trueBlue for point it out.

Post by Norm // Feb 24, 2006, 9:24am

Norm
Total Posts: 862
pic
http://forums1.caligari.com/truespace/images/tuts/fso/fsoMDArray1.jpg


Here is the internal setup of the object I attached. It shows a set up scenario to test with is all. Slider is set to max of 4, becasue that is all the lines that exist in the text file. You can see it switching values for outA, outB and outC. You can move slider back'n'forth to see the action.


I wish to add something more to this so will be working on that next. I should first run through the code so it is clearer for you. You can see where I made some mistakes trying to create the array of arrays/multidimensional array. I will go over them so you are not left confused or such.


Here is image showing the pertinent code:


http://forums1.caligari.com/truespace/images/tuts/fso/fsoMDArray2.jpg


All the fso (FileSystemObject) items remain unchanged. The twist was down in the first "for" loop, where dataArray[i] = new Array(aElements); comes into play.


The line immediately before this "for" loop, dataArray = new Array(aIndex), creates a single dimension array that is the same "length" as the rline array (text file contents). Specifically, length refers to number of rows in the text file.


Once this array was created properly, the inner arrays could be constructed. dataArray[i] , actually names each inner array with a numerical character like: dataArray0, dataArray1 .... each pass through the "for", creates another new inner array, until end of text file rows are reached. Remember from previous description of this tutorial. The rline array reads entire lines of the text file (row). The length of rline array gave us the value for "aIndex".


The inner loop for (a= 0; < SubMsg.length;; a++) , populates each element of the inner array. With the location.txt file I supply, first row in text file holds following values: 1,2,3. When we hit the first "for" loop the first time, it sets the value for "i" to 0. So we are beginning to work on dataArray[0]. The code continues into the inner "for", where dataArray[0][0] is created. Then the individual elements found in that "row" of the text file (1,2,3) is passed into dataArray[0][0], on first pass into this inner "for" (vlaue of 1 is passed), then dataArray [0][1] where value of 2 is passed, then the last element in the "row" is passed to dataArray[0][2]. Once finished with the first inner array, the inner "for" is exited and control returns to the outer "for" loop again.


Second time through the outer "for", we get our second inner array created (dataArray[1]). Enter inner "for" again and it reads second line of text, populates the second inner array and exits the inner "for" loop.


For this scenario, only four lines exist in the location.txt file, so once all the inner loops are created and the entire array is populated with values, the output connectors can be checked for any change. The inFrame input connector is the trigger here. As you slide the slider, value for inFrame increases or decreases accordingly. Based on the value of inFrame, the output connectors are populated with values:


http://forums1.caligari.com/truespace/images/tuts/fso/fsoMDArray3.jpg


The above image shows the OnComputeOutputs function. It uses inFrame to set values for ouput connectors using this format: params.conValue("outA") = dataArray[inFrame][0];

. As the value of inFrame is increased or decreased, the output connectors are re-evaluated and new inFrame value forces the call to array for respective info.


Whew :)

Post by Wigand // Aug 21, 2006, 6:24am

Wigand
Total Posts: 462
pic
I tried the FSO for my own and you can find my results in an other thread.

Well, it is possible, to "CreateObject()" like FSO, but is it possible to create

objects like "Excel" or all the other objects I can find in my VB6 object-explorer too? I tried Excel, but had no success.


I see, (Norm) you used a hard coded path in your script, and so did I. It would be much easier to use "CommonDialog" but I read that CommonDialog needs a container, but in a script language it seems not possible!?


All of these things are matters of security too. Someone could develop a computer virus and put it into a TruePlay sceene. What do you think about that problem?
Awportals.com is a privately held community resource website dedicated to Active Worlds.
Copyright (c) Mark Randall 2006 - 2024. All Rights Reserved.
Awportals.com   ·   ProLibraries Live   ·   Twitter   ·   LinkedIn