Comments (13)
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.
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.
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.
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.
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.
Just pushed Part 1 of this effort :
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.
-
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 callnocbreak()
followed bycbreak()
. Kinda weird, really. -
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 usewtimeout()
. -
If you've called
timeout(0)
, or have just never calledtimeout
, you can callnodelay()
, 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 calledtimeout()
with a non-zero value,getch()
will wait that number of milliseconds before returningERR
.
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.
@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.
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.
Documented the resolution.
from pdcurses.
@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.
@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.
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.
I'll revisit this at a later date.
from pdcurses.
Related Issues (20)
- Is it normal that several styles don't work correctly in PowerShell? HOT 7
- Enabling support for showing window after process put to sleep (SDL2) HOT 4
- SDL_GetError() returns "Parameter 'src' is invalid" after call to initscr() for sdl2 HOT 2
- ncurses compat: add WACS_D_LRCORNER and other double line drawings
- SDL2 port missing support for PDC_PRESERVE_SCREEN HOT 4
- WinCon, endwin() kills QuickEdit/InsertMode options and more.. HOT 8
- touchoverlap() un-touches parts of lines HOT 1
- addition of vt port from Bill-Gray HOT 1
- additional gitpod config
- No rule to make target '../common/libobjs.mif'. Stop. HOT 5
- Unable to get mouse position when hovering HOT 9
- SDL2 build fails for Mac/Linux in Github HOT 2
- When resizing the SDL2 window, the surface isn't refreshed
- Build failure when building PDcurses DLL library for Window console HOT 1
- Debugging? HOT 1
- printw.c - for Unicode? HOT 3
- wresize doesn't return ERR if the window size requested is too big HOT 3
- Unable to initialize soft label keys HOT 2
- missing escapes in configure script HOT 1
- Scrolling and inserting/deleting lines
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pdcurses.