Sliders and Timers

  • Okay, here is a question.

    I have a cocoa app in which I have set up an NSTimer.  That timer is
    configured to send a message periodically.

    There are some sliders on a window in this application.  If I start
    moving a slider, the timer is frozen until I release the mouse button.

    Any way to get the timer pulse delivered while I move the slider?

    I considered moving the timer into another thread (NSThread), but I'm
    not sure if that is the ideal solution or not?

    The other thread should ideally be able to update other controls (not
    the sliders) while I am moving the slider.

    Any "easy" way to do this in Cocoa?

    (I'm fairly new to Cocoa, have been playing with it on and off for a
    time, but have been looking at it somewhat more seriously over the
    past few days and am quite pleased so far, but this one is a blocker
    for what I am trying to do...)

    Thank you!

    _________________________________________________________________
    Need personalized email and website? Look no further. It's easy
    with Doteasy $0 Web Hosting! Learn more at www.doteasy.com
  • On 2007 Sep, 23, at 17:22, Frank D. Engel, Jr. wrote:

    > If I start moving a slider, the timer is frozen until I release the
    > mouse button.

    More precisely, I'd say not that the timer is frozen, but the method
    which receives the timer's firing and sends your "periodic message"
    is delayed from running until after your main thread becomes
    unblocked by your moving the slider.

    > Any way to get the timer pulse delivered while I move the slider?
    > I considered moving the timer into another thread (NSThread), but
    > I'm not sure if that is the ideal solution or not?

    Yes, I believe that's what you should do.  Schedule the timer in
    another thread, in which your message will be sent.

    > The other thread should ideally be able to update other controls
    > (not the sliders) while I am moving the slider.  Any "easy" way to
    > do this in Cocoa?

    Look at -[NSObject
    performSelectorOnMainThread:withObject:waitUntilDone:modes:].

    > (I'm fairly new to Cocoa, have been playing with it on and off for
    > a time, but have been looking at it somewhat more seriously over
    > the past few days and am quite pleased so far, but this one is a
    > blocker for what I am trying to do...)

    Well, multithreading is never a good place to start, but you've got
    to do what you've got to do!
  • On Sep 23, 2007, at 17:22, Frank D. Engel, Jr. wrote:

    > I have a cocoa app in which I have set up an NSTimer.  That timer is
    > configured to send a message periodically.
    >
    > There are some sliders on a window in this application.  If I start
    > moving a slider, the timer is frozen until I release the mouse button.
    >
    > Any way to get the timer pulse delivered while I move the slider?

    The slider is probably running its own event loop in mouseDown:, which
    bypasses normal event handling.  Try creating the timer and then
    scheduling it manually in NSDefaultRunLoopMode and
    NSEventTrackingRunLoopMode, or kCFRunLoopCommonModes.

    http://www.cocoabuilder.com/archive/message/cocoa/2001/4/18/24587

    > I considered moving the timer into another thread (NSThread), but
    > I'm not sure if that is the ideal solution or not?

    I'd try the runloop approach first.

    --
    Adam
  • Thank you, that works perfectly!

    That's exactly what I needed.

    On Sep 23, 2007, at 9:24 PM, Adam R. Maxwell wrote:

    >
    > On Sep 23, 2007, at 17:22, Frank D. Engel, Jr. wrote:
    >
    >> I have a cocoa app in which I have set up an NSTimer.  That timer
    >> is configured to send a message periodically.
    >>
    >> There are some sliders on a window in this application.  If I
    >> start moving a slider, the timer is frozen until I release the
    >> mouse button.
    >>
    >> Any way to get the timer pulse delivered while I move the slider?
    >
    > The slider is probably running its own event loop in mouseDown:,
    > which bypasses normal event handling.  Try creating the timer and
    > then scheduling it manually in NSDefaultRunLoopMode and
    > NSEventTrackingRunLoopMode, or kCFRunLoopCommonModes.
    >
    > http://www.cocoabuilder.com/archive/message/cocoa/2001/4/18/24587
    >
    >> I considered moving the timer into another thread (NSThread), but
    >> I'm not sure if that is the ideal solution or not?
    >
    > I'd try the runloop approach first.
    >
    > --
    > Adam
    >
    >

    _________________________________________________________________
    Need personalized email and website? Look no further. It's easy
    with Doteasy $0 Web Hosting! Learn more at www.doteasy.com
  • OK,

    Looking at this more closely, I'm starting to notice an issue here.

    This really does work fine for the most part, but even though this
    solves the problem for moving sliders and so forth, there is still a
    sometimes-noticeable lag when switching windows, working with certain
    UI components, and so forth.

    I'm trying to accomplish what will turn into "soft" near-real-time
    control of external hardware, and this lag is very undesirable.  I
    don't care if it takes the extra fraction of a second, or even a
    second or two in extreme cases, to update the UI on the screen to
    reflect modified values, but I don't want to delay the updates and
    output to the hardware just because I'm switching windows or opening
    a new one.

    I think the only solution in this case might be to move the update
    cycle into a separate thread; that is another reason I had initially
    been looking at that approach.

    The issue is that I'm using Cocoa Bindings to update the UI.  This
    leads to a fairly simple mechanism that is working very well with
    this exception.

    I suppose my initial question is this:

    If I update a variable in a second "update cycle" thread, will that
    still be reflected in the UI due to the bindings, and if so, will
    Cocoa correctly handle the thread sync with the bindings, or will I
    need to take special action to manage this?

    Note that there may be thousands of variables to consider at any
    given time, although in the majority of the update cycles, only a
    handful will be touched (could be a thousand or more now and then).
    I'm dealing with arrays of objects, where each array may contain a
    few hundred objects, each object has multiple variables, and several
    variables from each object are subject to change at any given time.
    I have controls on my UI which control which array member is bound to
    a given section of the interface at any point in time, so the user
    can choose which object(s) he is looking at; the interface allows
    multiple windows to be open at any given time as well, and spread out
    across multiple screens or whatever.

    I'm open to any advice on this.

    Thank you!

    On Sep 24, 2007, at 4:56 PM, Frank D. Engel, Jr. wrote:

    > Thank you, that works perfectly!
    >
    > That's exactly what I needed.
    >
    >
    > On Sep 23, 2007, at 9:24 PM, Adam R. Maxwell wrote:
    >
    >>
    >> On Sep 23, 2007, at 17:22, Frank D. Engel, Jr. wrote:
    >>
    >>> I have a cocoa app in which I have set up an NSTimer.  That timer
    >>> is configured to send a message periodically.
    >>>
    >>> There are some sliders on a window in this application.  If I
    >>> start moving a slider, the timer is frozen until I release the
    >>> mouse button.
    >>>
    >>> Any way to get the timer pulse delivered while I move the slider?
    >>
    >> The slider is probably running its own event loop in mouseDown:,
    >> which bypasses normal event handling.  Try creating the timer and
    >> then scheduling it manually in NSDefaultRunLoopMode and
    >> NSEventTrackingRunLoopMode, or kCFRunLoopCommonModes.
    >>
    >> http://www.cocoabuilder.com/archive/message/cocoa/2001/4/18/24587
    >>
    >>> I considered moving the timer into another thread (NSThread), but
    >>> I'm not sure if that is the ideal solution or not?
    >>
    >> I'd try the runloop approach first.
    >>
    >> --
    >> Adam
    >>
    >>

    >

    -----------------------------------------------------------
    Frank D. Engel, Jr.  <fde101...>

    $ ln -s /usr/share/kjvbible /usr/manual
    $ true | cat /usr/manual | grep "John 3:16"
    John 3:16 For God so loved the world, that he gave his only begotten
    Son, that whosoever believeth in him should not perish, but have
    everlasting life.
    $
previous month september 2007 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Go to today