Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: WSH Panel Mod (Read 801538 times) previous topic - next topic
0 Members and 3 Guests are viewing this topic.

WSH Panel Mod

Reply #1276
Thanks, but I think v1.5.0 has an important bug (in all recent versions), that makes f2k crash.

I have several panels that worked fine with v1.4.4, but since I've tried the previews and now the first public beta of v1.5, I have constantly abrupt crashes.  Since I was developing new panels, I thought they were caused by bugs in my code, but now I've restored an old backup with WSHPM v1.4.4 and my old script, and that version works without crashes.  As soon as I replace the WSH extension with one of the v1.5 versions, the crashes begin.

Unfortunately, it is not easy to find the origin of the bug, as I can't see the console when f2k is crashing.  But I've found a function that crashes systematically when it is called after having selected a new track manually.  Here is the code:
Code: [Select]
function is_radio(metadb) {
    var p;
    if (! metadb) {return(false);}
    try {p = fb.TitleFormat("%path%").EvalWithMetadb(metadb);} catch(e) {return(false);}
    if (p.substr(0, 32) == "FOO_LASTFM_RADIO://play.last.fm/") {return(true);}
    if (p.substr(0, 7) == "http://") {return(true);}
    return(false);
}

I can't be sure that the metadb passed to the function is not null, but the first test should return immediately if it's not the case.  The rest is pretty trivial, so I wonder why this function crashes.

Is it possible that metadb.Dispose() doesn't make the metadb handle null in v1.5?

And, btw, is it necessary or prohibited to use metadb.Dispose() in on_playback_new_track(metadb)?  For example, should I need this:
Code: [Select]
function on_playback_new_track(metadb) {
    // some code
    metadb.Dispose();  // necessary?
}


I can post here (or elsewhere) the foobar crash reports, if that can help.

WSH Panel Mod

Reply #1277
OK, I have written an intentionally bad script to demonstrate the problem:

Take care!  It is dangerous!   
Code: [Select]
var g_metadb = null;

function is_radio(metadb) {
    var p;
    if (! metadb) {return(false);}
    try {p = fb.TitleFormat("%path%").EvalWithMetadb(metadb);} catch(e) {return(false);}
    if (p.substr(0, 32) == "FOO_LASTFM_RADIO://play.last.fm/") {return(true);}
    if (p.substr(0, 7) == "http://") {return(true);}
    return(false);
}

function on_playback_new_track(metadb) {
    g_metadb = metadb;
    fb.trace("**** is_radio called from on_playback_new_track(): "+is_radio(g_metadb));
}

function on_mouse_lbtn_up() {
    g_metadb && g_metadb.Dispose(); // this line is responsible of the bug!
    fb.trace("**** is_radio called from on_mouse_lbtn_up(): "+is_radio(g_metadb));
}


Clicking on the panel clears the g_metadb global variable and calls is_radio().
When you start f2k without playback, g_metadb = null, and you can click on the panel without problem.
When a track begins to play, is_radio() is called, again without problem, because g_metadb is correctly initialized.
But now, when you click on the panel, F2K crashes, because g_metadb has been Disposed, but is not null.

I don't know what instruction makes F2K crash, but I guess it's TitleFormat() or its EvalWithMetadb() method.

WSH Panel Mod

Reply #1278
in your mouse click function..
Code: [Select]
if(g_metadb) {
  g_metadb.Dispose();
  g_metadb = null;
}

WSH Panel Mod

Reply #1279
in your mouse click function..
Code: [Select]
if(g_metadb) {
  g_metadb.Dispose();
  g_metadb = null;
}

Is it really necessary?  IMO, a Disposed object should be made null automatically.  (But I don't know if it's possible.)

Anyway, the script above works with v1.4 without problem.  Something has changed in v1.5, that causes the crashes.  What?

And IMO, being programmed with a scripting language, the WSH panels can crash with an error message, but foobar itself should never crash.  The only crash I have had with v1.4 was caused by an infinite loop in my code.  I have had to kill foobar.  Now, with v1.5 beta, foobar crashes regularly.  I don't want to blame T.P.Wang: he does an excellent work, and anyway, the current version is a beta. But I think there is something to improve here, and wanted to let him know.

[BTW, there is also this bug to fix, reported in the Help thread.]

WSH Panel Mod

