ProblemWithRequesterFunctionsEntering a modal loop

BlitzMax Forums/MaxGUI Module/ProblemWithRequesterFunctionsEntering a modal loop

Fabian.(Posted 2006) [#1]
Sorry the missing space characters in the topic's title, I was limited to a fixed topic title length.
Try the following code:

The example creates two windows and two buttons. If you click on a button, two notify boxes (requesters) open, first one of them, then the second. Normally the second opens directly after the first, except you do the following:
Click Button1.
Leave the requester opened and press Button2.
Now go back to the first requester and press "OK".
The second requester for the first window doesn't appear.
The problem doesn't only apply to the Notify function, it applies to all functions entering a modal loop to wait until their requester closes, polling the system, which could make other parts of code to also open a requester, blocking the first requester function's modal loop to exit.
I added the DocStack function to show you which function calls which.
Is there a way how I can make the second requester always appear directly after the first one closes?
I think it would be usefull if we had the possibility to open a requester without entering a modal loop.


Grisu(Posted 2006) [#2]
Could you please tell, what OS you use?


Dreamora(Posted 2006) [#3]
Working here on WinXP SP2 without any problems.

One thing you could try is making those requester calls really modal (they aren't at the moment).
To do so, add ",true" after their message text. Then they are modal.
Currently there isn't anything modal in that example source.


Fabian.(Posted 2006) [#4]
Sorry, maybe I said this wrong, I should have said "local loop" instead of "modal loop", it doesn't have anything to do with whether a dialog box is modal or not. My problem is that the Notify function (or any other requester function) enters a local loop, waiting for the system until the the window closes. In this time there could be another event which causes the programme to call this function (or any other requester function) and enter another local loop; this second local loop prohibits the first one to exit, even if the first requester closes. So it could happen that the Notify function (or any other requester function) doesn't return directly after the requester closes, so the code I wrote after the call to this function could be executed too late.
Working here on WinXP SP2 without any problems.
Sure? Try this:
1.: Start the example.
2.: Click the "Button1" button.
3.: A notify box opens, it shows: "Button1: notify A"
4.: Leave the notify box open and click the "Button2" button.
5.: Another notify is shown: "Button2: notify A"
6.: Don't click this second notify box, get back to the first one.
7.: Press the "OK" button of this dialog box.
8.: Normally a notify box showing "Button1: notify B" should appear directly thereafter, but it doesn't, the Notify function doesn't return to my program although its dialog box has already been closed.
This problem could be solved if we had some functions which just open the requester, but don't wait until it closes.


Dreamora(Posted 2006) [#5]
This problem can't be solved.

You mix window with app. Just because you open 2 windows you don't have 2 apps.
Due to that, the code can't and won't jump between codeblocks.

What you do is:

Notify 1A
Notify 1B

So far no problem.
But by breaking the requester handling with your second window (you call a requester while one is active, you should have a global state that prevents that to happen), you enter a new call stack in between Notify 1A and 1B which results in:

Notify 1A
<-- Notify 2A, Notify 2B
Notify 1B

This means as long as Notify 2B hasn't been closed, the old part can't go on.

There are 2 simple ways around that problem with default requesters:
- Call requesters only in a linear way instead of trying to call it parallel (at least until we have multithreading if we ever have it)
- Use a state variable that is set if a requester is active and disable all other "requester start functionality" until the running requester has been finished. Thats after all the way modal / pseudo modal stuff is meant.

The only way to solve your way keeping that type of code structuring is to create your own not-requesters through BM windows you open that fake the behavior and add event hooks to react to it.

Default requesters will never work differently as you mainly try to use them wrong. Requesters, as their name already implies, request an action from a user. Going on without waiting for that action is quite pointless and undesired.
Think about it and the result of your "idea" with a simple confirm requester: What shall your following code do, if you don't know if the user will click on "ok" or "cancel"? The following if that takes care of the further processing will totally break.
FileRequester would be an even worse example of what happens when the code would go on before the requester returned.


Fabian.(Posted 2006) [#6]
This problem can't be solved.
It can, as I said:
This problem could be solved if we had some functions which just open the requester, but don't wait until it closes.
But okey, for now I wrote these functions myself ( pub.Requester ); here's the example written with them:

These functions solve my problem, but they're Win32 only. However I think it's possible to write them platform independent.