Skip to main content

Notice

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

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #200
RepaintRect will use less CPU only if the area it's redrawing is smaller then your whole panel. Otherwise there will be no difference.

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #201
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.

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #202

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 :)
Decalicatan Decalicatan


Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #204
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.
Decalicatan Decalicatan

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #205

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).
I'm late

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #206
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.

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #207
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.
Decalicatan Decalicatan

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #208
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!

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #209
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`.

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #210
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 ?

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #211
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")`.

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #212
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.

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #213
It's not an easy problem. You can try to look at the code of the Biography script by Wilb, there, it calls a VBScript in order to download images (well his VBScript can actually download any kind of file).

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #214
  • 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:
    • Install foobar2000 in default configuration
    • Edit DUI layout by replacing Playlist Tabs container with Spider Monkey Panel
    • Edit default script with adding
      Code: [Select]
      const obj = new ActiveXObject('Shell.Application');
      in initialization section (for example, right after "use strict";)
    • Save script (or reload it) many times (10-20 times will do) to produce noticeable growing of memory used by foobar2000 process

    This specific scenario is described here just for the sake of reproducibility. But generally speaking, it looks like Spider Monkey Panel leaks memory on script reload by not "freeing" COM objects instantiated in reloaded script.

    This behavior makes it problematic to iteratively develop scripts with relatively memory hungry COM objects (like 1-2 MB on instantiation).

  • I'd like to control foobar2000 UI with keyboard and, in doing so, to focus on Spider Monkey Panel by using standard Tab/Shift-Tab keys. However, now it's not possible.

    Can this feature be added?

    I suggest to extend JavaScript API with things like Spoiler (click to show/hide)
    And also add checkbox in Panel Features menu (named "Can be focusable by Tab key"), off by default to be backward compatible. Checkbox state should be mirrored in related window property on script reload.

    These property/functions/preference are possibly not so good named. Any other names will be also fine for me.

  • Given that Spider Monkey Panel JavaScript API allows to instantiate a COM object, it would be nice if this instantiation ability in addition to default registry-based approach of locating required DLLs in system-wide locations would also support decoupled from registry, private, manifest-file-based side-by-side DLL assemblies.

    If this would be possible, third-party DLLs with useful COM objects could be distributed with custom Spider Monkey Panel scripts and being used from these scripts without requiring administrator rights for registering DLLs in system registry.

    Technically, it requires usage of Activation Contexts and Activation Context API.

    My little brain dump concerning possible implementation:Spoiler (click to show/hide)

  • As a somewhat amalgamation of all items above, here is an example for enabling usage and control of AutoHotkey scripts from Spider Monkey Panel script by loading in-process COM server without requiring administrator rights for registering related DLL.

    AutoHotkey allows users of most levels of computer skill to automate repetitive tasks in any Windows application. User interfaces can easily be created, extended or modified by AutoHotkey.

    Loading in-process AutoHotkey DLL (instead of separate program) and controlling AutoHotkey script execution from Spider Monkey Panel script solved my problem of synchronous startup and termination of both scripts.

    Background in (not-)short:Spoiler (click to show/hide)

    Note that this example uses Microsoft.Windows.ActCtx ActiveX object available starting from Windows Server 2003 (for desktop users it means, starting from Windows Vista).

    Example:Spoiler (click to show/hide)

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #215
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.

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #216
@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).

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #217
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 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 structure and calling CreateActCtx, ActivateActCtx and DeactivateActCtx.

There are also other function in Activation Context API, 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.

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #218
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 structure and calling CreateActCtx, ActivateActCtx and 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 =)

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #219
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 (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 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 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.)

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #220
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);

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #221
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.

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #222
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


Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #224
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