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