class: TerminalView
class definition
changed:
#initialize
#processInput:n:
#readAnyAvailableData
#readerProcessLoop
category of: #readAnyAvailableData
improved (aka fixed) slow handling of ctrl-s/ctrl-c
when a lot of output was coming in (try ls -lR / and
then press ctrl-s)
--- a/TerminalView.st Tue Jul 30 09:13:45 2013 +0200
+++ b/TerminalView.st Tue Jul 30 10:51:32 2013 +0200
@@ -17,7 +17,8 @@
numberOfColumns numberOfLines shellTerminateAction rangeStartLine
rangeEndLine state savedCursor shellCommand shellDirectory
filterStream localEcho translateNLToCRNL inputTranslateCRToNL
- autoWrapFlag masterWindow alternateKeypadMode noColors'
+ autoWrapFlag masterWindow alternateKeypadMode noColors
+ sizeOfOutstandingInputToBeProcessed'
classVariableNames:'Debug DebugKeyboard'
poolDictionaries:''
category:'Views-TerminalViews'
@@ -1124,7 +1125,8 @@
showMatchingParenthesis := false.
self insertMode: false.
alwaysAppendAtEnd := false.
- collectSize := 100.
+ collectSize := 4096.
+ sizeOfOutstandingInputToBeProcessed := 0.
st80Mode := false.
trimBlankLines := true.
localEcho := false.
@@ -1153,7 +1155,7 @@
VT100TerminalView openShell
"
- "Modified: / 5.5.1999 / 17:54:47 / cg"
+ "Modified: / 30-07-2013 / 10:43:07 / cg"
!
initializeKeyboardMap
@@ -1658,8 +1660,24 @@
!
processInput:buffer n:count
+ "actually: output coming from the connected application (aka input to me);
+ the stuff coming from the application is a mix of plain text and CSI escape sequences.
+ If we process each character individually, things are trivial, but slow.
+ Therefore, we collect big chunks of non-escaped text and buffer them to make
+ use of the inherited buffered output optimizations (see TextCollector).
+ Thus, we collect until an escape sequence is encountered, and flush the buffered stuff then,
+ proceed in single-character mode (processState0:) until the sequence is finished, and continue
+ collecting.
+ This makes this terminalView's speed usable and actually competitive with some existing
+ console applications (it is *much* faster than the MSWindows command.com window, btw.)"
+
|sensor|
+ "/ remember how much is in the queue...
+ [
+ sizeOfOutstandingInputToBeProcessed := sizeOfOutstandingInputToBeProcessed - count.
+ ] valueUninterruptably.
+
Debug ifTrue:[
'VT100: processInput - state: ' print. state print.
' got: ' print. count printCR
@@ -1824,37 +1842,9 @@
].
].
- "Created: / 10.6.1998 / 17:26:09 / cg"
- "Modified: / 29.4.1999 / 11:08:48 / cg"
- "Modified: / 28.1.2002 / 20:41:36 / micha"
-!
-
-readAnyAvailableData
- "read data from the stream,
- and sends me #processInput:n: events if something arrived.
- Returns the amount of data read."
-
- |buffer n bufferSize|
-
- outStream isNil ifTrue:[^ 0].
-
- bufferSize := 512. "/ 1024.
-
- buffer := String new:bufferSize.
- ExternalStream readErrorSignal handle:[:ex |
- n := 0
- ] do:[
- n := outStream nextAvailableBytes:bufferSize into:buffer startingAt:1.
- ].
- n > 0 ifTrue:[
- self pushEvent:#processInput:n: with:buffer with:n.
- ].
-
- ^ n
-
- "Created: / 5.5.1999 / 17:57:39 / cg"
- "Modified: / 8.5.1999 / 20:14:14 / cg"
- "Modified: / 28.1.2002 / 21:10:25 / micha"
+ "Created: / 10-06-1998 / 17:26:09 / cg"
+ "Modified: / 28-01-2002 / 20:41:36 / micha"
+ "Modified: / 30-07-2013 / 10:47:19 / cg"
!
sendLine:aString
@@ -1919,6 +1909,47 @@
!TerminalView methodsFor:'reader process'!
+readAnyAvailableData
+ "read data from the stream,
+ and sends me #processInput:n: events if something arrived.
+ Returns the amount of data read."
+
+ |buffer n bufferSize|
+
+ outStream isNil ifTrue:[^ 0].
+
+ "/ avoid too many processInput messages to be in the buffer,
+ "/ otherwise, the reaction on ctrl-s/ctrl-c is too slow, as
+ "/ many processInput messages are in the sensor's queue before the keypress
+ "/ event. We need another queue, actually so the sensor's keypress events
+ "/ are not blocked while reading a lot of input.
+ [sizeOfOutstandingInputToBeProcessed > 4096] whileTrue:[
+ Delay waitForSeconds:0.1
+ ].
+
+ bufferSize := 4096. "/ 512. "/ 1024.
+
+ buffer := String new:bufferSize.
+ ExternalStream readErrorSignal handle:[:ex |
+ n := 0
+ ] do:[
+ n := outStream nextAvailableBytes:bufferSize into:buffer startingAt:1.
+ ].
+ n > 0 ifTrue:[
+ self pushEvent:#processInput:n: with:buffer with:n.
+ "/ remember how much is in the queue...
+ [
+ sizeOfOutstandingInputToBeProcessed := sizeOfOutstandingInputToBeProcessed + n.
+ ] valueUninterruptably
+ ].
+
+ ^ n
+
+ "Created: / 05-05-1999 / 17:57:39 / cg"
+ "Modified: / 28-01-2002 / 21:10:25 / micha"
+ "Modified (comment): / 30-07-2013 / 10:50:03 / cg"
+!
+
readerProcessLoop
"look for the commands output,
and send me #processInput:n: events whenever something arrives."
@@ -1939,6 +1970,7 @@
true "(sensor userEventCount > 10)" ifTrue:[
"/ give terminalView a chance to
"/ send out the character.
+Transcript showCR:'d'.
Delay waitForSeconds:0.01.
]
] ifFalse:[
@@ -1972,6 +2004,8 @@
]
]
]
+
+ "Modified: / 30-07-2013 / 10:30:38 / cg"
!
startReaderProcess
@@ -2116,11 +2150,11 @@
!TerminalView class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libwidg2/TerminalView.st,v 1.155 2013-07-29 16:30:51 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libwidg2/TerminalView.st,v 1.156 2013-07-30 08:51:32 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libwidg2/TerminalView.st,v 1.155 2013-07-29 16:30:51 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libwidg2/TerminalView.st,v 1.156 2013-07-30 08:51:32 cg Exp $'
! !