It seems that you guys (Stephane & Juan) both making same mistake. :) You trying to assign multiple different roles to Transcript at once: - be a stream - be a GUI element (can draw/update itself on a screen)..
Hey.. Transcript is not a swiss knife! It is just a stream (kind of special one), but other than that.. it is just a stream. And what you see on a screen - it is just a view of it. So, Juan it is cool that you have better Transcript... still it having same deficiencies which i shown to Stephane not long ago, and tried to convince him that Transcript is a stream, not a window. A Transcript window is just a view of real transcript. And i think this is quite easy to make this separation and have sound model. On 18 February 2011 19:33, Juan Vuletich <j...@jvuletich.org> wrote: > Hi Eliot, > > Eliot Miranda wrote: >> >> Hi John, >> >> good questions. >> >> On Thu, Feb 17, 2011 at 6:21 AM, John B Thiel <jbth...@gmail.com >> <mailto:jbth...@gmail.com>> wrote: >> >> Cog VM -- Thanks and Performance / Optimization Questions >> >> ... >> (Also, any notoriously slow subsystems? For example, Transcript >> writing is glacial.) >> >> >> Someone should replace the Transcript's reliance on (I think) some kind of >> FormMorph which moved huge numbers of bits on each write. But this is not a >> VM issue. It's a Smalltalk issue. Whoever did this would instantly become >> a hero. > > There are other problems with Transcript besides performance. It is easy to > break the UI if called at the wrong times. In those cases, it is usually > needed to kill Squeak from the OS. Besides, it is not thread safe. > > Instantly becoming a hero sounds cool, so this is my attempt at it :) I only > tried this in Cuis, but I believe it should work on Squeak and Pharo without > much trouble. After loading this code, you can evaluate 'Smalltalk at: > #Transcript put: NewTranscript'. > > Some good properties of this are: > - Very fast. > - Thread safe! > - Doesn't use Morphic at all. Can be used to debug Morphic itself. > - Doesn't do delayed execution (no events, no forked processes). Immediate > visual feedback. > - Can show itself on Display, log to File, both, or none. > - Can be used for headless or remote images (for example, web servers). > > Some possible downsides are: > - Output only. Not a text editor. We have the Workspace and the Transcripter > for that. > - No seamless Morphic integration. I'll do one for Cuis, though. > > If no serious problems are found, I'll remove TranscriptStream from Cuis, > and rename this class as Transcript. > > Cheers, > Juan Vuletich > > 'From Cuis 3.0 of 31 January 2011 [latest update: #790] on 18 February 2011 > at 2:36:31 pm'! > !classDefinition: #NewTranscript category: #'System-Support'! > Object subclass: #NewTranscript > instanceVariableNames: '' > classVariableNames: '' > poolDictionaries: '' > category: 'System-Support'! > > !NewTranscript commentStamp: '<historical>' prior: 0! > A new implementation of Transcript. > - Thread safe. > - Very fast. > - Independent of Morphic or any other UI framework. > - Inmediate feedback. > - Can log to file. > - Not an editor. Only used for output. > - All protocol is on the Class side! > > !classDefinition: 'NewTranscript class' category: nil! > NewTranscript class > instanceVariableNames: 'entries firstIndex lastIndex accessSemaphore > unfinishedEntry logToFile showOnDisplay innerRectangle lastDisplayTime'! > > !DateAndTime methodsFor: 'squeak protocol' stamp: 'jmv 2/18/2011 12:57'! > printWithMsOn: aStream > "Print with millisecond resolution, no leading space, no offset." > > | ps | > self printYMDOn: aStream withLeadingSpace: false. > aStream nextPut: $T. > self printHMSOn: aStream. > ps _ (self nanoSecond // 1000000) printString padded: #left to: 3 > with: $0. > aStream nextPut: $.. > aStream nextPutAll: ps! ! > > > !NewTranscript class methodsFor: 'preferred protocol' stamp: 'jmv 2/18/2011 > 14:16'! > clear > | stream | > accessSemaphore critical: [ > "Having at least one entry simplifies handling of the entries > circular collection" > firstIndex _ 1. > lastIndex _ 1. > entries at: 1 put: 'Transcript'. > unfinishedEntry reset. > > logToFile ifTrue: [ > stream _ StandardFileStream forceNewFileNamed: self > filename. > [ > stream nextPutAll: 'Transcript log started: > '. > DateAndTime now printOn: stream. > stream > lf; > nextPutAll: > '------------------------------------------------------------------------'; > lf > ] ensure: [ stream close ]]]. > self display! ! > > !NewTranscript class methodsFor: 'preferred protocol' stamp: 'jmv 2/18/2011 > 14:16'! > log: aString > self addEntry: aString. > self display! ! > > !NewTranscript class methodsFor: 'preferred protocol' stamp: 'jmv 2/18/2011 > 11:49'! > logToFile > " > self logToFile > " > logToFile _ true! ! > > !NewTranscript class methodsFor: 'old Transcript compatibility' stamp: 'jmv > 2/18/2011 11:20'! > cr > "WriteStream protocol. > In the older TranscriptStream, it added a CR character. > Now, finish the current incomplete entry." > > self finishEntry! ! > > !NewTranscript class methodsFor: 'old Transcript compatibility' stamp: 'jmv > 2/18/2011 11:20'! > crtab > "WriteStream protocol. > End the current entry, and start a new one starting with a single tab > character." > > self cr; tab! ! > > !NewTranscript class methodsFor: 'old Transcript compatibility' stamp: 'jmv > 2/18/2011 11:21'! > endEntry > "For compatibility with old TranscriptStream. nop here"! ! > > !NewTranscript class methodsFor: 'old Transcript compatibility' stamp: 'jmv > 2/18/2011 11:21'! > flush > "For compatibility with old TranscriptStream. nop here"! ! > > !NewTranscript class methodsFor: 'old Transcript compatibility' stamp: 'jmv > 2/18/2011 14:17'! > nextPut: aCharacter > "WriteStream protocol. > Append aCharacter to the unfinishedEntry. > cr characters sent with this message do NOT finish the current > unfinishedEntry." > > unfinishedEntry nextPut: aCharacter. > self displayUnfinishedEntry! ! > > !NewTranscript class methodsFor: 'old Transcript compatibility' stamp: 'jmv > 2/18/2011 14:17'! > nextPutAll: aString > "WriteStream protocol. > Append aString to the unfinishedEntry. > cr characters sent with this message do NOT finish the current > unfinishedEntry." > > unfinishedEntry nextPutAll: aString. > self displayUnfinishedEntry! ! > > !NewTranscript class methodsFor: 'old Transcript compatibility' stamp: 'jmv > 2/18/2011 11:20'! > print: anObject > "Stream protocol" > anObject printOn: self! ! > > !NewTranscript class methodsFor: 'old Transcript compatibility' stamp: 'jmv > 2/18/2011 11:22'! > show: anObject > "Old TranscriptStream protocol." > self nextPutAll: anObject asString! ! > > !NewTranscript class methodsFor: 'old Transcript compatibility' stamp: 'jmv > 2/18/2011 11:22'! > space > "WriteStream protocol. > Append a space character to the receiver." > > self nextPut: Character space! ! > > !NewTranscript class methodsFor: 'old Transcript compatibility' stamp: 'jmv > 2/18/2011 11:22'! > tab > "WriteStream protocol. > Append a tab character to the receiver." > > self nextPut: Character tab! ! > > !NewTranscript class methodsFor: 'private' stamp: 'jmv 2/18/2011 12:59'! > addEntry: aString > "Add a new entrie to the entries circular list. If full, a new entry > will replace the oldest one." > | msg now | > logToFile ifTrue: [ > now _ DateAndTime now. > msg _ String streamContents: [ :strm | > now printWithMsOn: strm. > strm > nextPutAll: ' process:'; > nextPutAll: Processor activeProcess priority > printString; > nextPut: $ ; > nextPutAll: Processor activeProcess hash > printString; > nextPut: $ ; > nextPutAll: aString; > lf ]]. > > self addEntry: aString logToFile: msg! ! > > !NewTranscript class methodsFor: 'private' stamp: 'jmv 2/18/2011 12:34'! > addEntry: aString logToFile: otherString > "Add a new entrie to the entries circular list. If full, a new entry > will replace the oldest one." > | stream | > accessSemaphore critical: [ > > "Internal circular collection" > lastIndex _ lastIndex \\ self maxEntries + 1. > firstIndex = lastIndex ifTrue: [ > firstIndex _ firstIndex \\ self maxEntries + 1 ]. > entries at: lastIndex put: aString. > > "external file" > otherString ifNotNil: [ > [ > stream _ StandardFileStream fileNamed: self > filename. > stream > setToEnd; > nextPutAll: otherString; > flush] > ensure: [ stream close ] > ] > ]! ! > > !NewTranscript class methodsFor: 'private' stamp: 'jmv 2/18/2011 14:16'! > finishEntry > | newEntry | > newEntry _ unfinishedEntry contents. > unfinishedEntry reset. > self addEntry: newEntry. > self display! ! > > !NewTranscript class methodsFor: 'displaying' stamp: 'jmv 2/18/2011 14:20'! > display > showOnDisplay ifTrue: [ > self displayOn: Display. > lastDisplayTime _ DateAndTime now ]! ! > > !NewTranscript class methodsFor: 'displaying' stamp: 'jmv 2/18/2011 14:09'! > displayOn: aForm > " > experimentos > NewTranscript displayOn: Display > " > | font port count i string x y fh f | > aForm border: (innerRectangle outsetBy: 3) width: 3. > aForm fill: innerRectangle fillColor: Color white. > port _ BitBlt toForm: aForm. > port clipWidth: innerRectangle right. > font _ StrikeFont default. > font installOn: port foregroundColor: Color black. > > fh _ font height. > count _ innerRectangle height // fh-1. > x _ innerRectangle left. > y _ innerRectangle top. > f _ firstIndex-1. > firstIndex > lastIndex ifTrue: [ f _ f - self maxEntries ]. > i _ (lastIndex - count max: f) \\ self maxEntries + 1. > [ > string _ entries at: i. > port displayString: string from: 1 to: string size at: x@y > strikeFont: font kern: font baseKern negated. > y _ y + fh. > i = lastIndex > ] whileFalse: [ i _ i \\ self maxEntries + 1 ]. > > string _ unfinishedEntry contents. > port displayString: string from: 1 to: string size at: x@y > strikeFont: font kern: font baseKern negated.! ! > > !NewTranscript class methodsFor: 'displaying' stamp: 'jmv 2/18/2011 14:23'! > displayUnfinishedEntry > showOnDisplay ifTrue: [ > (lastDisplayTime isNil or: [ (DateAndTime now - > lastDisplayTime) totalSeconds > 1 ]) > ifTrue: [ ^self display ]. > self displayUnfinishedEntryOn: Display ]! ! > > !NewTranscript class methodsFor: 'displaying' stamp: 'jmv 2/18/2011 14:14'! > displayUnfinishedEntryOn: aForm > > | font port count string x y fh | > port _ BitBlt toForm: aForm. > port clipWidth: innerRectangle right. > font _ StrikeFont default. > font installOn: port foregroundColor: Color black. > > fh _ font height. > count _ innerRectangle height // fh-1. > x _ innerRectangle left. > > string _ unfinishedEntry contents. > y _ ((lastIndex - firstIndex \\ self maxEntries) min: count-1) + 1 * > font height + innerRectangle top. > port displayString: string from: 1 to: string size at: x@y > strikeFont: font kern: font baseKern negated.! ! > > !NewTranscript class methodsFor: 'class initialization' stamp: 'jmv > 2/18/2011 13:13'! > initialize > " > self initialize > " > showOnDisplay _ true. > innerRectangle _ 20@20 extent: 300@500. > logToFile _ false. > entries _ Array new: self maxEntries. > unfinishedEntry _ '' writeStream. > accessSemaphore _ Semaphore forMutualExclusion. > self clear! ! > > !NewTranscript class methodsFor: 'constants' stamp: 'jmv 2/18/2011 12:33'! > filename > ^'transcript.txt'! ! > > !NewTranscript class methodsFor: 'constants' stamp: 'jmv 2/18/2011 12:59'! > maxEntries > ^1000! ! > > NewTranscript initialize! > > > > -- Best regards, Igor Stasenko AKA sig.