Folks -
I have just released a bunch of updates. Most of these were painstakingly culled from the Squeak list by Stefan, for which we thank all of you, and him, greatly.
I decided to jump the gun and release the symbol printing changes after living with them all day. Hey, what are test pilots for anyway? Thanks to Roel Wuyts for taking the lead here. Note my comment on 2040 regarding the new usage of Symbol>>isLiteral. There is a fair chance this will break something. All I can say is it's the RIght Thing to do, and we will happily fix anything that breaks.
- Dan ------------------------- 2006PWSfixes-mjg
2007FourTweaks-di -- Dan Ingalls -- 24 April 2000 Changes the compilation of ifNotNil: for better code and more consistency with decompilation. Changes interval>>valuesInclude: to avoid slow fraction computations. Changes Symbol>>storeOn: to take advantage of the #'any chars' construct. Changes the comment in SystemDictionary>>recompileAllFrom: because it used to omit classes.
2008ModProjClassHack -- Dan Ingalls -- 5 April 2000 Prefatory to putting new classes into local environments, classes added in isolated projects must not be revoked upon exit. This hack accomplishes this, at the cost of added classes not being local to the project.
2009HighlightingSelFix-sr -- Stephan Rudlof -- 23 April 2000 Fix for PluggableListMorph/SimpleHierarchicalListMorph: Highlighting/unhighlighting works correctly now, if colors of StringMorphs are changed programmatically to highlight/unhighlight colors of PluggableListMorph and SimpleHierarchicalListMorph.
2010CPPPluginEnh-rmf -- Robert M Fure -- 20 April 2000 WARNING: I didn't test this enhancement --sma Here's a very small file-in that gives C++-generation capability to the CCodeGenerator and friends. I wrote it while developing a plug-in that interfaces to a C++ DLL. How does it differ from the ordinary mode? Mostly just two things: 1) Places generated code in a file with a .cpp suffix. 2) Puts extern ''C'' in the right places so that the plug-in's exported
Routines have the names that the Squeak plug-in mechanism expects them to. To create a C++ plug-in, just do the usual thing, adding the trivial class method isCPP ^ true to your plug-in class (the one that actually gets translated into C/C++)."
2011PNG-dsm -- Duane Maxwell, Bob Arning -- 19 April 2000 This changeset implements a reader for Portable Network Graphics (PNG) files. This is an alpha release. While it seems to read all of the PNG test images, more testing is needed. It does little to no error checking, and does not utilize the gamma information. It also doesn't yet write PNG files - this is left as an exercise for the reader. See http://www.cdrom.com/pub/png/ for more information about PNG Submitted by Duane Maxwell/Entrypoint"
2012FormEditor-sma -- Stefan Matthias Aust -- 22 April 2000 The FormEditor's blank cursor doesn't work and is irritating. A crosshair is better."
2013ContextTrace-sma -- Stefan Matthias Aust -- 22 April 2000 As discussed in the mailing list, #trace: walkbacked if traced object didn't have correct print strings. This patch wrapps printing in an exception handler and unifies tracing on Transcript and on files, also providing a new method trace: aBlock on: aStream for general usage."
2014KwSpeedup-av -- Andres Valloud -- 22 April 2000 Speedup of String>>keywords and removal of isEmtpy."
2015SimpleMouseBtnFix-jlb -- Jim Benson -- 13 April 2000 Here's a fix for a small bug in the SimpleButtonMorph. The line: 'oldColor _ nil' was inserted to reset the cmd-drag flag."
2016HttpSocketFix-gr -- Gerardo Richarte -- 14 April 2000 Ok, I'm not sure if this a bug or not, but, I know that I needed to fix/change this in order to get out of an infinite loop when updating my image from a remote server (I'm actually using a swiki as updates server, but I don't think this makes a big difference), and it happened every time I tried to update. What I changed is size for position in: bytesRead _ self primSocket: socketHandle receiveDataInto: buf startingAt: 1 count: (length - response size). for: bytesRead _ self primSocket: socketHandle receiveDataInto: buf startingAt: 1 count: (length - response position). as response is initialized with a String new: length, response size is always = length, so length - response size is 0, and then nothing is read. What I don't understand is why this works sometimes... can somebody help me on this? Ok, I checked #size implementation in 'response class', and it says 'readLimit max: position', so I think #size is not what's needed... Why was it working? was it working when all the response came before entering this method (in beginning?) no way, becouse it still worked when some 'data was late' were printer on the Transcript. Conclusion: I don't know if this fix is right or wrong, but I'm sure I needed it."
2017RobustCQ-ls -- Lex Spoon -- 8 April 2000 WARNING: Untested, just copied --sma Two changes to the BSD-style listenLoop in ConnectionQueue to deal with unusual circumnstances. First, make the listener socket be an instance variable instead of a temporary variable. This way, when the CQ is destroy-ed, the listening socket can also be conveniently destroyed. Second, if the listener socket becomes invalid, restart the listenLoop from scratch. This is important if a ConnectionQueue is saved, because the socket will become invalid when the image starts up again."
2018Speedups-av -- Andres Valloud -- 11 April 2000 Fast implementations of methods related to copying a SequenceableCollection, padding it with anObject, etc."
2019Array2DEnh-sma -- Stefan Matthias Aust -- 22 April 2000 Refactored and improved Array2D, including changes from Michael Rüger. It's still not really useful and I'd propose to move it out of the Collection hierarchy."
2020CloseBoxFlashFix-jmm -- John M McIntosh johnmci@smalltalkconsulting.com -- 31 March 2000 The close box and the grow box get redrawing continuously when the red button is down, this results in lots of redraw activity. Change the logic to remember state and only redraw when needed"
2021SemaphoreCmp-sma -- Stefan Matthias Aust -- 22 April 2000 Discussing a problem with comparing Semaphores, Wim Boot and Tim Rowledge agreed upon
I think Semaphore comparison (including #hash) should be identity based, not content based.
So I implemented (but not really tested) it that way."
2022LowSpace-go -- Georg Gollmann -- 30 March 2000 The current LowSpaceWatcher just alerts the user. This is not useful for servers or for situations when objects are cached and should be discarded when space becomes tight. I have now generalized the mechanism used in my MailArchiver (http://macos.tuwien.ac.at/Squeak/mailArchiver.html). As an example setup is now: Smalltalk memoryHogs add: ArchivedMail When space is low #freeSomeSpace gets sent: ArchivedMail>freeSomeSpace ''Remove all cached text from my instances.'' self allInstancesDo: [:m | m purgeText] If freeSomeSpace fails to free enough memory - maybe because no memoryHogs have been registered - the old behavior (alert the user) is invoked."
2023SchedulingBugFix-fm -- Florin Mateoc -- 9 April 2000 WARNING: I didn't test this as much as probably needed --sma If you try (after saving your image) ""[1 halt] fork"", first of all the notifier view will be hidden behind the active window. Then if you select 'resume' Squeak hangs. The first problem is that the scheduling code does not expect a controller (in this case the notifier) to be started from a non-UI thread, actually you get interesting results even if you say ""[1 inspect] fork"". The second problem is that the debugger code does not expect to have been started from a non-UI thread (with interruptedController being nil)."
2024DecompileFix-th -- Torge Husfeldt jean.jaques.gelee@gmx.de -- 17 March 2000 Fixes a bug in decompiling while constructs. Now creates a ReturnNode as seems appropriate. Example: [true] whileTrue: [^#symbol] Used to decompile as: [true] whileTrue: [#symbol]. ^ self"
2025HeapFix-mir -- Michael Rüger -- 22 March 2000 fixes a bug when enumerating Heaps."
2026HirBrowserFix-mir -- Michael Rüger -- 22 March 2000 This change set fixes a problem when removing a class which is currently in the class list of a hierarchy browser"
2027ColorPickerFix-raa -- Bob Arning -- 26 March 2000 - handle ColorPickerMorph instances which existed prior to addition of <theSelectorDisplayMorph>"
2028MinimumSize-jlb -- Jim Benson -- 27 March 2000 This changeset allows you to modify the minimum extent to which a window may be resized. To set this extent, send the message #minimumExtent: to the window"
2029ScaleMorph-rcs -- Russell Swane -- 16 March 2000 Modified ScaleMorph. Added some options on appearance, so most times a ScaleMorph would be used, should be able to use as is without subclassing. Also split #drawOn: into multiple submethods for a subclass I've been using. New interface is a strict superset of old interface so nothing should break."
2030HandMorphCleanUp-sma -- Stefan Matthias Aust -- 24 March 2000 Get rid of 'isKindOf: HandMorph'"
2031EnvEditorFix-mjt -- Mike Thomas -- 24 March 2000 While investigating Squeak's music interface at one this morning Australian EST I noticed that the horizontal scale gets crowded when you increase the maxTime by dragging the envelope end point to the right. This changeset provides dynamic calculation of the major and minor tick points to resolve the problem."
2032FileDir-bf -- Bert Freudenberg -- 22 March 2000 Enforces the absoluteness of FileDirectories for Windows. Also corrects FileDirclass>>splitName:to:, for the DOS 'C:' case (which makes the specialized fullNameFor: method obsolete) and for the Unix '/foo' case. sma added support for Windows UNC names, i.e. \magus\dev\dir\file.txt"
2033MissingTextColor-dns -- David N Smith -- 24 March 2000 TextColor supports each of the three RGB colors at full intensity(red, green, blue), all three paired combinations (rg,gb,br: cyan, magenta, yellow) at full intensity, and it supports black, but no white. White is basic: it is all three of the colors at full intensity. It's the only basic color missing. sma added method categories and a missing #hash method."
2034GradientWorld-raa -- Bob Arning -- 24 March 2000 Permit the world to be drawn with a gradient. Note that the world has a #color: method that sets the fillColor2 to be the same as color, thus eliminating the gradient. So, if you want to change the color and keep the gradient, calls to #color: should be followed by a call to #gradientFillColor:. World color: Color green. World gradientFillColor: Color lightGreen
2035Celeste-dvf -- Daniel Vainsench -- 8 April 2000 I like Celeste, but it's slow at reading 10,000 message categories (not slower than any other mailer I know of, but still not fast enough). This changeset makes it read only the latest 100, adding a menu option to read the rest. Should at some point give an indication if not showing all messages. If anyone finds this useful, or has whatever comments, I'd be happy to hear. I made the constant 100 a method and changed the default to 200 --sma"
2036WarpBltFix-kfr -- Karl Ramberg -- 22 April 2000 Hey, my first bug fix. Two displaying objects were overlapping creating a unwanted effect."
2037FreeCellWorldBug-smg -- Sean McGrath -- 27 March 2000 Open a morphic World, new morph, games, freecell, statistics: UndefinedObject(Object)>>doesNotUnderstand: AlignmentMorph(Morph)>>openInWindowLabeled:inWorld: AlignmentMorph>>openInWindowLabeled:inWorld: AlignmentMorph(Morph)>>openInWindowLabeled: FreeCellStatistics>>display FreeCell>>statistics [] in SimpleButtonMorph>>doButtonAction BlockContext>>ensure: CursorWithMask(Cursor)>>showWhile: SimpleButtonMorph>>doButtonAction In Morph, openInWindowLabeled: aString ^self openInWindowLabeled: aString inWorld: World World in nil. Changing 'World' to 'self currentWorld' fixes the symptom. I have no idea what the problem is, since I understand very little Morphic. This is probably a general problem. There're are some 106 users of the global 'World' I'm too tired to check them all. Most of them should be tranlated into a test whether we're running a full screen world or an MVC world. The others might be candidates for #currentWorld. --sma"
2038FileCntBrwEnh-sma -- Stefan Matthias Aust -- 22 April 2000 Now my beloved brown browser also has a handy >>file into new changeset<< feature."
2039PlgTextMorphFix-sr -- Stephan Rudlof -- 29 March 2000 Dan changed the line [self setText: textToAccept shallowCopy. to [self setText: self getText. ; probably to save time. It this was his goal, reverting to the previous version given here should be correct. If he had another intention there is needed more thinking..."
2040SymbolPrinting-rwdi -- Roel Wuyts, Dan Ingalls -- 25 April 2000 This changeSet incorporates Roel Wuyts's suggested change to print symbols with a #-sign in their printString. It also uses the #'any chars' construct to ensure that any symbol can be printed as a literal. NOTE: This implies a change in the definition of Symbol>>isLiteral to always return true (it used only to return true for symbols that can be printed without string quotes as #someSymbol). If you really want to test whether a symbol can be printed without string quotes, then use the expression (Scanner isLiteralSymbol: theSymbol).
Fix: Some methods that can destroy the sort order were not blocked. addAll: was inconsistent in not returning its argument. Enhancement: Testing for inclusion is considerably faster now.
'From Squeak2.8alpha of 13 January 2000 [latest update: #2042] on 27 April 2000 at 1:23:18 pm'!
!SortedCollection methodsFor: 'accessing' stamp: 'go 4/27/2000 11:05'! at: anInteger put: anObject "Storing into a SortedCollection with at:put: is not allowed."
self shouldNotImplement! !
!SortedCollection methodsFor: 'testing' stamp: 'go 4/27/2000 13:05'! includes: anObject "Answer whether anObject is one of the receiver's elements."
| idx | idx := self indexForInserting: anObject. ^(array atPin: idx) = anObject or: [(array atPin: idx - 1) = anObject ]! !
!SortedCollection methodsFor: 'adding' stamp: 'go 4/27/2000 13:19'! add: newObject
^super insert: newObject before: (self indexForInserting: newObject)! !
!SortedCollection methodsFor: 'adding' stamp: 'go 4/27/2000 13:16'! addAll: aCollection "Optimize for large additions."
aCollection size > (self size // 3) ifTrue: [ aCollection do: [ :each | super addLast: each ]. self reSort ] ifFalse: [ aCollection do: [ :each | self add: each ]]. ^aCollection! !
!SortedCollection methodsFor: 'adding' stamp: 'go 4/26/2000 17:26'! addFirst: newObject
self shouldNotImplement! !
!SortedCollection methodsFor: 'adding' stamp: 'go 4/26/2000 17:10'! addLast: newObject
self shouldNotImplement! !
!SortedCollection methodsFor: 'private' stamp: 'go 4/26/2000 17:17'! insert: anObject before: spot
self shouldNotImplement! !
Hi Georg.
!SortedCollection methodsFor: 'testing' stamp: 'go 4/27/2000 13:05'! includes: anObject "Answer whether anObject is one of the receiver's elements."
| idx | idx := self indexForInserting: anObject. ^(array atPin: idx) = anObject or: [(array atPin: idx - 1) =
anObject ]! !
How will this behave when aSortedCollection has a sortBlock like [:x :y | x <= y], and/or when the collection has duplicate elements in terms of order? Also, it relies on #indexForInserting:. What if anObject is not compatible with the order relationship specified in the sortBlock? Then it will fail instead of answering false.
s _ SortedCollection sortBlock: [:x :y | x x + x y < (y x + y y)]. 1 to: 5 do: [:each | 1 to: 5 do: [:some | s add: each @ some]]. s includes: 3@3.
In this example, the collection includes 3@3. The index for inserting 3@3 is 26, but neither array at: 26 or array at: 25 is 3@3. Moreover, this fails:
s includes: #garbage.
*Perhaps* this could be fixed with exceptions... if the block triggers one, then the object is incompatible and therefore it's not in the collection... I do not think this assumption would be valid all the time.
Along these lines, I implemented QuickSearch for sorted collections as a separate class whose instances are algorithms that know how to search. It has the advantage that it avoids these problems when you do know what's inside a collection, and you can also use the algorithm with something that is not a sorted collection, or even with a different sort block. Together with an adapter, you can even run it in things other than sequenceable collections, such as file streams.
!SortedCollection methodsFor: 'adding' stamp: 'go 4/27/2000 13:16'! addAll: aCollection "Optimize for large additions."
aCollection size > (self size // 3) ifTrue: [ aCollection do: [ :each | super addLast: each ]. self reSort ] ifFalse: [ aCollection do: [ :each | self add: each ]]. ^aCollection! !
This may modify aCollection, although the collection supposed to be modified was the receiver. Merge sort would be ok, but only if both collections had equivalent (or nil) sortBlocks.
Andres.
At 12:03 Uhr -0700 27.04.2000, Andres Valloud wrote:
s _ SortedCollection sortBlock: [:x :y | x x + x y < (y x + y y)]. 1 to: 5 do: [:each | 1 to: 5 do: [:some | s add: each @ some]]. s includes: 3@3.
In this example, the collection includes 3@3. The index for inserting 3@3 is 26, but neither array at: 26 or array at: 25 is 3@3.
A valid observation, thanks. I was not aware how little a SortedCollection actually knows about its content.
!SortedCollection methodsFor: 'adding' stamp: 'go 4/27/2000 13:16'! addAll: aCollection "Optimize for large additions."
aCollection size > (self size // 3) ifTrue: [ aCollection do: [ :each | super addLast: each ]. self reSort ] ifFalse: [ aCollection do: [ :each | self add: each ]]. ^aCollection! !
This may modify aCollection, although the collection supposed to be modified was the receiver. Merge sort would be ok, but only if both collections had equivalent (or nil) sortBlocks.
Sorry, I do not understand this one. Can you elaborate ?
Georg
Hi Georg.
addAll: aCollection "Optimize for large additions."
aCollection size > (self size // 3) ifTrue: [ aCollection do: [ :each | super addLast: each ]. self reSort ] ifFalse: [ aCollection do: [ :each | self add: each ]]. ^aCollection! !
Sorry, I do not understand this one. Can you elaborate ?
The message addAll: works by adding stuff to the receiver. Hence,
x addAll: aCollection
gets you x with all its elements plus the elements of aCollection, all of those in x. aCollection is not modified by this process. Now, with the method above, you may get an equivalent answer but the receiver may be left untouched by addAll:. This would happen when aCollection size <= (self size // 3). In that case, aCollection would have its elements and those of x, so the answer of this message would be equivalent. But aCollection is modified instead of x. So, you could have this happen:
x _ (1 to: 10) asSortedCollection. y _ (11 to: 12) asSortedCollection. x addAll: y. x size <alt-p> 10
How come it's 10 when I added stuff to it? And surprisingly,
y size <alt-p> 12
?!??!...
What I meant by merge sort is that when collections are large, the cost of resorting is huge. So, when addAll: is sent with a big collection to another big collection, you could do merge sort and create a third temp one whose contents would replace the receiver's when the process is finished. Alas, you can only do this if the sort blocks are both nil or are compatible.
I do not think that the sort blocks can be determined to be compatible... it would take too much (even if they sent the same messages, you would also have to verify that they were supposed to send the same messages to the same kind of objects). That leaves the case when the sort blocks are both nil, in which you can safely do merge sort.
Andres.
While adding the new version of #addAll: to my image, I noticed that this method was never implemented correctly. Instead of returning the added collection as all other implementors of #addAll: do, it returned a the receiver. Fixing this as Georg did will break at least OrderedCollection>>sortBy:
I reimplemented this method as
^ (self asSortedCollection: aBlock) asOrderedCollection
which should do the job. Hopefully nothing else breaks. I've attached the whole change set so that you all can test the code.
bye
squeak-dev@lists.squeakfoundation.org