Shoutbox

MsgPlus.LoadScriptFile() problem - Printable Version

-Shoutbox (https://shoutbox.menthix.net)
+-- Forum: MsgHelp Archive (/forumdisplay.php?fid=58)
+--- Forum: Messenger Plus! for Live Messenger (/forumdisplay.php?fid=4)
+---- Forum: Scripting (/forumdisplay.php?fid=39)
+----- Thread: MsgPlus.LoadScriptFile() problem (/showthread.php?tid=80415)

MsgPlus.LoadScriptFile() problem by Jeroen Noten on 12-25-2007 at 02:44 PM

Hello, I script my own script and I've got a problem with the MsgPlus.LoadScriptFile() function. The documentation it says:

quote:
The whole content of the file is parsed and immediately placed in a running state (newly defined functions can be executed from anywhere in your script and lines belonging to the global scope are executed).

When I define a function in the external script file I can't execute this function in the rest of the script. Is this a bug? Or do I do something wrong?

Thanks,
Jeroen Noten

P.s. I'm Dutch, sorry if my English is not correct.
RE: MsgPlus.LoadScriptFile() problem by Volv on 12-25-2007 at 03:12 PM

quote:
IRC Scripting Support channel

<JeroenNoten> I am loading an external script file with MsgPlus.LoadScriptFile(). I define a function in the external file, but I can't execute the function after loading the file. In the documentation it says it's possible. What do I do wrong?

<Volv> Are you getting any errors in your Script Debugging window? Also, if you haven't already done the following which is in the documentation then you should try: It is recommended to use Unicode text files. The path is relative to the script's directory by default, to override this behavior, prefix the path with "\". Example: "\C:\directory\script.js".

RE: MsgPlus.LoadScriptFile() problem by Spunky on 12-25-2007 at 05:39 PM

quote:
Originally posted by Volv
prefix the path with "\". Example: "\C:\directory\script.js".

It will be

code:
"\\C:\\directory\\script.js

as you would need to escape your slashes

RE: MsgPlus.LoadScriptFile() problem by Eljay on 12-25-2007 at 10:10 PM

Confirmed, sort of. It's quite hard to explain so I'll show examples that hopefully explain themselves. :P

Example 1:

code:
// main.js (this is in the script's root so it is loaded automatically)
Debug.Trace('1. Before LoadScriptFile');
MsgPlus.LoadScriptFile('\\C:\\test.js');
Debug.Trace('3. After LoadScriptFile');

code:
// C:\test.js
Debug.Trace('2. During LoadScriptFile');
quote:
Originally posted by Debug output
Script is starting
1. Before LoadScriptFile
3. After LoadScriptFile
2. During LoadScriptFile
Script is now loaded and ready

As you can see, test.js isn't executed immediately, but after main.js has finished being executed.


Example 2:
code:
// main.js (test.js remains the same as above)
function OnEvent_Initialize(){
  Debug.Trace('1. Before LoadScriptFile');
  MsgPlus.LoadScriptFile('\\C:\\test.js');
  Debug.Trace('3. After LoadScriptFile');
}
quote:
Originally posted by Debug output
Script is starting
Script is now loaded and ready
1. Before LoadScriptFile
2. During LoadScriptFile
3. After LoadScriptFile

For some reason, when called after the initial script load by Plus!, the order is correct meaning that test.js was executed immediately.
RE: MsgPlus.LoadScriptFile() problem by Matti on 12-26-2007 at 10:07 AM

I also experienced this behaviour. It seems like Plus! Live executes the script files in an order like this:

  1. Load the script files in the main script directory (Scripts\Script Name\)
  2. Execute the global codes while loading the files.
  3. Load the script files as requested by MsgPlus.LoadScriptFile().
So in fact, when you do a LoadScriptFile() call while it's still loading other script files, Plus! simply adds the file to it's "to-do" list and immediately returns. When all the script files in the main directory are already loaded and the call comes from an event, Plus! will load it immediately.

The problem is that this stops me from doing clean-up actions before the script is initialized. For example, I want to make sure that old script files which I used in Countdown Live v1 are removed before the script tries to load them. Because I can't, I have to remove them after they were loaded, which stops the script from working because of overlapping functions, and thus I have to ask the user to restart the script.

Sounds like a Plus! bug or limitation to me, yes! :P
RE: MsgPlus.LoadScriptFile() problem by CookieRevised on 12-26-2007 at 10:33 AM

Note that LoadScriptFile is not meant to be a "insert all the code from the loaded script in this very spot" function.

LoadScriptFile behaves just the same as how Plus! loads multiple script files in the main script folder.

The global scope of scripts is first completely parsed before they are executed. That is the reason why you can get away with:

code:
function DoSomething() {
    Debug.Trace(mystring)
}
var mystring = "Hello World"

The same happens in Eljay's first example. Everything is in the global scope, so main.js is parsed. With that, Plus! sees that LoadScript is used, so it appends the test.js script to main.js. In other words you'll get one giant script like this:
code:
Debug.Trace('1. Before LoadScriptFile');
MsgPlus.LoadScriptFile('\\C:\\test.js'); // mainingless once this is parsed
Debug.Trace('3. After LoadScriptFile');
Debug.Trace('2. During LoadScriptFile');
with the expected output: 1 3 2 once it is executed...

However, in his second example, he puts MsgPlus.LoadScriptFile in a function. Which means it is not in the global scope anymore. And thus will not be executed (the stuff which is in the loaded script) until Initialize function is executed. Which is done after the globale scope of main.js is parsed and after the global scope of main.js is executed.

So it does:
1) parse global scope of Main.js (and any other script file in the script directory)
2) execute all the stuff as if it was 1 giant script.
3) function Initialize is called
3.1) Debug.Output("1")
3.2) The test.js script is parsed and executed, thus you'll get "2" as output. However, although it seems like it was executed in the scope of this function, it is not. The debug.output in test.js is still in the global scope. Just the execution of main.js is halted for a while while test.js is parsed and executed.
3.3) Debug.Output("3").

