Hydrogenaudio Forums

Hosted Forums => foobar2000 => 3rd Party Plugins - (fb2k) => Topic started by: TheQwertiest on 2018-10-01 11:01:15

Title: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2018-10-01 11:01:15
Spider Monkey Panel     (https://img.shields.io/github/release/theqwertiest/foo_spider_monkey_panel.svg) (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/master/CHANGELOG.md) (https://ci.appveyor.com/api/projects/status/4fg787ijr73u7mxc/branch/master?svg=true) (https://ci.appveyor.com/project/TheQwertiest/foo-spider-monkey-panel/branch/master)

fb2k component that allows for creation of full-fledged CUI/DUI panels using JavaScript! 

Base functionality includes:
 - Graphics functions: drawing text, external images, lines, rectangles, etc.
 - Access fonts and colours settings from the main preferences of CUI/DUI.
 - Execution of main menu and context menu commands.
 - Creation of custom buttons and menus.
 - Capture of keystrokes/mouse movement/clicks.
 - Capture of foobar2000 events with callbacks.
 - Processing and changing of file tags.
 - Playlists management: create, destroy, sort, change, rename and do anything that fb2k can do.
 - Access Media Library with ability to sort and filter it's contents.
 - Per panel settings storage.
 - Built-in web and filesystem access.
 - And more!

Getting started!
 - Use Installation Guide (https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/Installation).
 - Take a look at Documentation and Samples (https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/Script-documentation)

JScript Panel users
Spoiler (click to show/hide)

Links
 - Download link (https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/latest)
 - Changelog (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/master/CHANGELOG.md)
 - Detailed list of API Changes (https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes)
 - Wiki (https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki)
 - Current tasks and plans (https://github.com/TheQwertiest/foo_spider_monkey_panel/projects/1)
 - Nightly build (https://ci.appveyor.com/api/projects/theqwertiest/foo-spider-monkey-panel/artifacts/_result%2FWin32_Release%2Ffoo_spider_monkey_panel.fb2k-component?branch=master&job=Configuration%3A%20Release)

Credits
 - marc2003 (https://github.com/marc2k3): original foo_jscript_panel (https://github.com/marc2k3/foo_jscript_panel), sample scripts (https://github.com/marc2k3/smp_2003) and multiple contributions to this project.
 - T.P. Wang (https://hydrogenaud.io/index.php?action=profile;u=44175): original WSH Panel Mod (https://code.google.com/archive/p/foo-wsh-panel-mod). 
 - #jsapi IRC channel (https://wiki.mozilla.org/IRC): wouldn't make it through without them, love you guys! 
    Especially huge thanks to sfink and jonco, who spent literally tens of hours helping me! 
 - Respective authors (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/master/THIRD_PARTY_NOTICES.md) of the code being used in this project.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-01 11:15:34
Version: 1.0.0
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.0.0
Changelog (relative to the latest version of JScript Panel (https://github.com/marc2k3/foo_jscript_panel)):
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v100

Huge thanks to marc2003 (https://github.com/marc2k3) for porting samples and testing the component!
Title: Re: Spider Monkey Panel
Post by: seriousstas on 2018-10-02 21:24:31
Tried to see the cover:
foobar2000 \ user-components \ foo_spider_monkey_panel \ samples \ basic \ GetAlbumArtV2.txt

Code: [Select]
Error: Spider Monkey Panel v1.0.0 (GetAlbumArtV2 by T.P Wang)
g_img.Dispose is not a function

File: <main>
Line: 35, Column: 3

Stack trace:
   on_playback_new_track @ <main>: 35: 3
How to adapt this :
https://hydrogenaud.io/index.php/topic,110938.0.html
Library tree ?
Title: Re: Spider Monkey Panel
Post by: WilB on 2018-10-03 00:51:55
Library Tree is in the process of being ported.
Title: Re: Spider Monkey Panel
Post by: MordredKLB on 2018-10-03 05:01:20
@TheQwertiest , I can't tell you how excited I am for this! Really want to check it out, but I need to finish my themes 1.0 release before I have to redo everything again :)

You said it's fast, but have you done performance benchmarking? What kind of speed increase are you seeing when initializing 10k files in your playlist component?

I saw this bit in the API docs:
Quote
utils.CreateHtmlWindow() method.
This method allows the creation of HTML windows rendered by IE8 engine.
utils.CreateHtmlWindow(html_code, { width: window_w, height: window_h, title: window_title, data: callback_data, fn: callback_fn }).
If that's using ActiveX to create the window, you can bump it up to IE11 using the FEATURE_BROWSER_EMULATION (https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)) registry key. Not ideal for sharing themes, but probably possible nonetheless.
Title: Re: Spider Monkey Panel
Post by: Black_Over_Bills_Mothers on 2018-10-03 09:32:06
@TheQwertiest , This is great work, at last an engine that has the latest ECMA support. Now I can use string.startsWith and array.findIndex. Heaven knows what I can do with those async functions!

@WilB, You just knew someone would ask 'What about porting your wonderful Biography panel'.....
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-03 09:44:54
Tried to see the cover:
foobar2000 \ user-components \ foo_spider_monkey_panel \ samples \ basic \ GetAlbumArtV2.txt
Oops, forgot to nuke that `Dispose` call (will be fixed in v1.0.1).
For now you can just remove the following lines:
Code: [Select]
if (g_img)
    g_img.Dispose();

How to adapt this :
https://hydrogenaud.io/index.php/topic,110938.0.html
Library tree ?
See @WilB 's reply above: it's being ported =)

Library Tree is in the process of being ported.
Nice! Looking forward to ;)
Title: Re: Spider Monkey Panel
Post by: Black_Over_Bills_Mothers on 2018-10-03 09:56:39
@TheQwertiest

I think I've found a problem. The following line;
    fb.RunContextCommandWithMetadb("ReplayGain/Scan as albums (by folders)",plman.GetPlaylistSelectedItems(plman.ActivePlaylist));

gives this error;
'RunContextCommandWithMetadb' failed:
handle argument is invalid
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-03 09:59:12
You said it's fast, but have you done performance benchmarking? What kind of speed increase are you seeing when initializing 10k files in your playlist component?
I was too lazy to perform any proper benchmarking. AFAIK most(?) operations are faster by at least an order of magnitude. There is one regression I've encountered though (https://bugzilla.mozilla.org/show_bug.cgi?id=1474914), so `Playlist` performance might be further increased by rewriting initialization without `reverse`.

you can bump it up to IE11 using the FEATURE_BROWSER_EMULATION (https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/general-info/ee330730(v=vs.85)) registry key. Not ideal for sharing themes, but probably possible nonetheless.
I'm in progress of total rewrite of `CreateHtmlWindow`, since current implementation has some nasty bugs (like fb2k lockup when user closes html window). As a side effect it should work properly with IE=edge and it will support loading htmls from file.

@TheQwertiest

I think I've found a problem. The following line;
    fb.RunContextCommandWithMetadb("ReplayGain/Scan as albums (by folders)",plman.GetPlaylistSelectedItems(plman.ActivePlaylist));

gives this error;
'RunContextCommandWithMetadb' failed:
handle argument is invalid
See https://github.com/TheQwertiest/foo_spider_monkey_panel/issues/19

Bug will be fixed in v1.0.1
Title: Re: Spider Monkey Panel
Post by: Black_Over_Bills_Mothers on 2018-10-03 10:19:35
@TheQwertiest re issue #19
I've tried 'Build: 21:06:31, Oct  2 2018' patch from github and still get the same problem
Title: Re: Spider Monkey Panel
Post by: WilB on 2018-10-03 10:26:28
@Black_Over_Bills_Mothers
Quote
You just knew someone would ask 'What about porting your wonderful Biography panel'.....

Yes, Biography, Library Tree & YouTube Track Manager are all in the process of being ported... Spider Monkey Panel is a really great advancement that will enable them to be used with the newer ECMA features. To implement these properly may take a little time, but hopefully they are not far away...
Title: Re: Spider Monkey Panel
Post by: loz on 2018-10-03 11:07:47
I'm just going to flat out make a request even before I RTFM...

Please, for the love of all that is, add an album rating method. Something similar to jsp_rating would be nice but I'm not that picky. That is the only feature left that I want in foobar and the one thing I miss about not using custom database. (Having custom notes in custom db was nice too but I can do that with a .txt)

And if not, because marc2003 wouldn't do it either when I asked, I'm still going to use this component because it looks great. Thanks for this.
Title: Re: Spider Monkey Panel
Post by: Black_Over_Bills_Mothers on 2018-10-03 12:16:03
Can we please have a better development environment. Links to an external editor such as Notepad++ or at least add text search and brace matching. I know you can export and import script but it's a pain.
Title: Re: Spider Monkey Panel
Post by: fbuser on 2018-10-03 14:53:11
Can we please have a better development environment. Links to an external editor such as Notepad++ or at least add text search and brace matching.
I'd consider this as a waste of time to implement such functionality. Just place one line like include('path/to/script.js') in the panel code area and do the code editing of this script with an editor of your choice.
Title: Re: Spider Monkey Panel
Post by: Black_Over_Bills_Mothers on 2018-10-03 15:10:25
Can we please have a better development environment. Links to an external editor such as Notepad++ or at least add text search and brace matching.
I'd consider this as a waste of time to implement such functionality. Just place one line like include('path/to/script.js') in the panel code area and do the code editing of this script with an editor of your choice.
Seems interesting but could you explain a little further please.
Title: Re: Spider Monkey Panel
Post by: Sergey77 on 2018-10-03 17:12:35
@Black_Over_Bills_Mothers
Quote
You just knew someone would ask 'What about porting your wonderful Biography panel'.....

Yes, Biography, Library Tree & YouTube Track Manager are all in the process of being ported... Spider Monkey Panel is a really great advancement that will enable them to be used with the newer ECMA features. To implement these properly may take a little time, but hopefully they are not far away...
@WilB, great news!
looking forward to new versions of your cool scripts! (Don't forget JScript's version :) )
And I want to test Spider Monkey Panel
@TheQwertiest, thanks a lot for your great work!
Wish you creative success in the development of this project!
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-03 20:42:39
I've tried 'Build: 21:06:31, Oct  2 2018' patch from github and still get the same problem
That's weird, I'll recheck later.

Wish you creative success in the development of this project!
Haha, thanks!

Please, for the love of all that is, add an album rating method. Something similar to jsp_rating would be nice but I'm not that picky.
Not sure what you mean. Do you want another custom metadb field? Like `smp_album_rating`?
PS: Both JSP and SMP provide a way to edit tags via `UpdateFileInfoFromJSON`.

Seems interesting but could you explain a little further please.
See `docs/js_doc/Interfaces.js` and samples. This method works like `eval`, but accepts path to file and provides better error-reporting.

On another note: JSP and SMP `Configure` window uses the same editor engine as Notepad++ =)
Title: Re: Spider Monkey Panel
Post by: MordredKLB on 2018-10-03 22:19:37
On another note: JSP and SMP `Configure` window uses the same editor engine as Notepad++ =)
Maybe he wants Atom :)
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-04 00:10:53
Maybe he wants Atom :)
Well, to be fair, only internal editor engines are the same, the engine wrappers are different, thus the different experience in Notepad++ compared to `Configure` window in JSP/SMP =)
Title: Re: Spider Monkey Panel
Post by: loz on 2018-10-04 01:04:24
Please, for the love of all that is, add an album rating method. Something similar to jsp_rating would be nice but I'm not that picky.
Not sure what you mean. Do you want another custom metadb field? Like `smp_album_rating`?
PS: Both JSP and SMP provide a way to edit tags via `UpdateFileInfoFromJSON`.
custom metadb field? Like `smp_album_rating`
^ That exactly.  I don't want to be changing the actual tags in the files. I realize I could do this in m-TAGS but that just creates other issues for me personally atm. Custom database was also really good for such things but it just got to the point it crashed so often it was unusable.
Again, Thanks for this component. It looks great.
Title: Re: Spider Monkey Panel
Post by: mjm716 on 2018-10-04 02:59:47
Maybe he wants Atom :)
Well, to be fair, only internal editor engines are the same, the engine wrappers are different, thus the different experience in Notepad++ compared to `Configure` window in JSP/SMP =)

"wordwrap" option would be nice! ;)

great job by the way!
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-04 09:49:13
^ That exactly.  I don't want to be changing the actual tags in the files. I realize I could do this in m-TAGS but that just creates other issues for me personally atm. Custom database was also really good for such things but it just got to the point it crashed so often it was unusable.
Hm... Don't really want to add random tags. I'd rather make a generic method to add custom tags (well, if it's possible), smth like
Code: [Select]
utils.CreateCustomTag('smp_new_tag', 'number') ); // CreateCustomTag(tag_name, tag_type);
...
metadb.SetCustomTag('smp_new_tag', 'this is my tag value'); // SetCustomTag(tag_name, tag_value);

"wordwrap" option would be nice! ;)
Do you mean `linewrap` (when line is too big, part of it will move to the next line)?
If you do, then I can add in v1.0.1.
Title: Re: Spider Monkey Panel
Post by: loz on 2018-10-04 10:29:35
^ That exactly.  I don't want to be changing the actual tags in the files. I realize I could do this in m-TAGS but that just creates other issues for me personally atm. Custom database was also really good for such things but it just got to the point it crashed so often it was unusable.
Hm... Don't really want to add random tags. I'd rather make a generic method to add custom tags (well, if it's possible), smth like
Code: [Select]
utils.CreateCustomTag('smp_new_tag', 'number') ); // CreateCustomTag(tag_name, tag_type);
...
metadb.SetCustomTag('smp_new_tag', 'this is my tag value'); // SetCustomTag(tag_name, tag_value);
That would be fine. Great even. I could actually do more with that.
Title: Re: Spider Monkey Panel
Post by: mjm716 on 2018-10-04 11:08:00
Do you mean `linewrap` (when line is too big, part of it will move to the next line)?
If you do, then I can add in v1.0.1.

Notepad++ actually calls it wordwrap - but yes, linewrap option would be great!
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-04 17:25:12
That would be fine. Great even. I could actually do more with that.
It seems that this is impossible... From fb2k SDK:
Quote
List of fields that you provide is expected to be fixed at run-time. The backend will enumerate your fields only once and refer to them by indexes later.
I.e. all fields must be defined when component loads and can't be added afterwards.
Another way might be to configure custom tags from the component's preferences page, but that would be possible only if component configuration is loaded before fields enumeration (which I doubt is the case).
Title: Re: Spider Monkey Panel
Post by: MordredKLB on 2018-10-04 20:41:39
You could add a customProperties field to the metadb and then expose some methods to store and read arbitrary JSON from it. It's kind of ugly and hacky, but since you're abstracting it away from the end-user it'd hide the ugly implementation details and be pretty seamless.

To be clear, I'm not really advocating this approach, but it's doable.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-05 11:48:23
Version: 1.0.1
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.0.1
Changelog
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v101
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-05 12:29:49
Version: 1.0.2
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.0.2
Changelog
Hotfix for v1.0.1 (see changelog above (https://hydrogenaud.io/index.php/topic,116669.msg963027.html#msg963027))
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-05 13:32:09
You said it's fast, but have you done performance benchmarking? What kind of speed increase are you seeing when initializing 10k files in your playlist component?
I've benchmarked playlist script a bit:
Playlist initialization speed is mostly the same. Profiling showed that bad performance of `Array.reverse()` is the main culprit. So it should greatly improve once I remove it.

But!!! I've noticed that CPU usage is halved during playlist scrolling!
- Normal scrolling: ~3.5% SMP vs ~7.5% JSP.
- Erratic scrolling in huge playlist: ~5% SMP vs ~10% JSP.

Another thing that I've noticed is that erratic scrolling in JSP has small hitches, while SMP does not suffer from it. Most likely caused by differences in GC management policy - JScript immediately destroys any resources that are no longer used, no matter how long it takes, while SpiderMonkey has a `budget` - it can spend only as much time in GC as allowed by budget.

Measured same performance increase during scrolling in @WilB 's Library Tree as well.

PS: I have a 6-core CPU and SMP/JSP are single-threaded, so to get a clearer picture results should be multiplied by six. Thus ~21% SMP vs ~45% JSP in normal scrolling and 30% SMP vs 60% JSP in erratic.
Title: Re: Spider Monkey Panel
Post by: Sergey77 on 2018-10-05 17:50:36
I noticed same interrupt of Shpeck visualization for both panels jsplaylist-mod script in JSP and SMP.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-06 12:57:54
I noticed same interrupt of Shpeck visualization for both panels jsplaylist-mod script in JSP and SMP.
What do you mean? Shpeck visualization is a separate component/panel and is not a part of SMP nor jsplaylist-mod :\
Title: Re: Spider Monkey Panel
Post by: Sergey77 on 2018-10-06 14:09:15
I noticed same interrupt of Shpeck visualization for both panels jsplaylist-mod script in JSP and SMP.
What do you mean? Shpeck visualization is a separate component/panel and is not a part of SMP nor jsplaylist-mod :\
Yes, but I mean these separate components (Shpeck and jsplaylist-mod) work at the same time in diferent CUI panels.
When together displaying the panel with Shpek and another panel with jsplaylist-mod, the visualization is displaying with jerks during a file playback.
This behavior of visualization when running jsplaylist-mod as in JSP or as in SMP is the same.
But when activated CUI Playlist view panel (jsplaylist-mod panel is not active), Shpeck visualization is displayed smoothly, without jerks.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-06 16:22:17
When together displaying the panel with Shpek and another panel with jsplaylist-mod, the visualization is displaying with jerks during a file playback.
Can't reproduce: Shpeck visualization(with MilkDrop2) is smooth with both stock CUI playlist and `jsplaylist-mod` script.
Possible cause of hitches you are experiencing: Shpeck is pretty CPU intensive, so, if your CPU is practically used up by Shpeck, then any additional CPU load might cause stuttering.

PS: I've tested `jsplaylist-mod` script a bit, and it does not seem to cause any meaningful CPU load during casual usage. And CPU load is close to nil when idle (i.e. when there is no interaction with playlist panel).
Title: Re: Spider Monkey Panel
Post by: Sergey77 on 2018-10-06 17:19:53
Did you test synchronous work the panels (Shpeck and jsplaylist-mod) during music playback? (triangle cursor of jsplaylist-mod should flashing)
Shpeck (with MilkDrop2) stuttering synchronous with flashing cursor. Shpeck works stable without playback.
Maybe it really depends on my hardware speed. Let's see maybe someone else will report of similar problem.
In any case, thanks for your time!
Title: Re: Spider Monkey Panel
Post by: Black_Over_Bills_Mothers on 2018-10-08 13:52:43
I have a script to automate the addition of new tracks/albums into my collection. This script calls fb.RunContextCommandWithMetadb function to remove all embedded images and then to Optimize and reduce file sizes - both core functionality. These two operations need to be performed sequentially. This has caused me two problems;
1) Firstly the call to fb.RunContextCommandWithMetadb does not block with means that the only way I can detect completeness is to catch the callback - okay but it would be better if the call could block - maybe optionally.
2) Both calls generate a popup window asking the user to click either close or OK button. Can this request be circumvented in some way?
Title: Re: Spider Monkey Panel
Post by: MordredKLB on 2018-10-09 17:36:09
Those are both built in functionality of foobar. There's nothing Spidermonkey or JScript can do to control those operations once it tells foobar to start them.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-11 10:17:01
Version: 1.0.3
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.0.3
Changelog
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v103

Note: v1.0.0 API changelog was missing description of on_notify_data callback behaviour change. It is rectified now: see wiki (https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v100) or callbacks doc (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/master/component/docs/Callbacks.js).
Title: Re: Spider Monkey Panel
Post by: Decalicatan_Decalicatan on 2018-10-12 12:31:39
@TheQwertiest , thanks for the component

