It is currently October 13th, 2024, 12:54 am

[BUG?] Delay bang in OnRefreshAction's nested variable

Report bugs with the Rainmeter application and suggest features.
User avatar
death.crafter
Rainmeter Sage
Posts: 1398
Joined: April 24th, 2021, 8:13 pm

Re: [BUG?] Delay bang in OnRefreshAction's nested variable

Post by death.crafter »

Yincognito wrote: June 25th, 2021, 4:04 pm Plain example based on your log reply:

Code: Select all

[Variables]
StartMessageIdx=1
MiddleMessageIdx=1
EndMessageIdx=1
StartMessage1=[!Log "1"]
MiddleMessage1=[!Log "1.5"][!Delay 3000][!Log "2.5"]
EndMessage1=[!Log "3"]

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
BackgroundMode=2
SolidColor=47,47,47,255
OnRefreshAction=[#StartMessage[#StartMessageIdx]][#MiddleMessage[#MiddleMessageIdx]][#EndMessage[#EndMessageIdx]]

---Meters---

[DummyMeter]
Meter=Image
W=100
H=100
SolidColor=255,0,0,255
LeftMouseUpAction=[!Log "1"][!Log "1.5"][!Delay 3000][!Log "2.5"][!Log "3"]
The OnRefreshAction gets things wrong, while the LeftMouseUpAction gets things right.
Ofc it does. Cause now the nuts are:

[!Log "1"], [!Log "1.5"], [!Delay 3000], [!Log "2.5"], [!Log "3"]
from the Realm of Death
User avatar
Yincognito
Rainmeter Sage
Posts: 8441
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG?] Delay bang in OnRefreshAction's nested variable

Post by Yincognito »

death.crafter wrote: June 25th, 2021, 4:10 pm Ofc it does. Cause now the nuts are:

[!Log "1"], [!Log "1.5"], [!Delay 3000], [!Log "2.5"], [!Log "3"]
These were ALWAYS the nuts. There was never a separate [!Log "1.5"][!Delay 3000][!Log "2.5"] nut. Remember, a nut (or an action, however you want to call it) is always a single bang, and not a collection of 3 (!!!) bangs like above, irrespective if they are part of some plain or nested variable:
Bangs are action commands that control various aspects of skins and Rainmeter. They are executed when used with action options in the skin.
Source here and here. The !Delay bang itself is a single nut or action, just like the !Log bangs or any other bang, for that matter.

I like the way you defend your view - I'm like that as well -, but really, logic and Rainmeter's structure is pretty clear on this one.

EDIT: So that we're clear: a nested variable IS NOT a bang / action / nut. Period. It is a variable (string or number, but mostly a string) that can (or not) contain the text of any number of bangs / actions. Don't be fooled by the fact they both use the same "separators", i.e. square brackets. :D
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
death.crafter
Rainmeter Sage
Posts: 1398
Joined: April 24th, 2021, 8:13 pm

Re: [BUG?] Delay bang in OnRefreshAction's nested variable

Post by death.crafter »

Yincognito wrote: June 25th, 2021, 4:25 pm These were ALWAYS the nuts. There was never a separate [!Log "1.5"][!Delay 3000][!Log "2.5"] nut. Remember, a nut (or an action, however you want to call it) is always a single bang, and not a collection of 3 (!!!) bangs like above, irrespective if they are part of some plain or nested variable:

Source here and here. The !Delay bang itself is a single nut or action, just like the !Log bangs or any other bang, for that matter.

I like the way you defend your view - I'm like that as well -, but really, logic and Rainmeter's structure is pretty clear on this one.
Okay I am going nuts by all these nuts and bangs lol. It's may be that I can't perfectly relay it.

So let's say parts.

So when you use LeftMouseUpAction=[SomeAction1][SomeAction2][SomeAction2], it has 3 parts.

1. SomeAction1
2. SomeAction2
3. SomeAction3

Now these 3 will be executed in parallel with some time interval. Now Each action may have different parts.

