buffering on Windows - HUGE speed improvement if you are writing several short strings

This commit is contained in:
Adam D. Ruppe 2013-10-08 00:11:55 -04:00
parent d3aa892c63
commit 9410c07f9e
1 changed files with 42 additions and 13 deletions

View File

@ -602,8 +602,15 @@ http://msdn.microsoft.com/en-us/library/windows/desktop/ms683193%28v=vs.85%29.as
} }
} }
// only use this if you are sure you know what you want, since the terminal is a shared resource you generally really want to reset it to normal when you leave...
bool _suppressDestruction;
version(Posix) version(Posix)
~this() { ~this() {
if(_suppressDestruction) {
flush();
return;
}
if(type == ConsoleOutputType.cellular) { if(type == ConsoleOutputType.cellular) {
doTermcap("te"); doTermcap("te");
} }
@ -613,6 +620,7 @@ http://msdn.microsoft.com/en-us/library/windows/desktop/ms683193%28v=vs.85%29.as
version(Windows) version(Windows)
~this() { ~this() {
flush();
showCursor(); showCursor();
} }
@ -638,11 +646,12 @@ http://msdn.microsoft.com/en-us/library/windows/desktop/ms683193%28v=vs.85%29.as
if(foreground == Color.DEFAULT) if(foreground == Color.DEFAULT)
setTof = Color.white; setTof = Color.white;
// FIXME: is this if good? if(force == ForceOption.alwaysSend || foreground != _currentForeground || background != _currentBackground) {
//if(force == ForceOption.alwaysSend || foreground != _currentForeground || background != _currentBackground) { flush(); // if we don't do this now, the buffering can screw up the colors...
SetConsoleTextAttribute( SetConsoleTextAttribute(
GetStdHandle(STD_OUTPUT_HANDLE), GetStdHandle(STD_OUTPUT_HANDLE),
cast(ushort)((setTob << 4) | setTof)); cast(ushort)((setTob << 4) | setTof));
}
} else { } else {
import std.process; import std.process;
// I started using this envvar for my text editor, but now use it elsewhere too // I started using this envvar for my text editor, but now use it elsewhere too
@ -710,6 +719,8 @@ http://msdn.microsoft.com/en-us/library/windows/desktop/ms683193%28v=vs.85%29.as
version(Posix) version(Posix)
doTermcap("cm", y, x); doTermcap("cm", y, x);
else version(Windows) { else version(Windows) {
flush(); // if we don't do this now, the buffering can screw up the position
COORD coord = {cast(short) x, cast(short) y}; COORD coord = {cast(short) x, cast(short) y};
SetConsoleCursorPosition(hConsole, coord); SetConsoleCursorPosition(hConsole, coord);
} else static assert(0); } else static assert(0);
@ -777,6 +788,13 @@ http://msdn.microsoft.com/en-us/library/windows/desktop/ms683193%28v=vs.85%29.as
throw new Exception("write failed for some reason"); throw new Exception("write failed for some reason");
writeBuffer = writeBuffer[written .. $]; writeBuffer = writeBuffer[written .. $];
} }
} else version(Windows) {
while(writeBuffer.length) {
DWORD written;
/* FIXME: WriteConsoleW */
WriteConsoleA(hConsole, writeBuffer.ptr, writeBuffer.length, &written, null);
writeBuffer = writeBuffer[written .. $];
}
} }
// not buffering right now on Windows, since it probably isn't on ssh anyway // not buffering right now on Windows, since it probably isn't on ssh anyway
} }
@ -898,7 +916,7 @@ http://msdn.microsoft.com/en-us/library/windows/desktop/ms683193%28v=vs.85%29.as
_cursorX++; _cursorX++;
} }
if(_cursorX >= width) { if(_wrapAround && _cursorX >= width) {
_cursorX = 0; _cursorX = 0;
_cursorY++; _cursorY++;
} }
@ -917,6 +935,8 @@ http://msdn.microsoft.com/en-us/library/windows/desktop/ms683193%28v=vs.85%29.as
writeStringRaw(s); writeStringRaw(s);
} }
/* private */ bool _wrapAround = true;
deprecated alias writePrintableString writeString; /// use write() or writePrintableString instead deprecated alias writePrintableString writeString; /// use write() or writePrintableString instead
private string writeBuffer; private string writeBuffer;
@ -927,9 +947,7 @@ http://msdn.microsoft.com/en-us/library/windows/desktop/ms683193%28v=vs.85%29.as
version(Posix) { version(Posix) {
writeBuffer ~= s; // buffer it to do everything at once in flush() calls writeBuffer ~= s; // buffer it to do everything at once in flush() calls
} else version(Windows) { } else version(Windows) {
DWORD written; writeBuffer ~= s;
/* FIXME: WriteConsoleW */
WriteConsoleA(hConsole, s.ptr, s.length, &written, null);
} else static assert(0); } else static assert(0);
} }
@ -1603,6 +1621,14 @@ struct RealTimeConsoleInput {
goto mod_switch; goto mod_switch;
} }
break; break;
// this is an extension in my own terminal emulator
case 20:
..
case 36:
modifierState |= ModifierState.windows;
modGot -= 20;
goto mod_switch;
default: default:
} }
@ -1642,7 +1668,8 @@ struct RealTimeConsoleInput {
default: default:
} }
} else if(terminal.terminalInFamily("rxvt")) { } else if(terminal.terminalInFamily("rxvt")) {
// FIXME: figure these out // FIXME: figure these out. rxvt seems to just change the terminator while keeping the rest the same
// though it isn't consistent. ugh.
} else { } else {
// maybe we could do more terminals, but linux doesn't even send it and screen just seems to pass through, so i don't think so; xterm prolly covers most them anyway // maybe we could do more terminals, but linux doesn't even send it and screen just seems to pass through, so i don't think so; xterm prolly covers most them anyway
// so this space is semi-intentionally left blank // so this space is semi-intentionally left blank
@ -1797,11 +1824,11 @@ interface CustomEvent {}
version(Windows) version(Windows)
enum ModifierState : uint { enum ModifierState : uint {
shift = 4, shift = 4,
ctrl = 8, control = 8,
// i'm not sure if the next two are available // i'm not sure if the next two are available
alt = 256, alt = 256,
// windows = 512, windows = 512,
meta = 4096, // FIXME sanity meta = 4096, // FIXME sanity
} }
@ -1810,7 +1837,9 @@ enum ModifierState : uint {
shift = 4, shift = 4,
alt = 2, alt = 2,
control = 16, control = 16,
meta = 8 meta = 8,
windows = 512 // only available if you are using my terminal emulator; it isn't actually offered on standard linux ones
} }
/// GetNextEvent returns this. Check the type, then use get to get the more detailed input /// GetNextEvent returns this. Check the type, then use get to get the more detailed input