Polling the mouse

Scott Raney raney at metacard.com
Thu Feb 21 15:01:01 EST 2002


On Thu, 21 Feb 2002 Jim Hurley <jphurley at jps.net> wrote:

> >Yes.  The full list of functions to avoid because they are deprecated is:
> >the mouse
> >the mouseClick
> >the mouseH
> >the mouseV
> >the mouseLoc
> >the optionKey
> >the commandKey
> >the controlKey
> >
> >And the very worst thing to do with any of these is "repeat until
> ><function>", which will condemn you to the fires of eternal damnation
> >in multiuser hell ;-)
> >
> >The last 3 can be safely acquired with "the keysDown", but be careful
> >to not sit in a repeat loop calling that or you may hang your app or
> >at the very least have the gods of multiuser development strike you
> >down.

One more note on this: as of engine version 2.4.2, the last three are
also now done asynchronously and so won't be a problem anymore.  And
they've always been safe to use a single time in a "mouseDown" or
"mouseUp" handler.  It's getting them in a repeat loop that will
potentially cause problems.

(snip)

> For some time I have been using HC, MC and/or RR to build Turtle 
> Graphics into HyperTalk and allow grade school students to use the 
> package to program their own solutions to problems in mathematics and 
> physics. There are two areas in this work in which HyperCard is quite 
> superior to MC or RR. (And there are many others, of course, in which 
> MC and RR are infinitely superior to HC.) The most serious problem is 
> the glacial speed with which MC draws images (in many cases this 
> problem is lethal) and the second, and much less important, is the 
> problems students have in polling the mouse.
> > There appears to be no remedy in the offing to the speed problem. 

Actually the current release is pretty close to HC in performance,
the primary remaining difference being due to running in color vs
black and white (anywhere from 8 to 32 times as much data to move
around, you know).

> However, regarding mouse-polling, my earlier question dealt with the 
> reliability and continued viability of the mouseClick function.
> 
> As an example, students create a button which, when clicked, sends a 
> satellite on its way into orbit around the earth--leaving a line in 
> its wake to show the trajectory. (The student has programmed the 
> turtle to obey the laws of Newtonian gravity.) When the student is 
> satisfied with the length of the trajectory, he or she clicks again 
> (anywhere on the screen) to stop the process. This is accomplished 
> with a "repeat until the mouseClick" or "if the mouseClick then exit 
> repeat."
> 
> So my question is three-fold:
> 
> 1. Is this a reliable operation given the current state of the MC 
> engine? That is, is there a bug similar to that in "repeat until the 
> mouse is down?"
> 2. We know that we may lose the mouse() function in the future. Is 
> mouseClick vulnerable as well?
> 3. If mouseClick will not be an option, what is the work-around so 
> that the student may click anywhere on the screen to exit a repeat 
> loop, and hopefully one which is simple enough for an eighth grader 
> to discover? (Since the student clicked the button to start the 
> process, it is more natural to click again to stop the process. It 
> would be awkward to have to move to the keyboard.)

The short answer to your question is, don't use a repeat loop, use
"send .. in" to draw the segments instead, and cancel the message if
you get a mouseDown.

The long answer, and probably much more than you want to know, is that
"the mouseClick" is really the problem here, not "the mouse".  "the
mouse" could in theory be done asynchronously.  If this were changed
you'd still have the performance issue to deal with (i.e., "repeat
until" would never be as smooth as using mouseMove messages and would
eventually cause the OS to start penalizing your app), but reliability
wouldn't because this information can be queried directly from the OS
on all platforms.  You'd also be subject to the normal behavior of
async functions (e.g., in HC, "the mouse" returns "down" if the user
clicked down anytime between when the handler started running and when
the function is called, whereas an async implementation would only
return "down" if it was actually down when you made the call).

The problem with "the mouseClick" is that of state management and
event order: it has to wait for the mouse to go down and then back up.
Worse, at least for HC compatibility, is that if you do something in a
script that takes a few seconds and click twice in that interval, "the
mouseClick" will return true *twice*.  This means that it's necessary
to maintain a queue of these mouse events and check the whole queue
each time the function is called to see if there is both a mouseDown
and a mouseUp message in it, and pull them out as a pair if so.  And
of course you can't just leave the rest of the events in the queue
either, because some of them (like socket events and redraws) need to
be handled independently of what the currently running handler is
doing.  Doing this cross-platform is horrendously complicated, and
results in compromized reliability for *everything*, not just the
mouseClick function.  Which is why we want to (and plan to) remove
this functionality, or at least substantially modify it to remove this
queueing aspect (e.g., the mouseClick would return true only if you
clicked down and up any time between the start of the handler and when
you made the call, and once it returned true *all* state information
would be tossed out so it wouldn't return true again until the user
clicked again after the function returned true, even if they clicked
multiple times before the first call).

Whew.
  Scott

> Jim Hurley
> -- 

********************************************************
Scott Raney  raney at metacard.com  http://www.metacard.com
MetaCard: You know, there's an easier way to do that...




More information about the use-livecode mailing list