Giter Site home page Giter Site logo

Comments (13)

wmcbrine avatar wmcbrine commented on May 23, 2024

It's fairly ancient, alright, but still applicable, to the extent that PDCurses still works on DOS. See here: https://www.mail-archive.com/[email protected]/msg00038.html (and the two followups).

from pdcurses.

GitMensch avatar GitMensch commented on May 23, 2024

Just out of interest: Did you tested current PDCurses on DOS?
To fix the port specific issue (actually only dos seems to need this, maybe there are other that should not call their sleep with less then 20) a possible solution would be to have pdcutil export a static int MIN_SLEEP that would be used in getch.

from pdcurses.

wmcbrine avatar wmcbrine commented on May 23, 2024

It's not just DOS, really. The core of this routine is a call to napms(), and the core of that, on every platform, is a routine to yield the time slice back to the operating system. And the documentation for every such function includes a disclaimer like this one, from SDL_Delay(): "It waits at least the specified time, but possibly longer due to OS scheduling." (Some of them also mention a lack of true millisecond resolution, where -- like napms() -- they accept ms for convenience.) I realize that modern systems have tightened things up quite a bit, but still, as long as napms() is giving up time slices, you can't rely on it for precise timing.

I don't see a reason to change the interval, but I'll see about clarifying the documentation.

from pdcurses.

Bill-Gray avatar Bill-Gray commented on May 23, 2024

On DOS, all those 50-millisecond intervals will get bumped to one clock tick of 54.93 milliseconds. And, as William says, non-realtime OSes may do all sorts of odd things.

Ignoring that... if SP->delaytenths is non-zero, you get exactly the number of "50-millisecond" delays you asked for; in DOS, they may be about 10% longer than you actually wanted. Otherwise, you get that amount truncated to a multiple of 50 milliseconds (set win->_delayms = 140, and you get two 50-ms waits.)

@GitMensch, I assume it's this last point that's causing trouble for you? You have a situation where the difference between (say) 140 milliseconds and 100 milliseconds is noticeable? (Or -- more problematically -- a situation where win->_delayms = 1 results in a 50 ms wait.)

It wouldn't be so hard to revise the code to wait 50 milliseconds or the remaining time, whichever is less, and repeat until remaining_time = 0. The current code is surprisingly ugly; improving on it would not be a high hurdle. But do you have a situation where its current "not-quite-right" behavior actually matters?

from pdcurses.

wmcbrine avatar wmcbrine commented on May 23, 2024

The current code is surprisingly ugly; improving on it would not be a high hurdle.

I'm not seeing that, but by all means, go ahead.

from pdcurses.

Bill-Gray avatar Bill-Gray commented on May 23, 2024

Just pushed Part 1 of this effort :

Bill-Gray/PDCursesMod@723e183

