"====================================================================== | | Smalltalk Transcript object (TextCollector class) | | $Revision: 1.7.5$ | $Date: 2000/05/28 16:56:52$ | $Author: pb$ | ======================================================================" "====================================================================== | | Copyright 1988-92, 1994-95, 1999, 2000 Free Software Foundation, Inc. | Written by Paolo Bonzini. | | This file is part of the GNU Smalltalk class library. | | The GNU Smalltalk class library is free software; you can redistribute it | and/or modify it under the terms of the GNU Lesser General Public License | as published by the Free Software Foundation; either version 2.1, or (at | your option) any later version. | | The GNU Smalltalk class library is distributed in the hope that it will be | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser | General Public License for more details. | | You should have received a copy of the GNU Lesser General Public License | along with the GNU Smalltalk class library; see the file COPYING.LESSER. | If not, write to the Free Software Foundation, 59 Temple Place - Suite | 330, Boston, MA 02111-1307, USA. | ======================================================================" Stream subclass: #TextCollector instanceVariableNames: 'semaphore receiver selector' classVariableNames: '' poolDictionaries: '' category: 'Streams' ! TextCollector comment: 'I am a thread-safe class that maps between standard Stream protocol and a single message to another object (its selector is pluggable and should roughly correspond to #nextPutAll:). I am, in fact, the class that implements the global Transcript object.'! !TextCollector class methodsFor: 'accessing'! new self shouldNotImplement ! message: receiverToSelectorAssociation "Answer a new instance of the receiver, that uses the message identified by anAssociation to perform write operations. anAssociation's key is the receiver, while its value is the selector." ^self basicNew initialize; message: receiverToSelectorAssociation ! ! !TextCollector methodsFor: 'set up'! message "Answer an association representing the message to be sent to perform write operations. The key is the receiver, the value is the selector" ^receiver -> selector ! message: receiverToSelectorAssociation "Set the message to be sent to perform write operations to the one represented by anAssociation. anAssociation's key is the receiver, while its value is the selector" receiver := receiverToSelectorAssociation key. selector := receiverToSelectorAssociation value ! ! !TextCollector methodsFor: 'accessing'! cr "Emit a new-line (carriage return) to the Transcript" self nl ! nextPut: aCharacter "Emit aCharacter to the Transcript" self nextPutAll: (String with: aCharacter) ! next: anInteger put: anObject "Write anInteger copies of anObject to the Transcript" self nextPutAll: (String new: anInteger withAll: anObject) ! nextPutAll: aString "Write aString to the Transcript" semaphore critical: [ self primNextPutAll: aString. Processor idle ] ! show: aString "Write aString to the Transcript" semaphore critical: [ self primNextPutAll: aString. Processor idle ] ! showCr: aString "Write aString to the Transcript, followed by a new-line character" semaphore critical: [ self primNextPutAll: aString. self primNextPutAll: Character nl asString. Processor idle ] ! showOnNewLine: aString "Write aString to the Transcript, preceded by a new-line character" semaphore critical: [ self primNextPutAll: Character nl asString. self primNextPutAll: aString. Processor idle ] ! ! !TextCollector methodsFor: 'printing'! print: anObject "Print anObject's representation to the Transcript" semaphore critical: [ self primNextPutAll: anObject printString. Processor idle ] ! printOn: aStream "Print a representation of the receiver onto aStream" self == Transcript ifTrue: [ aStream nextPutAll: 'Transcript' ] ifFalse: [ super printOn: aStream ] ! ! !TextCollector methodsFor: 'storing'! store: anObject "Print Smalltalk code which evaluates to anObject on the Transcript" semaphore critical: [ self primNextPutAll: anObject storeString. Processor idle ] ! storeOn: aStream "Print Smalltalk code which evaluates to the receiver onto aStream" self == Transcript ifTrue: [ aStream nextPutAll: 'Transcript' ] ifFalse: [ super storeOn: aStream ] ! ! !TextCollector methodsFor: 'private'! primNextPutAll: aString "Private - Forward the writing request to the actual object" receiver perform: selector with: aString ! initialize "Private - Initialize the receiver's instance variables" semaphore := Semaphore forMutualExclusion ! ! Smalltalk at: #Transcript put: (TextCollector message: stdout -> #nextPutAllFlush:)!