While Loop & Switch Case troubles

7 views (last 30 days)
Yale Brewer
Yale Brewer on 7 Jun 2015
Edited: Jan on 7 Jun 2015
Having a bit of trouble with a while loop and switch case (code below)
what I am trying to do:
A GUI returns a updates a global variable (command), which then causes code sections to execute (in this case dummy code), I want to to be able to jump from case 0 to say case 3 and back again before exiting by selecting case 5.
Problem:
While loop, without the pause(0.0000000001) does not seem to let the GUI update the global variable, or it does (Ctrl+C) shows the variable to have changed, but does not detect it has changed and therefore remains stuck in case 0.
having this pause in there is obviously inefficient and to my mind a pointless exercise
Question:
Is there a better way of achieving this and getting rid of this pause, and can anyone suggest a reason why this might be the case that a short pause (no matter how short) is required inside the while loop?
Thank you!
if true
clear all; close all; clc
gui = UserInterface; % load UI
pause(1)
global command; % command is a global returned by UI
command = 0;
while command ~= 6
pause(0.000000000000001) % WHY??????? If no pause in loop, does not detect change of command
switch(command)
case 0
display('case 0')
case 1
display('case 1')
case 2
display('case 2')
case 3
display('case 3')
case 4
display('case 4')
case 5
command = 6;
display('case 5')
otherwise
command = 6;
display('exit at otherwise statement')
end
end
end

Accepted Answer

Walter Roberson
Walter Roberson on 7 Jun 2015
The rules for timer interrupts are different than the rules for graphics interrupts (or at least have been; I can't say for R2014b onwards.)
Timer interrupts can, as of a couple of years ago (but not earlier) interrupt between any two lines of code, with actual lines seemingly important; the discussion implied that multiple commands on the same line would be handled as a group.
Graphics interrupts, however, at least up to R2014a, happen only when there is a pause() or uiwait() or waitfor() or drawnow(), or a return to the command line.
I recommend against using global variables. You should instead have the callbacks store the information in a place the loop can find it, and periodically the loop should drawnow() to give a chance for queued interruptions to happen, and the loop should fetch the current stored value.
Example:
guifig = gcf;
while true
drawnow();
handles = guidata(guifig);
command = handles.command;
....
end
  1 Comment
Yale Brewer
Yale Brewer on 7 Jun 2015
Thanks, that explains a lot! had a bit of a change and now use the 'UserData' element of the figure to store which radiobutton was selected, which I call back inside while loop... pause no longer required!
thanks!

Sign in to comment.

More Answers (1)

Jan
Jan on 7 Jun 2015
Edited: Jan on 7 Jun 2015
A loop is a bad method to catch a change, because it costs processor time without solving any work.
waitfor is smarter for this job:
set(FigHandle, 'UserData', []);
waitfor(FigHandle, 'UserData');
UserData = get(FigHandle, 'UserData');
Now let the callback in the GUI change the UserData, e.g. set it to the wanted command instead of using ugly global variables, which are prone to bugs.
The pause command was necessary in your code to let Matlab process graphic events like mouse clicks in the figure, as Walter has explained already. A drawnow would be sufficient also.
pause(0.000000000000001) is the same as pause(0.01), because this is the shortest possible pause. Several Java callbacks work "more reliabale" (if this is not a contradiction) with pause(0.02), e.g. after updates of teh graphics before a getframe.

Categories

Find more on Graphics Performance in Help Center and File Exchange

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!