Reply #1280
Code: [Select]
v1.5.0 Beta 2
- FIX: Fix a bug that foobar2000 will crash when calling EvalWithMetadb() method from a metadb handle after disposed.
- FIX: Fix "Variable uses an Automation type not supported in JScript" error while using plman.InsertPlaylistItems() and plman.InsertPlaylistItemsFilter().

WSH Panel Mod

Reply #1281
Great!  That was fast! 

A new beta just for the two bugs I've reported!  I am the center of the world! 

Thanks T.P.!

WSH Panel Mod

Reply #1282
Just for my education, can I know what Dispose() does exactly?  Does it destroy the object completely?

Can I assume that a disposed object is null?  Or undefined?
In other words, is this valid:
Code: [Select]
metadb && metadb.Dispose();
if (! metadb) return;

WSH Panel Mod

Reply #1283
use typeof like this to find out

Code: [Select]
fb.trace(typeof metadb);


i did a quick test myself....
Code: [Select]
g_metadb = fb.GetFocusItem();
fb.trace(typeof g_metadb); //object
g_metadb && g_metadb.Dispose();
fb.trace(typeof g_metadb); //object again - not sure if this should be the case???

WSH Panel Mod

Reply #1284
Thanks.  I didn't know that typeof is available in jscript.

I agree with you.  IMO, a Disposed object should be null.  But I wonder if it's possible, since Dispose() is a method of the object.  It is probably impossible to destroy the object when the method is running.  (Not sure though: I'm not a low-level programmer.)

[EDIT]
Indeed, the test "if (! object)" doesn't work with disposed objects.  In is_radio() in my example above, the following lines are executed.  But I can confirm that the bug is fixed.  Foober doesn't crash any more.  Thanks again! 

Maybe it is possible to test if the object has been disposed with another check than (! object)?
Something like:
if (object.Disposed) return;

Anyway, currently, I will follow your suggestion, Marc, and force any object to null each time it is disposed.


BTW, the other bug, with InsertPlaylistItems(), is fixed too. 

WSH Panel Mod

Reply #1285
@r0lZ:
WSH Panel Mod v1.5.0 Beta 2 is released addressed that crash.

Even though, you will get script error instead if you are coding like that.

Dispose() means freeing or releasing resources from an object. It has nothing to do with the null.

WSH Panel Mod

Reply #1286
Dispose() means freeing or releasing resources from an object. It has nothing to do with the null.

OK, thanks for the precision.

So, if I use Dispose() then object = null, I can be sure that the object is completely destroyed?

And, BTW, is it necessary to use Dispose() if I do "object = null"?  In other words, when the object is "nullified", does it call Dispose() by itself and free the resources automatically?

WSH Panel Mod

Reply #1287
affecting "null" to an existing object doesn't free it, the pointed object is kept in memory but is no more adressed. As T.P said, the Dispose() allows to release the ressources and so to free the memory

WSH Panel Mod

Reply #1288
OK, I wanted to be sure, because I also write scripts in AutoHotkey_L, and in that language, the resources are automatically freed when an object is made null (or when the variable is assigned to another object).  It's handy, but not really necessary.


BTW, I still need to know if I need to Dispose() the metadb passed by WSHPM to a callback, for example to on_playback_new_track(metadb)

In other words, I don't know if the metadb is automatically freed by the calling code, or if it's the responsibility of the code in the on_playback_new_track() to do it.  Also, if the metadb is passed as a pointer, and is therefore not a copy of another metadb, it might be dangerous to Dispose it.

Currently, I assume that I don't need to Dispose the metadb.  Is it correct?

WSH Panel Mod

Reply #1289
In fact, even in JScript, it will get freed, but not immediately, because there's something called Garbage Collection.
If you want something behaves like AutoHotkey_L, then use VBScript, it doesn't have Garage Collection.
And FYI, Here is a LINK describes that(though somewhat out-of-date).

Generally speaking, it's no need to call Dispose() on objects which are passed by callbacks.
And in fact, the only reason to call Dispose() is that you are creating new instances of (IGdi*, IMenuObj, IFbFileInfo, etc) again and again.

Quote
Currently, I assume that I don't need to Dispose the metadb. Is it correct?

So yes.

WSH Panel Mod

Reply #1290
Thanks for the complete response.  It's exactly what I supposed, although I didn't know that jscript has a garbage collection mechanism.  (BTW, it remembers me the good old Commodore 64 time, when the garbage collection of the native Basic language was freezing your program during several seconds!)