which simply causes getch to wait a specified number of milliseconds, rather than waitcount 50-millisecond intervals. (Subject to the limitations we've discussed; not all platforms can get the timing that exactly.) If getch() gets a character before then, it returns that character; otherwise, it'll return ERR.

The actual wait can be zero to an infinite number of milliseconds (it defaults to infinity). I eventually figured out that there are three different ways to set how long getch will wait for input. This is true both in ncurses and PDCurses, though there are some subtle differences between the two.

  1. You can call halfdelay() to set the delay time in tenths of seconds. The delay time must be positive. Once you've done this at any point in your code, you're committed; the following methods will have no effect, unless you call nocbreak() followed by cbreak(). Kinda weird, really.

  2. You can call timeout() to set a delay time in milliseconds, which can be (and defaults to being) zero. This can be on a window-specific basis, if you use wtimeout().

  3. If you've called timeout(0), or have just never called timeout, you can call nodelay(), which takes a Boolean. If that Boolean is TRUE, the wait time is zero. If it's FALSE (the default) the wait time is infinite, i.e., getch() will hang until you hit a key. If you've called timeout() with a non-zero value, getch() will wait that number of milliseconds before returning ERR.

To test this, I wrote a small test program :

https://www.projectpluto.com/xfer/keytest.c

which I compiled with both ncurses and PDCurses. I could then run, say, ./keytest h4 t113 d to see the effects of calling halfdelay(4), timeout(113), and nodelay(stdscr,FALSE), in that order. Following that, the program shows typed characters and dots to indicate that getch() returned without anything being entered. In the above case, halfdelay(4) trumps everything else; you get five dots a second, plus output telling you what keys you're hitting.

If you call timeout(100) followed by nodelay(), ncurses just follows the last command received. nodelay(stdscr,TRUE) causes getch() to wait until a key is hit; nodelay(stdscr,TRUE) causes no delay at all (effectively, the waiting time is either infinite or zero.) Do the same thing with PDCurses, and the nodelay() call is ignored. You can see this with ./keytest t100 d (for the TRUE case) or ./keytest t100 k (FALSE case).

I suspect the behavior resulting from mixing halfdelay(), timeout() and nodelay() is really undefined; you should probably pick one and stick to it. If such is true, the logic could suddenly become much simpler :

halfdelay() sets how long getch() waits for input, in tenths of a second.
timeout() sets how long getch() waits for input, in milliseconds.
nodelay() sets the time getch() waits for input to zero or infinity.

I hesitate to do that, largely because I've tried to maintain backward compatibility even in cases where that means weird behavior.

from pdcurses.

GitMensch avatar GitMensch commented on May 23, 2024

@wmcbrine What do you say to the changes so far? What do you think about the "backward compatibility vs. weird behavior" Bill mentioned?

from pdcurses.

Bill-Gray avatar Bill-Gray commented on May 23, 2024

Further complicating matters, halfdelay works on a global basis (any key/mouse event in any window will get the same delay). timeout and nodelay work on a window-by-window basis. I'm having a tough time seeing how that would work out in practice... I could imagine a situation where you're generally accepting keystrokes without any delay(nodelay(stdscr,TRUE)), but then put up a window into which the user types some text. For that window, you'd set blocking input (very long timeout or nodelay(win,FALSE).)

My current patch does make it possible to have timeout work for the exact desired number of milliseconds on platforms supporting that capability, without loss on platforms that don't let you do that. The logic is (admittedly only slightly) more logical. Given the above "further complications", that may be the best we can do.

from pdcurses.

wmcbrine avatar wmcbrine commented on May 23, 2024

Documented the resolution.

from pdcurses.

GitMensch avatar GitMensch commented on May 23, 2024

@wmcbrine the documentation is a good thing - but I wonder if you see any issues with the patch provided in Bill-Gray@723e183 ?

from pdcurses.

Bill-Gray avatar Bill-Gray commented on May 23, 2024

@GitMensch, I'm still curious as to the situation where the finer/more accurate resolution is actually needed? (I'm not arguing against my own patch. I'm confident in its workings and it's slightly less messy than the original code. I also prefer it because it "does it right" instead of messily hacking things up into 50 millisecond chunks. But is there a situation where a user can see the difference between 1/20 second and millisecond resolution?)

from pdcurses.

GitMensch avatar GitMensch commented on May 23, 2024

But is there a situation where a user can see the difference between 1/20 second and millisecond resolution?)

I think there are not many. The complete issue is a result of actually testing it the first time and recognizing the difference between ncurses and pdcurses with no trace why pdcurses behaved differently (which is now fixed by the documentation update).
The scenario is a tight loop where data is read from a serial port, then displayed, then a read with a timeout is used (which may abort the loop) then starting the next loop iteration.

If it is possible to have a better precision "if it is available" without complicating things then I'd argue this is a good thing - applications using PDCurses may currently be ~49ms later than applications using ncurses.

from pdcurses.

wmcbrine avatar wmcbrine commented on May 23, 2024

I'll revisit this at a later date.

from pdcurses.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.