It seems there is an issue with the on_main_menu() function. As soon as I try to trigger one of the menu items, foobar2000 crashes :-(.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-12 14:26:03
@TheQwertiest , thanks for the component

It seems there is an issue with the on_main_menu() function. As soon as I try to trigger one of the menu items, foobar2000 crashes :-(.
Thanks for the report!
I'll look into it (#25 (https://github.com/TheQwertiest/foo_spider_monkey_panel/issues/25)).
Title: Re: Spider Monkey Panel
Post by: Decalicatan_Decalicatan on 2018-10-14 21:56:21
@TheQwertiest you're welcome ^^.

I think I may have found another bug  O:) : using Columns UI and the "MainMenuManager All-In-One", as soon as I try to change to another layout --> instant crash...

Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-15 10:35:29
@TheQwertiest you're welcome ^^.

I think I may have found another bug  O:) : using Columns UI and the "MainMenuManager All-In-One", as soon as I try to change to another layout --> instant crash...
Could not reproduce the bug (on the latest build at least). Can you try the latest build (https://ci.appveyor.com/api/projects/theqwertiest/foo-spider-monkey-panel/artifacts/_result%2FWin32_Release%2Ffoo_spider_monkey_panel.fb2k-component?branch=master&job=Configuration%3A%20Release)?
Title: Re: Spider Monkey Panel
Post by: Decalicatan_Decalicatan on 2018-10-15 17:26:24
My bad, I tried with a new portable installation and is fine. I think I may have messed up one of the js files in the "docs".

Anyway, on_main_menu() works fine now. Thanks!
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-15 21:36:33
My bad, I tried with a new portable installation and is fine. I think I may have messed up one of the js files in the "docs".

Bug reproduced: see #29 (https://github.com/TheQwertiest/foo_spider_monkey_panel/issues/29)
Title: Re: Spider Monkey Panel
Post by: loz on 2018-10-20 18:18:33
I have the following code in ratings.txt to set ratings using keyboard shortcuts:
Code: [Select]
// RATING HOTKEYS
function on_main_menu(index) {
switch (index) {
case 1: // set rating File>Spider Monkey Panel>1 is run
panel.metadb.SetRating(panel.tf('$if2(%smp_rating%,0)') == 1 ? 0 : 1);
panel.metadb.RefreshStats();
break;
}
 }

This, and every variation I have tried crashes foobar instantly. Now I'm assuming it's either something with my configuration or my code since I pretty much modified what I had in js_panel, but just in case it's something with spider monkey I thought I'd the thread aware this is happening. (Crash reports and full code attached if needed). Thanks.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-20 22:17:13
I have the following code in ratings.txt to set ratings using keyboard shortcuts:
Code: [Select]
// RATING HOTKEYS
function on_main_menu(index) {
switch (index) {
case 1: // set rating File>Spider Monkey Panel>1 is run
panel.metadb.SetRating(panel.tf('$if2(%smp_rating%,0)') == 1 ? 0 : 1);
panel.metadb.RefreshStats();
break;
}
 }

This, and every variation I have tried crashes foobar instantly. Now I'm assuming it's either something with my configuration or my code since I pretty much modified what I had in js_panel, but just in case it's something with spider monkey I thought I'd the thread aware this is happening. (Crash reports and full code attached if needed). Thanks.
Thanks for the report!
This is a known bug, which will be fixed in v1.0.4, which is expected to be released before the end of the next week.

PS: You can use the `nightly build` from the link in the OP for the time being. It should be noted though, that `nightly build` might be less stable than the `release build` and might have API incompatibilities, which are not documented. So it should be used only if you want to help me by testing it (thus making `release-build` more stable), or if you want to get your bug-fixes as soon as possible by accepting the risk of potential instability.
Title: Re: Spider Monkey Panel
Post by: loz on 2018-10-20 22:53:58
Ok great. Just making sure. I'll wait a few days for the stable as this is a minor issue for me and everything else seems to be working nicely.
Title: Re: Spider Monkey Panel
Post by: TheQwertiest on 2018-10-24 21:40:47
Version: 1.0.4
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.0.4
Changelog
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v104

Note: reset SMP advanced settings for better performance - Preferences>Advanced>Tools>Right-Click on Spider Monkey Panel>Reset Branch.

Huge thanks to @WilB for all the bug reports!
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: loz on 2018-10-25 10:50:11
Fixed
  • Fixed crash when `on_main_menu` callback was invoked.
Can confirm my issues with this have been fixed. Thanks.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: embe on 2018-10-25 14:19:51
I'm having problem with displaying buttons with 'track info + seekbar + buttons' config. All I get are these rectangles. Do I need some special font installed for it?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2018-10-25 22:43:08
I'm having problem with displaying buttons with 'track info + seekbar + buttons' config. All I get are these rectangles. Do I need some special font installed for it?
That's because nobody reads `Readme` nowadays...

Quote from: samples/readme.md
- "complete" scripts: 
         Should work fine on any system.
         Most scripts require the installation of FontAwesome (https://github.com/FortAwesome/Font-Awesome/blob/fa-4/fonts/fontawesome-webfont.ttf?raw=true)."
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2018-11-05 21:04:14
Version: 1.0.5
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.0.5
Changelog:
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v105
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2018-11-19 19:08:10
Version: 1.1.0
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.1.0
Changelog:
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v110
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2018-11-20 11:49:00
Version: 1.1.1
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.1.1
Changelog
Hotfix for v1.1.0 (see changelog above (https://hydrogenaud.io/index.php/topic,116669.msg965016.html#msg965016))
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AlexR on 2018-11-28 07:48:36
Do not work callback on_colours_changed()
version 1.1.1, foobar 1.4.1
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AlexR on 2018-11-28 11:29:39
Do not work callback on_colours_changed()
version 1.1.1, foobar 1.4.1, DUI
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2018-11-29 16:15:24
Do not work callback on_colours_changed()
version 1.1.1, foobar 1.4.1, DUI
Yep, that's a bug, will be fixed in the next version =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-09 11:01:17
Version: 1.1.2
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.1.2
Changelog:
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v112
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: SUPERCOOLMAN on 2019-01-13 01:33:37
trying to re-create an ancient foo_uie_albumart behaviour where pictures/arts in all user specified sub-directories of currently playing track are collected when track playback starts, then runs slideshow cycling through all the art every X second as specified by user

the component can load jpg, pg, bmp...etc. but not webp or other newer formats. I was wondering if it's possible for SMP to handle webp. maybe through some codec installed on the system?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-16 14:17:19
I was wondering if it's possible for SMP to handle webp. maybe through some codec installed on the system?
TLDR: SMP does not have functionality to load images that are not supported by fb2k.

Full answer:
SMP uses foobar2000 API to load album art and `Gdiplus::Bitmap` (https://docs.microsoft.com/en-us/windows/desktop/api/gdiplusheaders/nf-gdiplusheaders-bitmap-bitmap(inconstwchar_inbool)) to load external images. AFAIK neither fb2k nor GDI+ have the ability to work with webp files.
It's probably possible to write a fb2k component that can load webp files as images though (and maybe even work as album art source for fb2k).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-17 10:53:43
Version: 1.1.3
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.1.3
Changelog:
Spoiler (click to show/hide)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Decalicatan_Decalicatan on 2019-01-19 18:21:25
I don't know if the issue is with the latest version (1.1.3) or if it was already there before, but I can't update ratings (foo_playcount) anymore with fb.RunContextCommandWithMetadb. For example with the rating.txt script. It does simple nothings :(

Thanks in advance. And ty for all the work you have already done with the component!
Regards
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: hlhp on 2019-01-20 10:47:39
I am new to Spider Monkey Panel and J script panel.
I want to embed play back statistic information into the file.

Is there a function to edit metadata? (I only found retrieve info from metadata)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Rhand on 2019-01-20 11:28:36
This command doesn't work anymore with new spider panel.
buttons.buttons.albumart = new _button(bs * 6.8, 0, bs, bs, {normal : "Albumart.png", hover: "Albumart_h.png"}, function () { fb.RunContextCommand("Run service/AlbumArt"); },"AlbumArt"); Hope you can solve this
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-20 15:11:12
Version: 1.1.4
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.1.4
Changelog
Hotfix for v1.1.3 (see changelog above (https://hydrogenaud.io/index.php/topic,116669.msg967258.html#msg967258))
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-20 15:12:44
@Decalicatan_Decalicatan @Rhand : the issue should be fixed in v1.1.4. Thanks for the bug report!
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-20 15:19:26
I am new to Spider Monkey Panel and J script panel.
I want to embed play back statistic information into the file.

Is there a function to edit metadata? (I only found retrieve info from metadata)
Depends on what you mean: you can't edit some most stats provided by `foo_playcount` (e.g. %play_count%), but you can write additional custom tags with `FbMetadbHandleList.UpdateFileInfoFromJSON()` (you can read more about the method and it's usage in the documentation included with component: `Configure Panel` dialog > menu > Help > View Help).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Decalicatan_Decalicatan on 2019-01-20 16:25:18
@Decalicatan_Decalicatan @Rhand : the issue should be fixed in v1.1.4. Thanks for the bug report!

ty!
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: hlhp on 2019-01-21 02:36:39
Depends on what you mean: you can't edit some most stats provided by `foo_playcount` (e.g. %play_count%), but you can write additional custom tags with `FbMetadbHandleList.UpdateFileInfoFromJSON()` (you can read more about the method and it's usage in the documentation included with component: `Configure Panel` dialog > menu > Help > View Help).
Thank you, adding custom tags is the only thing I want.   ;)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-21 14:43:01
Version: 1.1.5
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.1.5
Changelog
Hotfix II for v1.1.3 (see changelog above (https://hydrogenaud.io/index.php/topic,116669.msg967258.html#msg967258))
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: hlhp on 2019-01-23 03:10:19
I want to find meta value(first value) by name.

According to the documentation.
I need to...
1. Check if there are matched name in the meta. if yes, go to step 2.
2. Find out how many meta in it.
3. Loop through the meta(s) to find the idx numbers for the name
4. Use the idx to get the Value out.

Is there any better way to doing this?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-01-23 09:06:46
I want to find meta value(first value) by name.

According to the documentation.
I need to...
1. Check if there are matched name in the meta. if yes, go to step 2.
2. Find out how many meta in it.
3. Loop through the meta(s) to find the idx numbers for the name
4. Use the idx to get the Value out.

Is there any better way to doing this?

There is also a MetaFind method, which returns the index of the meta field (or -1 if not found) =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: hlhp on 2019-01-24 14:58:14
There is also a MetaFind method, which returns the index of the meta field (or -1 if not found) =)

Thank you it works.
I thought it only return like Boolean, I should read the documentation more carefully.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-06 16:53:34
First of all, a big thank you to @TheQwertiest for this component. I've been away from the forum for sometime and this is really a great surprise. It's good to have a jscript component back with official support and with the developer active in the forum. I'm following the migration instructions from JScript panel 2 and so far no problem. The only issue I found which was not mentioned in the official docs, nor in the forum, is that I can no more include both JScommon and Helpers in the preprocessor because some constants and variables are declared on both scripts.
I solved the problem by copying the few functions I actually needed, from JScommon to a new script, which replaced JScommon in the preprocessors where Helpers is also included. I like it better this way, it is definitely cleaner, but I just wanted to make sure that it is an intended behavior and I did not mess anything up.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-07 13:20:50
First of all, a big thank you to @TheQwertiest for this component.
You are very welcome :)

The only issue I found which was not mentioned in the official docs, nor in the forum, is that I can no more include both JScommon and Helpers in the preprocessor because some constants and variables are declared on both scripts.
Well, it was probably intended that way (that is for Br3tt's scripts to be self-sufficient).
I wouldn't know anyway, since I've never actually delved into them - it's only thanks to marc2003 that Br3tt's scripts were even included in SMP =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: anamorphic on 2019-02-08 05:00:59
I too, would like to heap many thanks upon TheQwertiest one for this component. I do believe it will be quite fun once I figure out how to write scripts. ;)

For now though I just have a minor, issue / question / request. (An issquesest?) If one (me) did not want to see the SMP Playback Statistics in track properties, how could one (I) turn display of them off? Might it please be possible? (We looked for options)

The thing is with 'Selection Properties' (DUI) element, all stats are lumped / jumbled together under 'Other' along with official Playback Statistics (foo_playcount) component. So I guess that is limitation of the element. However the original PS 'Rating' (displayed as stars) is gone altogether, replaced by SMP 'Rating' (with no stars, because not using it) - not very complementary. I'd prefer to see my original ratings.

Not sure what / if you can do anything about this, but mentioning just in case.

(Of course, one could design a far superior 'Selection Properties' element with this very fine component. :D Even so... Edit: and I just found the 'properties.txt' sample after posting, typical!)

Cheers
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-08 10:54:29
I just noticed the stats show up twice in the properties tab. I still have JScript panel installed of course. It's not a problem, I just wonder why this happens:

Spoiler (click to show/hide)

Now, in the picture above you will also notice the custom database tags. I don't know how SMP statistics work, but if the values are pinned to primary tags or a combination of primary tags, like the official playback statistics component does, than this is potentially a custom database replacement. I've seen a previous request by @loz for custom tags, but I did not understand if they're planned to be implemented. Anyway I definitely second that request.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-08 21:02:31
Eventually I ran into a problem. I use some text files to share layout settings between jscript panels and panel stack splitter. I have a script which deletes a specific file when triggered, using the FileSystemObject DeleteFile method. It's a very simple script and it always worked with JScript Panel, but since migrating to Spider Monkey Panel the delete action is denied because the file is in use by foobar2000. I cannot even delete the file manually.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-09 12:19:02
For now though I just have a minor, issue / question / request. (An issquesest?) If one (me) did not want to see the SMP Playback Statistics in track properties, how could one (I) turn display of them off? Might it please be possible? (We looked for options)

The thing is with 'Selection Properties' (DUI) element, all stats are lumped / jumbled together under 'Other' along with official Playback Statistics (foo_playcount) component. So I guess that is limitation of the element. However the original PS 'Rating' (displayed as stars) is gone altogether, replaced by SMP 'Rating' (with no stars, because not using it) - not very complementary. I'd prefer to see my original ratings.
Not sure if I can do anything about it (apart from renaming the metatag, which I won't do :P).
@Peter : could you help us out, please? Is there a way to hide and/or reorder the priority of the metadata provided by components?

I just noticed the stats show up twice in the properties tab. I still have JScript panel installed of course. It's not a problem, I just wonder why this happens:
That is the intended behaviour: SMP and JSP use different (internal) tags to avoid potential compatibility issues.

I've seen a previous request by @loz for custom tags, but I did not understand if they're planned to be implemented. Anyway I definitely second that request.
This is something I'm planning to look into (that is the ability to add customs tags via SMP API), but it's rather low on my priority list.

Eventually I ran into a problem. I use some text files to share layout settings between jscript panels and panel stack splitter. I have a script which deletes a specific file when triggered, using the FileSystemObject DeleteFile method. It's a very simple script and it always worked with JScript Panel, but since migrating to Spider Monkey Panel the delete action is denied because the file is in use by foobar2000. I cannot even delete the file manually.
Could you provide the script (or it's relevant parts)?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-09 15:46:45
Eventually I ran into a problem. I use some text files to share layout settings between jscript panels and panel stack splitter. I have a script which deletes a specific file when triggered, using the FileSystemObject DeleteFile method. It's a very simple script and it always worked with JScript Panel, but since migrating to Spider Monkey Panel the delete action is denied because the file is in use by foobar2000. I cannot even delete the file manually.
Could you provide the script (or it's relevant parts)?

Sure, as I said it's a pretty simple one. The panel is resized via PSS (panel stack splitter) and this triggers either a delete or a create file action.
Code: [Select]
function on_size(){
    switch (window.Height){
        case 0:
        if (fso.FileExists(SettingsPath + "PlaylistVisible")) fso.DeleteFile(SettingsPath + "PlaylistVisible");
        RefreshPSS();
        break;
        case 1:
        if (!fso.FileExists(SettingsPath + "PlaylistVisible")) fso.CreateTextFile(SettingsPath + "PlaylistVisible");
        RefreshPSS();
        break;  
        case 2:
        if (fso.FileExists(SettingsPath + "PlaylistVisible")) fso.DeleteFile(SettingsPath + "PlaylistVisible");
        RefreshPSS();
        break;
    }

Here's also the relevant code from another script, included in the preprocessor:
Code: [Select]
var fso = new ActiveXObject("Scripting.FileSystemObject"); 
var SettingsPath = fb.ProfilePath + "settings\\";

function RefreshPSS() {
var Refresh_sys = window.GetProperty("Refresh_sys",true);
 if (Refresh_sys < true) {
if (fb.IsPlaying || fb.IsPaused) { 
fb.RunMainMenuCommand("View/Show status bar");
fb.RunMainMenuCommand("View/Show status bar");
} else {
fb.RunMainMenuCommand("View/Show status bar");
fb.RunMainMenuCommand("View/Show status bar");
}
} else {
if (fb.IsPlaying || fb.IsPaused) { 
fb.RunMainMenuCommand("Playback/Play or Pause");
fb.RunMainMenuCommand("Playback/Play or Pause");
} else {
fb.RunMainMenuCommand("Playback/Play");
fb.RunMainMenuCommand("Playback/Stop");
}
}
}

The script seems to work for a few times right after foobar2000 start up, but eventually something happens which blocks the file, and I can't figure out what it could even be.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-09 16:24:28
I just noticed the stats show up twice in the properties tab. I still have JScript panel installed of course. It's not a problem, I just wonder why this happens:
That is the intended behaviour: SMP and JSP use different (internal) tags to avoid potential compatibility issues.

I see, I never noticed before that JScript panel had its own! I though it was reading Spider Monkey Panel statistics.  :))
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-09 18:15:50
The script seems to work for a few times right after foobar2000 start up, but eventually something happens which blocks the file, and I can't figure out what it could even be.

TLDR: Use the following code fso.CreateTextFile(path).Close(); or let file = fso.CreateTextFile(path); file.Close();

Full story: the problem is caused by your usage of fso.CreateTextFile: CreateTextFile returns a file object, which contains an open handle to the file, which will be closed only in two cases - when object is destroyed and when it's closed manually. The lifetime of JS objects is variable, i.e. objects might not be immediately destroyed when there are no references to them, so in your case: object is alive & not closed > handle remains open > file remains locked.

PS: Plz, don't over-quote =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-09 20:32:18
TLDR: Use the following code fso.CreateTextFile(path).Close(); or let file = fso.CreateTextFile(path); file.Close();

Full story: the problem is caused by your usage of fso.CreateTextFile: CreateTextFile returns a file object, which contains an open handle to the file, which will be closed only in two cases - when object is destroyed and when it's closed manually. The lifetime of JS objects is variable, i.e. objects might not be immediately destroyed when there are no references to them, so in your case: object is alive & not closed > handle remains open > file remains locked.

Thanks, that was it. So, the real question is: why did it work with JScript panel?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-09 21:11:12
Thanks, that was it. So, the real question is: why did it work with JScript panel?
Because GC behaves differently in JScript and SMP (Microsoft's jscript is quite outdated in that way).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: WebSkater on 2019-02-12 13:59:01
Hi,
after installing Spider Monkey Panel in perfect working fb2k v1.3.20 on W7 x64 - and not making any use of it, i only installed it - I can't write rating tags to foo_playcount's database anymore. Modifying already existing rating tags stored in the database isn't possible either. Writing rating tags direct to files is still working. After uninstalling Spider Monkey Panel everything is working as before and writing and modifying rating tags in files or in the database is possible again without any issue !

Seems Spider Monkey Panel and the official Playback Statistics (foo_playcount) can't work together without making trouble.

Any ideas or suggestion?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-12 14:34:41
Replied on GitHub.

PS: please, do not duplicate bug reports in the future - posting it in one place (here or on GitHub) is good enough =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: WebSkater on 2019-02-12 17:28:08
Hi TheQwertiest,
sorry for duplicate posting, but I'm not very experienced in posting + "forum behaviour". Till now reading alone helped me over the years to solve my problems with foobar.

"Replied on GitHub"
means you noticed my post and are aware of the problem, but not that you have answered to it, right ? Stupid question, I know, but after "closing Github post by accident" and reopening and not seeing an answer after that in Github I'm really unsecure about this. Or I'm making something wrong again?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: michtar on 2019-02-13 13:01:46
I'm not sure if it's a system specific, user  :-[ , script or Spider Monkey Panel problem but:
- mouse-on and double click functions of "album art" sample stopped working. They used to work with SMP and work fine with JScript Panel.

- tested on clean portable install, Foobar 1.4.2, default components + Spider Monkey Panel 1.1.5, default path, Windows 7
- as far as I noticed script did not change
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-13 13:30:35
I'm not sure if it's a system specific, user  :-[ , script or Spider Monkey Panel problem but:
- mouse-on and double click functions of "album art" sample stopped working. They used to work with SMP and work fine with JScript Panel.

Thanks for the bug report! Will be fixed in the next version (kudos to marc2003).
In the mean time you can apply the fix manually - https://github.com/marc2k3/smp_2003/commit/c12b44f25fb5b810a7c92366e324191a2a0ce5bf
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: michtar on 2019-02-14 09:47:34
In the mean time you can apply the fix manually - https://github.com/marc2k3/smp_2003/commit/c12b44f25fb5b810a7c92366e324191a2a0ce5bf
Works (obviously). Thanks marc2003/TheQwertiest.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: dwmartin0906 on 2019-02-14 12:37:22
I was wondering if anyone else was having this problem with the SMP thumbs panel.  It works fine except when displaying the thumbs in a grid.  They display fine initially, but when clicking on a specific thumb to display it I get the following error.  Any ideas?

Error: Spider Monkey Panel v1.1.5 (Thumbs by marc2003)
_.drawOverlay is not a function

File: thumbs.js
Line: 100, Column: 5

Stack trace:
  _thumbs/this.paint@thumbs.js:100:5
  on_paint@<main>:58:2
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-15 09:09:00
I was wondering if anyone else was having this problem with the SMP thumbs panel.  It works fine except when displaying the thumbs in a grid.  They display fine initially, but when clicking on a specific thumb to display it I get the following error.  Any ideas?

Error: Spider Monkey Panel v1.1.5 (Thumbs by marc2003)
_.drawOverlay is not a function

File: thumbs.js
Line: 100, Column: 5

Stack trace:
  _thumbs/this.paint@thumbs.js:100:5
  on_paint@<main>:58:2
Yup, that's a bug =) Will be fixed in the next version (again kudos to marc2003).
In the mean time you can apply the fix manually - https://github.com/marc2k3/smp_2003/commit/a0e578ec06211b1d4b01f529962142bf50a75da5
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: dwmartin0906 on 2019-02-15 10:19:33
Thank you both very much.  That fixed it.  Amazing what one little period can do, isn't it?  I was a COBOL programmer for over 35 years so I understand how much damage one little typo can do.  At least you don't have to deal with hard copies, punch cards and 4 hour compile times like I had to in the beginning.  Debugging was a total nightmare.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-15 10:37:46
Yeah, script languages are quite convenient in that way (actually one of the reasons why WSH/JSP/SMP were developed in the first place).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-02-15 18:27:11
Hello!
Anybody knows if somebody already did a JS better than the default Album List DUI component?
The default Album List is "too slow" for me and many time starves.
I just need something providing a consolidated by folder structure view (as does Album List DUI) and some capability for searching the dBase by usual search patterns.
If I would be capable of programming in Java I would try myself, but I am not.
Thanks and regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: always.beta on 2019-02-16 00:31:56
Anybody knows if somebody already did a JS better than the default Album List DUI component?
https://hydrogenaud.io/index.php/topic,111060.0.html
Try it yourself
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-02-17 10:45:17
Hi Always.beta, many thanks!
Regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-22 13:31:35
From what I gather, the strict mode defined in the panel does not apply to the scripts processed with the include statement. Is this an intended behaviour?
BTW, is the strict mode kind of mandatory with SMP or is it just a scrpting suggestion by the developers? or is it merely the common practice with the latest ECMA versions?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: philodoxxx on 2019-02-22 16:46:28
 I have been experiencing an error on start up in Foobar related to the JS Smooth Browser sample script  in Spider Monkey Panel v1.1.5. See below:

Error: Spider Monkey Panel v1.1.5 (JS Smooth Browser by Br3tt aka Falstaff)
Resize failed:
Failed to create GdiPlus object (0x0: No error

File: jssb.js
Line: 3500, Column: 24

Stack trace:
  get_images@jssb.js:3500:24
  oBrowser/this.update@jssb.js:1526:3
  oBrowser/this.setSize@jssb.js:1548:3
  on_size@jssb.js:3120:3



If I reload the script it work's fine. The error only occurs at startup.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-23 23:41:55
So far I managed to upgrade all my scripts, but I still have a very old one by marc2003 that I can't get working on Spider Monkey Panel. The script is "Last.fm Album Art Downloader" with some little modifications I made over time and it still works perfectly on JScript Panel 2.1.4.

This is the script that works in JScript Panel:
Code: [Select]
// ==PREPROCESSOR==
// @name "Last.fm Album Art Downloader"
// @author "marc2003"
// @import "%fb2k_component_path%samples\complete\js\lodash.min.js"
// @import "%fb2k_component_path%samples\complete\js\helpers.js"
// @import "%fb2k_component_path%samples\complete\js\panel.js"
// ==/PREPROCESSOR==


var SettingsPath = fb.ProfilePath + "settings\\";
var library_tracks_only = false;
var folder_tf = fb.TitleFormat("$puts(folder,$trim($replace($lower($directory(%path%)),disc,,cd,)))$replace($directory_path(%path%),$ifequal($strstr($get(folder),$num($get(folder),$len($get(folder)))),1,\\%directoryname%,),)\\");
var filename_tf = fb.TitleFormat("front.jpg");

var panel = new _.panel("Last.fm Album Art Downloader", ["metadb", "custom_background"]);
var x = new ActiveXObject("Microsoft.XMLHTTP");
var ini = SettingsPath + "album-art.ini";
_.createFolder(SettingsPath);

panel.item_focus_change();

function on_metadb_changed() {
var np = fb.GetNowPlaying();
if (panel.metadb && np && np.Compare(panel.metadb) && np.RawPath.indexOf("file://") == 0 && (!library_tracks_only || fb.IsMetadbInMediaLibrary(np))) {
var ar = panel.tf("%album artist%");
var al = panel.tf("%album%");
var f = folder_tf.EvalWithMetadb(panel.metadb) + _.fbSanitise(filename_tf.EvalWithMetadb(panel.metadb));
var tmp = _.q(_.fbSanitise(ar + al));
var n = _.round(_.now() / 1000);
var t = utils.ReadINI(ini, "Timestamps", tmp, 0);

switch (true) {
case !_.tagged(ar):
case !_.tagged(al):
case _.isFile(f):
case n - t < ONE_DAY:
break;
default:
utils.WriteINI(ini, "Timestamps", tmp, n);
x.open("GET", "https://www.last.fm/music/" + encodeURIComponent(ar) + "/" + encodeURIComponent(al) + "/+images", true);
x.setRequestHeader("If-Modified-Since", "Thu, 01 Jan 1970 00:00:00 GMT");
x.send();
x.onreadystatechange = function () {
if (x.readyState == 4) {
if (x.status == 200) {
var o = _.first(_.filter(_.getElementsByTagName(x.responsetext, "img"), {"className" : "image-list-image"}));
if (o) {
var u = o.src.replace("avatar170s", "ar0");
_.runCmd("cscript //nologo " + _.q(fb.ProfilePath + "scripts\\JSP\\download.vbs") + " " + _.q(u) + " " + _.q(f), false);
window.SetTimeout(function () {
panel.item_focus_change();
}, 3000);
}
} else {
console.log("HTTP error: " + x.status);
}
}
}           
break;
}
}
RefreshPSS();
}

function RefreshPSS() {
var Refresh_sys = window.GetProperty("Refresh_sys",true);
 if (Refresh_sys < true) {
if (fb.IsPlaying || fb.IsPaused) { 
fb.RunMainMenuCommand("View/Show status bar");
fb.RunMainMenuCommand("View/Show status bar");
} else {
fb.RunMainMenuCommand("View/Show status bar");
fb.RunMainMenuCommand("View/Show status bar");
}
} else {
if (fb.IsPlaying || fb.IsPaused) { 
fb.RunMainMenuCommand("Playback/Play or Pause");
fb.RunMainMenuCommand("Playback/Play or Pause");
} else {
fb.RunMainMenuCommand("Playback/Play");
fb.RunMainMenuCommand("Playback/Stop");
}
}

}

...and this is my attempt to upgrade it for Spider Monkey Panel:
Code: [Select]
'use strict';

window.DefinePanel('Last.fm Album Art Downloader', {author:'marc2003'});
include(fb.ComponentPath + 'samples\\complete\\js\\lodash.min.js');
include(fb.ComponentPath + 'samples\\complete\\js\\helpers.js')
include(fb.ComponentPath + 'samples\\complete\\js\\panel.js');


var SettingsPath = fb.ProfilePath + "settings\\";
var library_tracks_only = false;
var folder_tf = fb.TitleFormat("$puts(folder,$trim($replace($lower($directory(%path%)),disc,,cd,)))$replace($directory_path(%path%),$ifequal($strstr($get(folder),$num($get(folder),$len($get(folder)))),1,\\%directoryname%,),)\\");
var filename_tf = fb.TitleFormat("front.jpg");

let panel = new _panel("Last.fm Album Art Downloader", ["metadb", "custom_background"]);
var x = new ActiveXObject("Microsoft.XMLHTTP");
var ini = SettingsPath + "album-art.ini";
_createFolder(SettingsPath);

panel.item_focus_change();

function on_metadb_changed() {
var np = fb.GetNowPlaying();
if (panel.metadb && np && np.Compare(panel.metadb) && np.RawPath.indexOf("file://") == 0 && (!library_tracks_only || fb.IsMetadbInMediaLibrary(np))) {
var ar = panel.tf("%album artist%");
var al = panel.tf("%album%");
var f = folder_tf.EvalWithMetadb(panel.metadb) + _fbSanitise(filename_tf.EvalWithMetadb(panel.metadb));
var tmp = _q(_fbSanitise(ar + al));
var n = _.round(_.now() / 1000);
var t = utils.ReadINI(ini, "Timestamps", tmp, 0);

switch (true) {
case !_tagged(ar):
case !_tagged(al):
case _isFile(f):
case n - t < ONE_DAY:
break;
default:
utils.WriteINI(ini, "Timestamps", tmp, n);
x.open("GET", "https://www.last.fm/music/" + encodeURIComponent(ar) + "/" + encodeURIComponent(al) + "/+images", true);
x.setRequestHeader("If-Modified-Since", "Thu, 01 Jan 1970 00:00:00 GMT");
x.send();
x.onreadystatechange = function () {
if (x.readyState == 4) {
if (x.status == 200) {
var o = _first(_filter(_getElementsByTagName(x.responsetext, "img"), {"className" : "image-list-image"}));
if (o) {
var u = o.src.replace("avatar170s", "ar0");
_runCmd("cscript //nologo " + _q(fb.ProfilePath + "scripts\\SMP\\download.vbs") + " " + _q(u) + " " + _q(f), false);
window.SetTimeout(function () {
panel.item_focus_change();
}, 3000);
}
} else {
console.log("HTTP error: " + x.status);
}
}
}
break;
}
}
RefreshPSS();
}

function RefreshPSS() {
var Refresh_sys = window.GetProperty("Refresh_sys",true);
 if (Refresh_sys < true) {
if (fb.IsPlaying || fb.IsPaused) { 
fb.RunMainMenuCommand("View/Show status bar");
fb.RunMainMenuCommand("View/Show status bar");
} else {
fb.RunMainMenuCommand("View/Show status bar");
fb.RunMainMenuCommand("View/Show status bar");
}
} else {
if (fb.IsPlaying || fb.IsPaused) { 
fb.RunMainMenuCommand("Playback/Play or Pause");
fb.RunMainMenuCommand("Playback/Play or Pause");
} else {
fb.RunMainMenuCommand("Playback/Play");
fb.RunMainMenuCommand("Playback/Stop");
}
}

}

Unfortunately it doesn't crash, therefore I have no idea where the problem is, but it does not download the album cover (doubled checked with the JScript panel version).
Any insight will be much appreciated.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: zeremy on 2019-02-24 15:31:12
@davideleo

Replace line 45 with

Code: [Select]
var o = _.first(_.filter(_getElementsByTagName(x.responseText, "img"), {"className" : "image-list-image"}));

_.first and _.filter are from lodash.js
_getElementsByTagName is from helpers.js

x.responseText is valid (not x.responsetext)



Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-24 17:14:42
_.first and _.filter are from lodash.js
_getElementsByTagName is from helpers.js

x.responseText is valid (not x.responsetext)

Thanks so much @zeremy! I was going mad. It works now!
Why wouldn't SMP report an error, though?





Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: zeremy on 2019-02-24 17:26:59
Why wouldn't SMP report an error, though?

It is a known bug.

https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/Known-bugs
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-02-26 18:06:40
From what I gather, the strict mode defined in the panel does not apply to the scripts processed with the include statement. Is this an intended behaviour?
Not sure, gonna test it out with other JS engines to see how they handle it.

BTW, is the strict mode kind of mandatory with SMP or is it just a scrpting suggestion by the developers? or is it merely the common practice with the latest ECMA versions?
`strict mode` is not mandatory by any means, but it helps avoiding mistakes in the code (via stricter error checking) and might also increase it's performance. So, yes, it is a recommended mode of operation. You can read more about it >>here<< (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode)

I have been experiencing an error on start up in Foobar related to the JS Smooth Browser sample script  in Spider Monkey Panel v1.1.5. See below:
Could you please try the Nightly build (see the link in the first post of this thread) and see if it produces a more intelligible error message?

PS: @zeremy thanks for all the answers in this thread =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-27 21:30:31
Thanks so much @zeremy! I was going mad. It works now!

Seems like I spoke too soon. The script stopped working once again, but I can't tell if I got mistaken when I tested it or if I inadvertently made some changes in foobar2000 that affect SMP's behavior. Whatever is, I fixed it, but I still can't understand why SMP and JSP behave differently.

Here's the script as I'm usinig it now. The patch is marked by a comment:
Code: [Select]
var SettingsPath = fb.ProfilePath + "settings\\";
var library_tracks_only = false;
var folder_tf = fb.TitleFormat("$puts(folder,$trim($replace($lower($directory(%path%)),disc,,cd,)))$replace($directory_path(%path%),$ifequal($strstr($get(folder),$num($get(folder),$len($get(folder)))),1,\\%directoryname%,),)\\");
var filename_tf = fb.TitleFormat("front.jpg");

var panel = new _panel("Last.fm Album Art Downloader", ["metadb", "custom_background"]);
var x = new ActiveXObject("Microsoft.XMLHTTP");
var ini = SettingsPath + "album-art.ini";
_createFolder(SettingsPath);

panel.item_focus_change();

function on_playback_new_track(){   //edit for Spider Monkey Panel
panel.item_focus_change();
}

function on_metadb_changed() {
var np = fb.GetNowPlaying();
console.log("SMP: metadb changed");
console.log("SMP: metadb_func = " + (typeof on_metadb_changed == 'function'));
console.log("SMP: if condition = " + (panel.metadb && np && np.Compare(panel.metadb) && np.RawPath.indexOf("file://") == 0 && (!library_tracks_only || fb.IsMetadbInMediaLibrary(np))));
if (panel.metadb && np && np.Compare(panel.metadb) && np.RawPath.indexOf("file://") == 0 && (!library_tracks_only || fb.IsMetadbInMediaLibrary(np))) {
var ar = panel.tf("$meta_sep(artist,', ',' and ')");
var al = panel.tf("%album%");
var f = folder_tf.EvalWithMetadb(panel.metadb) + _fbSanitise(filename_tf.EvalWithMetadb(panel.metadb));
var tmp = _q(_fbSanitise(ar + al));
var n = _.round(_.now() / 1000);
var t = utils.ReadINI(ini, "Timestamps", tmp, 0);

switch (true) {
case !_tagged(ar):
case !_tagged(al):
case _isFile(f):
case n - t < ONE_DAY:
break;
default:
utils.WriteINI(ini, "Timestamps", tmp, n);
x.open("GET", "https://www.last.fm/music/" + encodeURIComponent(ar) + "/" + encodeURIComponent(al) + "/+images", true);
x.setRequestHeader("If-Modified-Since", "Thu, 01 Jan 1970 00:00:00 GMT");
x.send();
x.onreadystatechange = function () {
if (x.readyState == 4) {
if (x.status == 200) {
var o = _.first(_.filter(_getElementsByTagName(x.responseText, "img"), {"className" : "image-list-image"}));
if (o) {
var u = o.src.replace("avatar170s", "ar0");
_runCmd("cscript //nologo " + _q(fb.ProfilePath + "scripts\\SMP\\download.vbs") + " " + _q(u) + " " + _q(f), false);
window.SetTimeout(function () {
panel.item_focus_change();
}, 3000);
}
} else {
console.log("HTTP error: " + x.status);
}
}
}
break;
}
}
RefreshPSS();
}

function RefreshPSS() {
var Refresh_sys = window.GetProperty("Refresh_sys",true);
 if (Refresh_sys < true) {
if (fb.IsPlaying || fb.IsPaused) { 
fb.RunMainMenuCommand("View/Show status bar");
fb.RunMainMenuCommand("View/Show status bar");
} else {
fb.RunMainMenuCommand("View/Show status bar");
fb.RunMainMenuCommand("View/Show status bar");
}
} else {
if (fb.IsPlaying || fb.IsPaused) { 
fb.RunMainMenuCommand("Playback/Play or Pause");
fb.RunMainMenuCommand("Playback/Play or Pause");
} else {
fb.RunMainMenuCommand("Playback/Play");
fb.RunMainMenuCommand("Playback/Stop");
}
}

}

From what I can understand of marc2003's original script, the code responsible for the download is all in the on_metadb_changed function, but because we want the code to be executed also when a new track is played, the on_metadb_changed function is invoked by the item_focus_change method of the panel object, on line 11. As far as I know this part of the code should be read only on panel start up, but with the console I was able to see that the item_focus_change method is executed on playback of a new track by JSP. So, is this one of those incorrect behaviors tolerated by JSP, but not by SMP? Or is the item_focus_change method triggered by some other event, I thought maybe it could be related to the built-in playcount, which is set differently by default in JSP and SMP?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: zeremy on 2019-02-28 17:20:03
@davideleo

The difference is that JSP panel.js is different from SMP panel.js

Compare the two files and you will see that in JSP panel.js

Code: [Select]
function on_playback_new_track() {
panel.item_focus_change();
}
is defined

In SMP panel.js  it is not defined
Your edit added the missing function.

TIL : When migrating a custom JSP script we should also check its include files.

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-28 17:45:08
Compare the two files and you will see that in JSP panel.js

Code: [Select]
function on_playback_new_track() {
panel.item_focus_change();
}
is defined

In SMP panel.js  it is not defined
Your edit added the missing function.

Can you please point me to the relevant code lines? I've been comparing the two panel.js versions for the last two days, but I couldn't find it. I must say the whole panel script is pretty hard for me to read, because of the many cross-references and the use of activex objects that I'm not familiar with.

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: zeremy on 2019-02-28 17:53:58
JSP
https://github.com/marc2k3/foo_jscript_panel/blob/master/foo_jscript_panel/samples/complete/js/panel.js#L15

SMP
https://github.com/marc2k3/smp_2003/blob/a0e578ec06211b1d4b01f529962142bf50a75da5/js/panel.js
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-02-28 18:03:40
JSP
https://github.com/marc2k3/foo_jscript_panel/blob/master/foo_jscript_panel/samples/complete/js/panel.js#L15

SMP
https://github.com/marc2k3/smp_2003/blob/a0e578ec06211b1d4b01f529962142bf50a75da5/js/panel.js


OMG! I can't believe I totally ignored those callabacks  :-[  I was concentrating on the panel object only.
Thanks.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: philodoxxx on 2019-03-05 18:11:15



I have been experiencing an error on start up in Foobar related to the JS Smooth Browser sample script  in Spider Monkey Panel v1.1.5. See below:
Could you please try the Nightly build (see the link in the first post of this thread) and see if it produces a more intelligible error message?

PS: @zeremy thanks for all the answers in this thread =)



 The error is pretty much the same with the nightly build:

Error: Spider Monkey Panel v1.1.6-beta+0191969 (JS Smooth Browser by Br3tt aka Falstaff)
Resize failed:
Failed to create GdiPlus object (0X0): No error

File:
Line: 3500, Column: 24

Stack trace:
  get_images@:3500:24
  oBrowser/this.update@:1526:3
  oBrowser/this.setSize@:1548:3
  on_size@:3120:3
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: zeremy on 2019-03-05 19:28:42
@philodoxxx

Try clearing the Panel Properties
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-03-06 11:13:03
The error is pretty much the same with the nightly build:
Could you try again with the latest Nightly? It should produce a proper error message now.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: zeremy on 2019-03-06 18:20:15
@TheQwertiest

You can reproduce @philodoxxx error if you select Display > Album Art Grid

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-03-06 19:00:19
@TheQwertiest
You can reproduce @philodoxxx error if you select Display > Album Art Grid
Thanks!
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-09 14:41:24
I noticed on one of my scripts that the on_paint() function always increases memory usage, without releasing it, until eventually foobar2000 has no alternative, but crash. I can't tell if this was happening before switching to SMP, because I never really analysed my scripts in this connection, but the flaw is likely in something I ignore about memory allocation and garbage collection.
I'm posting here the on_paint() code, only, because the complete script is quite long, but if it helps I can post the rest of it. For reference: it's a playlist manager script.

Code: [Select]
function on_paint(gr) {
var PlaylistVisible = (fso.FileExists(SettingsPath + "PlaylistVisible"));
var MenuVisible = fso.FileExists(SettingsPath + "MenuVisible");
VisibleItemsCount = (wh / row_height);
ScrollerHeight = Math.max(wh * VisibleItemsCount / UserPlaylistsCount, 30);
    ScrollerExtension = ScrollerHeight - (wh * VisibleItemsCount / UserPlaylistsCount);
    scrollbar_w = MenuVisible?17:0;
idxStart = Math.max(idxStart, SysPlaylistsCount); 
idxEnd = Math.min(TotalPlaylistsCount, idxStart + Math.ceil(VisibleItemsCount));
var x = gr.CalcTextWidth(" ", font);
    var w = ww - x - scrollbar_w;
var h = row_height;
    for (i = idxStart; i < idxEnd; i++) {       
        var y = row_height*(i - idxStart);
        var MouseHover = (x <= mouse_x) && (mouse_x <= x + w) && (y <= mouse_y) && (mouse_y < y + h);
var ActiveVisible = PlaylistVisible && plman.ActivePlaylist == i;
        var icon = plman.PlayingPlaylist == i && fb.IsPlaying?String.fromCharCode(57369):String.fromCharCode(57368);
        var text = "  " + icon + (MenuVisible?"   " + plman.GetPlaylistName(i):"") + (SHOW_COUNT?" [" + plman.PlaylistItemCount(i) + "]":"");
        var textColor = ActiveVisible?colours.White:offcolour;
        var bgColor = MouseHover?setAlpha(colours.Gray, 60):setAlpha(colours.Black, 0);
        if (!dragging && !scrolling) gr.FillSolidRect(x, y, w, h, bgColor);
        if (ActiveVisible) gr.FillSolidRect(x/2, y, x/2, h, RGBA(255,255,255,255));
gr.GdiDrawText(text, font, textColor, x, y, w, h, IFormat);
        if (dragging && MouseHover) gr.FillSolidRect(x, y + drag_down*row_height, w, 1, offcolour);
        }
       
    scrollbar_y = (idxStart - SysPlaylistsCount) * (wh - ScrollerExtension) / UserPlaylistsCount;   
   
    gr.SetSmoothingMode(1);
    if (MenuVisible && (scrollbar || (SCROLLBAR_MODE == 0))) gr.FillRoundRect(ww - scrollbar_w, scrollbar_y, scrollbar_w, ScrollerHeight, 1, 1, RGBA(255,255,255,100));
    gr.SetSmoothingMode(0);  
}

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-03-11 14:26:45
@philodoxxx Thanks for the bug report! It will be fixed in the next release, in the meantime you can apply the following fix manually - https://github.com/TheQwertiest/foo_spider_monkey_panel/pull/62/files

I noticed on one of my scripts that the on_paint() function always increases memory usage, without releasing it...
Doesn't look like there is anything that could cause a memory leak in your code. To diagnose the issue I need the full (i.e. working) sample. Ideally it should be stripped down as much as possible =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-03-11 14:29:34
[EDIT] Accidental double-post
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-11 18:08:11
To diagnose the issue I need the full (i.e. working) sample. Ideally it should be stripped down as much as possible =)

If you mean the whole script, here it is:
Code: [Select]
'use strict';

window.DefinePanel('YouFy Playlist Manager', {author:'davideleo'});
include(fb.ComponentPath + 'docs\\Flags.js');
include(fb.ComponentPath + 'docs\\Helpers.js');
include(fb.ProfilePath + 'scripts\\SMP\\YouFy common.js');

var i = 0;
var SysPlaylistsCount = 0;
var UserPlaylistsCount = 0;
var TotalPlaylistsCount = 0
var idxStart = 0;
var idxEnd = 0;
var idxFrom = -1;
var idxTo = -1;
var mouse_x = -1;
var mouse_y = -1;
var dragging = false;
var scrollbar = false;
var scrolling = false;
var SCROLLBAR_MODE = window.GetProperty("Scrollbar Mode", 2); //0=always, 1=never, 2=auto hide
var SHOW_COUNT = window.GetProperty("Show TrackCount", true);
var row_height = Number(ReadSettingsValue("RowHeight", 45));
var DPI = ReadSettingsValue("DPI", 96);
var iconfont = ReadSettingsValue("iconfont","youfy mdl2 assets");
var font_size = 16;
var font_height = font_size * DPI / 72;   
var font = gdi.Font(iconfont, font_height, 0);
var IFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX;
count_playlists();


function on_size() {
    ww = window.Width;
    wh = window.Height;
}


function on_paint(gr) {
var PlaylistVisible = (fso.FileExists(SettingsPath + "PlaylistVisible"));
var MenuVisible = fso.FileExists(SettingsPath + "MenuVisible");
VisibleItemsCount = (wh / row_height);
ScrollerHeight = Math.max(wh * VisibleItemsCount / UserPlaylistsCount, 30);
    ScrollerExtension = ScrollerHeight - (wh * VisibleItemsCount / UserPlaylistsCount);
    scrollbar_w = MenuVisible?17:0;
idxStart = Math.max(idxStart, SysPlaylistsCount); 
idxEnd = Math.min(TotalPlaylistsCount, idxStart + Math.ceil(VisibleItemsCount));
var x = gr.CalcTextWidth(" ", font);
    var w = ww - x - scrollbar_w;
var h = row_height;
    for (i = idxStart; i < idxEnd; i++) {       
        var y = row_height*(i - idxStart);
        var MouseHover = (x <= mouse_x) && (mouse_x <= x + w) && (y <= mouse_y) && (mouse_y < y + h);
var ActiveVisible = PlaylistVisible && plman.ActivePlaylist == i;
        var icon = plman.PlayingPlaylist == i && fb.IsPlaying?String.fromCharCode(57369):String.fromCharCode(57368);
        var text = "  " + icon + (MenuVisible?"   " + plman.GetPlaylistName(i):"") + (SHOW_COUNT?" [" + plman.PlaylistItemCount(i) + "]":"");
        var textColor = ActiveVisible?colours.White:offcolour;
        var bgColor = MouseHover?setAlpha(colours.Gray, 60):setAlpha(colours.Black, 0);
        if (!dragging && !scrolling) gr.FillSolidRect(x, y, w, h, bgColor);
        if (ActiveVisible) gr.FillSolidRect(x/2, y, x/2, h, RGBA(255,255,255,255));
gr.GdiDrawText(text, font, textColor, x, y, w, h, IFormat);
        if (dragging && MouseHover) gr.FillSolidRect(x, y + drag_down*row_height, w, 1, offcolour);
        }
       
    scrollbar_y = (idxStart - SysPlaylistsCount) * (wh - ScrollerExtension) / UserPlaylistsCount;   
   
    gr.SetSmoothingMode(1);
    if (MenuVisible && (scrollbar || (SCROLLBAR_MODE == 0))) gr.FillRoundRect(ww - scrollbar_w, scrollbar_y, scrollbar_w, ScrollerHeight, 1, 1, RGBA(255,255,255,100));
    gr.SetSmoothingMode(0);  
}


function on_mouse_move(x, y) {
drag_down = y >= mouse_y;
    mouse_x = x;
    mouse_y = y;
    scrollbar = (UserPlaylistsCount > VisibleItemsCount && SCROLLBAR_MODE != 1);   
    if(scrolling){
        scrollbar_y = Math.max(exScrollbar_y + y - lbtn_down_y, 0);
        if(scrollbar_y + ScrollerHeight > wh) scrollbar_y = wh - ScrollerHeight;
        idxStart = Math.floor(scrollbar_y * UserPlaylistsCount  / (wh - ScrollerExtension)) + SysPlaylistsCount;
        if(idxStart > TotalPlaylistsCount - VisibleItemsCount) idxStart = TotalPlaylistsCount - VisibleItemsCount;
    }
window.Repaint();   
}
 

function on_mouse_lbtn_down(x, y){  
    if(x > ww - scrollbar_w) {
        if(y > scrollbar_y && y < scrollbar_y + ScrollerHeight) {
            exScrollbar_y = scrollbar_y;
            lbtn_down_y = y;
            scrolling = true;
        } else {
            if (y < scrollbar_y) idxStart = Math.max(idxStart - VisibleItemsCount,0);
            if (y > scrollbar_y + ScrollerHeight) idxStart = Math.min(idxStart + VisibleItemsCount, TotalPlaylistsCount - VisibleItemsCount);
        }
    } else {
        idxFrom = GetPlaylistIdx(y);
        plman.ActivePlaylist = idxFrom;
        fso.CreateTextFile(SettingsPath + "PlaylistVisible").Close();
        if (plman.GetPlaylistName(plman.ActivePlaylist)){
            WriteSettingsValue("ActivePlaylist",plman.GetPlaylistName(plman.ActivePlaylist));
            WriteSettingsValue("PlaylistType",plman.IsAutoPlaylist(plman.ActivePlaylist)?"Autoplaylist":"Playlist");
        }
        RefreshPSS();
        dragging = true;
mouse_y = y;
    }
    window.Repaint();
}


function on_mouse_leave() {
    mouse_x = -1;
    mouse_y = -1;
    scrollbar = false;
    window.Repaint();
}


function on_mouse_lbtn_up(x, y){
    idxTo = GetPlaylistIdx(y);
    if (dragging) plman.MovePlaylist(idxFrom,idxTo);
    dragging = false;
    scrolling = false;
    window.Repaint();
    RefreshPSS();
}


function on_mouse_lbtn_dblclk(x, y){
    if(x < ww - scrollbar_w){
plman.PlayingPlaylist = GetPlaylistIdx(y);
fb.Play();
window.Repaint();
    }
}


function on_mouse_rbtn_down(x, y, mask){
    var idx = GetPlaylistIdx(y);
    var ContextMenu = window.CreatePopupMenu();
    var _ScrollbarOption = window.CreatePopupMenu();
    ContextMenu.AppendMenuItem(MF_STRING, 1, "Rename...");
    ContextMenu.AppendMenuItem(MF_STRING, 2, "Remove");
    ContextMenu.AppendMenuItem(MF_STRING, 3, "Save...");
    ContextMenu.AppendMenuItem(MF_STRING, 11, "Move to top");
    ContextMenu.AppendMenuItem(MF_STRING, 12, "Move to bottom");
    ContextMenu.AppendMenuSeparator();
    if (plman.IsAutoPlaylist(idx)){
        ContextMenu.AppendMenuItem(MF_STRING, 4, "AutoPlaylist Format");
        ContextMenu.AppendMenuSeparator();
    }
    ContextMenu.AppendMenuItem(MF_STRING, 5, "Show Track Count");
    ContextMenu.CheckMenuItem(5, SHOW_COUNT?1:0);
    _ScrollbarOption.AppendTo(ContextMenu,0, "Show Scrollbar");
    _ScrollbarOption.AppendMenuItem(MF_STRING, 6, "Always");
    _ScrollbarOption.AppendMenuItem(MF_STRING, 7, "Never");
    _ScrollbarOption.AppendMenuItem(MF_STRING, 8, "Auto Hide");  
    _ScrollbarOption.CheckMenuRadioItem(6,8,SCROLLBAR_MODE + 6);
    if (mask == 6||mask == 14){
        ContextMenu.AppendMenuSeparator();
        ContextMenu.AppendMenuItem(MF_STRING, 9, "Properties");
        ContextMenu.AppendMenuItem(MF_STRING, 10, "Configure...");
    }
   
    if(idx != null){
        switch(ContextMenu.TrackPopupMenu(x, y, 0)){
            case 1:
            plman.ActivePlaylist = idx;
            fb.RunMainMenuCommand("File/Rename Playlist") ;
            break;
           
            case 2:
            plman.RemovePlaylist(idx);
UserPlaylistsCount = TotalPlaylistsCount - SysPlaylistsCount;
            plman.ActivePlaylist = Math.min(idx, UserPlaylistsCount - 1);
            window.Repaint();
            break;
           
            case 3:
            plman.ActivePlaylist = idx;
            fb.SavePlaylist();
            break;
           
            case 4:
            plman.ShowAutoPlaylistUI(idx);
            break;
           
            case 5:
            SHOW_COUNT = !SHOW_COUNT;
            window.SetProperty("Show TrackCount", SHOW_COUNT);
            ContextMenu.CheckMenuItem(5, SHOW_COUNT);
            window.Repaint();
            break;
           
            case 6:
            SCROLLBAR_MODE = 0;
            window.SetProperty("Scrollbar Mode", 0);
            _ScrollbarOption.CheckMenuRadioItem(6,8,6);               
            break;
           
            case 7:
            SCROLLBAR_MODE = 1;
            window.SetProperty("Scrollbar Mode", 1);
            _ScrollbarOption.CheckMenuRadioItem(6,8,7);
            break;
           
            case 8:
            SCROLLBAR_MODE = 2;
            window.SetProperty("Scrollbar Mode", 2);
            _ScrollbarOption.CheckMenuRadioItem(6,8,8);
            break;
           
            case 9:
            window.ShowProperties()
            break;
           
            case 10:
            window.ShowConfigure();
            break;
           
            case 11:
            plman.MovePlaylist(idx, SysPlaylistsCount);
            window.Repaint();
            break;
           
            case 12:
            plman.MovePlaylist(idx, TotalPlaylistsCount - 1);
            window.Repaint();
            break;
           
            default:     
            break;
        }
    }
}


function on_drag_over(action, x, y, mask){
    mouse_x = x;
    mouse_y = y;
window.Repaint(); 
}


function on_drag_drop(action, x, y) {
var idx = GetPlaylistIdx(y);
action.Playlist = idx;
action.ToSelect = false;
plman.ActivePlaylist = idx;
}


function on_playlists_changed() {
count_playlists();
window.Repaint();
}


function on_notify_data(name, info) {
    switch(name) {
        case "refresh":
        window.Repaint();
RefreshPSS();
        break;
        case "row height":
        row_height = info;
        window.Repaint();
        break;
    }
}


function GetPlaylistIdx(y) {
    return Math.floor(y / row_height) + idxStart;
}


function count_playlists(){         //system playlists are prefixed with a "#" and must be hidden from the playlist manager.
TotalPlaylistsCount = plman.PlaylistCount;
SysPlaylistsCount = 0;
for (i = 0; i < TotalPlaylistsCount; i++) {              
if (plman.GetPlaylistName(i).search("#") == 0) {
if (i > SysPlaylistsCount) plman.MovePlaylist(i, SysPlaylistsCount);
SysPlaylistsCount = SysPlaylistsCount + 1;
}
}
UserPlaylistsCount = TotalPlaylistsCount - SysPlaylistsCount;
}

If you really are willing to review my script (in which case I'd be eternally grateful), for completeness here's also the preprocessed "YouFy common" script:
Code: [Select]
// *****************************************************************************************************************************************
// Additional functions & flags for the YouFy skin
// *****************************************************************************************************************************************

var fso = new ActiveXObject("Scripting.FileSystemObject");
var SettingsPath = fb.ProfilePath + "settings\\";
var SkinPath = fb.ProfilePath + "skins\\YouFy\\";
var ImagesPath = fb.TitleFormat("%images_path%").Eval(true) + "\\";
var ThumbsPath = ImagesPath + "thumbs\\";
var BackgroundPath = ImagesPath + "background\\";
var offcolour = RGB(120,120,120);


function ReadSettingsValue(folder,default_value) {
   if (!fso.FolderExists(SettingsPath)) fso.CreateFolder(SettingsPath);
   var FolderPath = SettingsPath + folder +"\\";
   if(!fso.FolderExists(FolderPath)) {
      WriteSettingsValue(folder,default_value);
      return default_value;  
   } else {
      var FolderObj = fso.GetFolder(FolderPath);
      var FolderEnumerator = new Enumerator(FolderObj.Files);
      if(fso.FileExists(FolderEnumerator.item(1))) {
          return FolderEnumerator.item(1).Name;
        } else {
WriteSettingsValue(folder,default_value);
return default_value
        }
   }
}


function WriteSettingsValue(folder,value) {
   if (!fso.FolderExists(SettingsPath)) fso.CreateFolder(SettingsPath);
   var FolderPath = SettingsPath + folder;  
   if(fso.FolderExists(FolderPath)) {
       var FolderObj = fso.GetFolder(FolderPath);
       var FolderEnumerator = new Enumerator(FolderObj.Files);
       for (var i = 1; i < FolderObj.Files.Count + 1; i++) {
           fso.DeleteFile(FolderEnumerator.item(i));
       }
   } else {
       fso.CreateFolder(FolderPath);
   }
   fso.CreateTextFile(FolderPath + "\\" + value).Close();
}


function RefreshPSS() {
var Refresh_sys = window.GetProperty("Refresh_sys",true);
 if (Refresh_sys < true) {
if (fb.IsPlaying || fb.IsPaused) { 
fb.RunMainMenuCommand("View/Show status bar");
fb.RunMainMenuCommand("View/Show status bar");
} else {
fb.RunMainMenuCommand("View/Show status bar");
fb.RunMainMenuCommand("View/Show status bar");
}
} else {
if (fb.IsPlaying || fb.IsPaused) { 
fb.RunMainMenuCommand("Playback/Play or Pause");
fb.RunMainMenuCommand("Playback/Play or Pause");
} else {
fb.RunMainMenuCommand("Playback/Play");
fb.RunMainMenuCommand("Playback/Stop");
}
}

}


function Get_taskbar_colour() {
    var Shell = new ActiveXObject("WScript.Shell");
    if (Shell.RegRead("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize\\ColourPrevalence")) {
        if (Shell.RegRead("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize\\EnableTransparency")) {
            return AccentPalette(7);
            } else {
            return AccentPalette(6);
        }  
        } else {
        if (Shell.RegRead("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize\\EnableTransparency")) {
            return "0-0-0";
            } else {
            return "16-16-16";
        }
    }
}


function AccentPalette(item) {
    var Shell = new ActiveXObject("WScript.Shell");
    item = item -1;
    AccentPaletteArray = Shell.RegRead("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Accent\\AccentPalette");
//  return AccentPaletteArray[4*item] + "-" + AccentPaletteArray[1+4*item] + "-" + AccentPaletteArray[2+4*item];
    return RGB(AccentPaletteArray[4*item], AccentPaletteArray[1+4*item], AccentPaletteArray[2+4*item]);
}


function Get_dpi() {
    var Shell = new ActiveXObject("WScript.Shell");
return Shell.RegRead("HKEY_CURRENT_USER\\Control Panel\\Desktop\\WindowMetrics\\AppliedDPI");
}

var library_items = fb.GetLibraryItems();


function list_values(tag, handle_list = library_items, query = tag + " PRESENT", split = true){
var tags = [];
var items = fb.GetQueryItems(handle_list, query)
for (var i = 0; i < items.Count; i++) {
var handle = items[i];
var meta_num = fb.TitleFormat("$meta_num(" + tag + ")").EvalWithMetadb(handle);
for (var j = 0; j < meta_num; j++) {
tags.push(fb.TitleFormat("$meta(" + tag + "," + j + ")").EvalWithMetadb(handle));
}
}
fb.ShowPopupMessage(_.uniq(tags.sort(), true).join("\n"));
}



All in all the script works fluently and the on_paint routine doesn't actually use much memory. What leaves me perplexed is that it is never released. Why would that even happen, unless something's not working properly with the GC?


P.S.
I also wanted to explain that I realized the issue was with the on_paint function because the on_mouse_move function always triggers a repaint. By simply moving the mouse over the panel, the memory increases. After commenting out the repaint instruction, moving the mouse over the panel doesn't increase memory usage by one byte.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-11 19:47:51
I also wanted to explain that I realized the issue was with the on_paint function because the on_mouse_move function always triggers a repaint. By simply moving the mouse over the panel, the memory increases. After commenting out the repaint instruction, moving the mouse over the panel doesn't increase memory usage by one byte.

I uploaded a short video (https://www.dropbox.com/s/p1yrvbnytaq5b66/2019-03-11%2020-30-51.mp4?dl=0) to show what I mean (and maybe it is also of help to who is willing to take a look at my script).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: philodoxxx on 2019-03-11 20:39:49
@philodoxxx Thanks for the bug report! It will be fixed in the next release, in the meantime you can apply the following fix manually - https://github.com/TheQwertiest/foo_spider_monkey_panel/pull/62/files

Thank you. Switching out those few lines in the script did indeed fix the issue. Regards.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-03-12 10:24:50
@davideleo your script looks like this for me
Spoiler (click to show/hide)
And there were no apparent memory leaks :\
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-12 13:41:22
@davideleo your script looks like this for me
Yes, that's because you are missing the "Youfy MDL2 assets" font, which is a collage-font I put together for this skin. Actually there are also a few variables which take their value from text files created by another script.


And there were no apparent memory leaks :\
So, that's a clue, isn't it? Doesn't it close in on the interaction with other scripts or components? I actually already tested it without the black sheep of foobar2000's plug-ins, foo_customdb, but nothing changed.
What about the GC settings in the advanced preferences? Should I  mess around with them?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-12 16:02:38
I tested all of my scripts and it turned out it's a general problem. Every on_paint() function seems to increase memory and never release it. Even worse is that there is likely an on_playback_newtrack() function with the same problem, but I still didn't find out which one. That means my foobar2000 is bound to crash sooner or later at every session, even if I don't touch it.
What really put me down is that I also tested the only script I have by another author (marc2003's Last.fm Bio) and guess what? No memory leak at all. This is the proof that the problem is in my scripting.

@TheQwertiest when you write that there were no apparent memory leaks, do you mean that triggering the on_mouse_move() doesn't increase memory usage or that the memory increase is then released? BTW thanks a lot for taking a look.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: juniiflow on 2019-03-13 10:14:47
Anyone knows a quick way to remove or move the now playing arrow on j smooth?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Strigoy on 2019-03-13 12:58:06
Uh, this 'Edit' menu problem drives me nuts )) I don't get it, why this happens (this only affects 'Edit' submenu, others work just fine):

(https://i.imgur.com/7NQBTxp.png)

but if I use default Menu everything works just fine =>

(https://i.imgur.com/fnDOzg7.png)

I'm using snippet from MainMenuManager All-In-One.js

Speaking of which: I got couple of questions:
1)
Code: [Select]
contextman.InitNowPlaying(); 
this is getting called twice for some reason

2)
Am I MisSinG SoMetHing wItH thE CasE herE?
Code: [Select]
    menuman1.Init('file');
    menuman2.Init('edit');
    menuman3.Init('View');
    menuman4.Init('playback');
    menuman5.Init('library');
    menuman6.Init('help');
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Strigoy on 2019-03-13 21:54:14
Nevermind, guh... I've spent so much time trying to figure it out, but the problem was with panel settings... just unchecked 'grab focus' and it's working as intended.

My god, that's so silly...
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-03-14 12:25:39
Uh, this 'Edit' menu problem drives me nuts )) I don't get it, why this happens (this only affects 'Edit' submenu, others work just fine):
Not sure what's going on here - it works fine for me (both with `Grab Focus` enabled and disabled).

1) this is getting called twice for some reason
2) Am I MisSinG SoMetHing wItH thE CasE herE?
Because reasons :D
Those are just typos.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-14 16:40:17
@davideleo your script looks like this for me
Spoiler (click to show/hide)
And there were no apparent memory leaks :\

I tested my script on a clean installation with no other plug-in, but spider monkey panel. The memory leak was more than apparent. How did you test it?
I really need to get to the bottom of this problem, because it is making spider monkey panel unusable for me.


P.S.
BTW, on a clean installation I realized that the reason for that appearance is that the script does not find the "MenuVisible" file (without extension) in the "settings" folder inside the foobar2000 configuration folder. It is normally created by another script.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-14 18:12:21
P.P.S.
I tested some of the sample scripts to see if I could find at least one with a similar behaviour. Eventually I found that the "track info + seekbar + buttons" by marc2003 increases memory usage by 0,8-9 MB at every button click without releasing it, but it looks like marc2003 managed the issue, because it is released when (and apparently only if) the total memory delta is around 20MB.

EDIT
I made a mistake: it's not the button click that increases memory, but the playback state change, triggered by the button click.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-14 23:58:52
I made some steps forward in my inquiry on the memory-greedy script.

First of all I realized that memory usage increases only when several repaint actions are executed sequentially at close intervals, therefore I managed to lessen its impact by limiting the repaint action to when it is actually required, rather than on any on_mouse_move event.

That didn't solve the issue, though, and if I move the mouse very quickly, over the panel, I can still reproduce it, even if it takes longer to reach dangerous levels.

Anyway, I finally tested the same script on a JScript panel, on the same clean installation of the Spider Monkey panel. Here (https://www.dropbox.com/s/0yci9nfctu70cx6/2019-03-14%2023-38-45.mp4?dl=0)'s what happened (yes, I know I look like a weirdo). I moved the mouse up and down on the JScript panel for about one minute and - as you can see in the task manager - the memory level is stuck on 677,2 MB. There is only a slight increase towards the end, released right after. The same action on the Spider Monkey panel immediately starts raising the memory in use and after one minute it's well over 680 MB.

Sorry if I sound obsessed, but since I'm still learning javascript, it's very important for me to understand what I didn't get right, before I move on to more advanced scripting.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-03-15 09:08:25
but it looks like marc2003 managed the issue, because it is released when (and apparently only if) the total memory delta is around 20MB.
That's just GC kicking in - it has several triggers, one of which is the amount of allocated memory. I.e. you don't have to `Dispose` anything manually in 99.9% cases in SMP.

What about the GC settings in the advanced preferences? Should I  mess around with them?
You should not =)

when you write that there were no apparent memory leaks, do you mean that triggering the on_mouse_move() doesn't increase memory usage or that the memory increase is then released? BTW thanks a lot for taking a look.
The memory increase is minuscule and it's not permanent - it's  cleaned up properly after sometime with GC (i.e. it's not a leak).

[EDIT] Can you download the debug version of SMP and enable GC zeal and check if memory is still leaking for you?
Debug version: https://ci.appveyor.com/api/buildjobs/rylakh87w1kuotm2/artifacts/_result%2FWin32_Debug%2Ffoo_spider_monkey_panel.fb2k-component_debug
GC Zeal: Preferences > Advanced > Display > Spider Monkey Panel > GC > Zeal > Enable
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-03-15 12:59:12
@davideleo you can also try the latest Nightly build (which is available via link in OP) - I might have fixed the leak there.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-15 14:11:18
With the nightly build (1.1.6-beta+80ac164) the behavior is unchanged and when I try installing the debug version I get this message:
Quote
Failed to load DLL: foo_spider_monkey_panel.dll
Reason: This component is missing a required dependency, or was made for different version of foobar2000.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-15 15:53:14
With the nightly build (1.1.6-beta+80ac164) the behavior is unchanged...

I think it was not the latest version. Anyway I just tried  1.1.6-beta+f3d6584 and it behaves in the same way.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-03-15 15:54:10
With the nightly build (1.1.6-beta+80ac164) the behavior is unchanged
Are you sure? Note that GC does not kick in immediately, that is 10mb of allocated memory is not enough to trigger GC. Try reaching 100mb of allocations.

This component is missing a required dependency, or was made for different version of foobar2000
I will send you a PM with missing dlls later this evening or tomorrow.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-15 20:25:07
Are you sure? Note that GC does not kick in immediately, that is 10mb of allocated memory is not enough to trigger GC. Try reaching 100mb of allocations.

You are right! I gave the job to a timer, set to execute the repaint action once every millisecond. Right after startup, foobar2000 was using 677MB. After about 7 minutes the GC kicked in and memory usage dropped from 825MB to 690MB. I didn't clear the timer the first time and watched it repeat the cycle with the exact same values.
Just to make sure I tested the release version, too, and to my surprise it performed even better, dropping from 820MB to 687MB.
That's quite encouraging, even though I don't really understand why a script like mine would use so much memory for what to me looks basically like reassigning already allocated variables.



I will send you a PM with missing dlls later this evening or tomorrow.

Thanks a lot, I really appreciate your attention.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-03-16 12:06:53
I don't really understand why a script like mine would use so much memory for what to me looks basically like reassigning already allocated variables

GC is tuned for the best performance with multiple active SMP panels and heavy-allocating scripts, so it might be not aggressive enough for simple (that is light-allocating) scripts. That said, your case helped me to discover a bug, which made GC to be more lenient with memory allocation than it should've been. You can check out the fix with the latest Nightly build =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-16 17:10:51
You can check out the fix with the latest Nightly build =)

I just tested the script with beta version 2fdc8be and it behaves similarly, perhaps slightly worst: GC kicked in at 835MB (higher threshold than beta f3d6584) and dropped to 694MB (higher residual than beta f3d6584).
The fact remains that with JScript panel the same script does not raise memory usage at all. I recorded one more video (https://www.dropbox.com/s/p6fn2aj9odp7bcb/2019-03-16%2017-04-44.mp4?dl=0) which shows the task manager while two identical foobar2000 installations run the same script, one with JScript panel and one with Spider Monkey panel. The timer is set on start-up, and the two installations are launched simultaneously. Mind that no dispose() method was added in the JScript panel version.



GC is tuned for the best performance with multiple active SMP panels and heavy-allocating scripts, so it might be not aggressive enough for simple (that is light-allocating) scripts.

I'm a bit puzzled now: is JScript panel better tuned for light-allocating scripts? Is it more advisable for simple ones like mine?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-03-17 22:39:09
I just tested the script with beta version 2fdc8be and it behaves similarly
Hm... That's weird... I'm currently reworking GC a bit, so hopefully the memory usage will go down with next builds.

The fact remains that with JScript panel the same script does not raise memory usage at all.
Because JSP does not have GC at all, which has it advantages like never using more memory than currently needed, but at the cost of the performance. See the following post for a bit more info and performance trade-off example: https://hydrogenaud.io/index.php/topic,116669.msg963036.html#msg963036

I'm a bit puzzled now: is JScript panel better tuned for light-allocating scripts? Is it more advisable for simple ones like mine?
I've never said anything like that. SMP and JSP are different beasts with different memory allocation policies. SMP uses (generally) more memory than JSP, but provides enhanced performance and smoother UX instead.
What I did say, is that I tuned SMP GC policies for more heavy scripts. So, while it uses more memory with light scripts than it could've (i.e. it would accumulate more memory before purging it), it consumes CPU time drastically less with heavy scripts than it would've otherwise (which results in smoother UX and etc and etc).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-18 20:59:57
I've never said anything like that. SMP and JSP are different beasts with different memory allocation policies. SMP uses (generally) more memory than JSP, but provides enhanced performance and smoother UX instead.
What I did say, is that I tuned SMP GC policies for more heavy scripts. So, while it uses more memory with light scripts than it could've (i.e. it would accumulate more memory before purging it), it costumes CPU time drastically less with heavy scripts than it would've otherwise (which results in smoother UX and etc and etc).

I see, that makes sense, thanks for the explanation. I couldn't quite relate it to what I's experiencing because other heavy-looking scripts by professional coders didn't increase memory usage as much and my fear was that I was ignoring some basic good practice in my scripts. Eventually I found at least one professional script with a much bigger impact on memory and that reassured me a bit.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-03-19 15:01:43
@davideleo Please try the latest build again.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-20 14:34:04
I'm testing beta 6cc1cbd. The memory increases at a similar pace than the previous ones, but apparently GC comes round more often and with a smaller truck.
With foobar2000 starting up at 670-680 MB, beta 2fdc8be and the stable release both need at least 825-835 MB (but today it was 850-860 MB, just to make things more random!) before dropping to more or less 700 MB. Beta 6cc1cbd drops from 800-810 MB to 760 MB.
My two cents: by looking at the first cycle only, it would seem a lot better. I wonder, though, whether a higher garbage residual means that, on the long run, the average memory usage is bound to increase more rapidly. What is also hard to tell is how multiple panels, working together in a real usage set up, would actually perform: analytically speaking the single panel is better off with a lower peak, but a higher residual means that the overall uncollected garbage level is generally higher. So, except for the very rare case of all scripts approaching their memory cap at the same time, I can't tell really which one is more advisable.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-03-20 15:53:02
With foobar2000 starting up at 670-680 MB, beta 2fdc8be and the stable release both need at least 825-835 MB (but today it was 850-860 MB, just to make things more random!) before dropping to more or less 700 MB. Beta 6cc1cbd drops from 800-810 MB to 760 MB.
Mind though, that you should differentiate between total memory usage (i.e. via task manager) and SMP memory usage (via `window.TotalMemoryUsage`).

What is also hard to tell is how multiple panels, working together in a real usage set up, would actually perform: analytically speaking the single panel is better off with a lower peak, but a higher residual means that the overall uncollected garbage level is generally higher
Whatever the case it should not `leak` anymore. That is, SMP average memory usage should stay mostly the same.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-20 20:37:40
Whatever the case it should not `leak` anymore. That is, SMP average memory usage should stay mostly the same.

I monitored the memory values for over 2 hours (not literally, I recorded 2 hours of task manager and then scrolled the frames through) because I was curious of the GC behavior on the long run, so now I have a bigger picture. The new beta stabilizes already after the first GC action, whereas the previous beta and the stable release keep on raising the baseline - and to a lesser extent the peak level - for over one hour! That's a long time and if you don't know it will come to an end, it really looks like a bad memory leak. The comparison I made above did not take this into account: I compared the stabilized memory baseline of the new beta with the still growing baseline of the other two. Once the values are stable, the winner is the new beta by all means.


Mind though, that you should differentiate between total memory usage (i.e. via task manager) and SMP memory usage (via `window.TotalMemoryUsage`).
You shouldn't have told me. Now I know what I'll do in the next days.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-20 20:46:39
And now for something completely different: is it possible to read and edit the search pattern of an autoplaylist via JScript?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Ottodix on 2019-03-21 09:17:26
And now for something completely different: is it possible to read and edit the search pattern of an autoplaylist via JScript?

Yep :) plman.ShowAutoPlaylistUI(pl_idx);
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-03-21 14:57:29
Yep :) plman.ShowAutoPlaylistUI(pl_idx);

As far as I know that opens the autoplaylist properties dialog window. I want to read (and possibly edit) the query pattern by code.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-03-21 15:26:19
And now for something completely different: is it possible to read and edit the search pattern of an autoplaylist via JScript?
fb2k does not provide such API, so neither SMP nor JSP have this feature.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-04-03 17:12:29
I apologize for the lack of updates (and the promised fixes), so here is a bit info to those who care(^^):
Recently my motivation suffered a huge blow from Mozilla and it's shenanigans, which (coupled with my usual lack of free time) mostly stalled any progress on the next SMP release. Hopefully, the motivation will restore itself (at least partially) soon enough, but it may take some time...
Regardless, the current SMP version (and the nightly build as well) should be stable enough to last till the new release =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-04-03 18:20:19
No need to apologize: as far as I remember, hardly any component has had the support you've been providing so far.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: WilB on 2019-04-03 18:47:50
@TheQwertiest
Code: [Select]
huge blow from Mozilla and it's shenanigans

That's disappointing news & hopefully not too restrictive in the future. All your excellent hard work & effort is much appreciated on this marvellous plug-in.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: wcs13 on 2019-04-20 17:51:41
Hi everybody,
So this may be the successor of the excellent JScript Panel ! Great news !
Is there an updated list of the already-compatible scripts, with the corresponding codes ? That would help a lot.
I'm thinking about marc2003 scripts... Plus WilB's Biography View... etc..
Thanks.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-04-20 22:28:38
Is there an updated list of the already-compatible scripts, with the corresponding codes ?
There is no such list (yet?).
All WilB's script are SMP compatible though.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-04-20 22:33:47
@davideleo , @WilB , thanks for your kind words and support, really appreciated =)

That's disappointing news & hopefully not too restrictive in the future.
It was not anything really huge (like DMCA), but rather the state of the current and the future support of Mozilla SpiderMonkey embeddings...
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-04-22 17:15:22
Version: 1.2.0
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.2.0
Changelog:
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v120
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: kutuzof on 2019-04-23 15:03:23
https://drive.google.com/open?id=1Me4EUu65bn9vCJ4E1ZUgubPx48DaHXqK
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-04-23 19:16:46
@kutuzof , can you try the latest Nightly build and see if it fixes the freeze?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: louiscoim on 2019-04-23 20:41:28
Hello TheQwertiest, and everybody else, off course..

I have very simple question:

Is there a way to port WSH Coverflow  to an SMP Script?

I mean, I know Chronial's Coverflow or even Bubble Coverflow are more advanced components, but my PC doesn't support them as
I get the pixelformat error because of my old Intel HD graphics chip.. I tried everything possible to fix this issue (from drivers to installing open EL/GL solutions)..
If it isn't possible, no need to tell me why, I don't know much about scripting and I must say that: I admire a lot Your work and think it's awesome!!

Anyway, Thanks in Advance.

Peace
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: kutuzof on 2019-04-24 07:39:49
@kutuzof , can you try the latest Nightly build and see if it fixes the freeze?

Thanks, I tried the nightly build, while it seems to work well.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-04-24 16:35:15
Version: 1.2.1
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.2.1
Changelog
Hotfix for v1.2.0 (see changelog above (https://hydrogenaud.io/index.php/topic,116669.msg970630.html#msg970630))
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-04-24 17:09:04
How safe is it to add custom methods and properties to default SMP objects?

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-04-24 18:53:04
Never tried, but should be probably safe (if it works :D), since all SMP objects are proper JS objects. Obviously there are some limitations - e.g. you can't make a deep copy of (most) SMP objects (unless it's stated explicitly otherwise in docs).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: acmodeu on 2019-04-24 21:05:30
Tried to migrate to Spider Monkey. Added volume bar from https://github.com/timonwong/foo_uie_wsh_panel_mod/blob/master/samples/Volbar%20with%20GdiDrawText.txt
Got this on gr.FillGradRect(  0, 0, pos , wh, 90, RGB(240,240,240), RGB(46,48,63));

Code: [Select]
Error: Spider Monkey Panel v1.2.1 (MyScript v1.2.3 by Me)
FillGradRect failed:
GdiPlus error: SetBlendTriangularShape failed with error (0X2): InvalidParameter

File: <main>
Line: 45, Column: 2

Stack trace:
  on_paint@<main>:45:2
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-04-24 21:42:10
Tried to migrate to Spider Monkey. Added volume bar from https://github.com/timonwong/foo_uie_wsh_panel_mod/blob/master/samples/Volbar%20with%20GdiDrawText.txt
Got this on gr.FillGradRect(  0, 0, pos , wh, 90, RGB(240,240,240), RGB(46,48,63));


I think the error is generated when the width argument is equal to 0, that is when "pos" is equal to "ww". I guess you have to manage that eventuality with something like:
Code: [Select]
line 51         if (pos != ww) gr.FillGradRect(pos, 0, ww - pos, wh, 90, RGB(240, 240, 240), RGB(190, 190, 190));


P.S.
I just realized you got the error on the previous FillGradRect function, on line 50. Obviously the same applies to both:

Code: [Select]
    if (pos != 0) gr.FillGradRect(0, 0, pos, wh, 90, RGB(240, 240, 240), RGB(100, 230, 100));
    if (pos != ww) gr.FillGradRect(pos, 0, ww - pos, wh, 90, RGB(240, 240, 240), RGB(190, 190, 190));

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-04-24 22:37:02
@acmodeu, there is no need to update this sample manually - it's available as part of SMP package (samples/basic/Volbar with GdiDrawText.js).

PS: @davideleo, your reasoning is correct =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-04-24 22:43:23
Is there a way to port WSH Coverflow  to an SMP Script?
You can try using the following guide: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/JScript-to-SpiderMonkey-migration-guide
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: acmodeu on 2019-04-25 14:59:16
@davideleo, @TheQwertiest thank you guys!
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Ottodix on 2019-04-25 17:35:14
Big thanks TheQuertiest for your work on this component!

I released a theme based on this, you can get it there if you want to try it:
(https://i.ibb.co/4Tmh9TB/preview-tn.jpg)   https://github.com/Ottodix/Eole-foobar-theme

Most of this theme is made possible by SMP
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-04-25 17:53:56
Looks awesome! Guess it's time to make that script showcase page :D
It might be a good idea to create a separate thread for your theme though, otherwise it might get lost in this thread and not get the attention it deserves...
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-05-01 18:56:47
Conceptual question: what is the use of setting to null the variable that holds the graphics object, after using the GetGraphics() and thereon the ReleaseGraphics() methods?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Ottodix on 2019-05-02 14:03:59
Conceptual question: what is the use of setting to null the variable that holds the graphics object, after using the GetGraphics() and thereon the ReleaseGraphics() methods?
Making sure that the GC collect and free up the allocated memory for this graphic object, if you declared it as a global variable ? That's my guess
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-05-02 14:58:03
...if you declared it as a global variable...

In the sample scripts I've seen, it is always declared locally and nevertheless set to null at closure. But isn't it redundant after the ReleaseGraphics() method, given how spider monkey GC works?

P.S.
I noticed the StackBlur (text).js sample script does not bother to set the graphics object variable to null, after running the ReleaseGraphics() method. It's the only exception, though. What is the difference, for example, with the thumbs.js sample script? Why is setting the graphics object variable to null required in the latter and not in the first?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Joulupukki on 2019-05-02 20:52:09
@TheQwertiest: many thanks for your Spider Monkey Panel!

@TheQwertiest and other other developers:

Would it be possible to have a simple code for a simple volume control with 2 images: a dot and a knob with your panel?

(I've both images)

Thanks in advance.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Joulupukki on 2019-05-04 19:00:16
Well,, I swtched to WSH panel mod and the "DarkOne Volume Knob Panel  v3.1" vworks fine now  with my Foobar v1.4.3 (DUI).  :)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-05-13 15:20:15
I'm working on a one-panel theme and so I turned some of my stand-alone scripts to objects. With stand-alone scripts, though, we are able to draw portions of graphic elements by placing the drawing coordinates virtually outside of the window, relying on the fact that only the pixels inside the window will be painted. This is especially helpful (at least it helped me) in animating a scrolling motion.
Obviously this trick is not available in a one-panel script, where coordinates outside of the target area (the area I actually want to paint) are nevertheless inside the main window, and will be painted anyway.
So, is there a general way to mask or clip the portion of a graphic element that falls outside of a given area?
Let's say I have an object with x, y, width and height properties which define a region of the window, and than a draw() method which executes a few GdiGraphics methods. I want to make sure that when the draw() method is called, only the region defined by the object x, y, width and height properties is painted. How can I achieve that?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-05-13 19:19:54
For the record, I actually managed to get the above mentioned effect, but I cannot stress enough how much I dislike my solution:

Code: [Select]
var repainting = false;
var repaint_done = false;
var myObj = new PaintRegion(700, 400, 500, 300)


function on_paint(gr){
    myObj.paint(gr);
}


function PaintRegion(x, y, w, h){
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.paint = (gr) => {
        if (repainting) // some GdiGraphics method...
        repainting = !repainting ;
        if (!repaint_done) window.RepaintRect(this.x, this.y, this.w, this.h);
        repaint_done = true
    }
}

I'm not comfortable triggering a RepaintRect method with the on_paint() callback and I have to pay attention that whenever the on_paint event is called, the repainting and repaint_done global variables are set to the proper value. If this is the right direction I can work on it to make it safe, but I reckon there must be a better way.


P.S.
After some tests with multiple objects I settled on the following version which seems to be pretty fluent:
Code: [Select]
function PaintRegion(x, y, w, h){
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.repainting = false;
    this.repaint_done = false;
    this.paint = (gr) => {
        if (this.repainting) //draw something...;
        this.repainting = !this.repainting;
        if (!this.repaint_done) window.RepaintRect(this.x, this.y, this.w, this.h);
        this.repaint_done = !this.repaint_done
    }
}

Still looking forward to insights from skilled coders.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-05-13 23:44:11
Update: the above solution is okay if the objects are separate, but it gets buggy when they overlap.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2019-05-14 18:38:02
Unless I'm missing something, RepaintRect just clips the area that is currently drawn to the screen. So if I draw a rectangle from 0,0,100,100 to the gr buffer, and I'm only painting the region from (50,50 -> 100,100), the next time a full repaint is done, the rectangle will be completely drawn from 0,0 -> 100,100.

Also, it's my understanding that RepaintRect isn't something that causes a draw to happen immediately. It just specifies the region which will be drawn to the screen and that region is the union of the outermost extants of the region on the next draw cycle. So if I do RepaintRect(10,10,20,20) and then another RepaintRect(1000,1000,20,20) before the contents are actually drawn, when the drawcycle occurs it'll actually draw (10,10) -> (1020,1020). I'm assuming the underlying gdi stuff hasn't changed for Spidermonkey.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-05-14 20:27:04
Unless I'm missing something, RepaintRect just clips the area that is currently drawn to the screen. So if I draw a rectangle from 0,0,100,100 to the gr buffer, and I'm only painting the region from (50,50 -> 100,100), the next time a full repaint is done, the rectangle will be completely drawn from 0,0 -> 100,100.

Yes, unless you do this:
Code: [Select]
var myRegion = new PaintRegion(50, 50, 100, 100)


function on_paint(gr){
    myRegion.paint(gr);
}


function PaintRegion(x, y, w, h){
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.repainting = false;
    this.repaint_done = false;
    this.paint = (gr) => {
        if (this.repainting) {
            gr.FillSolidRect(0,0, window.Width, window.Height,0xFF000000);  // these are just examples,any other
            gr.DrawEllipse(80, 30, 200, 200, 2, 0xFFFFFFFF)                 // GdiGraphics method goes here.
            this.repaint_done = true;
            this.repainting = false;
        };
        if (!this.repaint_done) {
            this.repainting = true;
            window.RepaintRect(this.x, this.y, this.w, this.h);
            this.repaint_done = false;           
        };
    }
}

The full paint is done only if the repainting property is true, but this is set to false by default and it is not touched when a full paint is called. It is turned to true only for the RepaintRect method to reference it, and than back to false right after its execution. The repaint_done property works the other way round, in order to prevent a RepaintRect loop.
The above code works, but in my new project I built a system of nested objects, that pass the paint action (any action actually) on to their content, and that's where it gets tricky, but it's a very specific problem for that script.

Anyway, I'd prefer, and I'm still looking for (I still did not look into the Catrox scripts!  :-[ ), an alternative method that doesn't use the on_paint() callback to trigger the RepaintRect() method, for obvious safety reasons, but also because it would probably work in my nested objects chain.



Also, it's my understanding that RepaintRect isn't something that causes a draw to happen immediately.

I'm not sure about that. From what I read in the docs, it behaves like the Repaint() method. Doesn't that call an immediate window repaint?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-05-14 23:10:11
Sorry, I just realized the last line of code which resets the repaint_done property to false, must not be in the conditional section, but right after:
Code: [Select]
var myRegion = new PaintRegion(50, 50, 100, 100)


function on_paint(gr){
    myRegion.paint(gr);
}


function PaintRegion(x, y, w, h){
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.repainting = false;
    this.repaint_done = false;
    this.paint = (gr) => {
        if (this.repainting) {
            gr.FillSolidRect(0,0, window.Width, window.Height,0xFF000000);  // these are just examples,any other
            gr.DrawEllipse(80, 30, 200, 200, 2, 0xFFFFFFFF)                 // GdiGraphics method goes here.
            this.repaint_done = true;
            this.repainting = false;
        };
        if (!this.repaint_done) {
            this.repainting = true;
            window.RepaintRect(this.x, this.y, this.w, this.h);    
        };
       this.repaint_done = false;  // <---------
    }
}

I don't really understand why, though. It seems that the RepaintRect method aborts the execution of the previously called on_paint() function that triggered it. Is that correct?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-05-15 00:11:46
I don't really understand why, though. It seems that the RepaintRect method aborts the execution of the previously called on_paint() function that triggered it. Is that correct?

Alright, I think I understand now what @MordredKLB was telling me in his previous reply (https://hydrogenaud.io/index.php/topic,116669.msg971412.html#msg971412): the new paint event called by the RepaintRect() method is queued and executed only when the first paint event that triggered it is popped off the stack. Right?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2019-05-15 01:23:49
Alright, I think I understand now what @MordredKLB was telling me in his previous reply (https://hydrogenaud.io/index.php/topic,116669.msg971412.html#msg971412): the new paint event called by the RepaintRect() method is queued and executed only when the first paint event that triggered it is popped off the stack. Right?
Not exactly. Say you have a function that calls window.RepaintRect() twice in a row so that two buttons are repainted. It's my understanding that your on_paint method will only be called once the next time a WM_PAINT message is received by the foobar window, and that the cliprect for the area drawn will be the union of the exterior bounds (although that I'm less sure on).

Basically the Javascript is single-threaded, but the operating system isn't, and it queues up the areas that will be drawn.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-05-18 16:19:43
I finally found out how @TheQwertiest managed to solve the above issue in his CatRox theme. It's pretty straightforward actually, but it took me a few days because it was buried in thousands of code lines. So, for who's interested, here is a proper and more reasonable way than the one I came up with:

Code: [Select]
var myRegion = new PaintRegion(100, 100, 200, 200)


function on_paint(gr){
    myRegion.paint(gr);
}


function PaintRegion(x, y, w, h){
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.paint = (gr) => {
        var clipImg = gdi.CreateImage(this.w, this.h)
        var grClip = clipImg.GetGraphics();
        grClip.DrawEllipse(100, 50, 200, 200, 2, 0xFF000000)
        clipImg.ReleaseGraphics(grClip);
        gr.DrawImage(clipImg, this.x, this.y, this.w, this.h, 0, 0, this.w, this.h)
    }
}
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: cerbaire on 2019-06-05 11:43:45
Hello,

I have a question about on_size event. It has two parameters and documentation indicates that it corresponds to panel size.
I have tested that and saw that it correspond to window size.
I did not do the test with JScript panel, but I would like to know if it the same with the JScript Panel ?

Kind regards,
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-06-05 13:44:42
I have a question about on_size event. It has two parameters and documentation indicates that it corresponds to panel size.
I have tested that and saw that it correspond to window size.
That is impossible - SMP currently does not have a way to find the size of fb2k window. on_size arguments ARE panel width and height respectively.
You can easily verify this by creating a layout with two resizeable SMP panels (e.g. in DUI) and replacing the following line in the default script:
Code: [Select]
gr.GdiDrawText(g_text, g_font, g_hot ? g_textcolour_hl : g_textcolour, 0, 0, ww, wh, DT_VCENTER | DT_CENTER | DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX);
with
Code: [Select]
gr.GdiDrawText(`width: ${ww}, height ${wh}`, g_font, g_hot ? g_textcolour_hl : g_textcolour, 0, 0, ww, wh, DT_VCENTER | DT_CENTER | DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX);
Each panel will display it's size, which will change when they are resized.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: cerbaire on 2019-06-05 18:30:31
Thanks for you response.
I was already displaying width and height but is was the same for my for 4 panels.
After more testing, I decided to add a MinWidth and MaxWidth, idem with height. And it is not respected. I use CUI with horizontal and vertical splitter.
The thing is that a panel stretch to the size of the largest panel inside a column, even if larger than MaxWidth.
When you say 'resizeable SMP panel', do you mean that we can have them not resizeable?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-06-17 11:50:40
After more testing, I decided to add a MinWidth and MaxWidth, idem with height. And it is not respected. I use CUI with horizontal and vertical splitter.
MinWidth and MaxWidth properties (and window dimensions adjustment functionality) are not provided by SMP component, but rather by foo_ui_hacks =)
You can use the following code though from my CaTRoX theme though: https://github.com/TheQwertiest/CaTRoX_QWR/blob/61eecfa4159e3714d58f53ae942d5f1861e83fb2/theme/Scripts/Panel_Menu.js#L1018
Note, that you have to change assignments like MinWidth=True to MinWidth.Enabled=True.


When you say 'resizeable SMP panel', do you mean that we can have them not resizeable
I mean smth like parent vertical/horizontal splitter in DUI/CUI that allows for panel size adjustment. There are components that provide panels for CUI/DUI, which allow having other panels inside, but don't allow their resizing.

[EDIT] Disregard this, I can't read...
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Ottodix on 2019-06-26 10:11:57
Hi,

Does someone knows a trick to trigger a new evaluation of panel stack splitter scripts, from a SMP panel ?
There is the play/pause way, using the function below, because the PerTrack scripts of a PSS panel are evaluate on playback changes, but this creates some sound glitches, especially while playing live streams (because foobar can't buffer the stream when this is a live stream, it need to synchronize with the stream after a pause command)

Code: [Select]
function RefreshPSS() {
if (fb.IsPlaying || fb.IsPaused) {
fb.PlayOrPause();
fb.PlayOrPause();
}
else {
fb.Play();fb.Stop();
}
}
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: zeremy on 2019-06-26 19:38:11
Hi,

Does someone knows a trick to trigger a new evaluation of panel stack splitter scripts, from a SMP panel ?
There is the play/pause way, using the function below, because the PerTrack scripts of a PSS panel are evaluate on playback changes, but this creates some sound glitches, especially while playing live streams (because foobar can't buffer the stream when this is a live stream, it need to synchronize with the stream after a pause command)

Code: [Select]
function RefreshPSS() {
if (fb.IsPlaying || fb.IsPaused) {
fb.PlayOrPause();
fb.PlayOrPause();
}
else {
fb.Play();fb.Stop();
}
}

There is a trick you can try.

You will need to enable is the PSS panels "Evaluate scripts when track info is modified"

Change your function to
Code: [Select]

function RefreshPSS() {
let handle_list = plman.GetPlaylistItems(plman.ActivePlaylist);
handle_list.RefreshStats();
}

There is a limitation:  Your handle list cannot be empty.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Ottodix on 2019-06-26 21:28:21
Ah yes, thanks! By combining both methods, you end up with something which work all the time:
Code: [Select]
function RefreshPSS() {
if (fb.IsPlaying || fb.IsPaused) {
let handle_list = new FbMetadbHandleList(fb.GetNowPlaying());
handle_list.RefreshStats();
}
else {
fb.Play();fb.Stop();
}
}

Important point:
 "Evaluate scripts when track info is modified" needs to be enabled AND on the script tab of the PSS panel, "Titleformat mode on startup" needs to be on "now playing"
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-06-27 13:44:23
@cerbaire , I have to apologize: my last answer was answering the wrong question, since I've misread `MinWidth` (present in SMP/JSP) as `MinSize.Width` (foo_ui_hacks)... But you've probably read the (correct) answer by marc2003 by now, so I won't repeat it here... :shame_on_me:
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: cerbaire on 2019-06-27 19:17:17
@cerbaire , I have to apologize: my last answer was answering the wrong question, since I've misread `MinWidth` (present in SMP/JSP) as `MinSize.Width` (foo_ui_hacks)... But you've probably read the (correct) answer by marc2003 by now, so I won't repeat it here... :shame_on_me:
Thanks TheQwertiest, yes I saw marc2k3 response on GitHub.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: spuuunit on 2019-06-27 20:56:20
How can I use foobar2000 code with Spider Monkey Panel code?

This is what I want to do:
Code: [Select]
$if(%ispaused%,❚❚,▶)‌‌
%title%
%playback_time% / %length%

This is my Spider Monkey Panel code so far:
Code: [Select]
var font = gdi.Font("Segoe UI", 12, 0);

function Color(r, g, b) {
return 0xFF000000 | r << 16 | g << 8 | b;
}

function on_paint(gr) {
    gr.FillSolidRect(0, 0, 1000, 1000, Color(240,240,240));
    gr.GdiDrawText("Playing/Paused - Track Title", font, Color(0,0,0), 5, 1, 226, 1000);
    gr.GdiDrawText("00:00 / 00:00", font, Color(0,0,0), 237, 1, 1000, 1000);
}
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Decalicatan_Decalicatan on 2019-06-28 14:12:54
Hi everyone,

Does anyone ever hear of a SMP (or marc2003's jscript) code for an library search toolbar (like the Quicksearch toobar component for example?)
There used to be a WSH toolbar in one of Br3tt's theme (xchange I think) but it's kind of old and I'm not sure I will be able to port it to SMP.

Thanks in advance
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-06-29 00:27:57
Hi everyone,

Does anyone ever hear of a SMP (or marc2003's jscript) code for an library search toolbar (like the Quicksearch toobar component for example?)
There used to be a WSH toolbar in one of Br3tt's theme (xchange I think) but it's kind of old and I'm not sure I will be able to port it to SMP.


Not sure it helps, but here is an adaptation of the script I wrote for my config. It was not meant to work in a component-like fashion, so you might have to edit the code here and there (no window properties, sorry). My coding is much more naive than marc2003's or Br3tt's, but perhaps this makes it easier to grasp and modify.
For reasons I don't understand, it only works with columns ui, maybe some more advanced coder can figure out why,
I still didn't find the time to handle the typing animation when the text's length exceeds that of the width of the panel, so make sure the panel is wide enough for your average search strings.
Search results are displayed in a playlist called "Search results [your search string]", which is overwritten at every new search.

Code: [Select]
"use strict";

include(fb.ComponentPath + "docs\\flags.js");
include(fb.ComponentPath + "docs\\helpers.js");
include(fb.ComponentPath + "samples\\complete\\js\\lodash.min.js");


var font_height = 18;
var fontcolor = colours.White;
var text = "";
var cursor = 0;
var set_cursor = false;
var selection_lx = 0;
var selection_rx = 0;
var selection = "";
var mouse_lbtn_down = false;
var count = 0;
var timerID;
var timer = false;
var edit = false;
var writing = false;
var ctrla = false;
var dblclk = false;
var dblclk_lx = 0;
var dblclk_rx = 0;
var mouse_lbtn_down_x = 0;
var mouse_move_x = 0;
var obj = new ActiveXObject("htmlfile");
var autocomplete = new Array();
var history = new Array();
history.push(text);
var currentState = 0;
var ww = 0;
var wh = 0;
var text_x = 0;


function on_size(){
    ww = window.Width;
    wh = window.Height; 
}


function on_paint(gr){   
    var iconfont = "Segoe mdl2 assets";   
    var font = gdi.Font(iconfont, font_height, 0);
    var selection_color = colours.Black;
    var icon = String.fromCharCode(57492);
    var textheigth = gr.CalcTextHeight(icon, font); 
    text_x = wh + gr.CalcTextWidth(" ", font);
   
    dblclk_lx = Math.max(text.slice(0, getPos(mouse_lbtn_down_x, text, font, gr)).toString().lastIndexOf(" ") + 1, 0);
    dblclk_rx = getPos(mouse_lbtn_down_x, text, font, gr) + (text + " ").slice(getPos(mouse_lbtn_down_x, text, font, gr)).toString().indexOf(" ") + 1;
    selection_lx = getPos(Math.min(mouse_lbtn_down_x, mouse_move_x), text, font, gr);
    selection_rx = getPos(Math.max(mouse_lbtn_down_x, mouse_move_x), text, font, gr);
    if (dblclk) selection_lx = Math.min(selection_lx, dblclk_lx);
    if (dblclk) selection_rx = Math.max(selection_rx, dblclk_rx);
    if (ctrla) selection_lx = 0;
    if (ctrla) selection_rx = text.length;
       
    var selection_x = text_x + (gr.CalcTextWidth(text.slice(0, selection_lx), font));
    var selection_w = gr.CalcTextWidth(text.slice(selection_lx, selection_rx), font);
    var text1 = text.slice(0, selection_lx);
    var text2 = text.slice(selection_lx, selection_rx);
    var text3 = text.slice(selection_rx);
    if (set_cursor) {
        cursor = getPos(mouse_lbtn_down_x, text, font, gr);
        set_cursor = false;
    }
    selection = text2;
    var cursor_x = text_x + gr.CalcTextWidth(text.slice(0, cursor), font);
   

    gr.DrawRect(0, 0, ww - 1, wh - 1, 1, fontcolor);
    gr.GdiDrawText(icon, font, fontcolor, 0, 0, wh, wh, DT_CENTER | DT_VCENTER | DT_SINGLELINE); 
    gr.FillSolidRect(selection_x, (wh - textheigth)/2, selection_w, textheigth, colours.Gray);      
    gr.GdiDrawText(text1, font, fontcolor, text_x, 0, gr.CalcTextWidth(text1, font), wh, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
    gr.GdiDrawText(text2, font, selection_color, text_x + gr.CalcTextWidth(text1, font), 0, gr.CalcTextWidth(text2, font), wh, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
    gr.GdiDrawText(text3, font, fontcolor, text_x + gr.CalcTextWidth(text1, font) + gr.CalcTextWidth(text2, font), 0, gr.CalcTextWidth(text3, font), wh, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
    if (selection_w == 0 && edit && count%2 == 1) gr.DrawLine(cursor_x, (wh - textheigth)/2, cursor_x, (wh + textheigth)/2, 1, fontcolor);
    if (text == "" && !edit) gr.GdiDrawText("Search", font, fontcolor, text_x, 0, ww - text_x, wh, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
    writing = false;
}


function on_mouse_move(x, y){
    window.SetCursor(IDC_IBEAM);
    if (mouse_lbtn_down){
        mouse_move_x = x;
        window.Repaint();
}
}


function on_mouse_lbtn_down(x, y){
    edit = true;
    mouse_lbtn_down = true;
    mouse_lbtn_down_x = x;
    set_cursor = true;
    unselect();
    window.Repaint();
}


function on_mouse_lbtn_up(x, y){
    mouse_lbtn_down = false;
}


function on_mouse_lbtn_dblclk(x, y){
    mouse_lbtn_down = true;
    mouse_lbtn_down_x = x;
    dblclk = true;   
    window.Repaint();
}
   
   
function on_mouse_leave(){
    mouse_lbtn_down = false;
    edit = writing;
}


function on_focus(is_focused){
    if (is_focused){
        timerID = window.SetInterval(function() {
            count++;
            window.Repaint();
            }, 500);   
        timer = true
    } else {
        window.ClearInterval(timerID);
        timer = false;
        count = 0;
        window.Repaint();
    }
}


function on_char(code){
    if (code > 31) {
        if (selection_lx < selection_rx){
            text = text.slice(0, selection_lx) + String.fromCharCode(code) + text.slice(selection_rx);
            cursor = selection_lx + 1;
            unselect();
        } else {           
            text = text.slice(0, cursor) + String.fromCharCode(code) + text.slice(cursor);
            cursor = cursor + 1;
        }
        newState(text);
        var autocompleteMenu = window.CreatePopupMenu();
        var filtered_list = _.uniq(autocomplete, true).filter(filterAutocomplete);
        for (var i = 0; i < filtered_list.length; i++){
            autocompleteMenu.AppendMenuItem(MF_STRING, i + 1, filtered_list[i]);
        }
        var ret = autocompleteMenu.TrackPopupMenu(text_x, wh, 0);
        if (ret > 0){
            text = filtered_list[ret - 1];
            cursor = text.length;
        }
        writing = true;
        window.Repaint();
    }
}
       

function on_key_down(vkey){
    var ShiftKeyPressed = utils.IsKeyPressed(VK_SHIFT);
    var ControlKeyPressed = utils.IsKeyPressed(VK_CONTROL);
    if (!ControlKeyPressed){      
        switch (vkey){           
            case 8: //backspace           
            if (selection_lx < selection_rx){
                text = text.slice(0, selection_lx) + text.slice(selection_rx);
                cursor = selection_lx;
                unselect();
            } else {
                text = text.slice(0, Math.max(cursor - 1, 0)) + text.slice(cursor);
                cursor = Math.max(cursor - 1, 0);
            }
            newState(text);
            break;
           
            case 13: //enter
            search();
            text = "";
            cursor = 0;
            history = [];
            newState(text);
            break;
           
            case 37: //left arrow
            cursor = Math.max(cursor - 1, 0);
            break;
           
            case 39: //right arrow
            cursor = Math.min(cursor + 1, text.length);
            break;
           
            case 46: //delete
            if (selection_lx < selection_rx){
                text = text.slice(0, selection_lx) + text.slice(selection_rx);
                cursor = selection_lx;
                unselect();
            } else {
                text = text.slice(0, cursor) + text.slice(cursor).slice(1);
            }
            newState(text);
            break;
        }
    } else {
        switch (vkey){
            case 65: //ctrl + A
            ctrla = true;
            break;
           
            case 67: //ctrl + C
            obj.parentWindow.clipboardData.setData("Text", selection);
            break;
           
            case 86: //ctrl + V
            var clipboard = obj.parentWindow.clipboardData.getData("Text") + "";
            if (selection_lx < selection_rx){
                text = text.slice(0, selection_lx) + clipboard + text.slice(selection_rx);
            } else {
                text = text.slice(0, cursor) + clipboard + text.slice(cursor);
            }
            cursor = selection_lx + clipboard.length;
            unselect();
            newState(text);           
            break;
           
            case 88: //ctrl + X
            obj.parentWindow.clipboardData.setData("Text", selection);
            text = text.slice(0, selection_lx) + text.slice(selection_rx);
            cursor = selection_lx;
            unselect();
            newState(text);
            break;
           
            case 89: //ctrl + Y
            currentState = Math.max(currentState - 1, 0);
            text = history[currentState];
            cursor = text.length;
            break;
           
            case 90: //ctrl + Z
            currentState = Math.min(currentState + 1, history.length - 1);
            text = history[currentState];
            cursor = text.length;
            break;        
        }
    }
    window.Repaint();
}
           

function getPos(x, text, font, gr){
    var pos;
    for (var i = 0; i <= text.length; i++){
        if (x < text_x + gr.CalcTextWidth(text.slice(0, i + 1), font)){
            pos = i;
            i = text.length + 1;

        } else {
            pos = text.length;
        }
    }
    return pos;
}

   
function unselect(){
    mouse_move_x = mouse_lbtn_down_x;
    dblclk = false;
    ctrla = false;
}


function newState(text){
    history.slice(currentState);
    history.unshift(text);
    currentState = 0;
}


function search(){
    autocomplete.push(text);
    autocomplete.sort();
   
    var SortOrder = "%album artist%|%release date%|%album%|%discnumber%|%set subtitle%|%tracknumber%|%path%";
    try {
        var queryItems = fb.GetQueryItems(fb.GetLibraryItems(), text);
    }
    catch(Error){
        var queryItems = fb.CreateHandleList();
    }
   
    var index = -1;    
    for (var i = 0; i < plman.PlaylistCount; i++) {
       if (plman.GetPlaylistName(i).indexOf("Search results [") == 0) index = i;
    }
    if (index > -1){
        plman.RemovePlaylist(index);
    } else {
        index = plman.PlaylistCount;
    }
    plman.CreatePlaylist(index,"Search results [" + text + "]");
    plman.InsertPlaylistItems(index, 0, queryItems);
    plman.SortByFormat(index, SortOrder); 
    plman.ActivePlaylist = index;
}


function filterAutocomplete(value){
    return value.indexOf(text) == 0;
}
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: CrowRabbit on 2019-06-29 14:40:24
Hi,

I wrote to able use Spider Monkey Panel in TypeScript.
https://github.com/FuCrowRabbit/SpiderMonkeyPanelForTypeScript

Thanks.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: spuuunit on 2019-06-29 14:46:23
Oh god I just figured out how to write my panel! Kind of like a short status bar:

Code: [Select]
var font = gdi.Font("Segoe UI", 12, 0);
var play_pause = fb.TitleFormat('$if(%ispaused%,❚❚,▶)');
var title = fb.TitleFormat('%title%');
var time1 = fb.TitleFormat('%playback_time%');
var time2 = fb.TitleFormat('%length%');


function on_playback_pause() {  // + play
    window.Repaint();
}
function on_playback_new_track() {
    window.Repaint();
}
function on_playback_seek() {
window.Repaint();
}
function on_playback_time() {
window.Repaint();
}


function Color(r, g, b) {
return 0xFF000000 | r << 16 | g << 8 | b;
}
function on_paint(gr) {
    gr.FillSolidRect(0, 0, 1000, 1000, Color(240,240,240));
    gr.GdiDrawText(play_pause.Eval() + " " + title.Eval(), font, Color(0,0,0), 5, 1, 226, 1000);
    gr.GdiDrawText(time1.Eval() + " / " + time2.Eval(), font, Color(0,0,0), 237, 1, 1000, 1000);
}

But does anyone know if there's a way to update just one string, and not the whole panel like window.Repaint(); does?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-06-29 15:05:48
@spuuunit , you can use `RepaintRect(w,h)` instead of `Repaint()` if you want to redraw only part of the panel.

@CrowRabbit , TS typings would be nice, but I'm wary of the duplicated documentation: there is already a JSDoc version https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/master/component/docs/js/foo_spider_monkey_panel.js , and it would be a pain to have to maintain the same docs in TS typings as well... (I mean method descriptions and stuff, I'm fine with maintaining the interface itself)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: spuuunit on 2019-06-29 15:34:06
@spuuunit , you can use `RepaintRect(w,h)` instead of `Repaint()` if you want to redraw only part of the panel.

@CrowRabbit , TS typings would be nice, but I'm wary of the duplicated documentation: there is already a JSDoc version https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/master/component/docs/js/foo_spider_monkey_panel.js , and it would be a pain to have to maintain the same docs in TS typings as well... (I mean method descriptions and stuff, I'm fine with maintaining the interface itself)

Thanks! But how exactly does that look like, is it like this: window.RepaintRect(0, 1000, 0, 1000); Does that cover the whole area? Because nothing is updating for me.

And another thing: The playback time that increases every second is what I want to update. Is it worth updating just that area all the time, rather than the whole panel, to save resources? Or does panel update affect resources so little that I shouldn't bother?

EDIT: This is my panel by the way. 4 tags and a background color: https://imgur.com/Pds7rqY
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-06-29 16:17:26
That's cause you are using it wrong =)
The method prototype is `window.RepaintRect(x,y,w,h)` and you calling it like `window.RepaintRect(x,w,y,h)`. So, in your case, the correct call would be `window.RepaintRect(0, 0, 1000, 1000)`.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: spuuunit on 2019-06-29 16:32:34
Oh shit thanks! =) But does RepaintRect require less computer power than only Repaint? If so I'll go with that.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-06-29 16:37:26
RepaintRect will use less CPU only if the area it's redrawing is smaller then your whole panel. Otherwise there will be no difference.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: spuuunit on 2019-06-29 16:47:28
Ok thanks!

I have 2 more questions, sorry to be a nuicense.  O:)
1. Is it possible to draw text right aligned?
2. Is it possible to draw an external image, a PNG for example.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Decalicatan_Decalicatan on 2019-06-29 18:43:04

Not sure it helps, but here is an adaptation of the script I wrote for my config. It was not meant to work in a component-like fashion, so you might have to edit the code here and there (no window properties, sorry). My coding is much more naive than marc2003's or Br3tt's, but perhaps this makes it easier to grasp and modify.
For reasons I don't understand, it only works with columns ui, maybe some more advanced coder can figure out why,
I still didn't find the time to handle the typing animation when the text's length exceeds that of the width of the panel, so make sure the panel is wide enough for your average search strings.
Search results are displayed in a playlist called "Search results [your search string]", which is overwritten at every new search.

Thank you! Very much appreciated :)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-06-30 11:45:56
Thank you! Very much appreciated :)

Don't bother ask if you need help understanding the script or indications on which variables must be edited to change the appearance.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Decalicatan_Decalicatan on 2019-07-01 10:26:53
Don't bother ask if you need help understanding the script or indications on which variables must be edited to change the appearance.

Thanks for the offer ^^ ....

Maybe you can help me for a more generic question then:
Where can I find character codes if I wanted to change the search icon in the line "var icon = String.fromCharCode(57492);").
(I already managed to change the font / color / other stuffs)

Thanks in advance.. and thanks once again to profide me the script,, even I you prefer not to answer, which I can undersand.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-07-01 11:33:48

Maybe you can help me for a more generic question then:
Where can I find character codes if I wanted to change the search icon in the line "var icon = String.fromCharCode(57492);").
(I already managed to change the font / color / other stuffs)

Well, I guess it depends on the new font you chose. You can look it up in the windows character map application where it is shown as UTF-8 code, you than have to convert it to decimal in order to use it in the fromCharCode method (I use online converters for this purpose).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-07-01 11:37:10
1. Is it possible to draw text right aligned?
See documentation for `GdiDrawText` method, specifically `format` argument.

2. Is it possible to draw an external image, a PNG for example.
See docs for `LoadImageAsync`/`LoadImageAsyncV2`, `DrawImage`/`GdiDrawBitmap` methods and basic `LoadImageAsync.js`/`LoadImageAsyncV2.js` samples.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Decalicatan_Decalicatan on 2019-07-01 13:27:16
Well, I guess it depends on the new font you chose. You can look it up in the windows character map application where it is shown as UTF-8 code, you than have to convert it to decimal in order to use it in the fromCharCode method (I use online converters for this purpose).

Thank you. The hex to decimal conversion part was what I missed. Now it's working.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: spuuunit on 2019-07-01 23:17:03
1. Is it possible to draw text right aligned?
See documentation for `GdiDrawText` method, specifically `format` argument.

2. Is it possible to draw an external image, a PNG for example.
See docs for `LoadImageAsync`/`LoadImageAsyncV2`, `DrawImage`/`GdiDrawBitmap` methods and basic `LoadImageAsync.js`/`LoadImageAsyncV2.js` samples.

God thank you! I found those documentation files, didn't even know they were there. Finally I put together my panel and it's perfect. =)

Thank you TheQwertiest for an awesome plugin and all the support! This plugin must give endless possibilities for you guys who really know how to script. Keep up the good work!
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-07-02 15:01:36
I found those documentation files, didn't even know they were there. Finally I put together my panel and it's perfect.

FYI, there is a JS version and HTML version of the docs. You want the HTML version, which is accessible via `Context Menu`>`Configure Panel`>`Help`>`View Help`.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: cerbaire on 2019-07-12 14:12:14
1. Is it possible to draw text right aligned?
See documentation for `GdiDrawText` method, specifically `format` argument.

2. Is it possible to draw an external image, a PNG for example.
See docs for `LoadImageAsync`/`LoadImageAsyncV2`, `DrawImage`/`GdiDrawBitmap` methods and basic `LoadImageAsync.js`/`LoadImageAsyncV2.js` samples.

Is it possible to load an image directly from an url ?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-07-12 16:00:03
Is it possible to load an image directly from an url ?
Nope, you'll have to download it manually: SMP does not provide any direct means to work with the Web, you have to use a suitable COM object via `ActiveObjectX` interface (e.g. `ActiveObjectX("MSXML2.XMLHTTP")`.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: cerbaire on 2019-07-16 15:46:01
Is it possible to load an image directly from an url ?
Nope, you'll have to download it manually: SMP does not provide any direct means to work with the Web, you have to use a suitable COM object via `ActiveObjectX` interface (e.g. `ActiveObjectX("MSXML2.XMLHTTP")`.
I have created a code using XMLHttpRequest that can download binary stream of file under Chrome, but it does not work inside a SMP panel (using a the ActiveX component instead of XMLHttpRequest object), and then I don't find anyway to save the stream to filesystem.
Any clue appreciated.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Ottodix on 2019-07-17 18:48:47
It's not an easy problem. You can try to look at the code of the Biography script by Wilb, there (https://hydrogenaud.io/index.php/topic,112913.msg929674.html#new), it calls a VBScript in order to download images (well his VBScript can actually download any kind of file).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: whyonearth on 2019-07-22 03:20:00
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-07-22 11:24:06
With foobar2000 v 1.5 beta 6 and foo_spider_monkey_panel nightly build v1.2.2-beta+8a02533a I observe constant memory usage growing in following scenario

It's not really leaking: garbage collector in SMP has several triggers, two of them are `allocated memory trigger` and `allocation count trigger`. The problem is that I can't know the size of a loaded ActiveXObject, so it doesn't trigger GC as much as it should. But, if you are actively using your script (instead of just reloading it =)), it should encounter one of the GC triggers sooner or later and will free all the memory occupied by ActiveXObject's.

Regarding your suggestions: noted, but I don't think I'll work on these any times soon - I have a few major features that I really want to implement and it will take quite a lot of time... COM objects being a major PITA (and the lack of documentation) also doesn't help.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-07-22 11:48:06
@Awesomeo : moved SMP specific discussion here, as to not clutter @WilB 's thread.

And vice versa, I could have any PSS element that would react to changes in a particular SMP. So maybe something like $set_smp(smp_id,property,value) and $get_smp(smp_id,property).
This is not possible - PSS does not provide any way to extend it's API. What I will (probably) do is add an additional panel option, which would allow to define panel `events` that could be used by fb2k shortcuts.

Hm, not sure if I fully understand this, because both things happen at once for me: playback pauses and the library tree search field receives a space.
Playback pause/play shortcut uses 'on_key_down' event (which is not passed to script in this case), library tree uses 'on_key_up' event (which is passed).

However I've already checked other CUI panels with typing option, like 'Typefind' or 'Youtube Source Search' and keystrokes work locally in them, they don't execute foobar's global hotkeys
Dunno about Youtube Source, but it seems that 'Typefind' uses quite a hacky method to workaround this problem. I'm not quite ready to make such hacks (might change my mind though).
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: whyonearth on 2019-07-22 15:31:19
With foobar2000 v 1.5 beta 6 and foo_spider_monkey_panel nightly build v1.2.2-beta+8a02533a I observe constant memory usage growing in following scenario

It's not really leaking: garbage collector in SMP has several triggers, two of them are `allocated memory trigger` and `allocation count trigger`. The problem is that I can't know the size of a loaded ActiveXObject, so it doesn't trigger GC as much as it should. But, if you are actively using your script (instead of just reloading it =)), it should encounter one of the GC triggers sooner or later and will free all the memory occupied by ActiveXObject's.
OK, I think I understand this. SMP garbage collector had been tuned to kick-in based on reasonable criterias. And instantiation of ActiveX object doesn't produce any meaningful information that can contribute to this criteria, so garbage collector just have no reasons to react to growing memory usage.

Problem is, even though multiple saving/reloading is a laughable use-case (not in bad sense), I really did it on valid purpose, when I iteratively developed SMP script. Change script a little, save, try it out. Repeat.

With instantiation of AutoHotkey COM object (as I described in list item 4), memory usage grows in about 1-2 MB chunks on every save/reload event. I think, I have not so modern computer, with just 2GB RAM, and Windows 10 is memory-hungry too, so I hit OOM. I really did. Foobar2000 process just was killed. That's a bad experience.

So maybe, if tuning GC kick-in criteria now requires changes to C++ code and recompilation of SMP, the solution to my problem would be a possibility for user to contribute to criteria with JavaScript API.

Something like
Code: [Select]
window.TriggerSmpGcAsap()

Calling such function will trigger SMP garbage collector as soon as possible even though criterias defined in C++ code aren't fulfilled yet.

With this function I can do something like
Code: [Select]
const gc_memory_criteria = 20 * (1024 * 1024 * 1024); // 20 MB

function on_script_unload() {
  if (window.PanelMemoryUsage > gc_memory_criteria) {
    window.TriggerSmpGcAsap()
  }
}

Also, even though you don't know the size of a loaded ActiveXObject, but I (as user) can observe memory usage growing and make an assumption about this size. So maybe there could be a way to pass this information from JavaScript to component, like
Code: [Select]
const obj = newActiveXObject('Some.MemoryHungry.COM.Object')
window.AssumeObjectSizeInGcCriteria(obj, 2*1024*1024*1024 /*2 MB*/);

Regarding your suggestions: noted, but I don't think I'll work on these any times soon - I have a few major features that I really want to implement and it will take quite a lot of time... COM objects being a major PITA (and the lack of documentation) also doesn't help.
I totally agree about COM technology being PITA  :'(  and I didn't even interact with it in C++, so I can only imagine how it is (but I don't want to, sorry  ;D).

However, all of my suggestions for new SMP features don't directly touch COM.

I implemented Tab key focusing by setting WS_TABSTOP (https://docs.microsoft.com/en-us/windows/win32/winmsg/window-styles) window style for SMP control from AutoHotkey script. So I suggested adding of JavaScript API for enabling/disabling this style from SMP panel script.

And suggestion about extending JavaScript API for manipulating activation contexts also don't need COM programming at all. Just introducing thin wrapper for instantiating ACTCTX (https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-tagactctxa) structure and calling CreateActCtx (https://docs.microsoft.com/ru-ru/windows/win32/api/winbase/nf-winbase-createactctxa), ActivateActCtx (https://docs.microsoft.com/ru-ru/windows/win32/api/winbase/nf-winbase-activateactctx) and DeactivateActCtx (https://docs.microsoft.com/ru-ru/windows/win32/api/winbase/nf-winbase-deactivateactctx).

There are also other function in Activation Context API (https://docs.microsoft.com/en-us/windows/win32/sbscs/activation-context-reference), but they are possibly not so important for simple use-cases like mine.

But anyway, it's just a clarification. I understand that SMP development is driven by your motivation and motivation can be substantially lowered by unwanted distractions. I'm the only one who asked for this features, and I can live without them for long time or even forever, as I've found workarounds. So it's totally OK for me to know that these features wouldn't be implemented soon or wouldn't be implemented at all.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-07-22 17:08:18
Something like
Code: [Select]
window.TriggerSmpGcAsap()
I will not implement such method if I can avoid. Reason is simple: users ALWAYS try to shoot themselves in the foot, e.g. call `ForceGC` in every `on_paint` event and then complain that the performance is bad.
I'll try to think of a better way to solve your problem (hoping there is one).

window.AssumeObjectSizeInGcCriteria(obj, 2*1024*1024*1024 /*2 MB*/);
Same with exposing such internals. API should be kept as concise as possible (I would remove/reorganize quite a few methods from the current SMP if I could do so without breaking compatibility).

PS: `2*1024*1024*1024` is 2GB =)

And suggestion about extending JavaScript API for manipulating activation contexts also don't need COM programming at all. Just introducing thin wrapper for instantiating ACTCTX (https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-tagactctxa) structure and calling CreateActCtx (https://docs.microsoft.com/ru-ru/windows/win32/api/winbase/nf-winbase-createactctxa), ActivateActCtx (https://docs.microsoft.com/ru-ru/windows/win32/api/winbase/nf-winbase-activateactctx) and DeactivateActCtx (https://docs.microsoft.com/ru-ru/windows/win32/api/winbase/nf-winbase-deactivateactctx).
These are not general-purpose methods so they would never be placed in the core namespaces, maybe they could be added as static methods of ActiveXObject... (or perhaps a candidate for a SMP plugin, once/if such plugin API is implemented).

About tabbing: I'll take a look, but no ETA =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: whyonearth on 2019-07-22 18:33:33
PS: `2*1024*1024*1024` is 2GB =)
Yep, you are right, the code was wrong, the code comment is correct. Don't know how it happened. Thanks for noticing.

It's good to know that you've took a closer look at suggested features. I'll patiently wait.

If you don't want to give user any access to GC control knobs, it might be enough to force GC in C++ code just after invoking JS on_script_unload() callback (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/3467e78e0266a7e03c8c08a0cf1fc1acdd6305d6/foo_spider_monkey_panel/js_panel_window.cpp#L944) (maybe force conditionally, based on state of checkbox added in Panel Features menu). As far as I can deduce from looking at code, it should cover cases of saving script in panel configuration window and script reload. After all, on reload most (all?) references in unloaded script should be unreachable and targeted for garbage collection anyway.



As I'm using AutoHotkey, I'm looking for ways to push information from AutoHotkey script to SMP script (pulling information from AutoHotkey script and pushing information to AutoHotkey script could be done with COM object methods).

AutoHotkey can send (or post) windows messages (https://hotkeyit.github.io/v2/docs/commands/PostMessage.htm) to windows and controls with given parameters. As my limited understanding of SMP component code allows me to suppose, SMP's on_main_menu() callback is invoked based on specific window message number and argument passed to on_main_menu() callback is parameter of window message. So it could be used for my purposes.

However, window message number (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/5589fb60982f066b24f44f0315b0ce8fefd1444d/foo_spider_monkey_panel/user_message.h#L64) for invoking on_main_menu() callback can change between releases of SMP, because of possible changing of related enums where this number is defined. This makes relying on concrete number a bit reckless.

Can you provide separate callback (like on_wm_user_message()), which would be called on receving windows message with stable number? Or maybe you can expose main_menu_item message number in property accessible from JS script (like window.MAIN_MENU_ITEM_WM_NUMBER), so that I can push it to AutoHotkey script?

(Concrete names of functions and properties are not important.)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Ottodix on 2019-07-24 15:47:11
HI,

Is there a way to get a playlist track metadb without retrieving the whole content of the target playlist?
I'm trying to get the focused track of a playlist (any playlist, not the active one).
So i've got that
Code: [Select]
var focus_index = plman.GetPlaylistFocusItemIndex(playlistIndex);		
var metadbs = plman.GetPlaylistItems(playlistIndex);
metadb = metadbs[focus_index];

But in term of performance, it means that i will temporary create a object containing the whole playlist, isn't it an issue on very large playlist? I would prefer something like
Code: [Select]
plman.GetPlaylistItemByIndex(playlistIndex, item_index);
Or eventually, something like that, in order to get the FbMetadbHandle instead of just the index
Code: [Select]
plman.GetPlaylistFocusItem(playlistIndex);
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-07-24 16:45:45
I have created a code using XMLHttpRequest that can download binary stream of file under Chrome, but it does not work inside a SMP panel (using a the ActiveX component instead of XMLHttpRequest object), and then I don't find anyway to save the stream to filesystem.
Sorry, forgot to answer your post:
`xhr` in chrome/mozilla/edge is not the same as `*legacy* xhr` which is XMLHttpRequest activexobject.
It's possible to manually invoke it in JavaScript in SMP, but the problem is that it's impossible to save the file asynchronously, meaning that it will block the main thread until the operation is finished. The solution to this is to invoke the `download&save` operation in a separate process. One such example is the one @Ottodix mentioned: invoke the download with a separate VBScript via `cscript,exe`: VBScript file - `samples\complete\vbs\download.vbs`; example usage - `samples\complete\js\thumbs.js` (https://github.com/marc2k3/smp_2003/blob/98fb2425975dcd8d3e999a7f25282392403d60dd/js/thumbs.js#L525)

it might be enough to force GC in C++ code just after invoking JS on_script_unload() callback
Actually I was thinking about it when I was tuning GC, but decided against it exactly due to the scenario when user reloads script a lot to test his changes. I should try to trigger a minimal GC though, since minimal GC has minimal impact on UX.

Can you provide separate callback (like on_wm_user_message())
I can't, since it will tank the performance - crossing JS <> native boundary is not free and message loop is one of the most often called places.

Or eventually, something like that, in order to get the FbMetadbHandle instead of just the index
Uhm, you could just call `fb.GetFocusItem()` though? =)
But yea, there is currently no way to get a single track (except for the focused track) from the playlist without fetching the array containing the whole playlist.

[EDIT]: I can't currently think of a proper scenario when you would have a track index, but wouldn't have the whole playlist or means to access the corresponding track: you are either working with the whole playlist or you need a specific track because of it's status (that is selected, focused, queued and etc) which means that you can access them via corresponding methods.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Ottodix on 2019-07-25 10:29:40
Uhm, you could just call `fb.GetFocusItem()` though? =)

fb.GetFocusItem() works only on the active playlist. This is inside a on_item_focus_change(playlistIndex, from, to) callback.
In this callback, I would like to get the focused track handle, and this status is effectively focused, but ! Not in the active playlist unfortunately
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-07-25 10:44:58
Hm... Just wondering, why would you need a focused track from non-active playlist? =)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Ottodix on 2019-07-25 16:23:53
Hm... Just wondering, why would you need a focused track from non-active playlist? =)

this is a little bit complex, i'm building a side panel which show infos about the focused track, it needs to interact with others panels showing tracks from a playlist which is not necessary the active one (and i can't make it the active one without triggering on_playlist_switch everywhere, and it would be a major performance drawback on my layout).

I think i will try to trigger a refresh of this "info panel" without on_item_focus_change but instead with on_notify_data() and a custom on_focus_change function, all my panels are SMP panels anyway, it will allow me a better control

EDIT: Yes, it's much easier to control with with on_notify_data(), less foobar-logic-compliant, but it doesn't matter
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: thisbanisnotsettoexpire on 2019-07-26 02:15:20
Something like
Code: [Select]
window.TriggerSmpGcAsap()
I'll try to think of a better way to solve your problem (hoping there is one).
I (whyonearth) was banned for not really considering forum rules. I hope now I'm complying with them. Sorry for breaking the rules and for confusion with replying from new account.

Anyway, that OOM-on-repeated-script-reload error I was talking about was not an OOM error at all. Nevertheless, it's still error of resource exhaustion type.

So, I noted that there was some free memory at the time of crash. This is when I thought I might be wrong in my conclusions. Then I somehow did look more thoroughly at foobar2000 crash report and accidentally 93MB of .rar files extracted meaningful information (crash report is trimmed here):
Spoiler (click to show/hide)

So, code tried to access address zero, when last win32 error was error with code 1114 (ERROR_DLL_INIT_FAILED (https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--1000-1299-): A dynamic link library (DLL) initialization routine failed).

I examined AutoHotkey_H sources, then downloaded OllyDbg and tried to trace AutoHotkey DLL execution. Starting point was in DllGetClassObject (https://github.com/HotKeyIt/ahkdll/blob/eec985c16ff284ec77bde2423bb584c3a7fb1463/source/dllmain.cpp#L1199). Here's what I found.
Spoiler (click to show/hide)

Relevant links:Spoiler (click to show/hide)

So, when I naively chose Win32w_MT variant of AutoHotkey.dll from release distribution, I chose statically linked library (which I didn't know at the time) and this brought some fixed limits.

Good news, in recent version of Windows 10 this limit is raised: read here (https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/3546c3c4-1b36-4552-85c5-1b3ba860ee84/how-many-dlls-can-be-loaded-in-a-process-using-loadlibrary-?forum=windowssdk#2e017194-025e-4521-bee0-aad21fd1f805) and here (https://www.gearslutz.com/board/showpost.php?p=13729254&postcount=62&s=b7f43881db1fa1a81da3cc76ceba2e51). Bad news (for me), I'm not using the recent version of Windows 10.

So, while I can instead use dynamically linked AutoHotkey.dll (from Win32w directory), which is linked with vcruntime140.dll, just as foobar2000, and this replacement seems to fix crashes, I thought, maybe if SMP component would just unload COM DLL on unloading (i.e. reloading) SMP script, this also should fix my problem?

While, looking at the SMP code, I can find CoFreeUnusedLibraries (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/9252b68ba8caca8cecc0a9a9f64b76c8bacd314a/foo_spider_monkey_panel/js_objects/active_x_object.cpp#L420), I believe, in real usage component doesn't always work as expected.

Trying to prove that normally used CoFreeUnusedLibraries certainly should free FLS indexes allocated by COM DLL (at least, by AutoHotkey.dll), I did some experiments:
Spoiler (click to show/hide)

So, I think this is where SMP can be improved.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-07-26 15:15:44
@thisbanisnotsettoexpire : that's quite a research you did there =)
I'm not sure if this is SMP bug, since it seems that AHK reserves new FLS on every execution, but as I said I will add some GC on panel unload.

Not sure when will it happen though, since MS released a broken Visual Studio update, which made it impossible to compile SMP (and I just can't find enough motivation to go through the whole VS reinstallation process to get the working VS back).
<rant>This f***ing s***-show makes me wonder if they even go through QA before making a release...</rant>
<rant intensifies>And don't even get me started on this f***ing disgusting compact title-bar...</rant>
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2019-07-26 20:44:01
@thisbanisnotsettoexpire : that's quite a research you did there =)
I'm not sure if this is SMP bug, since it seems that AHK reserves new FLS on every execution, but as I said I will add some GC on panel unload.

Not sure when will it happen though, since MS released a broken Visual Studio update, which made it impossible to compile SMP (and I just can't find enough motivation to go through the whole VS reinstallation process to get the working VS back).
<rant>This f***ing s***-show makes me wonder if they even go through QA before making a release...</rant>
<rant intensifies>And don't even get me started on this f***ing disgusting compact title-bar...</rant>
Is this VS2019 - 16.2.0 you're talking about?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: thisbanisnotsettoexpire on 2019-07-27 04:07:27
As far as I can understand from sources, SMP allows to pass JS function as argument to COM object method. Passed function is wrapped in IDispatch-able gateway and this function could be invoked from COM object side by using gateway's ExecuteValue() (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/8a02533ad58ced877ace97dae7d482e5da5c17de/foo_spider_monkey_panel/convert/com.cpp#L79) method.

AutoHotkey_H COM object can assign value to variable in AutoHotkey script with ahkassign (https://hotkeyit.github.io/v2/docs/commands/ahkassign.htm) method. Though documentation says that only string value can be passed to that method and assigned to variable, in fact, as AutoHotkey_H sources show, CoCOMServer::ahkassign (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/dllmain.cpp#L803) recognizes different COM types (calling AssignVariant (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/script_com.cpp#L757), then VariantToToken (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/script_com.cpp#L620)). By passing VT_DISPATCH COM value to ahkassign, it's possible to assign AutoHotkey object to AutoHotkey script variable and then invoke IDispatch methods from AutoHotkey side by using same-named object methods.

I successfully tested this functionality of AutoHotkey_H COM object with Python script:
Spoiler (click to show/hide)

But when I used AutoHotkey_H COM object in SMP JS script in the same way as in Python script, trying to call JS function from AutoHotkey script side, it produced access violation error on ExecuteValue() call from AutoHotkey script.

JS script code:Spoiler (click to show/hide)

In tests I used following versions: Spoiler (click to show/hide)

I tried to trace SMP code with OllyDbg, found that ExecuteValue() is really called on SMP component side and (if my understanding is right) in this line (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/8a02533ad58ced877ace97dae7d482e5da5c17de/foo_spider_monkey_panel/convert/com.cpp#L97)
Code: [Select]
JS::RootedObject jsGlobal( pJsCtx_, heapMgr.Get( globalId_ ).toObjectOrNull() );
heapMgr.Get( globalId_ ) returned 0.

If I'm right, can it be fixed? (Just asking about possibility, not pushing to do it ASAP.)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: thisbanisnotsettoexpire on 2019-07-28 15:29:04
While, looking at the SMP code, I can find CoFreeUnusedLibraries (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/9252b68ba8caca8cecc0a9a9f64b76c8bacd314a/foo_spider_monkey_panel/js_objects/active_x_object.cpp#L420), I believe, in real usage component doesn't always work as expected.

Trying to prove that normally used CoFreeUnusedLibraries certainly should free FLS indexes allocated by COM DLL (at least, by AutoHotkey.dll), I did some experiments:

So, I think this is where SMP can be improved.
In that experiments I used CoUninitialize and it was critical for successful results, but, while it's OK to use this function in the end of execution of standalone script, now I believe (basing on CoUninitialize documentation (https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-couninitialize)), that using it in SMP is either not allowed at all, or at least would require cooperation between author of foobar2000, authors of all other components and author of SMP (i.e. it's impractical).

Turns out, just using CoFreeUnusedLibraries wasn't enough to produce noticable releasing of FLS indexes, because
Quote
CoFreeUnusedLibraries does not immediately release DLLs that have no active object. There is a 10-minute delay for multithreaded apartments (MTAs) and neutral apartments (NAs). For single-threaded apartments (STAs), there is no delay.

No, it's not a quote from CoFreeUnusedLibraries documentation (https://docs.microsoft.com/ru-ru/windows/win32/api/combaseapi/nf-combaseapi-cofreeunusedlibraries), it's a quote from CoFreeUnusedLibrariesEx documentation (https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cofreeunusedlibrariesex). Thanks a lot, Microsoft.

CoFreeUnusedLibrariesEx is specifically provided to set explicit delay for unloading DLLs with a way to force the unloading of DLLs without any delay, though remarks in CoFreeUnusedLibrariesEx documentation warn against forcing immediate unloading of DLLs.

With using CoFreeUnusedLibrariesEx I can consistently release FLS indexes in test script without CoUninitialize:
Spoiler (click to show/hide)

The problem is, with any reasonable delay (even reasonably small delay), there probably would still be no useful change in my original SMP's usage scenario (in the concrete case of using statically linked AutoHotkey DLL), because in reloading script new AutoHotkey COM object would be created by reloaded script in a time smaller than that delay and then AutoHotkey DLL wouldn't be unloaded and allocated FLS indexes wouldn't be released and foobar2000 will still crash after repeated script reloading.

But anyway, it looks like this particular mysterious mystery of strange mystery is resolved and, with this information, maybe TheQwertiest will come up with some heuristic to use the possibility of setting COM DLLs unload delay.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-07-29 13:17:50
Is this VS2019 - 16.2.0 you're talking about?
Yup

I tried to trace SMP code with OllyDbg, found that ExecuteValue() is really called on SMP component side and (if my understanding is right) in this line (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/8a02533ad58ced877ace97dae7d482e5da5c17de/foo_spider_monkey_panel/convert/com.cpp#L97)
Code: [Select]
JS::RootedObject jsGlobal( pJsCtx_, heapMgr.Get( globalId_ ).toObjectOrNull() );
heapMgr.Get( globalId_ ) returned 0.

If I'm right, can it be fixed? (Just asking about possibility, not pushing to do it ASAP.)
This should not ever happen - it's a bug.
Can you try the nightly build (see OP for the link) and check if the bug persists?

PS: Thanks for the detailed repro steps!
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: thisbanisnotsettoexpire on 2019-08-08 14:58:49
I tried to trace SMP code with OllyDbg, found that ExecuteValue() is really called on SMP component side and (if my understanding is right) in this line (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/8a02533ad58ced877ace97dae7d482e5da5c17de/foo_spider_monkey_panel/convert/com.cpp#L97)
Code: [Select]
JS::RootedObject jsGlobal( pJsCtx_, heapMgr.Get( globalId_ ).toObjectOrNull() );
heapMgr.Get( globalId_ ) returned 0.
I changed debugger from OllyDbg to x64dbg (https://x64dbg.com/) (it has 32-bit version and can debug 32-bit code, despite the name) and, coincidentally, place of error also changed. I didn't try to debug with OllyDbg again, so I can't say whether I was just plainly wrong in quoted bug report, or there was some misunderstanding on my side. However, after several attempts at debugging with x64dbg, I successfully found bugfix.

I patched foo_spider_monkey_panel v1.2.1 (https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.2.1) DLL at following offsets (from the beginning of file):
OffsetOriginal valuePatched value
0x3F7790xFF0x90
0x3F77A0xD70x90

Originally I used runtime patching ability of x64dbg and exported patch in .1337 format. It looks like offsets in this patch are not from the beginning of the file, so it wasn't useful for me per se, but for completeness I paste it here:Spoiler (click to show/hide)

Original values are assembled as CALL EDI instruction and patch replaces it with NOPs.

In terms of C++ sources, patch removes this line (https://github.com/TheQwertiest/foo_spider_monkey_panel/blob/667bfffec3df96a8e8b36b70240739d728eddeac/foo_spider_monkey_panel/js_objects/active_x_object.cpp#L812) in ActiveXObject::Invoke method:
Code: [Select]
VariantClear( &args[i] );

After patching, I can execute JS script from quoted post without any errors, but with producing expected result of appending an entry to foobar2000 console. As ExecuteValue method is the default member of SMP's COM object (i.e. it is identified by DISPID_VALUE (https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/cb9d0131-c6bd-463d-9c40-7264856a10c5)), it can also be invoked from AutoHotkey side by using following syntax: Spoiler (click to show/hide)

If I'm right, can it be fixed? (Just asking about possibility, not pushing to do it ASAP.)
This should not ever happen - it's a bug.
Can you try the nightly build (see OP for the link) and check if the bug persists?
After replacing foo_spider_monkey_panel v1.2.1 to v1.2.2-beta+8a02533a I observe Access Violation error on the ahk.ahkExec('f.ExecuteValue()'); line. Though I can't say that it's the same bug. In absence of .pdb for nightly and having working stable DLL, I didn't try to debug nightly to find the cause of error.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-08-08 15:56:04
@thisbanisnotsettoexpire : that's some extensive debugging!
It's really weird though that `VariantClear` causes errors: it just cleans up arguments that were generated for function call (and it should be safe for well-formed COM types). Not doing this will cause memory leaks.

Nevertheless, I can't test nor debug this (nor continue the component development) since I still don't have a working Visual Studio installation: current version (16.2) is broken and I couldn't find a way to download the previous release...

PS: Corresponding .pdb symbols (as well as a debug build) are available on the appveyor agent - https://ci.appveyor.com/project/TheQwertiest/foo-spider-monkey-panel/builds/26070987/job/nxn00otulu6tyrl7/artifacts
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: thisbanisnotsettoexpire on 2019-08-09 14:06:02
It's really weird though that `VariantClear` causes errors: it just cleans up arguments that were generated for function call (and it should be safe for well-formed COM types). Not doing this will cause memory leaks.
Thanks for hint. I guess then it's working, but wrong solution. VariantClear (https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-variantclear):
Quote
clears a VARIANTARG by setting the vt field to VT_EMPTY. The current contents of the VARIANTARG are released first. [...] If the vtfield is VT_DISPATCH, the object is released.

So I've took an attempt to come up with solution from other side and patched AutoHotkey_H DLL v2.0-a100-H104:
Spoiler (click to show/hide)

It changes 0x6A 0x00 to 0x6A 0x01, i.e. PUSH 0 to PUSH 1.

In terms of original source, it modifies function CoCOMServer::ahkassign (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/dllmain.cpp#L803) by changing argument false in function call (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/dllmain.cpp#L812) to true:
Code: [Select]
AssignVariant(*var, value, false);

It means that AssignVariant (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/script_com.cpp#L757) is called with argument aRetainVar = true, then VariantToToken (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/script_com.cpp#L620) is called with argument aRetainVar = true, then reference count for an interface pointer to a COM object is incremented (https://github.com/HotKeyIt/ahkdll/blob/af0541bcb57240bcfbf29884cf358367be27962b/source/script_com.cpp#L718).

I'm not sure that it's correct bugfix (is AutoHotkey_H really must be responsible for incrementing reference counter?), but it also works with Spider Monkey Panel v1.2.2-beta+8a02533a.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-08-09 16:22:13
After some incredible shenanigans I've managed to get myself a working VS2019 16.1 installation (no thanks to Microsoft)!
Anyways...

@thisbanisnotsettoexpire : I've managed to reproduce your crash - it seems that the COM object passed to `ahkassign` does not have it's counter incremented.
Code: [Select]
...
function f();
...
ahk.assign('f', f);
...
SMP wraps function `f` in a COM object and passes it to `ahk.assign`.
So, we have the following scenario:
- COM object is created from JS object. It has a usage counter equal to 1.
- COM object is passed to ahk.assign. Usage counter was not incremented in ahk.assign.
- Local (to SMP) COM object is destroyed. Usage counter is decremented to zero thus the VARIANT is destroyed as well.
- If ahk tries to use said (destroyed) COM object it will invoke UB and most likely crash.

Quote
    is AutoHotkey_H really must be responsible for incrementing reference counter?
Yes, because the caller does not how the passed object will be utilized. COM object handling is the same as shared_ptr.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-08-09 17:06:29
@thisbanisnotsettoexpire : I've tested with the debug build of AHK and my guess was proven true - AHK assign does not increase ref count. This is the code which assigns my COM object to internal ASH variable: https://github.com/HotKeyIt/ahkdll/blob/7e6d355db20d6faf59d8a15fcc908b52ff7b5d80/source/script_com.cpp#L731
There is no reference increments going on unless aRetainVar was set to true (which is not the case for `ahkassign`).

[EDIT] Moreover, it seems that `ahkassign` will actually DECREASE refcount of the incoming object WITHOUT incrementing it in some cases (invoking UB if the caller didn't increase refcount) : e.g. https://github.com/HotKeyIt/ahkdll/blob/7e6d355db20d6faf59d8a15fcc908b52ff7b5d80/source/script_com.cpp#L698
This code is flawed and I can't find any sensible scenario when it would be a correct approach. Your AHK patch *is* the correct fix.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-08-12 12:02:11
Well f**k... VS 2019 was updated to 16.2 on the build agent, so now SMP can't be built there... And there is still no answer from Microsoft on this issue...
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: cerbaire on 2019-08-19 16:24:01
It's not an easy problem. You can try to look at the code of the Biography script by Wilb, there (https://hydrogenaud.io/index.php/topic,112913.msg929674.html#new), it calls a VBScript in order to download images (well his VBScript can actually download any kind of file).

Thank you Ottidix and TheQwertiest. It works great. It was finally quite simple but I did no get the idea by myself !
Another question ; I have an error 'can't access dead object' !
Any suggestion on why this error is raised ?
I will check the livecycle of my object, but if you have any clue (I reset SMP parameters in 'Advanced / Tools / SMP settings, but not sufficient)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Ottodix on 2019-08-19 16:43:30
Another question ; I have an error 'can't access dead object' !
Any suggestion on why this error is raised ?

It completely depend of your code, there is a lot of possible scenarios. One common mistake : if you send a object from another panel using window.NotifyOthers(name,info), you need to clone the object inside the corresponding callback on_notify_data(name,info) of the receiver panel, you can't just assign by reference to another variable. Because the "info" object is destructed at the end of this function.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-08-20 12:09:20
@cerbaire , Ottodix's suggestion is entirely correct. You can find more info about it in the documentation of `on_notify_data` callback (you can access HTML documentation via 'Configure...'>'Help'>'View Help').
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: cerbaire on 2019-08-20 17:05:13
@cerbaire , Ottodix's suggestion is entirely correct. You can find more info about it in the documentation of `on_notify_data` callback (you can access HTML documentation via 'Configure...'>'Help'>'View Help').

Thanks for your responses. I understand the problem, and I think I am not in the scenario of a on_notify_data call.
My object is a FbMetadbHandle stored in a list. I will check on which event I am binded, but I think I instantiate my object directly in the panel script so it is not binded to any documented SMP event. I check that tonight and let you know.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Ottodix on 2019-08-21 09:58:05
Then it's really impossible to help without the code, you can debug it yourself though. You can use a function like:

Code: [Select]
function debug_dead_item(metadb_list,index){
    console.log("desired index: "+index+", list length: "+metadb_list.length);
    console.log(metadb_list[index].RawPath);
}

Put checkpoints in your code with this function in order to trace when/where this object was available and when/where it's not anymore, and then you'll probably understand what's going on. This function will crash if the list or if the specified index doesn't exist, but it doesn't matter, the crash message will be as good an information than the console messages.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-08-21 10:28:32
Thanks for your responses. I understand the problem, and I think I am not in the scenario of a on_notify_data call.
My object is a FbMetadbHandle stored in a list. I will check on which event I am binded, but I think I instantiate my object directly in the panel script so it is not binded to any documented SMP event. I check that tonight and let you know.
The problem might be delayed: e.g.
Code: [Select]
// Pseudo code

let arr = []
on_notify_data(data) {
  // no error
  arr.push_back(data);
}

on_mouse_click() {
  // error
  console.log(arr[0].Path);
}
On another note: what SMP version are you using?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: cerbaire on 2019-08-21 12:18:14
Thanks for your responses. I understand the problem, and I think I am not in the scenario of a on_notify_data call.
My object is a FbMetadbHandle stored in a list. I will check on which event I am binded, but I think I instantiate my object directly in the panel script so it is not binded to any documented SMP event. I check that tonight and let you know.
The problem might be delayed: e.g.
Code: [Select]
// Pseudo code

let arr = []
on_notify_data(data) {
  // no error
  arr.push_back(data);
}

on_mouse_click() {
  // error
  console.log(arr[0].Path);
}
On another note: what SMP version are you using?

I am using last nightly build available.
In the panel code, I call GetPlaylistItems(-1) in a setTimeout() and store index and FbMetadbHandle returned by GetPlaylistItems. Later, in a on_mouse_lbtn_up, I use the previous stored FbMetadbHandle, and it fail.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-08-21 14:22:02
I am using last nightly build available.
In the panel code, I call GetPlaylistItems(-1) in a setTimeout() and store index and FbMetadbHandle returned by GetPlaylistItems. Later, in a on_mouse_lbtn_up, I use the previous stored FbMetadbHandle, and it fail.
That's really weird. Can you provide a minimal repro scenario? So that I could reproduce it locally.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: cerbaire on 2019-08-22 00:14:50
I am using last nightly build available.
In the panel code, I call GetPlaylistItems(-1) in a setTimeout() and store index and FbMetadbHandle returned by GetPlaylistItems. Later, in a on_mouse_lbtn_up, I use the previous stored FbMetadbHandle, and it fail.
That's really weird. Can you provide a minimal repro scenario? So that I could reproduce it locally.
You're right ! I was storing FbMetadbHandle in a function called from on_notify_data, and using that handle after the callback end.
I replace the handle by the RawPath property and it works better!
Thank you for putting me in the right direction.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-08-22 11:16:49
You're right ! I was storing FbMetadbHandle in a function called from on_notify_data, and using that handle after the callback end.
I replace the handle by the RawPath property and it works better!
Thank you for putting me in the right direction.
No! You are using it wrong! Please, read documentation for the `on_notify_data`...
Your usage (for both FbMetadbHandle and FbMetadbHandle.RawPath) is covered explicitly in the method description.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: cerbaire on 2019-08-22 13:51:56
You're right ! I was storing FbMetadbHandle in a function called from on_notify_data, and using that handle after the callback end.
I replace the handle by the RawPath property and it works better!
Thank you for putting me in the right direction.
No! You are using it wrong! Please, read documentation for the `on_notify_data`...
Your usage (for both FbMetadbHandle and FbMetadbHandle.RawPath) is covered explicitly in the method description.
Right! I now use JSON.parse(JSON.stringify(metadb)) to store a copy of my handle and it works lke a charm. Thanks.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-08-22 15:17:06
Right! I now use JSON.parse(JSON.stringify(metadb)) to store a copy of my handle and it works lke a charm. Thanks.
Uhm... no...

Code: [Select]
...
 If you want to store the data from `info` you have to perform a deep copy:
- `String(info)` for strings.
...
So if you want to store `metadb.RawPath`, you store it like this:
Code: [Select]
// Pseudo code
g_storage = []
on_notify_data(metadb)
{
  // `String` performs a deep copy
  g_storage.push_back(String(metadb.RawPath))
}

You can't serialize `metadb` since it's not a serializable object (i.e. it will be restored into a simple struct instead after deserialization).
To clone metadb you'll have to clone metadbhandlelist instead (metadb does not have a copy constructor):
Code: [Select]
// Pseudo code
g_storage = []
on_notify_data(metadb)
{
  // FbMetadbHandleList constructor always performs a deep copy
  let tmpHandleList = new FbMetadbHandleList(metadb);
  g_storage.push_back(tmpHandleList[0]);
}
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2019-08-29 07:24:11
Is there a way to get an arbitrary URL to open in a browser from FSM (or jscript)? I was thinking this was simple, then when I tried to implement it, I realized that all the times I'd seen it done required foo_run, along with pre-defined URLs.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: thisbanisnotsettoexpire on 2019-08-29 10:11:42
Is there a way to get an arbitrary URL to open in a browser from FSM (or jscript)? I was thinking this was simple, then when I tried to implement it, I realized that all the times I'd seen it done required foo_run, along with pre-defined URLs.
Maybe Shell.ShellExecute (https://docs.microsoft.com/en-us/windows/win32/shell/shell-shellexecute) will work?
Code: [Select]
const objShell = new ActiveXObject("Shell.Application");
objShell.ShellExecute("https://hydrogenaud.io");
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: zeremy on 2019-08-29 12:53:42
Is there a way to get an arbitrary URL to open in a browser from FSM (or jscript)? I was thinking this was simple, then when I tried to implement it, I realized that all the times I'd seen it done required foo_run, along with pre-defined URLs.

Use Wshshell.Run with WScript.Shell

Sample function
https://github.com/marc2k3/smp_2003/blob/ed613ee3875cc914ea102a763758457431cdfc25/js/helpers.js#L516
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-08-29 15:42:35
Back from my holidays, the lastfm album art downloader is not working anymore. It is an old script by marc2003 that I modified now and then. It is quite obvious that the reason is a change in the lastfm web page HTML code. It is likely a silly problem, but I'm not familiar with HTML, so maybe someone here can help me out.

The following is - as far as I understand - the relevant code which needs some change:
Code: [Select]
include(fb.ComponentPath + 'samples\\complete\\js\\lodash.min.js');
include(fb.ComponentPath + 'samples\\complete\\js\\helpers.js')
include(fb.ComponentPath + 'samples\\complete\\js\\panel.js');

var x = new ActiveXObject("Microsoft.XMLHTTP");
var ar = panel.tf("$meta_sep(artist,', ',' and ')");
var al = panel.tf("%album%");

x.open("GET", "https://www.last.fm/music/" + encodeURIComponent(ar) + "/" + encodeURIComponent(al) + "/+images", true);
x.setRequestHeader("If-Modified-Since", "Thu, 01 Jan 1970 00:00:00 GMT");
x.send();

var o = _.first(_.filter(_getElementsByTagName(x.responseText, "img"), {"className" : "image-list-image"}));


The issue is in the last line of the above code. It used to fetch the first of the album covers on the album lastfm page, such as this one (https://www.last.fm/music/Alessandro+Alessandroni/Prisma+Sonoro/+images). I've been looking at this part of the HTML code (from line 1077 in the aforementioned example page):
Code: [Select]
    <ul class="image-list">
       
            <li class="image-list-item-wrapper">
                <a href="/music/Alessandro+Alessandroni/Prisma+Sonoro/+images/829db16b90ed471cbbfe248ef08ada39" class="image-list-item">
                    <img
                        src="https://lastfm-img2.akamaized.net/i/u/avatar170s/829db16b90ed471cbbfe248ef08ada39.webp"
                        alt="None"
                    >
                </a>
            </li>
       
            <li class="image-list-item-wrapper">
                <a href="/music/Alessandro+Alessandroni/Prisma+Sonoro/+images/72cd2e7b55604336b9003de58bf58d24" class="image-list-item">
                    <img
                        src="https://lastfm-img2.akamaized.net/i/u/avatar170s/72cd2e7b55604336b9003de58bf58d24.webp"
                        alt="None"
                    >
                </a>
            </li>
       
            <li class="image-list-item-wrapper">
                <a href="/music/Alessandro+Alessandroni/Prisma+Sonoro/+images/d002704049d844f4ba5dcc647614a483" class="image-list-item">
                    <img
                        src="https://lastfm-img2.akamaized.net/i/u/avatar170s/d002704049d844f4ba5dcc647614a483.webp"
                        alt="None"
                    >
                </a>
            </li>
       
    </ul>


I guess the parameters in the _getElementsByTagName function do not match the page HTML code anymore, but I cannot reference it properly.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2019-08-29 17:31:23
Maybe Shell.ShellExecute (https://docs.microsoft.com/en-us/windows/win32/shell/shell-shellexecute) will work?
Code: [Select]
const objShell = new ActiveXObject("Shell.Application");
objShell.ShellExecute("https://hydrogenaud.io");

Use Wshshell.Run with WScript.Shell

Sample function
https://github.com/marc2k3/smp_2003/blob/ed613ee3875cc914ea102a763758457431cdfc25/js/helpers.js#L516
Thanks, guys. thisban's code worked great, but I already had Marc's helper script in my theme so I saved a line of code :)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: MordredKLB on 2019-08-29 17:37:42
Back from my holidays, the lastfm album art downloader is not working anymore. It is an old script by marc2003 that I modified now and then. It is quite obvious that the reason is a change in the lastfm web page HTML code. It is likely a silly problem, but I'm not familiar with HTML, so maybe someone here can help me out.

The following is - as far as I understand - the relevant code which needs some change:
...

I guess the parameters in the _getElementsByTagName function do not match the page HTML code anymore, but I cannot reference it properly.
A few things:
1) The img's don't have "image-list-image" class attached to them anymore, so all images are being filtered out. You'd have to completely remove the _.filter section, or first get all "a" tags and filter by class="image-list-item" and then get all images from inside those. I haven't used those methods enough to know how to write that relevant code though.
2) Those are .webp images. Can SMP even handle those, presuming they can be scraped correctly?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-08-29 19:18:44
A few things:
1) The img's don't have "image-list-image" class attached to them anymore, so all images are being filtered out. You'd have to completely remove the _.filter section, or first get all "a" tags and filter by class="image-list-item" and then get all images from inside those. I haven't used those methods enough to know how to write that relevant code though.
2) Those are .webp images. Can SMP even handle those, presuming they can be scraped correctly?

Thanks, I'll try your suggested fixes. I don't know about the webp format yet. I wanted to fix the file download anyway, as a mean to better understand how to use the xmlhttp object. I found instructions on how to manually download the webp file as a jpg, so maybe it's possible to edit the code in order to emulate such method. Perhaps a better alternative would be to get the jpg url from the meta tag (line 65 of the HTML code in the above example page). This might be my next question.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-08-30 10:25:02
@davideleo , I think it should be fixed with the latest marc2003 scripts (https://github.com/marc2k3/smp_2003). Download them and put them in samples/complete.

@MordredKLB , SMP doesn't support .webp images.
[EDIT] MSDN indicates that there's some built-in support for .webp images, but there is no information on when and where such support is available (https://docs.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-constant-image-file-format-constants)

PS: I might have found a workaround that might allow me to work around MSVS issues.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-08-31 18:01:22
@davideleo , I think it should be fixed with the latest marc2003 scripts (https://github.com/marc2k3/smp_2003). Download them and put them in samples/complete.

Thanks for the link, but I cannot find the "Last.fm Album Art Downloader" script. As far as I know marc2003 stopped updating it since a few years, at least publicly.

However I tried fetching the jpg URL in the page metadata with this code:
Code: [Select]
let doc = new ActiveXObject('htmlfile');
doc.open();
doc.write(x.responseText);                       
var o = doc.querySelector("meta[property='og:image']").getAttribute("content");
doc.close();

The code correctly assigns the url, such as this one (https://lastfm-img2.akamaized.net/i/u/ar0/829db16b90ed471cbbfe248ef08ada39.jpg), to the variable "o", but the "download" visual basic script doesn't seem to like it as an argument. The code that runs the visual basic script is the following:
Code: [Select]
_runCmd("cscript //nologo " + _q(fb.ComponentPath + "samples\\complete\\vbs\\download.vbs") + " " + _q(o) + " " + _q(f), false);
where the variable "f" is the destination filename.

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-09-03 17:11:18
The code correctly assigns the url, such as this one (https://lastfm-img2.akamaized.net/i/u/ar0/829db16b90ed471cbbfe248ef08ada39.jpg), to the variable "o", but the "download" visual basic script doesn't seem to like it as an argument.

Problem solved. The issue was a leftover line of the previous code (commented out in the script below) which I naively thought to be harmless.


Code: [Select]
                        let doc = new ActiveXObject('htmlfile');
                        doc.open();
                        doc.write(x.responseText);                       
                        var o = doc.querySelector("meta[property='og:image']").getAttribute("content");
                        doc.close();                     
// var u = o.src.replace("avatar170s", "ar0");
     _runCmd("cscript //nologo " + _q(fb.ComponentPath + "samples\\complete\\vbs\\download.vbs") + " " + _q(o) + " " + _q(f), false);
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: cerbaire on 2019-09-06 18:53:33
Hello,

When I use image in my panels, for example with gdi.Image('path.to.img'), I can't delete the file from filesystem without closing foobar2000. Is there a best practice to release image handle?
Kind regards,
Nicolas
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: spuuunit on 2019-09-14 09:45:27
Hi, I just noticed that when I print out the track title for example ( fb.TitleFormat('%title%'); ) the character & does not display correctly. This is what it looks like (https://imgur.com/WZFkRYk). It's not a huge deal, but it would be nice if I could fix it. And ideas?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-09-14 13:44:39
Hi, I just noticed that when I print out the track title for example ( fb.TitleFormat('%title%'); ) the character & does not display correctly. This is what it looks like (https://imgur.com/WZFkRYk). It's not a huge deal, but it would be nice if I could fix it. And ideas?
What method are you calling to print the text? Which font are you using?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-09-15 17:26:00
I'm a little confused about the encodeURIComponent() function.
The lastfm album art downloader script uses the function to get the right URL of the lastfm album page, like this:
Code: [Select]
include(fb.ComponentPath + 'samples\\complete\\js\\panel.js');

var x = new ActiveXObject("Microsoft.XMLHTTP");
var ar = panel.tf("$meta_sep(album artist,', ',' and ')");
var al = panel.tf("%album%");
x.open("GET", "https://www.last.fm/music/" + encodeURIComponent(ar) + "/" + encodeURIComponent(al), true);

This usually worked fine, but with the Damned's "The MCA Singles A's + B's" I got
https://www.last.fm/music/The%20Damned/The%20MCA%20Singles%20A's%20%2B%20B's (https://www.last.fm/music/The%20Damned/The%20MCA%20Singles%20A's%20%2B%20B's)
whereas the URL of the lastfm album page is
https://www.last.fm/music/The%20Damned/The%20MCA%20Singles%20A's%20%252B%20B's (https://www.last.fm/music/The%20Damned/The%20MCA%20Singles%20A's%20%252B%20B's)

The encodeURIComponent() function properly converts the "+" character to "%2B", but the lastfm URL shows a sort of double encoding converting the "%" character to "%25" in turn, and thus the "+" character becomes "%252B".
Therefore I changed the code applying the function twce, like this:
Code: [Select]
"https://www.last.fm/music/" + encodeURIComponent(encodeURIComponent(ar)) + "/" + encodeURIComponent(encodeURIComponent(al))
getting a weird
https://www.last.fm/music/The%2520Damned/The%2520MCA%2520Singles%2520A's%2520%252B%2520B's (https://www.last.fm/music/The%2520Damned/The%2520MCA%2520Singles%2520A's%2520%252B%2520B's)
which surprisingly (at least for me) works as well.

Can anybody explain me the logic of this double encoding?


Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-09-16 14:43:18
Can anybody explain me the logic of this double encoding?
It seem that's just a bug in lastfm url generation.
`encodeURIComponent` seems to perform exactly as it's described in JavaScript docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-09-16 14:48:13
Version: 1.2.2-preview
Link: https://github.com/TheQwertiest/foo_spider_monkey_panel/releases/tag/v1.2.2-preview
Changelog:
Spoiler (click to show/hide)
Detailed description of API changes: https://github.com/TheQwertiest/foo_spider_monkey_panel/wiki/API-Changes#v122

PS: the version is called "preview", because it was built manually on my PC (instead of appveyor CI as before). Because of Microsoft shenanigans this is the only way right now. It will be republished as a proper non-preview version once MS fixes the bug (mind you, it's already been two months since the bug was reported). It will be the same though functionality-wise (unless there are bugs discovered, of course)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: davideleo on 2019-09-16 15:32:52
It seem that's just a bug in lastfm url generation.
`encodeURIComponent` seems to perform exactly as it's described in JavaScript docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent

Yes, sorry my question was not clear enough. How come the double encoding works? Unlike my code, lastfm's bug generates a double encoding of only one percentage character in the URL. In other words, why does
https://www.last.fm/music/The%2520Damned/The%2520MCA%2520Singles%2520A's%2520%252B%2520B's (https://www.last.fm/music/The%2520Damned/The%2520MCA%2520Singles%2520A's%2520%252B%2520B's)
lead me to
https://www.last.fm/music/The%20Damned/The%20MCA%20Singles%20A's%20%252B%20B's (https://www.last.fm/music/The%20Damned/The%20MCA%20Singles%20A's%20%252B%20B's)?
It is as if all "%25" were interpreted as "%", but one.
Mind that triple encoding doesn't work.

Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: spuuunit on 2019-09-16 20:55:00
What method are you calling to print the text? Which font are you using?

gr.GdiDrawText. Segoe UI, and that font has the '&' character.

Here's my code for clarity:
Code: [Select]
var font = gdi.Font("Segoe UI", 12, 0);
var play_pause = fb.TitleFormat('$if(%ispaused%,❚❚,▶)');
var title = fb.TitleFormat('%title%');
var time1 = fb.TitleFormat('%playback_time%');
var time2 = fb.TitleFormat(' / %length%');


function on_playback_pause() {
    window.Repaint();
}
function on_playback_new_track() {
    window.Repaint();
}
function on_playback_seek() {
window.Repaint();
}
function on_library_items_changed() {
window.Repaint();
}
function on_playback_time() {
window.RepaintRect(213, 3, 85, 12);
}


function Color(r, g, b) {
return 0xFF000000 | r << 16 | g << 8 | b;
}
function on_paint(gr) {
    var time_width = gr.CalcTextWidth(time1.Eval() + time2.Eval(), font);
    gr.FillSolidRect(0, 0, 1000, 1000, Color(240,240,240));
    gr.GdiDrawText(play_pause.Eval() + " " + title.Eval(), font, Color(0,0,0), 5, 1, 287 - time_width, 1000);
    gr.GdiDrawText(time1.Eval() + time2.Eval(), font, Color(0,0,0), 297 - time_width, 1, 1000, 1000);
}
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-09-16 21:45:13
@spuuunit : `GdiDrawText` (which uses `::DrawText` internally) uses `&` for some formatting rules (e.g. adding underscore to the following character). In your case you can just add `DT_NOPREFIX` flag (0x00000800) to the method. For more info about flags of `GdiDrawText` see corresponding section in docs/flags.js.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: spuuunit on 2019-09-17 17:39:55
@spuuunit : `GdiDrawText` (which uses `::DrawText` internally) uses `&` for some formatting rules (e.g. adding underscore to the following character). In your case you can just add `DT_NOPREFIX` flag (0x00000800) to the method. For more info about flags of `GdiDrawText` see corresponding section in docs/flags.js.

Oooh, I see. That makes sense. And thanks, I added that now. :)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Madthunder on 2019-09-18 19:31:05
I had a problem moving from 1.2.1 to 1.2.2 when using the updated jsplaylist-mod.

I seems like g_font_wd2 and g_font_wd3 were undefined in WSHplaylistmanager.js and WSHtopbar.js and so I had to add the following in both files (specifically, in the functions oPlaylistManager and oTopBar):

Code: [Select]
var g_font_wd2 = {
name: "Wingdings 2",
Size: 24
};

var g_font_wd3 = {
name: "Wingdings 3"
};

This fixes the problem for me.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-09-20 21:54:38
@Madthunder , nice catch! Will be fixed in the next release.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-09-30 16:09:52
@AndreaT , most likely you are using up all the memory =)

Quote
At least I can have it running for a while
Do you mean that the script doesn't fail immediately?

I will try to whip up a debug build that has a more detailed error message.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-02 16:27:44
@AndreaT , most likely you are using up all the memory =)

Quote
At least I can have it running for a while
Do you mean that the script doesn't fail immediately?

I will try to whip up a debug build that has a more detailed error message.

@TheQwertiest : Yes, exactly so, the script runs for a while, even for minutes, then it crashes randomly (but quite often when making a search or browsing/scrolling through the search's results).
Regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-10-02 17:30:47
@AndreaT, does it fail always in the same place (i.e. OrderByRelativePath)? If not, does it produce the same error message ("allocation overflow") ?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: Lasternom on 2019-10-04 16:40:59
Hi all,

I've got an questions. I'm trying to make a theme selector that would changes the whole colour scheme of foobar.
I was wondering if it's possible to change the default colours in Columns UI, as shown in the attached picture, this ofcourse with the SpiderMonkeyPanel.

My apologies If I'm asking this question in the wrong place.






Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-10-05 15:29:13
I've got an questions. I'm trying to make a theme selector that would changes the whole colour scheme of foobar.
I was wondering if it's possible to change the default colours in Columns UI, as shown in the attached picture, this ofcourse with the SpiderMonkeyPanel.

My apologies If I'm asking this question in the wrong place.
AFAIK, CUI/DUI does not provide such API, so SMP can't do much about it :\
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-07 17:47:56
@AndreaT, does it fail always in the same place (i.e. OrderByRelativePath)? If not, does it produce the same error message ("allocation overflow") ?

@TheQwertiest : I am sorry, I cannot be of help about, I didn't take care of that.
As soon as a new version with improved debugging will be available, I will reinstall the component and I will take care to update you more precisely.
Many thanks.
Kind regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-10-10 00:19:53
PS: Nightly builds are up again! (thanks to Appveyor team!) (no thanks to Microsoft...)
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-10 17:08:02
@TheQwertiest

SMP crash on Windows 10 Pro 32bit. But working perfectly on Windows 7 Ultimate 32bit

Hello, I don't know if this is a SMP problem or a problem of Biography 1.1.1, but this happens with FB 1.5 beta 17 and 18 on Windows 10 Pro 32bit ITA version.

To be noted that I am running exactly the same configuration also on Windows 7 Ultimate 32bit ITA without any significant problems.

Thanks and regards,
Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-10-11 10:36:29
@TheQwertiest

SMP crash on Windows 10 Pro 32bit. But working perfectly on Windows 7 Ultimate 32bit

Hello, I don't know if this is a SMP problem or a problem of Biography 1.1.1, but this happens with FB 1.5 beta 17 and 18 on Windows 10 Pro 32bit ITA version.

To be noted that I am running exactly the same configuration also on Windows 7 Ultimate 32bit ITA without any significant problems.

Well, you are out of memory =)
This error usually happens when there are too many images loaded (or the images are too big).
The difference between Win7 and Win10 might be caused by the difference in RAM/VRAM consumption by OS (i.e. Win10 consumes more memory than Win7).
PS: How much RAM and VRAM do you have?
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-11 13:01:42
@TheQwertiest

I was not out of memory, I had over 1GB available.
I have 4GB total (the max for a 32bit OS).

And also I do not agree on Windows 10 consuming more memory of Win7, it is the contrary.

Foobar (exactly the same configuration) uses 1100MB on Win7 and only 950MB on Win10.

And, question, why you point to the memory while the error is speaking about an "image/window resize error"?

Regarding the image size and the like, Biography 1.1.1 is fetching images from internet. Usually are small, a matter of kB.

Regards,
Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: TheQwertiest on 2019-10-11 15:59:38
why you point to the memory while the error is speaking about an "image/window resize error"?
Because `Resize` does not modify the current image, but creates a new resized image from the old one.

It might be something else though: it seems that GdiPlus might return `OutOfMemory` error even if the error has nothing to do with memory...
Another thing you could check is the amount of GDI handles used: open Task Manager (CTRL-SHIFT-ESC) > Details > Right-Mouse-Button on column header > Select columns > Check `GDI objects`. This will display the current number of GDI objects used by process.
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-13 08:20:20
@TheQwertiest

Hi, I checked the system and everything was within the normal limits.
So, I decided to remove the Biography script, delete all the sub-folders related to Biography, but not its install where the config files are.
Then I run Foobar again and reloaded the Biography script.
Doing so, it is finally working fine.
Probably there was something corrupted in the subfolders structure or in the ACL.
I think the real error was related to some disk write error / access denied in writing.
Regards, Andrea
Title: Re: Spider Monkey Panel (foo_spider_monkey_panel)
Post by: AndreaT on 2019-10-19 08:13:18
@TheQwertiest
Hello TheQwertiest, I am just reminding you that I am still having this blocking error with Library Tree:

Error: Spider Monkey Panel v1.2.2-preview+0db3c6a4 (Library Tree v2.1.2 by WilB)
OrderByRelativePath failed:
allocation size overflow

File: <main>
Line: 542, Column: 61

Stack trace:
  Panel/this.sort@<main>:542:61
  rootNames@<main>:1205:48
  Library/this.getLibrary@<main>:1190:119
  Timers/this.lib/<@<main>:2911:115



I contacted WilB once more and he gave me this reply:

Reply #255 – 2019-10-17 18:54:23
As far as I am aware this seems to be a bug in spider monkey panel and outside of my control, but I am open to suggestions. I just tried again with a 642K test library & all was OK here. That particular error seems to be occurring on panel initialisation and is explicitly related to view by folder structure. So you could try a different view (if the error is locking you out you could open panel properties and find SYSTEM.View By [it's probably the last entry] and change it to 1 to set a different view).

I thought you were debugging the issue with @TheQwertiest? It sounds as though the issue is reproducible and so it ought to be possible to resolve the cause.

HTH
Last Edit: 2019-10-17 19:08:22 by WilB


Can you help me solving this issue?
Many thanks and kind regards, Andrea
SimplePortal 1.0.0 RC1 © 2008-2019