For example if SomeAction2 is [#VarBang] with VarBang=[!Log "1"][!Delay 500]["path\to\an\App"] then SomeAction2 will be executed independently from the LeftMouseUpAction.

Think of this as fire cracker. Left mouse up action ignites the end. After LeftMouseUpAction=, each string inside [] is an individual cracker. So once you lit the end, individual crackers burst in some time interval, but they are independent of each other.

So what I am trying to say is that if you use [#NestedVariable] or [&NestedMeasure] then they will yield the result you get now.

And I am not defending my view. I was just getting a vibe that you were not getting what I am trying to say. May be you have already got it. So I will stop my stupid ranting now and let the pros take over :rolmfao:
from the Realm of Death
User avatar
Yincognito
Rainmeter Sage
Posts: 8441
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG?] Delay bang in OnRefreshAction's nested variable

Post by Yincognito »

death.crafter wrote: June 25th, 2021, 4:51 pmNow these 3 will be executed in parallel with some time interval. Now Each action may have different parts.

For example if SomeAction2 is [#VarBang] with VarBang=[!Log "1"][!Delay 500]["path\to\an\App"] then SomeAction2 will be executed independently from the LeftMouseUpAction.

Think of this as fire cracker. Left mouse up action ignites the end. After LeftMouseUpAction=, each string inside [] is an individual cracker. So once you lit the end, individual crackers burst in some time interval, but they are independent of each other.
Nope. Your mistake is that you consider collections of [!Bang...] as the action's (more like the option's) "independent parts".
In other words, in your fire cracker where Left mouse up action ignites the end, the individual crackers are each [!Bang...], and not "each string inside []". As I said, those [] square bracket separators are the cause of your confusion here. You equate measures, nested variables or section variables (all of which are enclosed between square brackets) inside an action / option with bangs, or the actual "independent parts" you talk about. It's the [!Bang...]-s which are the "atoms" of an action option, not the strings that happen to be square bracket enclosed.

But you're right, it's better to let the pros, aka de devs weigh in on all this (bug issue + syntax semantics). And no, your "ranting" is not stupid at all - you simply misunderstood some things, IMHO. I'll gladly admit I was wrong if the "pros" say so - which brings the question ... where are they? :D Just joking, of course - it's summer, nice weather, they deserve some time off.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
death.crafter
Rainmeter Sage
Posts: 1398
Joined: April 24th, 2021, 8:13 pm

Re: [BUG?] Delay bang in OnRefreshAction's nested variable

Post by death.crafter »

Yincognito wrote: June 25th, 2021, 5:36 pm Nope. Your mistake is that you consider collections of [!Bang...] as the action's (more like the option's) "independent parts".
In other words, in your fire cracker where Left mouse up action ignites the end, the individual crackers are each [!Bang...], and not "each string inside []". As I said, those [] square bracket separators are the cause of your confusion here. You equate measures, nested variables or section variables (all of which are enclosed between square brackets) inside an action / option with bangs, or the actual "independent parts" you talk about. It's the [!Bang...]-s which are the "atoms" of an action option, not the strings that happen to be square bracket enclosed.

But you're right, it's better to let the pros, aka de devs weigh in on all this (bug issue + syntax semantics). And no, your "ranting" is not stupid at all - you simply misunderstood some things, IMHO. I'll gladly admit I was wrong if the "pros" say so - which brings the question ... where are they? :D Just joking, of course - it's summer, nice weather, they deserve some time off.
Okay just one last time to make myself clear. I am talking about the internal operations here.

So in an action line I consider each parts inside a square bracket as one action, including the brackets.