My script is working very well now.  I have added "object = null" after the Dispose() of global objects, for safety and optimisation purposes, so, for example, my is_radio() function returns now immediately.  Anyway, even without that modification, my script did not crash any more with beta 2.  Thanks again!

I have still a request.  If it's possible, can you add an optional filename parameter to the LoadPlaylist() and SavePlaylist() functions?  Or, even better, create new functions to save an IFbMetadbHandleList to file and reload it?
Currently, it is possible to create a playlist file from the current playlist by writing the paths of the tracks to a m3u file, but as far as I know, there is no way to reload it without the file dialog of LoadPlaylist().
My goal is to save an internal IFbMetadbHandleList to a playlist from on_script_unload() (this part is possible although complicated), and reload it when the panel is initialising (and currently this part is impossible without user intervention).  I don't need to load the playlist in the GUI, so IMO a new function to load a playlist in a IFbMetadbHandleList would be handy, but if it's not possible, LoadPlaylist(filename) should be sufficient.  Since it is possible to drop files on a WSH panel and send them to a playlist, I guess it should be possible to do the same thing with a list of files contained in a m3u file.
Can you consider this?

WSH Panel Mod

Reply #1291
@T.P, if i enable Jscript9 in the editor (and have IE9 installed, obviously), does that mean we should get native JSON support? if i try and use JSON.parse without the external library i was using before, i get simply get a 'JSON' is undefined error. or have i got the wrong end of the stick completely about what this new feature is??

WSH Panel Mod

Reply #1292
@r0lZ:
Quote
I have still a request. If it's possible, can you add an optional filename parameter to the LoadPlaylist() and SavePlaylist() functions? Or, even better, create new functions to save an IFbMetadbHandleList to file and reload it?

Sorry but no.

@marc2003:
Fixed in v1.5.0 Beta 3, thanks for reporting.

WSH Panel Mod

Reply #1293
News:
WSH Panel Mod v1.5.0 Beta 4 is now released.
ChangeLog
Code: [Select]
- ADD: Add new timer methods: window.SetInterval(), window.SetTimeout(), window.ClearInterval() and window.ClearTimeout().
- CHG: Mark old timer methods as obsolete: window.CreateTimerInterval(), window.CreateTimerTimeout(), window.KillTimer(), please use the new ones.
- CHG: [Breaking Change] Callback functions now must be defined in global scope on script initialization (This change should not affect most scripts).

WSH Panel Mod

Reply #1294
thanks for the updates.

WSH Panel Mod

Reply #1295
Hello, I use the sample code provided in the .zip file to create a popup menu. I get the following output in the console:

Code: [Select]
WSH Panel Mod: Warning: Obsolete: Use AppendTo() method to create sub menu instead.


From what I've found by googling, I should not use the AppendMenuItem() and I should use the AppendTo() method instead. But I have no clue where to use it. I have tried just to rename the AppendMenuItem(...) to AppendTo(), but then I get type mismatch.

The sample code in the zip works fine, but I'd like to avoid cluttering the console!

EDIT: got it after reading the interfaces.txt carefully. You need to change this line:
Code: [Select]
basemenu.AppendMenuItem(MF_STRING | MF_POPUP, child1.ID, "File");

to this line:
Code: [Select]
child1.AppendTo(basemenu, MF_STRING | MF_POPUP, "File");


And do the same for child2, child3, etc...

WSH Panel Mod

Reply #1296
Code: [Select]
old:
_menu.AppendMenuItem(MF_STRING | MF_POPUP, _child.ID, "Background");

new:
_child.AppendTo(_menu, MF_STRING, "Background");


edit: Menu Sample (Advance).txt has the new method but not the MainMenuManager All-In-One.txt one you used.

WSH Panel Mod

Reply #1297
@T.P Wang: I'm using the latest beta and I found you added support for IE9 JScript engine which is great. Still if I want to use the native XMLHTTP object, I can't do it inside WSH panel, can I? I want to use ontimeout callback of native XMLHTTP.

WSH Panel Mod

Reply #1298
@thuan:
You can't, native XHR is provided in IE, not JScript.

WSH Panel Mod

Reply #1299
new timer api give me some work to replace the old ones ...

btw i noticed that timer interval keep running after at Aw, crashed! ... weird, should clear all the timers on crash no?