To better illustrate what happens you better make test.js like this:
code:
var mystring = "Hello World"
And as a first example, main.js like:[code]MsgPlus.LoadScriptFile('\\C:\\test.js');
Debug.Trace(mystring);
function OnEvent_Initialize() {
    Debug.Trace(mystring)
}
When you first run this script you'll get an error that mystring isn't defined on line 2. This is already proof that test.js is appended after main.js and not inserted.

So, remove that first Debug.Trace line and rerun the script.

Now you'll see that the script executes properly and mystring is printed because it was defined in the global scope of the script and thus also in the scope of the Initialize function.

To make it maybe even more clear, make main.js like:
code:
function OnEvent_Initialize(MessengerStart) {
      MsgPlus.LoadScriptFile('\\C:\\test.js');
      MsgPlus.AddTimer("1", 1000)
}

function OnEvent_Timer() {
      Debug.Trace(mystring);
}
This makes it very clear that even if you put MsgPlus.LoadScriptFile inside a function, it will not act as a "insert code in this spot" method.

After executing this script you'll see that mystring is printed properly, although it was not defined in the Timer event. This because it was loaded and thus defned in the global scope, when the test.js script was loaded in the Initialize function.

To recap:
- MsgPlus.LoadScriptFile is not meant to be an "insert code here" function
- MsgPlus.LoadScriptFile parses and executes script files on demand by appending the script file to the already executing main script. During this time the main script is temporary halted.
- Nomatter where you place it, the stuff inside the loaded script file is always put in the global scope, just like any other individual script file.
- sidenote: every individual script file in the script's directory is joined together with all the other script files to form one giant script. It is this giant script which is actually parsed and executed in Plus!. The individual script files are just there for your editing convenience.

-----------

So, actually, it is expected behaviour though, and I wouldn't expected it to behave any differently (again, it is not a "insert code here" function).

I hope all this makes some sense :p[/code]
RE: RE: MsgPlus.LoadScriptFile() problem by Volv on 12-26-2007 at 10:45 AM

quote:
Originally posted by SpunkyLoveMuff
quote:
Originally posted by Volv
prefix the path with "\". Example: "\C:\directory\script.js".

It will be

code:
"\\C:\\directory\\script.js

as you would need to escape your slashes

As I said, it's a direct quote from the documentation.
RE: MsgPlus.LoadScriptFile() problem by Matti on 12-26-2007 at 11:12 AM

Ooh... thank you Cookie! :D
I think I understand now! :P


RE: MsgPlus.LoadScriptFile() problem by Jeroen Noten on 12-28-2007 at 07:47 PM

quote:
Originally posted by Eljay
Confirmed, sort of. It's quite hard to explain so I'll show examples that hopefully explain themselves. :P

Example 1:
code:
// main.js (this is in the script's root so it is loaded automatically)
Debug.Trace('1. Before LoadScriptFile');
MsgPlus.LoadScriptFile('\\C:\\test.js');
Debug.Trace('3. After LoadScriptFile');

code:
// C:\test.js
Debug.Trace('2. During LoadScriptFile');
quote:
Originally posted by Debug output
Script is starting
1. Before LoadScriptFile
3. After LoadScriptFile
2. During LoadScriptFile
Script is now loaded and ready

As you can see, test.js isn't executed immediately, but after main.js has finished being executed.


Example 2:
code:
// main.js (test.js remains the same as above)
function OnEvent_Initialize(){
  Debug.Trace('1. Before LoadScriptFile');
  MsgPlus.LoadScriptFile('\\C:\\test.js');
  Debug.Trace('3. After LoadScriptFile');
}
quote:
Originally posted by Debug output
Script is starting
Script is now loaded and ready
1. Before LoadScriptFile
2. During LoadScriptFile
3. After LoadScriptFile

For some reason, when called after the initial script load by Plus!, the order is correct meaning that test.js was executed immediately.
Thank you! This was the problem, it's solved now. (But I found out it by myself already. ;))