So in an action like:
OnRefreshAction=[!ActivateConfig "SkinX"][!Delay 500][!CommandMeasure ActionTimer "Execute 1"]["#@#nircmd.exe" SendKeyPress lwin+prtsc"],
  • [!ActivateConfig "SkinX"]
  • [!Delay 500]
  • [!CommandMeasure ActionTimer "Execute 1"]
  • ["#@#nircmd.exe" SendKeyPress lwin+prtsc"]
are all different and independent actions. They may be bangs, they may be directories or may be apps. But they are independent in terms of execution. For example, ["#@#nircmd.exe" SendKeyPress lwin+prtsc"] wouldn't wait for ActionTimer to complete the task.

Now what I am saying is that these different parts are executed in series. If the one of the actions is a group of multiple actions then the next action in the original series will not wait for all the actions in the previous one to get completed.

As to why I am separating them, because they need to be separated before they are executed.

Similarly when we use LeftMouseUpAction=[#VariableBang1][#VariableBang2], where VariableBang1=[!Log 1][!Log 2][!Log 3] and VaraibleBang2=[!Log 4][!Log 5][!Log 6],
  • [#VariableBang1]
  • [#VariableBang2]
are the separate parts since they are in "[" "]". They will be executed just like the others, independent of each other.

No discrimination you see. Rainmeter is fair and square :rofl:

Now about why the square bracket theory: it's because they have to separate the bangs somewhere, in order to execute them.
For example in powershell if the bang would have been

Code: Select all

$bang=$bang='[explorer.exe $HOME][Start-Process "$env:APPDATA\Spotify\spotify.exe"][Write-Host "Hello death.crafter"]'
then I would have to break it up using

Code: Select all

[regex]::matches($bang, "((?<=\[).+?(?=\]))") | %{
	Invoke-Expression $_
}
So it must be something similar with Rainmeter.
Well I made my point. Now I can watch anime :P
from the Realm of Death
User avatar
Yincognito
Rainmeter Sage
Posts: 8441
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG?] Delay bang in OnRefreshAction's nested variable

Post by Yincognito »

death.crafter wrote: June 25th, 2021, 6:46 pmOkay just one last time to make myself clear. I am talking about the internal operations here.
Me too - but rest assured, this time I understood perfectly what you were trying to say. Unfortunately, it doesn't make sense from a practical (and also internal) behavior, no offense - see below. :)
death.crafter wrote: June 25th, 2021, 6:46 pmFor example, ["#@#nircmd.exe" SendKeyPress lwin+prtsc"] wouldn't wait for ActionTimer to complete the task.
Of course it won't, because ActionTimer is executed in a separate thread from the main Rainmeter process - bad example. It's one of the few things that are "independent" from that point of view:
Executes a series of Rainmeter actions independent of the normal skin Update cycle. This can allow the series of actions to be executed faster (or slower) than the rate defined in Update in [Rainmeter] and can be executed as fast as 1 millisecond apart.
What ActionTimer does is execute the list of actions defined in ActionListN, one after the other, in a separate thread outside the normal Update cycle, as fast as it possibly can.
Since the actions in ActionListN are executed in a separate thread from the main Rainmeter process, the skin will carry on updating normally, while the ActionTimer plugin will control the actions in the list.
Source: ActionTimer.
death.crafter wrote: June 25th, 2021, 6:46 pmNow what I am saying is that these different parts are executed in series. If the one of the actions is a group of multiple actions then the next action in the original series will not wait for all the actions in the previous one to get completed.
Let's suppose you are right, for the sake of the argument. Then this would:
- make the literal !Delay bang (which works, btw) in a group of multiple actions (say, in a String measure) impossible, since the the next action in the original series will execute before the delay completes and won't wait for all the actions in the previous group to get completed; this is not the case, as the issue is present only for nested variable scenarios
- make the whole Rainmeter action sequence system imposible, i.e. you wouldn't be able to do a [!SetOption SomeMeter SomeOption SomeValue][!UpdateMeter SomeMeter][!Redraw], because !UpdateMeter or !Redraw will run before the !SetOption and all that, depending on which action (or set of actions in a [part], it doesn't matter) takes less to complete; this would be true for more complex group of actions like you said, I only used simpletons to make things compact here; obviously, this doesn't happen either in practice

Anyway, this whole thing doesn't answer one simple question: if the literal !Delay in the middle of some action group works, why the heck it doesn't when within a section variable? When all things parsed, it's the same damn action list string.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Brian
Developer
Posts: 2738
Joined: November 24th, 2011, 1:42 am
Location: Utah

Re: [BUG?] Delay bang in OnRefreshAction's nested variable

Post by Brian »

This has been fixed for the next beta (hopefully :D).

This one is quite the conundrum. It comes down to 2 issues.
  1. Using a variable as a "bang replacement". I think we should refer to this going forward as "bang replacement variables" since they seem to come up often enough.
  2. The !Delay bang happens to be the only bang that is "pre-parsed" when executing an action. By "pre-parsed", I mean the action parser explicitly tests the "bang name", and if it is the "!Delay" bang, the rest of the bangs declared later are pushed to another list to be executed later instead of executing immediately.

    Here is the code: https://github.com/rainmeter/rainmeter/blob/master/Library/CommandHandler.cpp#L325-L334

Because #2 (above) explicity checks the bang name "before" execution means that any "bang replacement variables" are parsed later. By the time the replacement variables are replaced and executed, the remaining bangs (while executed in order) were not "visible" to the delay bang parsing.

That might not make sense, but it boils down to how the action parser works. It is somewhat hard to describe, but basically, the action parser uses a concept called "recursion" to execute each bang. This is because an action can accept a single bang (with or without brackets) or multiple bangs each surrounded by brackets. To parse correctly, you basically have to call same parsing function once you parse each bang. When that function returns, it continues with the next bang. "Bang replacement variables" were parsed after the "check for the delay bang" since they are not technically "real" bangs. Once the "bang replacement variable" is correctly substituted, it is sent back to the same parsing function. By this time, we are at a "different level" from the base level in the recursion cycle, and the "other bangs" (defined after the !Delay bang) are still executed in order, but were not attached to the delay bang itself.

I hope that makes at least a little bit of sense.

-Brian

PS - Forgive me if I pointed out something that had already been discussed. I skimmed more of this thread than I should have. :oops:
User avatar
death.crafter
Rainmeter Sage
Posts: 1398
Joined: April 24th, 2021, 8:13 pm

Re: [BUG?] Delay bang in OnRefreshAction's nested variable

Post by death.crafter »

Yincognito wrote: June 25th, 2021, 8:29 pm Of course it won't, because ActionTimer is executed in a separate thread from the main Rainmeter process - bad example. It's one of the few things that are "independent" from that point of view:
Hmm. What you say makes sense. But the action timer example was intentional. I wanted to show, quoting Brian, the bangs in a "bang replacement variable" are executed on a different level than the original bang sequence.
Yincognito wrote: June 25th, 2021, 8:29 pm - make the whole Rainmeter action sequence system imposible, i.e. you wouldn't be able to do a [!SetOption SomeMeter SomeOption SomeValue][!UpdateMeter SomeMeter][!Redraw], because !UpdateMeter or !Redraw will run before the !SetOption and all that, depending on which action (or set of actions in a [part], it doesn't matter) takes less to complete; this would be true for more complex group of actions like you said, I only used simpletons to make things compact here; obviously, this doesn't happen either in practice
Absolutely right. I was in the wrong to generalize it.
2. The !Delay bang happens to be the only bang that is "pre-parsed" when executing an action. By "pre-parsed", I mean the action parser explicitly tests the "bang name", and if it is the "!Delay" bang, the rest of the bangs declared later are pushed to another list to be executed later instead of executing immediately.
The only exception is the !Delay bang (as eluded to in the linked thread in your post). Once the delay bang is parsed, it sends the remaining defined bangs (declared after the delay bang sequentially) to a timing function that sends the remaining bangs back to the action parser after the defined delay.
Now quoting Brian's reply, my assumption about separating bangs in the first parsing was correct. And the bangs are parsed before they are executed. That is if a !Delay is met by the parser then parser will wait for the specified time and then parse and execute the next bang.Reference..

Anyway, it was a big fat bog I guess since Brian said it will be fixed it in the next beta.
from the Realm of Death
User avatar
Yincognito
Rainmeter Sage
Posts: 8441
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG?] Delay bang in OnRefreshAction's nested variable

Post by Yincognito »

Brian wrote: June 26th, 2021, 8:00 am[...] I hope that makes at least a little bit of sense.

-Brian

PS - Forgive me if I pointed out something that had already been discussed. I skimmed more of this thread than I should have. :oops:
death.crafter wrote: June 26th, 2021, 9:43 amI wanted to show, quoting Brian, the bangs in a "bang replacement variable" are executed on a different level than the original bang sequence.

Now quoting Brian's reply, my assumption about separating bangs in the first parsing was correct. And the bangs are parsed before they are executed. That is if a !Delay is met by the parser then parser will wait for the specified time and then parse and execute the next bang.Reference..
It makes perfect sense, Brian, thank you for the details. It seems death.crafter was correct in that !Delay was given "special treatment" compared to the other bangs (e.g. is being verified after and all that, he alluded to this at the beginning of our chat). Regarding the other issues in our conversation, you were right to skim through the thread because we (both) kind of migrated towards syntax semantics rather than talking about how the effects of this were wrong from a "execution's structure" point of view. Contrary to appearances, I didn't disagree with death.crafter regarding the separation of bangs (only on equating "bang replacement variables" with single bangs/actions), I just felt that it was wrong that the "preferrential treatment" of the !Delay bang (within a "bang replacement variable", true) was producing this kind of effects.

I'm glad it was solved - thanks so much. :rosegift: I'll test it as soon as I install the next beta and see if it works well in my actual coding environment, which obviously is much more complex than the simple samples used to illustrate the behavior.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
jsmorley
Developer
Posts: 22851
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: [BUG?] Delay bang in OnRefreshAction's nested variable

Post by jsmorley »

The beta is out...