I am looking for a way to pause script execution and wait for user input. Nothing in particular, just any keystroke or click, to allow to continue execution.
Right now I am trying to write something with the help of the new on-chart GUI controls.
I came up with this code, but it does not work at all.
// This procedure is supposed to wait until user clicks on the button
procedure wait_for_click( idmain )
{
local
id, n;
id = idmain + 10; // set to something different than idmain
do
{
// this loop searches the event queue
for( n = 0; id = GuiGetEvent( n, 0 ); n++ )
{
if( id == idmain )
break; // we found the id in the event queue, so exit the for loop
}
printf( "Waiting ...\n" );
ThreadSleep( 500 );
}
while( id != idmain );
GuiSetVisible( idmain, False ); // make the button invisible after the click
}
printf( " Hello 1\n" );
ContinueButtonId = 100;
GuiButton( "Click to Continue", ContinueButtonId, 10, 30, 130, 30, notifyClicked );
GuiSetVisible( ContinueButtonId, true );
printf( " Hello 2\n" );
wait_for_click( ContinueButtonId );
printf( " Hello 3\n" );
Can somebody help me fix the above?
Maybe the problem lies to what @Tomasz has already mentioned here:
I am just too stuck on the previous line of thought.
First and foremost: NO formula should EVER busy wait or pause for anything.
That is a rule that must be obeyed.
Pausing prevents proper refresh of chart!
The formula MUST always execute without pausing.
If you want to act upon key stroke use GetAsyncKeyState but if key is NOT pressed, do NOT wait. Just allow formula to proceed (end) and let it check state next time it runs (you can use RequestTimedRefresh if you want it to be re-run).
So:
if (GetAsyncKeyState( 'A' ) < 0) // key A held down
{
// do whatever you want
// BUT DO NOT PAUSE !
// DO NOT CALL ThreadSleep!
}
// other stuff that needs to be done unconditionally
// optionally:
RequestTimedRefresh(0.1); //if you want it to be re-executed
@Tomasz,
I should explain my situation for using it.
I have a sheet that display smaller charts.
I used the left and right arrow keys to move the active symbol(highlighted in darker box).
Without a way to slow down, I will always miss the tile that I want to get to.
I spent the last 2 afternoons and nights troubleshooting a script that refused to work. It had to do with processing text files, copying them, renaming etc.
I stepped again and again through the debugger and it worked perfectly. But in normal mode it would not work. I wanted to be able to examine the state of the text files at various steps of the script. So I just wanted to FREEZE the script, not from the debugger, but something like the breakpoint the debugger places.
I wanted to insert/remove those FREEZE points in the code fast. I did not want to place elaborate IF statements, redirect the code, close the files etc. That would be even more hasle.
Instead you should implement simple state machine so you act on transitions from key "up" to "down" (or vice versa).
keydown = GetAsyncKeyState( 'A' ) < 0;
prevkeydown = StaticVarGet("keystate");
StaticVarSet("keystate", keydown );
if( keydown and NOT prevkeydown )
{
// transition from NOT pressed to pressed, do whatever you want
}
@Tomasz, I do understand your logic, you are right, this is how charts work and should work in AFL. And again I did learn a bit more about how AFL works. Thank you for the time you take to explain things to us.
The particular script I was trying to debug had no chart, nothing to refresh. I should have written it in C++ instead, if I was any good at it (which I am not). It was a script that did a one time scan and processing of TXT files.
Actually I needed to make sure it would run for just one cycle, otherwise I risked corrupting the TXT files I was processing, therefore I used something like the following code:
if( ParamTrigger( "Run the script", "OK" ) )
{
// Run the script once only, prevent the script from running a 2nd time.
}