From m at jaromir.net Mon Feb 1 06:16:01 2021 From: m at jaromir.net (jaromir) Date: Mon, 1 Feb 2021 00:16:01 -0600 (CST) Subject: [squeak-dev] Transcript losing output when #processPreemptionYields = true In-Reply-To: <0C26F716-F092-42C4-BE09-5D66690C0867@gmail.com> References: <1612114094246-0.post@n4.nabble.com> <1612116683800-0.post@n4.nabble.com> <0C26F716-F092-42C4-BE09-5D66690C0867@gmail.com> Message-ID: <1612160161284-0.post@n4.nabble.com> > processPreemptionYields = true is a clearly broken policy (as your transcript bugs show) and is only supported for backwards compatibility. Thanks! May I ask why processPreemptionYields = true should be a broken policy? The Transcript is broken, can be fixed and the bug disappears. I'd say one's code should better be independent of the processPreemptionYields setting anyway. Assuming the order of processes is always guaranteed by processPreemptionYields = false may lead e.g. to using Processor yield rather than semaphores to synchronize processes etc. (I try to test my code against both settings to make sure it works) Thanks again, Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From jr at amanue.com Mon Feb 1 07:36:14 2021 From: jr at amanue.com (Jim Rosenberg) Date: Mon, 01 Feb 2021 02:36:14 -0500 Subject: [squeak-dev] Cannot read 4.3 image on Raspberry Pi In-Reply-To: <20210118141546.GA31888@shell.msen.com> References: <30761BA6E24B38D160E49291@chorder> <20210118141546.GA31888@shell.msen.com> Message-ID: <63BB2B023E075C08EF95DA13@chorder> > On Mon, Jan 18, 2021 at 07:07:25AM -0500, I wrote: >> Ouch! I have a lot of artistic work which is developed in Squeak on >> Linux -- currently only up to 4.3 (which is working fine for me, so I >> haven't upgraded). I'm trying to run one of my 4.3 images on a >> Raspberry Pi 3B+ which is at Raspbian 10 (buster), and with the current >> armv6 squeak VM, getting the message >> >> This interpreter (vers. 6521) cannot read image file (vers. 6504). >> >> Suggestions? --On Monday, January 18, 2021 09:15:46 AM -0500 "David T. Lewis" wrote: > If you do not mind installing development tools on your Raspberry Pi, then > the best thing to do is compile the VM yourself. Instructions for doing > this are at http://wiki.squeak.org/squeak/6354 > > If you have any difficulty building your VM, please ask for help. And > if it works without problems, please report back so we know. It built without a hitch, and worked fine with all but one of the images I tested it on. The image that caused me trouble uses sound. Everything else worked fine, but the default build seemed not to support sound at all. The only drivers were vm-sound-null and vm-sound-custom. I've had no luck with Linux sound on my desktop using anything other than vm-sound-pulse -- that works fine. squeak -h didn't show vm-sound-pulse as an available driver oh the version I built on the Raspberry Pi, so I set out to fix that. After installing the pulse development library, configure found it, and now I have an image on which everything just works. Thanks for the help!! lit-archive 82% squeak -version 4.19.5-3796 #1 Wed 20 Jan 2021 08:45:38 AM EST /usr/bin/cc Linux lit-archive 5.4.83-v7+ #1379 SMP Mon Dec 14 13:08:57 GMT 2020 armv7l GNU/Linux plugin path: /usr/local/lib/squeak/4.19.5-3796 [default: /usr/local/lib/squeak/4.19.5-3796/] * * * > You can find a precompiled VM for ARM v61 at http://squeakvm.org/unix/ > which may work, although it is out of date so I am not sure if it will > run on your Pi. Results here are not so happy. The display driver is marked in red on that web page as "experimental"; on my images it mangles bitmaps in SketchMorphs in a way that is completely unacceptable. It looks almost as though there was some kind of attempt to do after-the-fact anti-aliasing that just went haywire on my graphics. -Thanks, Jim From bruce.oneel at pckswarms.ch Mon Feb 1 07:56:30 2021 From: bruce.oneel at pckswarms.ch (Bruce O'Neel) Date: Mon, 01 Feb 2021 08:56:30 +0100 Subject: [squeak-dev] Cannot read 4.3 image on Raspberry Pi In-Reply-To: <63BB2B023E075C08EF95DA13@chorder> References: <63BB2B023E075C08EF95DA13@chorder> <30761BA6E24B38D160E49291@chorder> <20210118141546.GA31888@shell.msen.com> Message-ID: <1612166190-df0c69a5dbe963ffccc35a9360254e77@pckswarms.ch> Good news/bad news. The good news is that Pulse sound driver can be solved with: 1.  apt install libpulse-dev 2.  Make sure you say yes to clean, and rebuild. The bad news is that while sound might "work" in the sense that sounds will now be produced we seem to have a problem with the sounds skipping and having pops in them.  That's still being worked on.... cheers bruce > > On Mon, Jan 18, 2021 at 07:07:25AM -0500, I wrote: > >> Ouch! I have a lot of artistic work which is developed in Squeak on > >> Linux -- currently only up to 4.3 (which is working fine for me, so I > >> haven't upgraded). I'm trying to run one of my 4.3 images on a > >> Raspberry Pi 3B+ which is at Raspbian 10 (buster), and with the current > >> armv6 squeak VM, getting the message > >> > >> This interpreter (vers. 6521) cannot read image file (vers. 6504). > >> > >> Suggestions? > > --On Monday, January 18, 2021 09:15:46 AM -0500 "David T. Lewis" > wrote: > > > If you do not mind installing development tools on your Raspberry Pi, then > > the best thing to do is compile the VM yourself. Instructions for doing > > this are at http://wiki.squeak.org/squeak/6354 > > > > If you have any difficulty building your VM, please ask for help. And > > if it works without problems, please report back so we know. > > It built without a hitch, and worked fine with all but one of the images I > tested it on. The image that caused me trouble uses sound. Everything else > worked fine, but the default build seemed not to support sound at all. The > only drivers were vm-sound-null and vm-sound-custom. > > I've had no luck with Linux sound on my desktop using anything other than > vm-sound-pulse -- that works fine. squeak -h didn't show vm-sound-pulse as > an available driver oh the version I built on the Raspberry Pi, so I set > out to fix that. After installing the pulse development library, configure > found it, and now I have an image on which everything just works. Thanks > for the help!! > > lit-archive 82% squeak -version > 4.19.5-3796 #1 Wed 20 Jan 2021 08:45:38 AM EST /usr/bin/cc > Linux lit-archive 5.4.83-v7+ #1379 SMP Mon Dec 14 13:08:57 GMT 2020 armv7l > GNU/Linux > plugin path: /usr/local/lib/squeak/4.19.5-3796 [default: > /usr/local/lib/squeak/4.19.5-3796/] > > * * * > > > You can find a precompiled VM for ARM v61 at http://squeakvm.org/unix/ > > which may work, although it is out of date so I am not sure if it will > > run on your Pi. > > Results here are not so happy. The display driver is marked in red on that > web page as "experimental"; on my images it mangles bitmaps in SketchMorphs > in a way that is completely unacceptable. It looks almost as though there > was some kind of attempt to do after-the-fact anti-aliasing that just went > haywire on my graphics. > > -Thanks, Jim -------------- next part -------------- An HTML attachment was scrubbed... URL: From marcel.taeumel at hpi.de Mon Feb 1 13:10:44 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Mon, 1 Feb 2021 14:10:44 +0100 Subject: [squeak-dev] Transcript losing output when #processPreemptionYields = true In-Reply-To: <1551EFA6-AA72-485A-B857-8BA8AF693AA0@gmail.com> References: <1612116683800-0.post@n4.nabble.com> <1551EFA6-AA72-485A-B857-8BA8AF693AA0@gmail.com> Message-ID: Hi Eliot. > D’u hear that folks? We badly need to make sure that processPreemptionYields = false is the default. It already is. ;-) For quite some years now. Best, Marcel Am 31.01.2021 20:14:38 schrieb Eliot Miranda : _,,,^..^,,,_ (phone) > On Jan 31, 2021, at 10:11 AM, jaromir wrote: > > No no, it's set to true by default but I'm learning and have tested behavior > with processPreemptionYields = false :) I was not aware this is not supposed > to be a "production" feature. I applied the fix from the other Transcript > issue and it seemingly 'works' so it seemed to be another bug related to the > other one. D’u hear that folks? We badly need to make sure that processPreemptionYields = false is the default. > -- > Sent from: http://forum.world.st/Squeak-Dev-f45488.html > -------------- next part -------------- An HTML attachment was scrubbed... URL: From eric.gade at gmail.com Mon Feb 1 13:57:32 2021 From: eric.gade at gmail.com (Eric Gade) Date: Mon, 1 Feb 2021 08:57:32 -0500 Subject: [squeak-dev] Unicode Ranges you might want to copy In-Reply-To: <1775862c6d8.10f71a9b5728.3911329244202033832@zoho.com> References: <1775862c6d8.10f71a9b5728.3911329244202033832@zoho.com> Message-ID: Hi Timothy, I spent several (fruitless) days last year trying to get cuneiform fonts to render properly in Squeak (see here for examples of the fonts). There does seem to be an issue with rendering glyphs above a certain code point from what I recall. I am definitely interested in your work and what you end up finding out. On Sun, Jan 31, 2021 at 7:20 AM gettimothy via Squeak-dev < squeak-dev at lists.squeakfoundation.org> wrote: > Hi Folks, > > You might find the below handy. > > Fwiw, I have coded the UnicodeRangeBrowser SeasideApp to display all the > below (it times out before all display, I will be doing refactor and more > development). > > I am also coding a utility class to provide information such as below in a > variety of ways. > > fwiw, here are my current todo notes for this font information. > > unifont > > provide link to the unicode spec. > provide browser fonts list. > provide squeak fonts list. > provide phare fonts list ^self squeak fonts list: > what are Variant Selectors ? > > show gaps in the ranges. > > provide a link(s) to required fonts that will make a range display. > displays on: browser list, squeak, emacs, xterm... > status bar...broken, partial, full. > use cases for fonts > pairs with xyz example superscripts and subscripts > > > The goal is to show what works and to find/test fonts that will support > stuff. > I am modelling the Seaside app on > https://jrgraphix.net/research/unicode_blocks.php > But...for each unicode range, I intend to display smalltalk specific > helpers on what/where to get fonts for both the browser side and the image > side. > > --------------snip ------------------- > > (16r000020 asCharacter to: 16r00007F asCharacter) -> 'Basic Latin' > (16r0000A0 asCharacter to: 16r0000FF asCharacter) -> 'Latin-1 Supplement' > (16r000100 asCharacter to: 16r00017F asCharacter) -> 'Latin Extended-A' > (16r000180 asCharacter to: 16r00024F asCharacter) -> 'Latin Extended-B' > (16r000250 asCharacter to: 16r0002AF asCharacter) -> 'IPA Extensions' > (16r0002B0 asCharacter to: 16r0002FF asCharacter) -> 'Spacing Modifier > Letters' > (16r000300 asCharacter to: 16r00036F asCharacter) -> 'Combining > Diacritical Marks' > (16r000370 asCharacter to: 16r0003FF asCharacter) -> 'Greek and Coptic' > (16r000400 asCharacter to: 16r0004FF asCharacter) -> 'Cyrillic' > (16r000500 asCharacter to: 16r00052F asCharacter) -> 'Cyrillic > Supplementary' > (16r000530 asCharacter to: 16r00058F asCharacter) -> 'Armenian' > (16r000590 asCharacter to: 16r0005FF asCharacter) -> 'Hebrew' > (16r000600 asCharacter to: 16r0006FF asCharacter) -> 'Arabic' > (16r000700 asCharacter to: 16r00074F asCharacter) -> 'Syriac' > (16r000780 asCharacter to: 16r0007BF asCharacter) -> 'Thaana' > (16r000900 asCharacter to: 16r00097F asCharacter) -> 'Devanagari' > (16r000980 asCharacter to: 16r0009FF asCharacter) -> 'Bengali' > (16r000A00 asCharacter to: 16r000A7F asCharacter) -> 'Gurmukhi' > (16r000A80 asCharacter to: 16r000AFF asCharacter) -> 'Gujarati' > (16r000B00 asCharacter to: 16r000B7F asCharacter) -> 'Oriya' > (16r000B80 asCharacter to: 16r000BFF asCharacter) -> 'Tamil' > (16r000C00 asCharacter to: 16r000C7F asCharacter) -> 'Telugu' > (16r000C80 asCharacter to: 16r000CFF asCharacter) -> 'Kannada' > (16r000D00 asCharacter to: 16r000D7F asCharacter) -> 'Malayalam' > (16r000D80 asCharacter to: 16r000DFF asCharacter) -> 'Sinhala' > (16r000E00 asCharacter to: 16r000E7F asCharacter) -> 'Thai' > (16r000E80 asCharacter to: 16r000EFF asCharacter) -> 'Lao' > (16r000F00 asCharacter to: 16r000FFF asCharacter) -> 'Tibetan' > (16r001000 asCharacter to: 16r00109F asCharacter) -> 'Myanmar' > (16r0010A0 asCharacter to: 16r0010FF asCharacter) -> 'Georgian' > (16r001100 asCharacter to: 16r0011FF asCharacter) -> 'Hangul Jamo' > (16r001200 asCharacter to: 16r00137F asCharacter) -> 'Ethiopic' > (16r0013A0 asCharacter to: 16r0013FF asCharacter) -> 'Cherokee' > (16r001400 asCharacter to: 16r00167F asCharacter) -> 'Unified Canadian > Aboriginal Syllabics' > (16r001680 asCharacter to: 16r00169F asCharacter) -> 'Ogham' > (16r0016A0 asCharacter to: 16r0016FF asCharacter) -> 'Runic' > (16r001700 asCharacter to: 16r00171F asCharacter) -> 'Tagalog' > (16r001720 asCharacter to: 16r00173F asCharacter) -> 'Hanunoo' > (16r001740 asCharacter to: 16r00175F asCharacter) -> 'Buhid' > (16r001760 asCharacter to: 16r00177F asCharacter) -> 'Tagbanwa' > (16r001780 asCharacter to: 16r0017FF asCharacter) -> 'Khmer' > (16r001800 asCharacter to: 16r0018AF asCharacter) -> 'Mongolian' > (16r001900 asCharacter to: 16r00194F asCharacter) -> 'Limbu' > (16r001950 asCharacter to: 16r00197F asCharacter) -> 'Tai Le' > (16r0019E0 asCharacter to: 16r0019FF asCharacter) -> 'Khmer Symbols' > (16r001D00 asCharacter to: 16r001D7F asCharacter) -> 'Phonetic Extensions' > (16r001E00 asCharacter to: 16r001EFF asCharacter) -> 'Latin Extended > Additional' > (16r001F00 asCharacter to: 16r001FFF asCharacter) -> 'Greek Extended' > (16r002000 asCharacter to: 16r00206F asCharacter) -> 'General Punctuation' > (16r002070 asCharacter to: 16r00209F asCharacter) -> 'Superscripts and > Subscripts' > (16r0020A0 asCharacter to: 16r0020CF asCharacter) -> 'Currency Symbols' > (16r0020D0 asCharacter to: 16r0020FF asCharacter) -> 'Combining > Diacritical Marks for Symbols' > (16r002100 asCharacter to: 16r00214F asCharacter) -> 'Letterlike Symbols' > (16r002150 asCharacter to: 16r00218F asCharacter) -> 'Number Forms' > (16r002190 asCharacter to: 16r0021FF asCharacter) -> 'Arrows' > (16r002200 asCharacter to: 16r0022FF asCharacter) -> 'Mathematical > Operators' > (16r002300 asCharacter to: 16r0023FF asCharacter) -> 'Miscellaneous > Technical' > (16r002400 asCharacter to: 16r00243F asCharacter) -> 'Control Pictures' > (16r002440 asCharacter to: 16r00245F asCharacter) -> 'Optical Character > Recognition' > (16r002460 asCharacter to: 16r0024FF asCharacter) -> 'Enclosed > Alphanumerics' > (16r002500 asCharacter to: 16r00257F asCharacter) -> 'Box Drawing' > (16r002580 asCharacter to: 16r00259F asCharacter) -> 'Block Elements' > (16r0025A0 asCharacter to: 16r0025FF asCharacter) -> 'Geometric Shapes' > (16r002600 asCharacter to: 16r0026FF asCharacter) -> 'Miscellaneous > Symbols' > (16r002700 asCharacter to: 16r0027BF asCharacter) -> 'Dingbats' > (16r0027C0 asCharacter to: 16r0027EF asCharacter) -> 'Miscellaneous > Mathematical Symbols-A' > (16r0027F0 asCharacter to: 16r0027FF asCharacter) -> 'Supplemental > Arrows-A' > (16r002800 asCharacter to: 16r0028FF asCharacter) -> 'Braille Patterns' > (16r002900 asCharacter to: 16r00297F asCharacter) -> 'Supplemental > Arrows-B' > (16r002980 asCharacter to: 16r0029FF asCharacter) -> 'Miscellaneous > Mathematical Symbols-B' > (16r002A00 asCharacter to: 16r002AFF asCharacter) -> 'Supplemental > Mathematical Operators' > (16r002B00 asCharacter to: 16r002BFF asCharacter) -> 'Miscellaneous > Symbols and Arrows' > (16r002E80 asCharacter to: 16r002EFF asCharacter) -> 'CJK Radicals > Supplement' > (16r002F00 asCharacter to: 16r002FDF asCharacter) -> 'Kangxi Radicals' > (16r002FF0 asCharacter to: 16r002FFF asCharacter) -> 'Ideographic > Description Characters' > (16r003000 asCharacter to: 16r00303F asCharacter) -> 'CJK Symbols and > Punctuation' > (16r003040 asCharacter to: 16r00309F asCharacter) -> 'Hiragana' > (16r0030A0 asCharacter to: 16r0030FF asCharacter) -> 'Katakana' > (16r003100 asCharacter to: 16r00312F asCharacter) -> 'Bopomofo' > (16r003130 asCharacter to: 16r00318F asCharacter) -> 'Hangul Compatibility > Jamo' > (16r003190 asCharacter to: 16r00319F asCharacter) -> 'Kanbun' > (16r0031A0 asCharacter to: 16r0031BF asCharacter) -> 'Bopomofo Extended' > (16r0031F0 asCharacter to: 16r0031FF asCharacter) -> 'Katakana Phonetic > Extensions' > (16r003200 asCharacter to: 16r0032FF asCharacter) -> 'Enclosed CJK Letters > and Months' > (16r003300 asCharacter to: 16r0033FF asCharacter) -> 'CJK Compatibility' > (16r003400 asCharacter to: 16r004DBF asCharacter) -> 'CJK Unified > Ideographs Extension A' > (16r004DC0 asCharacter to: 16r004DFF asCharacter) -> 'Yijing Hexagram > Symbols' > (16r004E00 asCharacter to: 16r009FFF asCharacter) -> 'CJK Unified > Ideographs' > (16r00A000 asCharacter to: 16r00A48F asCharacter) -> 'Yi Syllables' > (16r00A490 asCharacter to: 16r00A4CF asCharacter) -> 'Yi Radicals' > (16r00AC00 asCharacter to: 16r00D7AF asCharacter) -> 'Hangul Syllables' > (16r00D800 asCharacter to: 16r00DB7F asCharacter) -> 'High Surrogates' > (16r00DB80 asCharacter to: 16r00DBFF asCharacter) -> 'High Private Use > Surrogates' > (16r00DC00 asCharacter to: 16r00DFFF asCharacter) -> 'Low Surrogates' > (16r00E000 asCharacter to: 16r00F8FF asCharacter) -> 'Private Use Area' > (16r00F900 asCharacter to: 16r00FAFF asCharacter) -> 'CJK Compatibility > Ideographs' > (16r00FB00 asCharacter to: 16r00FB4F asCharacter) -> 'Alphabetic > Presentation Forms' > (16r00FB50 asCharacter to: 16r00FDFF asCharacter) -> 'Arabic Presentation > Forms-A' > (16r00FE00 asCharacter to: 16r00FE0F asCharacter) -> 'Variation Selectors' > (16r00FE20 asCharacter to: 16r00FE2F asCharacter) -> 'Combining Half Marks' > (16r00FE30 asCharacter to: 16r00FE4F asCharacter) -> 'CJK Compatibility > Forms' > (16r00FE50 asCharacter to: 16r00FE6F asCharacter) -> 'Small Form Variants' > (16r00FE70 asCharacter to: 16r00FEFF asCharacter) -> 'Arabic Presentation > Forms-B' > (16r00FF00 asCharacter to: 16r00FFEF asCharacter) -> 'Halfwidth and > Fullwidth Forms' > (16r00FFF0 asCharacter to: 16r00FFFF asCharacter) -> 'Specials' > (16r010000 asCharacter to: 16r01007F asCharacter) -> 'Linear B Syllabary' > (16r010080 asCharacter to: 16r0100FF asCharacter) -> 'Linear B Ideograms' > (16r010100 asCharacter to: 16r01013F asCharacter) -> 'Aegean Numbers' > (16r010300 asCharacter to: 16r01032F asCharacter) -> 'Old Italic' > (16r010330 asCharacter to: 16r01034F asCharacter) -> 'Gothic' > (16r010380 asCharacter to: 16r01039F asCharacter) -> 'Ugaritic' > (16r010400 asCharacter to: 16r01044F asCharacter) -> 'Deseret' > (16r010450 asCharacter to: 16r01047F asCharacter) -> 'Shavian' > (16r010480 asCharacter to: 16r0104AF asCharacter) -> 'Osmanya' > (16r010800 asCharacter to: 16r01083F asCharacter) -> 'Cypriot Syllabary' > (16r01D000 asCharacter to: 16r01D0FF asCharacter) -> 'Byzantine Musical > Symbols' > (16r01D100 asCharacter to: 16r01D1FF asCharacter) -> 'Musical Symbols' > (16r01D300 asCharacter to: 16r01D35F asCharacter) -> 'Tai Xuan Jing > Symbols' > (16r01D400 asCharacter to: 16r01D7FF asCharacter) -> 'Mathematical > Alphanumeric Symbols' > (16r020000 asCharacter to: 16r02A6DF asCharacter) -> 'CJK Unified > Ideographs Extension B' > (16r02F800 asCharacter to: 16r02FA1F asCharacter) -> 'CJK Compatibility > Ideographs Supplement' > (16r0E0000 asCharacter to: 16r0E007F asCharacter) -> 'Tags' > > > > -- Eric -------------- next part -------------- An HTML attachment was scrubbed... URL: From Christoph.Thiede at student.hpi.uni-potsdam.de Mon Feb 1 14:29:00 2021 From: Christoph.Thiede at student.hpi.uni-potsdam.de (Thiede, Christoph) Date: Mon, 1 Feb 2021 14:29:00 +0000 Subject: [squeak-dev] Transcript error when forceUpdate: false (?) In-Reply-To: References: <1611345790068-0.post@n4.nabble.com> <20210123012610.GB93733@shell.msen.com> <8C121027-CFF5-4DF2-9D2E-18DA658DD743@rowledge.org> <1611599406320-0.post@n4.nabble.com> <1611607106337-0.post@n4.nabble.com> <9D4C563E-7F9D-454F-B5F3-CA7887DF7619@gmx.de> <,> <1ce14508a1654e369a26a946e546ae1d@student.hpi.uni-potsdam.de> <,> <9129c3b2dc13472e9875e00290276f76@student.hpi.uni-potsdam.de>, Message-ID: Hi Marcel, thanks for the explanation. Just to make sure I understand correctly: We are talking about maybe changing the transcript interface and/or even introducing a new pragma selector solely for the purpose of smoothly handling this super-edge case of the active project being switched just while an always-running background thread is logging something to the Transcript? This sounds a very bit speculative to me ... Is it really worth the raised complexity? :-) Best, Christoph ________________________________ Von: Squeak-dev im Auftrag von Taeumel, Marcel Gesendet: Donnerstag, 28. Januar 2021 12:14:11 An: squeak-dev Betreff: Re: [squeak-dev] Transcript error when forceUpdate: false (?) > I still don't see the point. Are you saying that the current project or it's UI process could change during a VM suspension point? If that code runs at 39 and the user switches projects at 40, yes, this can happen. > Then, what about something like "Project current evaluateUIMessage: [...]", which will unpreemptedly (using the new primitive solution) check the UI process and either evaluate the message directly or defer it? :-) Even the implementation of #evaluateUIMessage: would need something like :-) So, one could directly add this pragma to, for example, #endEntry, without adding such a new indirection. And at lower levels or more concise scopes, access should be controlled with a mutex. I suppose that the "trick" with only works in a green-threading model where exactly 1 thread (or Squeak process) is actually running at a time. Best, Marcel P.S.: Is every fallback code for failing primitives evaluated without preemption? Am 28.01.2021 11:28:24 schrieb Thiede, Christoph : I still don't see the point. Are you saying that the current project or it's UI process could change during a VM suspension point? Then, what about something like "Project current evaluateUIMessage: [...]", which will unpreemptedly (using the new primitive solution) check the UI process and either evaluate the message directly or defer it? :-) Best, Christoph ________________________________ Von: Squeak-dev im Auftrag von Taeumel, Marcel Gesendet: Donnerstag, 28. Januar 2021 11:13:55 An: squeak-dev Betreff: Re: [squeak-dev] Transcript error when forceUpdate: false (?) Hi Christoph. > What is that dangerous thing that could happen during a suspension point in the VM? What am I missing here? :-) It's only part of the problem. There could be a disconnect between the former "Project current uiProcess" comparison and how "addDeferredUIMessage" is processed later in the code. It would be better to no preempt this call as a whole. Best, Marcel Am 28.01.2021 10:59:50 schrieb Thiede, Christoph : Hi all, this is an interesting discussion, two thoughts from my side: 1. What is the problem with "Processor activeProcess == Project current uiProcess" not being a thread-safe expression? I see that it could be possible at many points that the VM interrupts the current process and resumes another one first; but still, activeProcess will always hold the same Process instance when the same process is active, independently of any interruptions, won't it? What is that dangerous thing that could happen during a suspension point in the VM? What am I missing here? :-) 2. To Levente's proposal of making Transcript calls thread-safe: > safelyNextPutAll: aString > > mutex critical: [ > stream nextPutAll: aString ] So this would delay the execution of any process that uses the Transcript, wouldn't it? Hm ... I would rather have expected the Transcript calls to be deferred when the Transcript is locked ATM - *unless* #forceUpdate is enabled, maybe. Let's keep everyday Transcript clients blocking-free whenever possible. Or imagine several processes writing to the Transcript, but the transcript not being opened at this time. There should no need to block any of the calling processes? Best, Christoph ________________________________ Von: Squeak-dev im Auftrag von Taeumel, Marcel Gesendet: Donnerstag, 28. Januar 2021 10:41:03 An: squeak-dev Betreff: Re: [squeak-dev] Transcript error when forceUpdate: false (?) Hi Tobias > A separate kind of log (that optionally could output to the transcript) Transcript can use stdout already. Not sure we want to shift the problem to the user again ... :-/ "Every time you provide an option, you expect users to make a decision." :-) Best, Marcel Am 28.01.2021 10:32:27 schrieb Tobias Pape : Hi apart from the debuggers, why bother making Transcript thread-safe in the first place? The Transcript is a mere output stream for debugging/logging etc., our stdout or stderr. A separate kind of log (that optionally could output to the transcript) would be more apt IMHO. Thread safety could be addressed there without complicating Transcript more… my 2ct -tobias > On 28. Jan 2021, at 09:05, Marcel Taeumel wrote: > > Hi Levente. > > Thanks für clarification. We are talking about more than one problem here. :-) I did just address the issue with errors/debuggers happening due to UI process disruptions. You are also concerned about the order of contents in the Transcript's contents. Both are very important and required for claiming that it would be thread-safe. > > (Which reminds me that I find it very strange that the UI components (e.g. PluggableTextMorph) do also check the Transcript's internal characterLimit. I would expect an append-only behavior when a Transcript window is open.) > > Anyway, your proposal about a safelyNextPut(All): looks good. :-) +1 > > Best, > Marcel >> Am 27.01.2021 23:05:21 schrieb Levente Uzonyi : >> >> Hi Marcel, >> >> On Tue, 26 Jan 2021, Marcel Taeumel wrote: >> >> > Hi Jaromir, >> > please take a look at Collections-mt.923 (inbox). Maybe those changes would satisfy all your current needs in this regard. :-) >> > >> > @all: Would Transcript now be thread-safe? Did I miss something? >> >> Not at all. The problem is not #endEntry but all the other >> methods writing to the stream e.g.: #nextPutAll:. >> The real solution is to replace the stream-like API with one that provides >> an easy way to write messages in a thread-safe way. E.g.: >> >> Transcript showStream: [ :stream | >> stream nextPutAll: 'Hello'; space; nextPutAll: ' World!'; cr ] >> >> Which guarantees that 'Hello World!' appears on the Transcript without >> being mixed with other messages. >> >> or >> >> Transcript show: 'Hello {1}!{2}' format: { 'World'. String cr }. >> >> The implementations could be e.g.: >> >> showStream: aBlock >> >> | string | >> string := String streamContents: aBlock. >> self safelyNextPutAll: string >> >> show: aString format: arguments >> >> | string | >> string := aString format: arguments. >> self safelyNextPutAll: string >> >> The last challenge is to implement #safelyNextPutAll: which involves >> making Transcript not be a TranscriptStream. >> Transcript should encapsulate the stream and use a Mutex (not a global one >> because its pointless) to provide thread-safety while writing the >> characters on it or reading its contents. E.g.: >> >> safelyNextPutAll: aString >> >> mutex critical: [ >> stream nextPutAll: aString ] >> >> For backwards compatibility, the stream-API methods must be provided for a >> while but those methods should be thread-safe on their own. E.g.: >> >> nextPutAll: aString >> >> self safelyNextPutAll: aString >> >> nextPut: aCharacter >> >> self safelyNextPutAll: aCharacter asString >> >> >> Levente >> >> > >> > Best, >> > Marcel >> > >> > Am 25.01.2021 21:38:36 schrieb jaromir : >> > >> > Well, I tried deferring the whole Transcript endEntry machinery to the UI >> > doOneCycle (bypassing the changed: #appendEntryLater mechanism) for >> > #forceUpdate = false only ... and it seems to avoid the problem! >> > >> > TranscriptStream >> endEntry >> > >> > deferredEntry ifNil: [ false ]. "this is a new instance variable" >> > self semaphore critical:[ >> > self class forceUpdate >> > ifTrue: [self changed: #appendEntry; reset] >> > ifFalse: [deferredEntry := true]. >> > >> > >> > TranscriptStream >> flushDeferredEntry >> > "This is run every UI cycle in doOneCycleNowFor:" >> > >> > deferredEntry ifTrue: [ >> > self class forceUpdate: true. >> > self endEntry. >> > deferredEntry := false. >> > self class forceUpdate: false. >> > ] >> > >> > doOneCycleNowFor: aWorld >> > >> > "... the whole body remains unchanged except:" >> > >> > capturingGesture ifFalse: >> > [aWorld runStepMethods. >> > Transcript flushDeferredEntry. "this is printing for #forceUpdate = >> > false" >> > self displayWorldSafely: aWorld]. >> > >> > >> > For #forceUpdate = true the endEntry mechanism remains unchanged and failing >> > as before... >> > >> > >> > >> > -- >> > Sent from: http://forum.world.st/Squeak-Dev-f45488.html >> > >> > >> > >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From gettimothy at zoho.com Mon Feb 1 14:30:29 2021 From: gettimothy at zoho.com (gettimothy) Date: Mon, 01 Feb 2021 09:30:29 -0500 Subject: [squeak-dev] Unicode Ranges you might want to copy In-Reply-To: References: <1775862c6d8.10f71a9b5728.3911329244202033832@zoho.com> Message-ID: <1775e008814.10ffc1dcd21434.8448180592071211373@zoho.com> Hi Eric Thanks for the heads up! Doing some lite browsing on the matter, I found these resources.... https://unicode-table.com/en/#control-character  https://css-tricks.com/almanac/properties/u/unicode-range/  http://www.alanwood.net/unicode/alphabetic_presentation_forms.html That last one looks very useful and I will ve working through it. The middle one claims that fonts can be loaded dynamically when needed. An intersting thing is that the alan wood site displays the $ sign under the currency range, but the jgraphix website does not! It is also somewhat apparent that "like" ranges are not contigous. Thanjs again for your gelp! Cheers, ---- On Mon, 01 Feb 2021 08:57:32 -0500 eric.gade at gmail.com wrote ---- Hi Timothy, I spent several (fruitless) days last year trying to get cuneiform fonts to render properly in Squeak (see here for examples of the fonts). There does seem to be an issue with rendering glyphs above a certain code point from what I recall. I am definitely interested in your work and what you end up finding out. On Sun, Jan 31, 2021 at 7:20 AM gettimothy via Squeak-dev wrote: Hi Folks, You might find the below handy. Fwiw, I have coded the UnicodeRangeBrowser  SeasideApp to display all the below (it times out before all display, I will be doing refactor and more development). I am also coding a utility class to provide information such as below in a variety of ways. fwiw, here are my current todo notes for this font information. unifont provide link to the unicode spec. provide browser fonts list. provide squeak fonts list. provide phare fonts list ^self squeak fonts list: what are Variant Selectors ? show gaps in the ranges. provide a link(s) to required fonts that will make a range display. displays on: browser list, squeak, emacs, xterm... status bar...broken, partial, full. use cases for fonts pairs with xyz   example superscripts and subscripts The goal is to show what works and to find/test fonts that will support stuff. I am modelling the Seaside app on https://jrgraphix.net/research/unicode_blocks.php   But...for each unicode range, I intend to display smalltalk specific helpers on what/where to get fonts for both the browser side and the image side. --------------snip ------------------- (16r000020 asCharacter to: 16r00007F asCharacter) -> 'Basic Latin' (16r0000A0 asCharacter to: 16r0000FF asCharacter) -> 'Latin-1 Supplement' (16r000100 asCharacter to: 16r00017F asCharacter) -> 'Latin Extended-A' (16r000180 asCharacter to: 16r00024F asCharacter) -> 'Latin Extended-B' (16r000250 asCharacter to: 16r0002AF asCharacter) -> 'IPA Extensions' (16r0002B0 asCharacter to: 16r0002FF asCharacter) -> 'Spacing Modifier Letters' (16r000300 asCharacter to: 16r00036F asCharacter) -> 'Combining Diacritical Marks' (16r000370 asCharacter to: 16r0003FF asCharacter) -> 'Greek and Coptic' (16r000400 asCharacter to: 16r0004FF asCharacter) -> 'Cyrillic' (16r000500 asCharacter to: 16r00052F asCharacter) -> 'Cyrillic Supplementary' (16r000530 asCharacter to: 16r00058F asCharacter) -> 'Armenian' (16r000590 asCharacter to: 16r0005FF asCharacter) -> 'Hebrew' (16r000600 asCharacter to: 16r0006FF asCharacter) -> 'Arabic' (16r000700 asCharacter to: 16r00074F asCharacter) -> 'Syriac' (16r000780 asCharacter to: 16r0007BF asCharacter) -> 'Thaana' (16r000900 asCharacter to: 16r00097F asCharacter) -> 'Devanagari' (16r000980 asCharacter to: 16r0009FF asCharacter) -> 'Bengali' (16r000A00 asCharacter to: 16r000A7F asCharacter) -> 'Gurmukhi' (16r000A80 asCharacter to: 16r000AFF asCharacter) -> 'Gujarati' (16r000B00 asCharacter to: 16r000B7F asCharacter) -> 'Oriya' (16r000B80 asCharacter to: 16r000BFF asCharacter) -> 'Tamil' (16r000C00 asCharacter to: 16r000C7F asCharacter) -> 'Telugu' (16r000C80 asCharacter to: 16r000CFF asCharacter) -> 'Kannada' (16r000D00 asCharacter to: 16r000D7F asCharacter) -> 'Malayalam' (16r000D80 asCharacter to: 16r000DFF asCharacter) -> 'Sinhala' (16r000E00 asCharacter to: 16r000E7F asCharacter) -> 'Thai' (16r000E80 asCharacter to: 16r000EFF asCharacter) -> 'Lao' (16r000F00 asCharacter to: 16r000FFF asCharacter) -> 'Tibetan' (16r001000 asCharacter to: 16r00109F asCharacter) -> 'Myanmar' (16r0010A0 asCharacter to: 16r0010FF asCharacter) -> 'Georgian' (16r001100 asCharacter to: 16r0011FF asCharacter) -> 'Hangul Jamo' (16r001200 asCharacter to: 16r00137F asCharacter) -> 'Ethiopic' (16r0013A0 asCharacter to: 16r0013FF asCharacter) -> 'Cherokee' (16r001400 asCharacter to: 16r00167F asCharacter) -> 'Unified Canadian Aboriginal Syllabics' (16r001680 asCharacter to: 16r00169F asCharacter) -> 'Ogham' (16r0016A0 asCharacter to: 16r0016FF asCharacter) -> 'Runic' (16r001700 asCharacter to: 16r00171F asCharacter) -> 'Tagalog' (16r001720 asCharacter to: 16r00173F asCharacter) -> 'Hanunoo' (16r001740 asCharacter to: 16r00175F asCharacter) -> 'Buhid' (16r001760 asCharacter to: 16r00177F asCharacter) -> 'Tagbanwa' (16r001780 asCharacter to: 16r0017FF asCharacter) -> 'Khmer' (16r001800 asCharacter to: 16r0018AF asCharacter) -> 'Mongolian' (16r001900 asCharacter to: 16r00194F asCharacter) -> 'Limbu' (16r001950 asCharacter to: 16r00197F asCharacter) -> 'Tai Le' (16r0019E0 asCharacter to: 16r0019FF asCharacter) -> 'Khmer Symbols' (16r001D00 asCharacter to: 16r001D7F asCharacter) -> 'Phonetic Extensions' (16r001E00 asCharacter to: 16r001EFF asCharacter) -> 'Latin Extended Additional' (16r001F00 asCharacter to: 16r001FFF asCharacter) -> 'Greek Extended' (16r002000 asCharacter to: 16r00206F asCharacter) -> 'General Punctuation' (16r002070 asCharacter to: 16r00209F asCharacter) -> 'Superscripts and Subscripts' (16r0020A0 asCharacter to: 16r0020CF asCharacter) -> 'Currency Symbols' (16r0020D0 asCharacter to: 16r0020FF asCharacter) -> 'Combining Diacritical Marks for Symbols' (16r002100 asCharacter to: 16r00214F asCharacter) -> 'Letterlike Symbols' (16r002150 asCharacter to: 16r00218F asCharacter) -> 'Number Forms' (16r002190 asCharacter to: 16r0021FF asCharacter) -> 'Arrows' (16r002200 asCharacter to: 16r0022FF asCharacter) -> 'Mathematical Operators' (16r002300 asCharacter to: 16r0023FF asCharacter) -> 'Miscellaneous Technical' (16r002400 asCharacter to: 16r00243F asCharacter) -> 'Control Pictures' (16r002440 asCharacter to: 16r00245F asCharacter) -> 'Optical Character Recognition' (16r002460 asCharacter to: 16r0024FF asCharacter) -> 'Enclosed Alphanumerics' (16r002500 asCharacter to: 16r00257F asCharacter) -> 'Box Drawing' (16r002580 asCharacter to: 16r00259F asCharacter) -> 'Block Elements' (16r0025A0 asCharacter to: 16r0025FF asCharacter) -> 'Geometric Shapes' (16r002600 asCharacter to: 16r0026FF asCharacter) -> 'Miscellaneous Symbols' (16r002700 asCharacter to: 16r0027BF asCharacter) -> 'Dingbats' (16r0027C0 asCharacter to: 16r0027EF asCharacter) -> 'Miscellaneous Mathematical Symbols-A' (16r0027F0 asCharacter to: 16r0027FF asCharacter) -> 'Supplemental Arrows-A' (16r002800 asCharacter to: 16r0028FF asCharacter) -> 'Braille Patterns' (16r002900 asCharacter to: 16r00297F asCharacter) -> 'Supplemental Arrows-B' (16r002980 asCharacter to: 16r0029FF asCharacter) -> 'Miscellaneous Mathematical Symbols-B' (16r002A00 asCharacter to: 16r002AFF asCharacter) -> 'Supplemental Mathematical Operators' (16r002B00 asCharacter to: 16r002BFF asCharacter) -> 'Miscellaneous Symbols and Arrows' (16r002E80 asCharacter to: 16r002EFF asCharacter) -> 'CJK Radicals Supplement' (16r002F00 asCharacter to: 16r002FDF asCharacter) -> 'Kangxi Radicals' (16r002FF0 asCharacter to: 16r002FFF asCharacter) -> 'Ideographic Description Characters' (16r003000 asCharacter to: 16r00303F asCharacter) -> 'CJK Symbols and Punctuation' (16r003040 asCharacter to: 16r00309F asCharacter) -> 'Hiragana' (16r0030A0 asCharacter to: 16r0030FF asCharacter) -> 'Katakana' (16r003100 asCharacter to: 16r00312F asCharacter) -> 'Bopomofo' (16r003130 asCharacter to: 16r00318F asCharacter) -> 'Hangul Compatibility Jamo' (16r003190 asCharacter to: 16r00319F asCharacter) -> 'Kanbun' (16r0031A0 asCharacter to: 16r0031BF asCharacter) -> 'Bopomofo Extended' (16r0031F0 asCharacter to: 16r0031FF asCharacter) -> 'Katakana Phonetic Extensions' (16r003200 asCharacter to: 16r0032FF asCharacter) -> 'Enclosed CJK Letters and Months' (16r003300 asCharacter to: 16r0033FF asCharacter) -> 'CJK Compatibility' (16r003400 asCharacter to: 16r004DBF asCharacter) -> 'CJK Unified Ideographs Extension A' (16r004DC0 asCharacter to: 16r004DFF asCharacter) -> 'Yijing Hexagram Symbols' (16r004E00 asCharacter to: 16r009FFF asCharacter) -> 'CJK Unified Ideographs' (16r00A000 asCharacter to: 16r00A48F asCharacter) -> 'Yi Syllables' (16r00A490 asCharacter to: 16r00A4CF asCharacter) -> 'Yi Radicals' (16r00AC00 asCharacter to: 16r00D7AF asCharacter) -> 'Hangul Syllables' (16r00D800 asCharacter to: 16r00DB7F asCharacter) -> 'High Surrogates' (16r00DB80 asCharacter to: 16r00DBFF asCharacter) -> 'High Private Use Surrogates' (16r00DC00 asCharacter to: 16r00DFFF asCharacter) -> 'Low Surrogates' (16r00E000 asCharacter to: 16r00F8FF asCharacter) -> 'Private Use Area' (16r00F900 asCharacter to: 16r00FAFF asCharacter) -> 'CJK Compatibility Ideographs' (16r00FB00 asCharacter to: 16r00FB4F asCharacter) -> 'Alphabetic Presentation Forms' (16r00FB50 asCharacter to: 16r00FDFF asCharacter) -> 'Arabic Presentation Forms-A' (16r00FE00 asCharacter to: 16r00FE0F asCharacter) -> 'Variation Selectors' (16r00FE20 asCharacter to: 16r00FE2F asCharacter) -> 'Combining Half Marks' (16r00FE30 asCharacter to: 16r00FE4F asCharacter) -> 'CJK Compatibility Forms' (16r00FE50 asCharacter to: 16r00FE6F asCharacter) -> 'Small Form Variants' (16r00FE70 asCharacter to: 16r00FEFF asCharacter) -> 'Arabic Presentation Forms-B' (16r00FF00 asCharacter to: 16r00FFEF asCharacter) -> 'Halfwidth and Fullwidth Forms' (16r00FFF0 asCharacter to: 16r00FFFF asCharacter) -> 'Specials' (16r010000 asCharacter to: 16r01007F asCharacter) -> 'Linear B Syllabary' (16r010080 asCharacter to: 16r0100FF asCharacter) -> 'Linear B Ideograms' (16r010100 asCharacter to: 16r01013F asCharacter) -> 'Aegean Numbers' (16r010300 asCharacter to: 16r01032F asCharacter) -> 'Old Italic' (16r010330 asCharacter to: 16r01034F asCharacter) -> 'Gothic' (16r010380 asCharacter to: 16r01039F asCharacter) -> 'Ugaritic' (16r010400 asCharacter to: 16r01044F asCharacter) -> 'Deseret' (16r010450 asCharacter to: 16r01047F asCharacter) -> 'Shavian' (16r010480 asCharacter to: 16r0104AF asCharacter) -> 'Osmanya' (16r010800 asCharacter to: 16r01083F asCharacter) -> 'Cypriot Syllabary' (16r01D000 asCharacter to: 16r01D0FF asCharacter) -> 'Byzantine Musical Symbols' (16r01D100 asCharacter to: 16r01D1FF asCharacter) -> 'Musical Symbols' (16r01D300 asCharacter to: 16r01D35F asCharacter) -> 'Tai Xuan Jing Symbols' (16r01D400 asCharacter to: 16r01D7FF asCharacter) -> 'Mathematical Alphanumeric Symbols' (16r020000 asCharacter to: 16r02A6DF asCharacter) -> 'CJK Unified Ideographs Extension B' (16r02F800 asCharacter to: 16r02FA1F asCharacter) -> 'CJK Compatibility Ideographs Supplement' (16r0E0000 asCharacter to: 16r0E007F asCharacter) -> 'Tags' -- Eric -------------- next part -------------- An HTML attachment was scrubbed... URL: From gettimothy at zoho.com Mon Feb 1 14:34:44 2021 From: gettimothy at zoho.com (gettimothy) Date: Mon, 01 Feb 2021 09:34:44 -0500 Subject: [squeak-dev] Unicode Ranges you might want to copy In-Reply-To: References: <1775862c6d8.10f71a9b5728.3911329244202033832@zoho.com> Message-ID: <1775e046cbe.12711f17821655.848042295265339979@zoho.com> To add to my previous repky, I am curious "how" the letters are written on a morphic display? Is it a bitblt thing? A primitive? A glob of pixels that morphic plops into place? cheers ---- On Mon, 01 Feb 2021 08:57:32 -0500 eric.gade at gmail.com wrote ---- Hi Timothy, I spent several (fruitless) days last year trying to get cuneiform fonts to render properly in Squeak (see here for examples of the fonts). There does seem to be an issue with rendering glyphs above a certain code point from what I recall. I am definitely interested in your work and what you end up finding out. On Sun, Jan 31, 2021 at 7:20 AM gettimothy via Squeak-dev wrote: Hi Folks, You might find the below handy. Fwiw, I have coded the UnicodeRangeBrowser  SeasideApp to display all the below (it times out before all display, I will be doing refactor and more development). I am also coding a utility class to provide information such as below in a variety of ways. fwiw, here are my current todo notes for this font information. unifont provide link to the unicode spec. provide browser fonts list. provide squeak fonts list. provide phare fonts list ^self squeak fonts list: what are Variant Selectors ? show gaps in the ranges. provide a link(s) to required fonts that will make a range display. displays on: browser list, squeak, emacs, xterm... status bar...broken, partial, full. use cases for fonts pairs with xyz   example superscripts and subscripts The goal is to show what works and to find/test fonts that will support stuff. I am modelling the Seaside app on https://jrgraphix.net/research/unicode_blocks.php   But...for each unicode range, I intend to display smalltalk specific helpers on what/where to get fonts for both the browser side and the image side. --------------snip ------------------- (16r000020 asCharacter to: 16r00007F asCharacter) -> 'Basic Latin' (16r0000A0 asCharacter to: 16r0000FF asCharacter) -> 'Latin-1 Supplement' (16r000100 asCharacter to: 16r00017F asCharacter) -> 'Latin Extended-A' (16r000180 asCharacter to: 16r00024F asCharacter) -> 'Latin Extended-B' (16r000250 asCharacter to: 16r0002AF asCharacter) -> 'IPA Extensions' (16r0002B0 asCharacter to: 16r0002FF asCharacter) -> 'Spacing Modifier Letters' (16r000300 asCharacter to: 16r00036F asCharacter) -> 'Combining Diacritical Marks' (16r000370 asCharacter to: 16r0003FF asCharacter) -> 'Greek and Coptic' (16r000400 asCharacter to: 16r0004FF asCharacter) -> 'Cyrillic' (16r000500 asCharacter to: 16r00052F asCharacter) -> 'Cyrillic Supplementary' (16r000530 asCharacter to: 16r00058F asCharacter) -> 'Armenian' (16r000590 asCharacter to: 16r0005FF asCharacter) -> 'Hebrew' (16r000600 asCharacter to: 16r0006FF asCharacter) -> 'Arabic' (16r000700 asCharacter to: 16r00074F asCharacter) -> 'Syriac' (16r000780 asCharacter to: 16r0007BF asCharacter) -> 'Thaana' (16r000900 asCharacter to: 16r00097F asCharacter) -> 'Devanagari' (16r000980 asCharacter to: 16r0009FF asCharacter) -> 'Bengali' (16r000A00 asCharacter to: 16r000A7F asCharacter) -> 'Gurmukhi' (16r000A80 asCharacter to: 16r000AFF asCharacter) -> 'Gujarati' (16r000B00 asCharacter to: 16r000B7F asCharacter) -> 'Oriya' (16r000B80 asCharacter to: 16r000BFF asCharacter) -> 'Tamil' (16r000C00 asCharacter to: 16r000C7F asCharacter) -> 'Telugu' (16r000C80 asCharacter to: 16r000CFF asCharacter) -> 'Kannada' (16r000D00 asCharacter to: 16r000D7F asCharacter) -> 'Malayalam' (16r000D80 asCharacter to: 16r000DFF asCharacter) -> 'Sinhala' (16r000E00 asCharacter to: 16r000E7F asCharacter) -> 'Thai' (16r000E80 asCharacter to: 16r000EFF asCharacter) -> 'Lao' (16r000F00 asCharacter to: 16r000FFF asCharacter) -> 'Tibetan' (16r001000 asCharacter to: 16r00109F asCharacter) -> 'Myanmar' (16r0010A0 asCharacter to: 16r0010FF asCharacter) -> 'Georgian' (16r001100 asCharacter to: 16r0011FF asCharacter) -> 'Hangul Jamo' (16r001200 asCharacter to: 16r00137F asCharacter) -> 'Ethiopic' (16r0013A0 asCharacter to: 16r0013FF asCharacter) -> 'Cherokee' (16r001400 asCharacter to: 16r00167F asCharacter) -> 'Unified Canadian Aboriginal Syllabics' (16r001680 asCharacter to: 16r00169F asCharacter) -> 'Ogham' (16r0016A0 asCharacter to: 16r0016FF asCharacter) -> 'Runic' (16r001700 asCharacter to: 16r00171F asCharacter) -> 'Tagalog' (16r001720 asCharacter to: 16r00173F asCharacter) -> 'Hanunoo' (16r001740 asCharacter to: 16r00175F asCharacter) -> 'Buhid' (16r001760 asCharacter to: 16r00177F asCharacter) -> 'Tagbanwa' (16r001780 asCharacter to: 16r0017FF asCharacter) -> 'Khmer' (16r001800 asCharacter to: 16r0018AF asCharacter) -> 'Mongolian' (16r001900 asCharacter to: 16r00194F asCharacter) -> 'Limbu' (16r001950 asCharacter to: 16r00197F asCharacter) -> 'Tai Le' (16r0019E0 asCharacter to: 16r0019FF asCharacter) -> 'Khmer Symbols' (16r001D00 asCharacter to: 16r001D7F asCharacter) -> 'Phonetic Extensions' (16r001E00 asCharacter to: 16r001EFF asCharacter) -> 'Latin Extended Additional' (16r001F00 asCharacter to: 16r001FFF asCharacter) -> 'Greek Extended' (16r002000 asCharacter to: 16r00206F asCharacter) -> 'General Punctuation' (16r002070 asCharacter to: 16r00209F asCharacter) -> 'Superscripts and Subscripts' (16r0020A0 asCharacter to: 16r0020CF asCharacter) -> 'Currency Symbols' (16r0020D0 asCharacter to: 16r0020FF asCharacter) -> 'Combining Diacritical Marks for Symbols' (16r002100 asCharacter to: 16r00214F asCharacter) -> 'Letterlike Symbols' (16r002150 asCharacter to: 16r00218F asCharacter) -> 'Number Forms' (16r002190 asCharacter to: 16r0021FF asCharacter) -> 'Arrows' (16r002200 asCharacter to: 16r0022FF asCharacter) -> 'Mathematical Operators' (16r002300 asCharacter to: 16r0023FF asCharacter) -> 'Miscellaneous Technical' (16r002400 asCharacter to: 16r00243F asCharacter) -> 'Control Pictures' (16r002440 asCharacter to: 16r00245F asCharacter) -> 'Optical Character Recognition' (16r002460 asCharacter to: 16r0024FF asCharacter) -> 'Enclosed Alphanumerics' (16r002500 asCharacter to: 16r00257F asCharacter) -> 'Box Drawing' (16r002580 asCharacter to: 16r00259F asCharacter) -> 'Block Elements' (16r0025A0 asCharacter to: 16r0025FF asCharacter) -> 'Geometric Shapes' (16r002600 asCharacter to: 16r0026FF asCharacter) -> 'Miscellaneous Symbols' (16r002700 asCharacter to: 16r0027BF asCharacter) -> 'Dingbats' (16r0027C0 asCharacter to: 16r0027EF asCharacter) -> 'Miscellaneous Mathematical Symbols-A' (16r0027F0 asCharacter to: 16r0027FF asCharacter) -> 'Supplemental Arrows-A' (16r002800 asCharacter to: 16r0028FF asCharacter) -> 'Braille Patterns' (16r002900 asCharacter to: 16r00297F asCharacter) -> 'Supplemental Arrows-B' (16r002980 asCharacter to: 16r0029FF asCharacter) -> 'Miscellaneous Mathematical Symbols-B' (16r002A00 asCharacter to: 16r002AFF asCharacter) -> 'Supplemental Mathematical Operators' (16r002B00 asCharacter to: 16r002BFF asCharacter) -> 'Miscellaneous Symbols and Arrows' (16r002E80 asCharacter to: 16r002EFF asCharacter) -> 'CJK Radicals Supplement' (16r002F00 asCharacter to: 16r002FDF asCharacter) -> 'Kangxi Radicals' (16r002FF0 asCharacter to: 16r002FFF asCharacter) -> 'Ideographic Description Characters' (16r003000 asCharacter to: 16r00303F asCharacter) -> 'CJK Symbols and Punctuation' (16r003040 asCharacter to: 16r00309F asCharacter) -> 'Hiragana' (16r0030A0 asCharacter to: 16r0030FF asCharacter) -> 'Katakana' (16r003100 asCharacter to: 16r00312F asCharacter) -> 'Bopomofo' (16r003130 asCharacter to: 16r00318F asCharacter) -> 'Hangul Compatibility Jamo' (16r003190 asCharacter to: 16r00319F asCharacter) -> 'Kanbun' (16r0031A0 asCharacter to: 16r0031BF asCharacter) -> 'Bopomofo Extended' (16r0031F0 asCharacter to: 16r0031FF asCharacter) -> 'Katakana Phonetic Extensions' (16r003200 asCharacter to: 16r0032FF asCharacter) -> 'Enclosed CJK Letters and Months' (16r003300 asCharacter to: 16r0033FF asCharacter) -> 'CJK Compatibility' (16r003400 asCharacter to: 16r004DBF asCharacter) -> 'CJK Unified Ideographs Extension A' (16r004DC0 asCharacter to: 16r004DFF asCharacter) -> 'Yijing Hexagram Symbols' (16r004E00 asCharacter to: 16r009FFF asCharacter) -> 'CJK Unified Ideographs' (16r00A000 asCharacter to: 16r00A48F asCharacter) -> 'Yi Syllables' (16r00A490 asCharacter to: 16r00A4CF asCharacter) -> 'Yi Radicals' (16r00AC00 asCharacter to: 16r00D7AF asCharacter) -> 'Hangul Syllables' (16r00D800 asCharacter to: 16r00DB7F asCharacter) -> 'High Surrogates' (16r00DB80 asCharacter to: 16r00DBFF asCharacter) -> 'High Private Use Surrogates' (16r00DC00 asCharacter to: 16r00DFFF asCharacter) -> 'Low Surrogates' (16r00E000 asCharacter to: 16r00F8FF asCharacter) -> 'Private Use Area' (16r00F900 asCharacter to: 16r00FAFF asCharacter) -> 'CJK Compatibility Ideographs' (16r00FB00 asCharacter to: 16r00FB4F asCharacter) -> 'Alphabetic Presentation Forms' (16r00FB50 asCharacter to: 16r00FDFF asCharacter) -> 'Arabic Presentation Forms-A' (16r00FE00 asCharacter to: 16r00FE0F asCharacter) -> 'Variation Selectors' (16r00FE20 asCharacter to: 16r00FE2F asCharacter) -> 'Combining Half Marks' (16r00FE30 asCharacter to: 16r00FE4F asCharacter) -> 'CJK Compatibility Forms' (16r00FE50 asCharacter to: 16r00FE6F asCharacter) -> 'Small Form Variants' (16r00FE70 asCharacter to: 16r00FEFF asCharacter) -> 'Arabic Presentation Forms-B' (16r00FF00 asCharacter to: 16r00FFEF asCharacter) -> 'Halfwidth and Fullwidth Forms' (16r00FFF0 asCharacter to: 16r00FFFF asCharacter) -> 'Specials' (16r010000 asCharacter to: 16r01007F asCharacter) -> 'Linear B Syllabary' (16r010080 asCharacter to: 16r0100FF asCharacter) -> 'Linear B Ideograms' (16r010100 asCharacter to: 16r01013F asCharacter) -> 'Aegean Numbers' (16r010300 asCharacter to: 16r01032F asCharacter) -> 'Old Italic' (16r010330 asCharacter to: 16r01034F asCharacter) -> 'Gothic' (16r010380 asCharacter to: 16r01039F asCharacter) -> 'Ugaritic' (16r010400 asCharacter to: 16r01044F asCharacter) -> 'Deseret' (16r010450 asCharacter to: 16r01047F asCharacter) -> 'Shavian' (16r010480 asCharacter to: 16r0104AF asCharacter) -> 'Osmanya' (16r010800 asCharacter to: 16r01083F asCharacter) -> 'Cypriot Syllabary' (16r01D000 asCharacter to: 16r01D0FF asCharacter) -> 'Byzantine Musical Symbols' (16r01D100 asCharacter to: 16r01D1FF asCharacter) -> 'Musical Symbols' (16r01D300 asCharacter to: 16r01D35F asCharacter) -> 'Tai Xuan Jing Symbols' (16r01D400 asCharacter to: 16r01D7FF asCharacter) -> 'Mathematical Alphanumeric Symbols' (16r020000 asCharacter to: 16r02A6DF asCharacter) -> 'CJK Unified Ideographs Extension B' (16r02F800 asCharacter to: 16r02FA1F asCharacter) -> 'CJK Compatibility Ideographs Supplement' (16r0E0000 asCharacter to: 16r0E007F asCharacter) -> 'Tags' -- Eric -------------- next part -------------- An HTML attachment was scrubbed... URL: From Christoph.Thiede at student.hpi.uni-potsdam.de Mon Feb 1 14:36:35 2021 From: Christoph.Thiede at student.hpi.uni-potsdam.de (Thiede, Christoph) Date: Mon, 1 Feb 2021 14:36:35 +0000 Subject: [squeak-dev] Unicode Ranges you might want to copy In-Reply-To: <1775e008814.10ffc1dcd21434.8448180592071211373@zoho.com> References: <1775862c6d8.10f71a9b5728.3911329244202033832@zoho.com> , <1775e008814.10ffc1dcd21434.8448180592071211373@zoho.com> Message-ID: Hi Timothy, do you also know Unicode class and, in particular, its class variables and its testing selectors? Not sure whether this is on the same abstraction level as your work - just wanted to add this pointer. Also note that Unicode class's character classification does not yet support UTF-16 characters - I have added this to my todo-list some disgracefully long time ago [1] and not yet managed to return back to this issue (so sorry, Levente!). Best, Christoph [1] http://forum.world.st/Unicode-td5113495.html ________________________________ Von: Squeak-dev im Auftrag von gettimothy via Squeak-dev Gesendet: Montag, 1. Februar 2021 15:30:29 An: eric.gade at gmail.com Cc: squeak-dev at lists.squeakfoundation.org Betreff: Re: [squeak-dev] Unicode Ranges you might want to copy Hi Eric Thanks for the heads up! Doing some lite browsing on the matter, I found these resources.... https://unicode-table.com/en/#control-character https://css-tricks.com/almanac/properties/u/unicode-range/ http://www.alanwood.net/unicode/alphabetic_presentation_forms.html That last one looks very useful and I will ve working through it. The middle one claims that fonts can be loaded dynamically when needed. An intersting thing is that the alan wood site displays the $ sign under the currency range, but the jgraphix website does not! It is also somewhat apparent that "like" ranges are not contigous. Thanjs again for your gelp! Cheers, ---- On Mon, 01 Feb 2021 08:57:32 -0500 eric.gade at gmail.com wrote ---- Hi Timothy, I spent several (fruitless) days last year trying to get cuneiform fonts to render properly in Squeak (see here for examples of the fonts). There does seem to be an issue with rendering glyphs above a certain code point from what I recall. I am definitely interested in your work and what you end up finding out. On Sun, Jan 31, 2021 at 7:20 AM gettimothy via Squeak-dev > wrote: Hi Folks, You might find the below handy. Fwiw, I have coded the UnicodeRangeBrowser SeasideApp to display all the below (it times out before all display, I will be doing refactor and more development). I am also coding a utility class to provide information such as below in a variety of ways. fwiw, here are my current todo notes for this font information. unifont provide link to the unicode spec. provide browser fonts list. provide squeak fonts list. provide phare fonts list ^self squeak fonts list: what are Variant Selectors ? show gaps in the ranges. provide a link(s) to required fonts that will make a range display. displays on: browser list, squeak, emacs, xterm... status bar...broken, partial, full. use cases for fonts pairs with xyz example superscripts and subscripts The goal is to show what works and to find/test fonts that will support stuff. I am modelling the Seaside app on https://jrgraphix.net/research/unicode_blocks.php But...for each unicode range, I intend to display smalltalk specific helpers on what/where to get fonts for both the browser side and the image side. --------------snip ------------------- (16r000020 asCharacter to: 16r00007F asCharacter) -> 'Basic Latin' (16r0000A0 asCharacter to: 16r0000FF asCharacter) -> 'Latin-1 Supplement' (16r000100 asCharacter to: 16r00017F asCharacter) -> 'Latin Extended-A' (16r000180 asCharacter to: 16r00024F asCharacter) -> 'Latin Extended-B' (16r000250 asCharacter to: 16r0002AF asCharacter) -> 'IPA Extensions' (16r0002B0 asCharacter to: 16r0002FF asCharacter) -> 'Spacing Modifier Letters' (16r000300 asCharacter to: 16r00036F asCharacter) -> 'Combining Diacritical Marks' (16r000370 asCharacter to: 16r0003FF asCharacter) -> 'Greek and Coptic' (16r000400 asCharacter to: 16r0004FF asCharacter) -> 'Cyrillic' (16r000500 asCharacter to: 16r00052F asCharacter) -> 'Cyrillic Supplementary' (16r000530 asCharacter to: 16r00058F asCharacter) -> 'Armenian' (16r000590 asCharacter to: 16r0005FF asCharacter) -> 'Hebrew' (16r000600 asCharacter to: 16r0006FF asCharacter) -> 'Arabic' (16r000700 asCharacter to: 16r00074F asCharacter) -> 'Syriac' (16r000780 asCharacter to: 16r0007BF asCharacter) -> 'Thaana' (16r000900 asCharacter to: 16r00097F asCharacter) -> 'Devanagari' (16r000980 asCharacter to: 16r0009FF asCharacter) -> 'Bengali' (16r000A00 asCharacter to: 16r000A7F asCharacter) -> 'Gurmukhi' (16r000A80 asCharacter to: 16r000AFF asCharacter) -> 'Gujarati' (16r000B00 asCharacter to: 16r000B7F asCharacter) -> 'Oriya' (16r000B80 asCharacter to: 16r000BFF asCharacter) -> 'Tamil' (16r000C00 asCharacter to: 16r000C7F asCharacter) -> 'Telugu' (16r000C80 asCharacter to: 16r000CFF asCharacter) -> 'Kannada' (16r000D00 asCharacter to: 16r000D7F asCharacter) -> 'Malayalam' (16r000D80 asCharacter to: 16r000DFF asCharacter) -> 'Sinhala' (16r000E00 asCharacter to: 16r000E7F asCharacter) -> 'Thai' (16r000E80 asCharacter to: 16r000EFF asCharacter) -> 'Lao' (16r000F00 asCharacter to: 16r000FFF asCharacter) -> 'Tibetan' (16r001000 asCharacter to: 16r00109F asCharacter) -> 'Myanmar' (16r0010A0 asCharacter to: 16r0010FF asCharacter) -> 'Georgian' (16r001100 asCharacter to: 16r0011FF asCharacter) -> 'Hangul Jamo' (16r001200 asCharacter to: 16r00137F asCharacter) -> 'Ethiopic' (16r0013A0 asCharacter to: 16r0013FF asCharacter) -> 'Cherokee' (16r001400 asCharacter to: 16r00167F asCharacter) -> 'Unified Canadian Aboriginal Syllabics' (16r001680 asCharacter to: 16r00169F asCharacter) -> 'Ogham' (16r0016A0 asCharacter to: 16r0016FF asCharacter) -> 'Runic' (16r001700 asCharacter to: 16r00171F asCharacter) -> 'Tagalog' (16r001720 asCharacter to: 16r00173F asCharacter) -> 'Hanunoo' (16r001740 asCharacter to: 16r00175F asCharacter) -> 'Buhid' (16r001760 asCharacter to: 16r00177F asCharacter) -> 'Tagbanwa' (16r001780 asCharacter to: 16r0017FF asCharacter) -> 'Khmer' (16r001800 asCharacter to: 16r0018AF asCharacter) -> 'Mongolian' (16r001900 asCharacter to: 16r00194F asCharacter) -> 'Limbu' (16r001950 asCharacter to: 16r00197F asCharacter) -> 'Tai Le' (16r0019E0 asCharacter to: 16r0019FF asCharacter) -> 'Khmer Symbols' (16r001D00 asCharacter to: 16r001D7F asCharacter) -> 'Phonetic Extensions' (16r001E00 asCharacter to: 16r001EFF asCharacter) -> 'Latin Extended Additional' (16r001F00 asCharacter to: 16r001FFF asCharacter) -> 'Greek Extended' (16r002000 asCharacter to: 16r00206F asCharacter) -> 'General Punctuation' (16r002070 asCharacter to: 16r00209F asCharacter) -> 'Superscripts and Subscripts' (16r0020A0 asCharacter to: 16r0020CF asCharacter) -> 'Currency Symbols' (16r0020D0 asCharacter to: 16r0020FF asCharacter) -> 'Combining Diacritical Marks for Symbols' (16r002100 asCharacter to: 16r00214F asCharacter) -> 'Letterlike Symbols' (16r002150 asCharacter to: 16r00218F asCharacter) -> 'Number Forms' (16r002190 asCharacter to: 16r0021FF asCharacter) -> 'Arrows' (16r002200 asCharacter to: 16r0022FF asCharacter) -> 'Mathematical Operators' (16r002300 asCharacter to: 16r0023FF asCharacter) -> 'Miscellaneous Technical' (16r002400 asCharacter to: 16r00243F asCharacter) -> 'Control Pictures' (16r002440 asCharacter to: 16r00245F asCharacter) -> 'Optical Character Recognition' (16r002460 asCharacter to: 16r0024FF asCharacter) -> 'Enclosed Alphanumerics' (16r002500 asCharacter to: 16r00257F asCharacter) -> 'Box Drawing' (16r002580 asCharacter to: 16r00259F asCharacter) -> 'Block Elements' (16r0025A0 asCharacter to: 16r0025FF asCharacter) -> 'Geometric Shapes' (16r002600 asCharacter to: 16r0026FF asCharacter) -> 'Miscellaneous Symbols' (16r002700 asCharacter to: 16r0027BF asCharacter) -> 'Dingbats' (16r0027C0 asCharacter to: 16r0027EF asCharacter) -> 'Miscellaneous Mathematical Symbols-A' (16r0027F0 asCharacter to: 16r0027FF asCharacter) -> 'Supplemental Arrows-A' (16r002800 asCharacter to: 16r0028FF asCharacter) -> 'Braille Patterns' (16r002900 asCharacter to: 16r00297F asCharacter) -> 'Supplemental Arrows-B' (16r002980 asCharacter to: 16r0029FF asCharacter) -> 'Miscellaneous Mathematical Symbols-B' (16r002A00 asCharacter to: 16r002AFF asCharacter) -> 'Supplemental Mathematical Operators' (16r002B00 asCharacter to: 16r002BFF asCharacter) -> 'Miscellaneous Symbols and Arrows' (16r002E80 asCharacter to: 16r002EFF asCharacter) -> 'CJK Radicals Supplement' (16r002F00 asCharacter to: 16r002FDF asCharacter) -> 'Kangxi Radicals' (16r002FF0 asCharacter to: 16r002FFF asCharacter) -> 'Ideographic Description Characters' (16r003000 asCharacter to: 16r00303F asCharacter) -> 'CJK Symbols and Punctuation' (16r003040 asCharacter to: 16r00309F asCharacter) -> 'Hiragana' (16r0030A0 asCharacter to: 16r0030FF asCharacter) -> 'Katakana' (16r003100 asCharacter to: 16r00312F asCharacter) -> 'Bopomofo' (16r003130 asCharacter to: 16r00318F asCharacter) -> 'Hangul Compatibility Jamo' (16r003190 asCharacter to: 16r00319F asCharacter) -> 'Kanbun' (16r0031A0 asCharacter to: 16r0031BF asCharacter) -> 'Bopomofo Extended' (16r0031F0 asCharacter to: 16r0031FF asCharacter) -> 'Katakana Phonetic Extensions' (16r003200 asCharacter to: 16r0032FF asCharacter) -> 'Enclosed CJK Letters and Months' (16r003300 asCharacter to: 16r0033FF asCharacter) -> 'CJK Compatibility' (16r003400 asCharacter to: 16r004DBF asCharacter) -> 'CJK Unified Ideographs Extension A' (16r004DC0 asCharacter to: 16r004DFF asCharacter) -> 'Yijing Hexagram Symbols' (16r004E00 asCharacter to: 16r009FFF asCharacter) -> 'CJK Unified Ideographs' (16r00A000 asCharacter to: 16r00A48F asCharacter) -> 'Yi Syllables' (16r00A490 asCharacter to: 16r00A4CF asCharacter) -> 'Yi Radicals' (16r00AC00 asCharacter to: 16r00D7AF asCharacter) -> 'Hangul Syllables' (16r00D800 asCharacter to: 16r00DB7F asCharacter) -> 'High Surrogates' (16r00DB80 asCharacter to: 16r00DBFF asCharacter) -> 'High Private Use Surrogates' (16r00DC00 asCharacter to: 16r00DFFF asCharacter) -> 'Low Surrogates' (16r00E000 asCharacter to: 16r00F8FF asCharacter) -> 'Private Use Area' (16r00F900 asCharacter to: 16r00FAFF asCharacter) -> 'CJK Compatibility Ideographs' (16r00FB00 asCharacter to: 16r00FB4F asCharacter) -> 'Alphabetic Presentation Forms' (16r00FB50 asCharacter to: 16r00FDFF asCharacter) -> 'Arabic Presentation Forms-A' (16r00FE00 asCharacter to: 16r00FE0F asCharacter) -> 'Variation Selectors' (16r00FE20 asCharacter to: 16r00FE2F asCharacter) -> 'Combining Half Marks' (16r00FE30 asCharacter to: 16r00FE4F asCharacter) -> 'CJK Compatibility Forms' (16r00FE50 asCharacter to: 16r00FE6F asCharacter) -> 'Small Form Variants' (16r00FE70 asCharacter to: 16r00FEFF asCharacter) -> 'Arabic Presentation Forms-B' (16r00FF00 asCharacter to: 16r00FFEF asCharacter) -> 'Halfwidth and Fullwidth Forms' (16r00FFF0 asCharacter to: 16r00FFFF asCharacter) -> 'Specials' (16r010000 asCharacter to: 16r01007F asCharacter) -> 'Linear B Syllabary' (16r010080 asCharacter to: 16r0100FF asCharacter) -> 'Linear B Ideograms' (16r010100 asCharacter to: 16r01013F asCharacter) -> 'Aegean Numbers' (16r010300 asCharacter to: 16r01032F asCharacter) -> 'Old Italic' (16r010330 asCharacter to: 16r01034F asCharacter) -> 'Gothic' (16r010380 asCharacter to: 16r01039F asCharacter) -> 'Ugaritic' (16r010400 asCharacter to: 16r01044F asCharacter) -> 'Deseret' (16r010450 asCharacter to: 16r01047F asCharacter) -> 'Shavian' (16r010480 asCharacter to: 16r0104AF asCharacter) -> 'Osmanya' (16r010800 asCharacter to: 16r01083F asCharacter) -> 'Cypriot Syllabary' (16r01D000 asCharacter to: 16r01D0FF asCharacter) -> 'Byzantine Musical Symbols' (16r01D100 asCharacter to: 16r01D1FF asCharacter) -> 'Musical Symbols' (16r01D300 asCharacter to: 16r01D35F asCharacter) -> 'Tai Xuan Jing Symbols' (16r01D400 asCharacter to: 16r01D7FF asCharacter) -> 'Mathematical Alphanumeric Symbols' (16r020000 asCharacter to: 16r02A6DF asCharacter) -> 'CJK Unified Ideographs Extension B' (16r02F800 asCharacter to: 16r02FA1F asCharacter) -> 'CJK Compatibility Ideographs Supplement' (16r0E0000 asCharacter to: 16r0E007F asCharacter) -> 'Tags' -- Eric -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Mon Feb 1 14:41:21 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Mon, 1 Feb 2021 14:41:21 0000 Subject: [squeak-dev] The Inbox: Kernel-ct.1369.mcz Message-ID: A new version of Kernel was added to project The Inbox: http://source.squeak.org/inbox/Kernel-ct.1369.mcz ==================== Summary ==================== Name: Kernel-ct.1369 Author: ct Time: 1 February 2021, 3:41:16.626697 pm UUID: 347948ea-2d23-fc4b-9ffc-a283fce06c65 Ancestors: Kernel-eem.1366 Hotfix for Context >> #isPrimFailToken: (simulator is broken ATM). See http://forum.world.st/The-Trunk-Kernel-eem-1366-mcz-tp5126558p5126617.html. =============== Diff against Kernel-eem.1366 =============== Item was changed: ----- Method: Context>>isPrimFailToken: (in category 'private') ----- isPrimFailToken: anObject + ^ anObject isArray - ^(self objectClass: anObject) isArray and: [anObject size = 2 and: [(anObject at: 1) == PrimitiveFailToken]]! From marcel.taeumel at hpi.de Mon Feb 1 14:43:44 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Mon, 1 Feb 2021 15:43:44 +0100 Subject: [squeak-dev] Transcript error when forceUpdate: false (?) In-Reply-To: References: <1611345790068-0.post@n4.nabble.com> <20210123012610.GB93733@shell.msen.com> <8C121027-CFF5-4DF2-9D2E-18DA658DD743@rowledge.org> <1611599406320-0.post@n4.nabble.com> <1611607106337-0.post@n4.nabble.com> <9D4C563E-7F9D-454F-B5F3-CA7887DF7619@gmx.de> <,> <1ce14508a1654e369a26a946e546ae1d@student.hpi.uni-potsdam.de> <,> <9129c3b2dc13472e9875e00290276f76@student.hpi.uni-potsdam.de> <,> Message-ID: Hi Christoph, > This sounds a very bit speculative to me ... Is it really worth the raised complexity? :-) We are talking about whether could help to make code thread-safe where a mutex might be not sufficient or possible. Whether or not this is useful to the average Smalltalk programmer using Transcript is pure speculation. The underlying issue is, however, real. :-) Now, it depends, how critical the systems are that you are developing. So, for people that want to process critical data, Transcript must work ... or an alternative logging mechanism has to be created for that purpose. This leads to the discussion about the features the underlying framework/library should provide ... ;-) Best, Marcel Am 01.02.2021 15:29:14 schrieb Thiede, Christoph : Hi Marcel, thanks for the explanation. Just to make sure I understand correctly: We are talking about maybe changing the transcript interface and/or even introducing a new pragma selector solely for the purpose of smoothly handling this super-edge case of the active project being switched just while an always-running background thread is logging something to the Transcript? This sounds a very bit speculative to me ... Is it really worth the raised complexity? :-) Best, Christoph [http://www.hpi.de/] Von: Squeak-dev im Auftrag von Taeumel, Marcel Gesendet: Donnerstag, 28. Januar 2021 12:14:11 An: squeak-dev Betreff: Re: [squeak-dev] Transcript error when forceUpdate: false (?)   > I still don't see the point. Are you saying that the current project or it's UI process could change during a VM suspension point? If that code runs at 39 and the user switches projects at 40, yes, this can happen. > Then, what about something like "Project current evaluateUIMessage: [...]", which will unpreemptedly (using the new primitive solution) check the UI process and either evaluate the message directly or defer it? :-) Even the implementation of #evaluateUIMessage: would need something like :-) So, one could directly add this pragma to, for example, #endEntry, without adding such a new indirection. And at lower levels or more concise scopes, access should be controlled with a mutex. I suppose that the "trick" with only works in a green-threading model where exactly 1 thread (or Squeak process) is actually running at a time. Best, Marcel P.S.: Is every fallback code for failing primitives evaluated without preemption?  Am 28.01.2021 11:28:24 schrieb Thiede, Christoph : I still don't see the point. Are you saying that the current project or it's UI process could change during a VM suspension point? Then, what about something like "Project current evaluateUIMessage: [...]", which will unpreemptedly (using the new primitive solution) check the UI process and either evaluate the message directly or defer it? :-) Best, Christoph [http://www.hpi.de/] Von: Squeak-dev im Auftrag von Taeumel, Marcel Gesendet: Donnerstag, 28. Januar 2021 11:13:55 An: squeak-dev Betreff: Re: [squeak-dev] Transcript error when forceUpdate: false (?)   Hi Christoph. >  What is that dangerous thing that could happen during a suspension point in the VM? What am I missing here? :-) It's only part of the problem. There could be a disconnect between the former "Project current uiProcess" comparison and how "addDeferredUIMessage" is processed later in the code. It would be better to no preempt this call as a whole. Best, Marcel Am 28.01.2021 10:59:50 schrieb Thiede, Christoph : Hi all, this is an interesting discussion, two thoughts from my side: 1. What is the problem with "Processor activeProcess == Project current uiProcess" not being a thread-safe expression? I see that it could be possible at many points that the VM interrupts the current process and resumes another one first; but still, activeProcess will always hold the same Process instance when the same process is active, independently of any interruptions, won't it? What is that dangerous thing that could happen during a suspension point in the VM? What am I missing here? :-) 2. To Levente's proposal of making Transcript calls thread-safe: > safelyNextPutAll: aString >  >          mutex critical: [ >                  stream nextPutAll: aString ] So this would delay the execution of any process that uses the Transcript, wouldn't it? Hm ... I would rather have expected the Transcript calls to be deferred when the Transcript is locked ATM - *unless* #forceUpdate is enabled, maybe. Let's keep everyday Transcript clients blocking-free whenever possible. Or imagine several processes writing to the Transcript, but the transcript not being opened at this time. There should no need to block any of the calling processes? Best, Christoph Von: Squeak-dev im Auftrag von Taeumel, Marcel Gesendet: Donnerstag, 28. Januar 2021 10:41:03 An: squeak-dev Betreff: Re: [squeak-dev] Transcript error when forceUpdate: false (?)   Hi Tobias > A separate kind of log (that optionally could output to the transcript) Transcript can use stdout already. Not sure we want to shift the problem to the user again ... :-/ "Every time you provide an option, you expect users to make a decision." :-) Best, Marcel Am 28.01.2021 10:32:27 schrieb Tobias Pape : Hi apart from the debuggers, why bother making Transcript thread-safe in the first place? The Transcript is a mere output stream for debugging/logging etc., our stdout or stderr. A separate kind of log (that optionally could output to the transcript) would be more apt IMHO. Thread safety could be addressed there without complicating Transcript more… my 2ct -tobias > On 28. Jan 2021, at 09:05, Marcel Taeumel wrote: > > Hi Levente. > > Thanks für clarification. We are talking about more than one problem here. :-) I did just address the issue with errors/debuggers happening due to UI process disruptions. You are also concerned about the order of contents in the Transcript's contents. Both are very important and required for claiming that it would be thread-safe. > > (Which reminds me that I find it very strange that the UI components (e.g. PluggableTextMorph) do also check the Transcript's internal characterLimit. I would expect an append-only behavior when a Transcript window is open.) > > Anyway, your proposal about a safelyNextPut(All): looks good. :-) +1 > > Best, > Marcel >> Am 27.01.2021 23:05:21 schrieb Levente Uzonyi : >> >> Hi Marcel, >> >> On Tue, 26 Jan 2021, Marcel Taeumel wrote: >> >> > Hi Jaromir, >> > please take a look at Collections-mt.923 (inbox). Maybe those changes would satisfy all your current needs in this regard. :-) >> > >> > @all: Would Transcript now be thread-safe? Did I miss something? >> >> Not at all. The problem is not #endEntry but all the other >> methods writing to the stream e.g.: #nextPutAll:. >> The real solution is to replace the stream-like API with one that provides >> an easy way to write messages in a thread-safe way. E.g.: >> >> Transcript showStream: [ :stream | >> stream nextPutAll: 'Hello'; space; nextPutAll: ' World!'; cr ] >> >> Which guarantees that 'Hello World!' appears on the Transcript without >> being mixed with other messages. >> >> or >> >> Transcript show: 'Hello {1}!{2}' format: { 'World'. String cr }. >> >> The implementations could be e.g.: >> >> showStream: aBlock >> >> | string | >> string := String streamContents: aBlock. >> self safelyNextPutAll: string >> >> show: aString format: arguments >> >> | string | >> string := aString format: arguments. >> self safelyNextPutAll: string >> >> The last challenge is to implement #safelyNextPutAll: which involves >> making Transcript not be a TranscriptStream. >> Transcript should encapsulate the stream and use a Mutex (not a global one >> because its pointless) to provide thread-safety while writing the >> characters on it or reading its contents. E.g.: >> >> safelyNextPutAll: aString >> >> mutex critical: [ >> stream nextPutAll: aString ] >> >> For backwards compatibility, the stream-API methods must be provided for a >> while but those methods should be thread-safe on their own. E.g.: >> >> nextPutAll: aString >> >> self safelyNextPutAll: aString >> >> nextPut: aCharacter >> >> self safelyNextPutAll: aCharacter asString >> >> >> Levente >> >> > >> > Best, >> > Marcel >> > >> > Am 25.01.2021 21:38:36 schrieb jaromir : >> > >> > Well, I tried deferring the whole Transcript endEntry machinery to the UI >> > doOneCycle (bypassing the changed: #appendEntryLater mechanism) for >> > #forceUpdate = false only ... and it seems to avoid the problem! >> > >> > TranscriptStream >> endEntry >> > >> > deferredEntry ifNil: [ false ]. "this is a new instance variable" >> > self semaphore critical:[ >> > self class forceUpdate >> > ifTrue: [self changed: #appendEntry; reset] >> > ifFalse: [deferredEntry := true]. >> > >> > >> > TranscriptStream >> flushDeferredEntry >> > "This is run every UI cycle in doOneCycleNowFor:" >> > >> > deferredEntry ifTrue: [ >> > self class forceUpdate: true. >> > self endEntry. >> > deferredEntry := false. >> > self class forceUpdate: false. >> > ] >> > >> > doOneCycleNowFor: aWorld >> > >> > "... the whole body remains unchanged except:" >> > >> > capturingGesture ifFalse: >> > [aWorld runStepMethods. >> > Transcript flushDeferredEntry. "this is printing for #forceUpdate = >> > false" >> > self displayWorldSafely: aWorld]. >> > >> > >> > For #forceUpdate = true the endEntry mechanism remains unchanged and failing >> > as before... >> > >> > >> > >> > -- >> > Sent from: http://forum.world.st/Squeak-Dev-f45488.html >> > >> > >> > >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From Christoph.Thiede at student.hpi.uni-potsdam.de Mon Feb 1 14:45:46 2021 From: Christoph.Thiede at student.hpi.uni-potsdam.de (Thiede, Christoph) Date: Mon, 1 Feb 2021 14:45:46 +0000 Subject: [squeak-dev] The Trunk: Kernel-eem.1366.mcz In-Reply-To: References: , Message-ID: <24f1800104c24bce9c173fb296a13f0b@student.hpi.uni-potsdam.de> Hi all, Eliot, thank you for the speed-up! I have uploaded Kernel-ct.1369 to the inbox to fix the regression in the simulator. @Levente I don't see the need for mirror primitives here; the PrimitiveFailToken is a concept internal to the simulator and iiuc mirror primitives should only be used when dealing with objects from the *simulated* code. Am I wrong? :-) Best, Christoph ________________________________ Von: Squeak-dev im Auftrag von Levente Uzonyi Gesendet: Donnerstag, 28. Januar 2021 15:56:07 An: The general-purpose Squeak developers list Betreff: Re: [squeak-dev] The Trunk: Kernel-eem.1366.mcz Hi Marcel, On Thu, 28 Jan 2021, Marcel Taeumel wrote: > Hi Levente. > > I also wonder why you used #objectClass: there instead of #class in the > previous version. Perhaps there was a good reason. > Maybe because of ProtoObject (and proxies)? I think the long-term plan was to not treat #class as a special send anymore so that proxies can override that interface. In that case there are two problems with the rewrite. Btw, Eliot didn't mention it in the other thread, but #class is currently a way to avoid suspension points, just like #==, #ifNil:ifNotNil:, #caseOf:otherwise:, ifTrue:ifFalse:, etc. Levente > > Best, > Marcel > > Am 28.01.2021 13:46:12 schrieb Levente Uzonyi : > > Hi Eliot, > > On Wed, 27 Jan 2021, commits at source.squeak.org wrote: > > > Eliot Miranda uploaded a new version of Kernel to project The Trunk: > > http://source.squeak.org/trunk/Kernel-eem.1366.mcz > > > > ==================== Summary ==================== > > > > Name: Kernel-eem.1366 > > Author: eem > > Time: 26 January 2021, 4:27:57.204259 pm > > UUID: 3a706d32-c2d6-416f-82c1-bbf735650385 > > Ancestors: Kernel-eem.1365 > > > > Slightly faster implementation of Context>>#isPrimFailToken:. > > Improve the comments in Context>>#isHandlerContext/#isUnwindContext. > > Nuke an obsolete method. > > > > =============== Diff against Kernel-eem.1365 =============== > > > > Item was changed: > > ----- Method: Context>>isHandlerContext (in category 'private-exceptions') ----- > > isHandlerContext > > + "Answer if the receiver is for a method that is marked as an exception handler. > > + BlockClosure>>#on:do: uses this primitive to identify itself to the VM > > + as an exception handler method, which the VM uses in primitive 197 > > + Context>>#findNextHandlerContextStarting, primitiveFindHandlerContext, > > + to accelerate the search for exception handlers." > > - "is this context for method that is marked?" > > ^method primitive = 199! > > > > Item was changed: > > ----- Method: Context>>isPrimFailToken: (in category 'private') ----- > > isPrimFailToken: anObject > > + ^(self objectClass: anObject) isArray > > - ^(self objectClass: anObject) == Array > > I think you meant to write > > ^(anObject isArray > > I also wonder why you used #objectClass: there instead of #class in the > previous version. Perhaps there was a good reason. > > > Levente > > > and: [anObject size = 2 > > + and: [(anObject at: 1) == PrimitiveFailToken]]! > > - and: [anObject first == PrimitiveFailToken]]! > > > > Item was changed: > > ----- Method: Context>>isUnwindContext (in category 'private-exceptions') ----- > > isUnwindContext > > + "Answer if the receiver is for a method that is marked as a non-local return/exception unwind protect. > > + BlockClosure>>#ensure: and BlockClosure>>#ifCurtailed: use this primitive to identify > > + themseves to the VM as unwind protect methods. The VM uses this in primitive 195 > > + Context>>#findNextUnwindContextUpTo:, primitiveFindNextUnwindContext, to > > + accelerate the search for unwind protects." > > - "is this context for method that is marked?" > > ^method primitive = 198! > > > > Item was removed: > > - ----- Method: Context>>tryPrimitiveFor:receiver:args: (in category 'private') ----- > > - tryPrimitiveFor: method receiver: receiver args: arguments > > - "If this method has a primitive index, then run the primitive and return its result. > > - Otherwise (and also if the primitive fails) return PrimitiveFailToken, > > - as an indication that the method should be activated and run as bytecodes." > > - | primIndex | > > - (primIndex := method primitive) = 0 ifTrue: [^{PrimitiveFailToken. nil}]. > > - ^ self doPrimitive: primIndex method: method receiver: receiver args: arguments! > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From Christoph.Thiede at student.hpi.uni-potsdam.de Mon Feb 1 14:48:00 2021 From: Christoph.Thiede at student.hpi.uni-potsdam.de (Thiede, Christoph) Date: Mon, 1 Feb 2021 14:48:00 +0000 Subject: [squeak-dev] The Trunk: Kernel-eem.1366.mcz In-Reply-To: <24f1800104c24bce9c173fb296a13f0b@student.hpi.uni-potsdam.de> References: , , <24f1800104c24bce9c173fb296a13f0b@student.hpi.uni-potsdam.de> Message-ID: <599ee95876bc41ab8f88f348d072f72a@student.hpi.uni-potsdam.de> Btw - independently of this change - it's a shame that we still need to nest #and: blocks just because #and: is inlined but #(and:){2,} are not. We should change this someday ... or just wait for Sista to arrive. :-) Best, Christoph ________________________________ Von: Thiede, Christoph Gesendet: Montag, 1. Februar 2021 15:45:46 An: The general-purpose Squeak developers list Betreff: AW: [squeak-dev] The Trunk: Kernel-eem.1366.mcz Hi all, Eliot, thank you for the speed-up! I have uploaded Kernel-ct.1369 to the inbox to fix the regression in the simulator. @Levente I don't see the need for mirror primitives here; the PrimitiveFailToken is a concept internal to the simulator and iiuc mirror primitives should only be used when dealing with objects from the *simulated* code. Am I wrong? :-) Best, Christoph ________________________________ Von: Squeak-dev im Auftrag von Levente Uzonyi Gesendet: Donnerstag, 28. Januar 2021 15:56:07 An: The general-purpose Squeak developers list Betreff: Re: [squeak-dev] The Trunk: Kernel-eem.1366.mcz Hi Marcel, On Thu, 28 Jan 2021, Marcel Taeumel wrote: > Hi Levente. > > I also wonder why you used #objectClass: there instead of #class in the > previous version. Perhaps there was a good reason. > Maybe because of ProtoObject (and proxies)? I think the long-term plan was to not treat #class as a special send anymore so that proxies can override that interface. In that case there are two problems with the rewrite. Btw, Eliot didn't mention it in the other thread, but #class is currently a way to avoid suspension points, just like #==, #ifNil:ifNotNil:, #caseOf:otherwise:, ifTrue:ifFalse:, etc. Levente > > Best, > Marcel > > Am 28.01.2021 13:46:12 schrieb Levente Uzonyi : > > Hi Eliot, > > On Wed, 27 Jan 2021, commits at source.squeak.org wrote: > > > Eliot Miranda uploaded a new version of Kernel to project The Trunk: > > http://source.squeak.org/trunk/Kernel-eem.1366.mcz > > > > ==================== Summary ==================== > > > > Name: Kernel-eem.1366 > > Author: eem > > Time: 26 January 2021, 4:27:57.204259 pm > > UUID: 3a706d32-c2d6-416f-82c1-bbf735650385 > > Ancestors: Kernel-eem.1365 > > > > Slightly faster implementation of Context>>#isPrimFailToken:. > > Improve the comments in Context>>#isHandlerContext/#isUnwindContext. > > Nuke an obsolete method. > > > > =============== Diff against Kernel-eem.1365 =============== > > > > Item was changed: > > ----- Method: Context>>isHandlerContext (in category 'private-exceptions') ----- > > isHandlerContext > > + "Answer if the receiver is for a method that is marked as an exception handler. > > + BlockClosure>>#on:do: uses this primitive to identify itself to the VM > > + as an exception handler method, which the VM uses in primitive 197 > > + Context>>#findNextHandlerContextStarting, primitiveFindHandlerContext, > > + to accelerate the search for exception handlers." > > - "is this context for method that is marked?" > > ^method primitive = 199! > > > > Item was changed: > > ----- Method: Context>>isPrimFailToken: (in category 'private') ----- > > isPrimFailToken: anObject > > + ^(self objectClass: anObject) isArray > > - ^(self objectClass: anObject) == Array > > I think you meant to write > > ^(anObject isArray > > I also wonder why you used #objectClass: there instead of #class in the > previous version. Perhaps there was a good reason. > > > Levente > > > and: [anObject size = 2 > > + and: [(anObject at: 1) == PrimitiveFailToken]]! > > - and: [anObject first == PrimitiveFailToken]]! > > > > Item was changed: > > ----- Method: Context>>isUnwindContext (in category 'private-exceptions') ----- > > isUnwindContext > > + "Answer if the receiver is for a method that is marked as a non-local return/exception unwind protect. > > + BlockClosure>>#ensure: and BlockClosure>>#ifCurtailed: use this primitive to identify > > + themseves to the VM as unwind protect methods. The VM uses this in primitive 195 > > + Context>>#findNextUnwindContextUpTo:, primitiveFindNextUnwindContext, to > > + accelerate the search for unwind protects." > > - "is this context for method that is marked?" > > ^method primitive = 198! > > > > Item was removed: > > - ----- Method: Context>>tryPrimitiveFor:receiver:args: (in category 'private') ----- > > - tryPrimitiveFor: method receiver: receiver args: arguments > > - "If this method has a primitive index, then run the primitive and return its result. > > - Otherwise (and also if the primitive fails) return PrimitiveFailToken, > > - as an indication that the method should be activated and run as bytecodes." > > - | primIndex | > > - (primIndex := method primitive) = 0 ifTrue: [^{PrimitiveFailToken. nil}]. > > - ^ self doPrimitive: primIndex method: method receiver: receiver args: arguments! > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From eliot.miranda at gmail.com Mon Feb 1 15:52:09 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon, 1 Feb 2021 07:52:09 -0800 Subject: [squeak-dev] Unicode Ranges you might want to copy In-Reply-To: References: Message-ID: Hi Eric, > On Feb 1, 2021, at 5:57 AM, Eric Gade wrote: > >  > Hi Timothy, > > I spent several (fruitless) days last year trying to get cuneiform fonts to render properly in Squeak (see here for examples of the fonts). > There does seem to be an issue with rendering glyphs above a certain code point from what I recall. Do you have any code for testing this, a workspace perhaps? If so, could you post it here? > I am definitely interested in your work and what you end up finding out. > >> On Sun, Jan 31, 2021 at 7:20 AM gettimothy via Squeak-dev wrote: >> Hi Folks, >> >> You might find the below handy. >> >> Fwiw, I have coded the UnicodeRangeBrowser SeasideApp to display all the below (it times out before all display, I will be doing refactor and more development). >> >> I am also coding a utility class to provide information such as below in a variety of ways. >> >> fwiw, here are my current todo notes for this font information. >> >> unifont >> >> provide link to the unicode spec. >> provide browser fonts list. >> provide squeak fonts list. >> provide phare fonts list ^self squeak fonts list: >> what are Variant Selectors ? >> >> show gaps in the ranges. >> >> provide a link(s) to required fonts that will make a range display. >> displays on: browser list, squeak, emacs, xterm... >> status bar...broken, partial, full. >> use cases for fonts >> pairs with xyz example superscripts and subscripts >> >> The goal is to show what works and to find/test fonts that will support stuff. >> I am modelling the Seaside app on https://jrgraphix.net/research/unicode_blocks.php >> But...for each unicode range, I intend to display smalltalk specific helpers on what/where to get fonts for both the browser side and the image side. >> >> --------------snip ------------------- >> >> (16r000020 asCharacter to: 16r00007F asCharacter) -> 'Basic Latin' >> (16r0000A0 asCharacter to: 16r0000FF asCharacter) -> 'Latin-1 Supplement' >> (16r000100 asCharacter to: 16r00017F asCharacter) -> 'Latin Extended-A' >> (16r000180 asCharacter to: 16r00024F asCharacter) -> 'Latin Extended-B' >> (16r000250 asCharacter to: 16r0002AF asCharacter) -> 'IPA Extensions' >> (16r0002B0 asCharacter to: 16r0002FF asCharacter) -> 'Spacing Modifier Letters' >> (16r000300 asCharacter to: 16r00036F asCharacter) -> 'Combining Diacritical Marks' >> (16r000370 asCharacter to: 16r0003FF asCharacter) -> 'Greek and Coptic' >> (16r000400 asCharacter to: 16r0004FF asCharacter) -> 'Cyrillic' >> (16r000500 asCharacter to: 16r00052F asCharacter) -> 'Cyrillic Supplementary' >> (16r000530 asCharacter to: 16r00058F asCharacter) -> 'Armenian' >> (16r000590 asCharacter to: 16r0005FF asCharacter) -> 'Hebrew' >> (16r000600 asCharacter to: 16r0006FF asCharacter) -> 'Arabic' >> (16r000700 asCharacter to: 16r00074F asCharacter) -> 'Syriac' >> (16r000780 asCharacter to: 16r0007BF asCharacter) -> 'Thaana' >> (16r000900 asCharacter to: 16r00097F asCharacter) -> 'Devanagari' >> (16r000980 asCharacter to: 16r0009FF asCharacter) -> 'Bengali' >> (16r000A00 asCharacter to: 16r000A7F asCharacter) -> 'Gurmukhi' >> (16r000A80 asCharacter to: 16r000AFF asCharacter) -> 'Gujarati' >> (16r000B00 asCharacter to: 16r000B7F asCharacter) -> 'Oriya' >> (16r000B80 asCharacter to: 16r000BFF asCharacter) -> 'Tamil' >> (16r000C00 asCharacter to: 16r000C7F asCharacter) -> 'Telugu' >> (16r000C80 asCharacter to: 16r000CFF asCharacter) -> 'Kannada' >> (16r000D00 asCharacter to: 16r000D7F asCharacter) -> 'Malayalam' >> (16r000D80 asCharacter to: 16r000DFF asCharacter) -> 'Sinhala' >> (16r000E00 asCharacter to: 16r000E7F asCharacter) -> 'Thai' >> (16r000E80 asCharacter to: 16r000EFF asCharacter) -> 'Lao' >> (16r000F00 asCharacter to: 16r000FFF asCharacter) -> 'Tibetan' >> (16r001000 asCharacter to: 16r00109F asCharacter) -> 'Myanmar' >> (16r0010A0 asCharacter to: 16r0010FF asCharacter) -> 'Georgian' >> (16r001100 asCharacter to: 16r0011FF asCharacter) -> 'Hangul Jamo' >> (16r001200 asCharacter to: 16r00137F asCharacter) -> 'Ethiopic' >> (16r0013A0 asCharacter to: 16r0013FF asCharacter) -> 'Cherokee' >> (16r001400 asCharacter to: 16r00167F asCharacter) -> 'Unified Canadian Aboriginal Syllabics' >> (16r001680 asCharacter to: 16r00169F asCharacter) -> 'Ogham' >> (16r0016A0 asCharacter to: 16r0016FF asCharacter) -> 'Runic' >> (16r001700 asCharacter to: 16r00171F asCharacter) -> 'Tagalog' >> (16r001720 asCharacter to: 16r00173F asCharacter) -> 'Hanunoo' >> (16r001740 asCharacter to: 16r00175F asCharacter) -> 'Buhid' >> (16r001760 asCharacter to: 16r00177F asCharacter) -> 'Tagbanwa' >> (16r001780 asCharacter to: 16r0017FF asCharacter) -> 'Khmer' >> (16r001800 asCharacter to: 16r0018AF asCharacter) -> 'Mongolian' >> (16r001900 asCharacter to: 16r00194F asCharacter) -> 'Limbu' >> (16r001950 asCharacter to: 16r00197F asCharacter) -> 'Tai Le' >> (16r0019E0 asCharacter to: 16r0019FF asCharacter) -> 'Khmer Symbols' >> (16r001D00 asCharacter to: 16r001D7F asCharacter) -> 'Phonetic Extensions' >> (16r001E00 asCharacter to: 16r001EFF asCharacter) -> 'Latin Extended Additional' >> (16r001F00 asCharacter to: 16r001FFF asCharacter) -> 'Greek Extended' >> (16r002000 asCharacter to: 16r00206F asCharacter) -> 'General Punctuation' >> (16r002070 asCharacter to: 16r00209F asCharacter) -> 'Superscripts and Subscripts' >> (16r0020A0 asCharacter to: 16r0020CF asCharacter) -> 'Currency Symbols' >> (16r0020D0 asCharacter to: 16r0020FF asCharacter) -> 'Combining Diacritical Marks for Symbols' >> (16r002100 asCharacter to: 16r00214F asCharacter) -> 'Letterlike Symbols' >> (16r002150 asCharacter to: 16r00218F asCharacter) -> 'Number Forms' >> (16r002190 asCharacter to: 16r0021FF asCharacter) -> 'Arrows' >> (16r002200 asCharacter to: 16r0022FF asCharacter) -> 'Mathematical Operators' >> (16r002300 asCharacter to: 16r0023FF asCharacter) -> 'Miscellaneous Technical' >> (16r002400 asCharacter to: 16r00243F asCharacter) -> 'Control Pictures' >> (16r002440 asCharacter to: 16r00245F asCharacter) -> 'Optical Character Recognition' >> (16r002460 asCharacter to: 16r0024FF asCharacter) -> 'Enclosed Alphanumerics' >> (16r002500 asCharacter to: 16r00257F asCharacter) -> 'Box Drawing' >> (16r002580 asCharacter to: 16r00259F asCharacter) -> 'Block Elements' >> (16r0025A0 asCharacter to: 16r0025FF asCharacter) -> 'Geometric Shapes' >> (16r002600 asCharacter to: 16r0026FF asCharacter) -> 'Miscellaneous Symbols' >> (16r002700 asCharacter to: 16r0027BF asCharacter) -> 'Dingbats' >> (16r0027C0 asCharacter to: 16r0027EF asCharacter) -> 'Miscellaneous Mathematical Symbols-A' >> (16r0027F0 asCharacter to: 16r0027FF asCharacter) -> 'Supplemental Arrows-A' >> (16r002800 asCharacter to: 16r0028FF asCharacter) -> 'Braille Patterns' >> (16r002900 asCharacter to: 16r00297F asCharacter) -> 'Supplemental Arrows-B' >> (16r002980 asCharacter to: 16r0029FF asCharacter) -> 'Miscellaneous Mathematical Symbols-B' >> (16r002A00 asCharacter to: 16r002AFF asCharacter) -> 'Supplemental Mathematical Operators' >> (16r002B00 asCharacter to: 16r002BFF asCharacter) -> 'Miscellaneous Symbols and Arrows' >> (16r002E80 asCharacter to: 16r002EFF asCharacter) -> 'CJK Radicals Supplement' >> (16r002F00 asCharacter to: 16r002FDF asCharacter) -> 'Kangxi Radicals' >> (16r002FF0 asCharacter to: 16r002FFF asCharacter) -> 'Ideographic Description Characters' >> (16r003000 asCharacter to: 16r00303F asCharacter) -> 'CJK Symbols and Punctuation' >> (16r003040 asCharacter to: 16r00309F asCharacter) -> 'Hiragana' >> (16r0030A0 asCharacter to: 16r0030FF asCharacter) -> 'Katakana' >> (16r003100 asCharacter to: 16r00312F asCharacter) -> 'Bopomofo' >> (16r003130 asCharacter to: 16r00318F asCharacter) -> 'Hangul Compatibility Jamo' >> (16r003190 asCharacter to: 16r00319F asCharacter) -> 'Kanbun' >> (16r0031A0 asCharacter to: 16r0031BF asCharacter) -> 'Bopomofo Extended' >> (16r0031F0 asCharacter to: 16r0031FF asCharacter) -> 'Katakana Phonetic Extensions' >> (16r003200 asCharacter to: 16r0032FF asCharacter) -> 'Enclosed CJK Letters and Months' >> (16r003300 asCharacter to: 16r0033FF asCharacter) -> 'CJK Compatibility' >> (16r003400 asCharacter to: 16r004DBF asCharacter) -> 'CJK Unified Ideographs Extension A' >> (16r004DC0 asCharacter to: 16r004DFF asCharacter) -> 'Yijing Hexagram Symbols' >> (16r004E00 asCharacter to: 16r009FFF asCharacter) -> 'CJK Unified Ideographs' >> (16r00A000 asCharacter to: 16r00A48F asCharacter) -> 'Yi Syllables' >> (16r00A490 asCharacter to: 16r00A4CF asCharacter) -> 'Yi Radicals' >> (16r00AC00 asCharacter to: 16r00D7AF asCharacter) -> 'Hangul Syllables' >> (16r00D800 asCharacter to: 16r00DB7F asCharacter) -> 'High Surrogates' >> (16r00DB80 asCharacter to: 16r00DBFF asCharacter) -> 'High Private Use Surrogates' >> (16r00DC00 asCharacter to: 16r00DFFF asCharacter) -> 'Low Surrogates' >> (16r00E000 asCharacter to: 16r00F8FF asCharacter) -> 'Private Use Area' >> (16r00F900 asCharacter to: 16r00FAFF asCharacter) -> 'CJK Compatibility Ideographs' >> (16r00FB00 asCharacter to: 16r00FB4F asCharacter) -> 'Alphabetic Presentation Forms' >> (16r00FB50 asCharacter to: 16r00FDFF asCharacter) -> 'Arabic Presentation Forms-A' >> (16r00FE00 asCharacter to: 16r00FE0F asCharacter) -> 'Variation Selectors' >> (16r00FE20 asCharacter to: 16r00FE2F asCharacter) -> 'Combining Half Marks' >> (16r00FE30 asCharacter to: 16r00FE4F asCharacter) -> 'CJK Compatibility Forms' >> (16r00FE50 asCharacter to: 16r00FE6F asCharacter) -> 'Small Form Variants' >> (16r00FE70 asCharacter to: 16r00FEFF asCharacter) -> 'Arabic Presentation Forms-B' >> (16r00FF00 asCharacter to: 16r00FFEF asCharacter) -> 'Halfwidth and Fullwidth Forms' >> (16r00FFF0 asCharacter to: 16r00FFFF asCharacter) -> 'Specials' >> (16r010000 asCharacter to: 16r01007F asCharacter) -> 'Linear B Syllabary' >> (16r010080 asCharacter to: 16r0100FF asCharacter) -> 'Linear B Ideograms' >> (16r010100 asCharacter to: 16r01013F asCharacter) -> 'Aegean Numbers' >> (16r010300 asCharacter to: 16r01032F asCharacter) -> 'Old Italic' >> (16r010330 asCharacter to: 16r01034F asCharacter) -> 'Gothic' >> (16r010380 asCharacter to: 16r01039F asCharacter) -> 'Ugaritic' >> (16r010400 asCharacter to: 16r01044F asCharacter) -> 'Deseret' >> (16r010450 asCharacter to: 16r01047F asCharacter) -> 'Shavian' >> (16r010480 asCharacter to: 16r0104AF asCharacter) -> 'Osmanya' >> (16r010800 asCharacter to: 16r01083F asCharacter) -> 'Cypriot Syllabary' >> (16r01D000 asCharacter to: 16r01D0FF asCharacter) -> 'Byzantine Musical Symbols' >> (16r01D100 asCharacter to: 16r01D1FF asCharacter) -> 'Musical Symbols' >> (16r01D300 asCharacter to: 16r01D35F asCharacter) -> 'Tai Xuan Jing Symbols' >> (16r01D400 asCharacter to: 16r01D7FF asCharacter) -> 'Mathematical Alphanumeric Symbols' >> (16r020000 asCharacter to: 16r02A6DF asCharacter) -> 'CJK Unified Ideographs Extension B' >> (16r02F800 asCharacter to: 16r02FA1F asCharacter) -> 'CJK Compatibility Ideographs Supplement' >> (16r0E0000 asCharacter to: 16r0E007F asCharacter) -> 'Tags' >> > -- > Eric Eliot _,,,^..^,,,_ (phone) -------------- next part -------------- An HTML attachment was scrubbed... URL: From Christoph.Thiede at student.hpi.uni-potsdam.de Mon Feb 1 16:29:03 2021 From: Christoph.Thiede at student.hpi.uni-potsdam.de (Thiede, Christoph) Date: Mon, 1 Feb 2021 16:29:03 +0000 Subject: [squeak-dev] Trying to understand unpreemptive execution/#valueNoContextSwitch Message-ID: <2762864ef6d64f20a9bffa0961e08f77@student.hpi.uni-potsdam.de> Hi all, in the context of the current Transcript debate [1], I am trying to figure out whether, and why Marcel's proposed implementation of [2] could work. As a minimum example to test #valueNoContextSwitch, I tried the following: "Try to run this infinite loop unpreemptively." [ [[false] whileFalse] valueNoContextSwitch. self inform: #done ] forkAt: Processor userBackgroundPriority. Now I would have expected my image (its UI process) to freeze while p2 is running unpreemptively. But - nothing happens, i.e., all other processes are still activated! I also exchanged valueNoContextSwitch with valueUninterruptably (which I implemented using primitive 123 analogously to ) with the same result. Here is my question: Am I misunderstanding the concept of unpreemptive/uninterruptable execution (are those two terms really synonyms?), or is unpreempted execution broken? Assuming the former is the case, what else would be a good and simple way to find out if a process is being run unpreemptively? And do we have any good documentation of this concept - self-documenting tests will be preferred? :-) Best, Christoph [1] http://forum.world.st/Transcript-error-when-forceUpdate-false-td5126397.html [2] http://forum.world.st/The-Inbox-Compiler-mt-454-mcz-td5126568.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From christoph.thiede at student.hpi.uni-potsdam.de Mon Feb 1 16:40:34 2021 From: christoph.thiede at student.hpi.uni-potsdam.de (Christoph Thiede) Date: Mon, 1 Feb 2021 10:40:34 -0600 (CST) Subject: [squeak-dev] Context >> #tempNamed:(put:) In-Reply-To: <203cc089281c42fdbc6c76989193d952@student.hpi.uni-potsdam.de> References: <203cc089281c42fdbc6c76989193d952@student.hpi.uni-potsdam.de> Message-ID: <1612197634550-0.post@n4.nabble.com> Hi all, please forgive me for pushing this proposal again after 13 months :-) Three questions here for everyone to answer: 1. What do you think about the proposal in general? Is it worth merging it into the Trunk? (Personally, I like to use it nearly every day ...) 2. If you have no objections, what keeps us from merging it? :-) 3. Naming battle: #tempNamed:[put:] vs #tempVarNamed:[put:]? Side note: If we get this into Trunk, we can also use it in Compiler to produce more comprehensible #DoItIn: methods, for instance, "(ThisContext tempNamed: 'failBlock') value" instead of "(ThisContext namedTempAt: 2) value" - provided that sources are available. Best, Christoph ----- Carpe Squeak! -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From eliot.miranda at gmail.com Mon Feb 1 18:08:33 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon, 1 Feb 2021 10:08:33 -0800 Subject: [squeak-dev] Trying to understand unpreemptive execution/#valueNoContextSwitch In-Reply-To: <2762864ef6d64f20a9bffa0961e08f77@student.hpi.uni-potsdam.de> References: <2762864ef6d64f20a9bffa0961e08f77@student.hpi.uni-potsdam.de> Message-ID: Hi Christoph, On Mon, Feb 1, 2021 at 8:29 AM Thiede, Christoph < Christoph.Thiede at student.hpi.uni-potsdam.de> wrote: > Hi all, > > > in the context of the current Transcript debate [1], I am trying to figure > out whether, and why Marcel's proposed implementation of > [2] could work. > > > As a minimum example to test #valueNoContextSwitch, I tried the following: > > > "Try to run this infinite loop unpreemptively." > > [ > > [[false] whileFalse] valueNoContextSwitch. > > self inform: #done > > ] forkAt: Processor userBackgroundPriority. > > > Now I would have expected my image (its UI process) to freeze while > p2 is running unpreemptively. > RTFM :-) An exact copy of BlockClosure>>value except that this version will not preempt the current process on block activation if a higher-priority process is runnable. Primitive. Essential. i.e. this has an effect only on activating the block. Once the block is running preemption is still possible. All that it guarantees is that no preemption is possible from immediately before the send of valueNoContextSwitch to the first send in the block activation. > But - nothing happens, i.e., all other processes are still activated! I > also exchanged valueNoContextSwitch with valueUninterruptably (which I > implemented using primitive 123 analogously to ) with > the same result. > > > Here is my question: Am I misunderstanding the concept of > unpreemptive/uninterruptable execution (are those two terms really > synonyms?), or is unpreempted execution broken? > They're not synonyms, but neither of them apply to valueNoContextSwitch, nor my proposed pragma which should perhaps be Assuming the former is the case, what else would be a good and simple way > to find out if a process is being run unpreemptively? > > And do we have any good documentation of this concept > - self-documenting tests will be preferred? :-) > A test might have a lower priority process in some kind of loop that invokes a block via valueNoContextSwitch, or calls a method marked with . This process would be run from a higher priority process that would loop waiting for a short delay (1 microsecond?). Ocne past its delay it would preempt the lower priority process, sample its pc and fail if the pc was the first pc of valueNoContextSwitch or a method marked with . A test with two such lower priority processes could be used to test processPreemptionYields == false. If processPreemptionYields == true then every preemption would cause the two lower priority processes to switch order. If processPreemptionYields == false the second one would not run until the first one yielded explicitly, or waited, etc. Best, > > Christoph > > > [1] > http://forum.world.st/Transcript-error-when-forceUpdate-false-td5126397.html > [2] http://forum.world.st/The-Inbox-Compiler-mt-454-mcz-td5126568.html > > > -- _,,,^..^,,,_ best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: From eliot.miranda at gmail.com Mon Feb 1 18:12:23 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon, 1 Feb 2021 10:12:23 -0800 Subject: [squeak-dev] Context >> #tempNamed:(put:) In-Reply-To: <1612197634550-0.post@n4.nabble.com> References: <203cc089281c42fdbc6c76989193d952@student.hpi.uni-potsdam.de> <1612197634550-0.post@n4.nabble.com> Message-ID: Hi Christoph, I have no objection. I'd like it if Context>>tempNamed:[put:] were in *Tools-Debugger-accessing rather than accessing. But other than that it looks good to me. On Mon, Feb 1, 2021 at 8:40 AM Christoph Thiede < christoph.thiede at student.hpi.uni-potsdam.de> wrote: > Hi all, > > please forgive me for pushing this proposal again after 13 months :-) > > Three questions here for everyone to answer: > > 1. What do you think about the proposal in general? Is it worth merging it > into the Trunk? (Personally, I like to use it nearly every day ...) > 2. If you have no objections, what keeps us from merging it? :-) > 3. Naming battle: #tempNamed:[put:] vs #tempVarNamed:[put:]? > > Side note: If we get this into Trunk, we can also use it in Compiler to > produce more comprehensible #DoItIn: methods, for instance, "(ThisContext > tempNamed: 'failBlock') value" instead of "(ThisContext namedTempAt: 2) > value" - provided that sources are available. > > Best, > Christoph > > > > ----- > Carpe Squeak! > -- > Sent from: http://forum.world.st/Squeak-Dev-f45488.html > > -- _,,,^..^,,,_ best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: From leves at caesar.elte.hu Mon Feb 1 18:20:01 2021 From: leves at caesar.elte.hu (Levente Uzonyi) Date: Mon, 1 Feb 2021 19:20:01 +0100 (CET) Subject: [squeak-dev] The Trunk: Kernel-eem.1366.mcz In-Reply-To: <24f1800104c24bce9c173fb296a13f0b@student.hpi.uni-potsdam.de> References: , <24f1800104c24bce9c173fb296a13f0b@student.hpi.uni-potsdam.de> Message-ID: Hi Chritoph, On Mon, 1 Feb 2021, Thiede, Christoph wrote: > > Hi all, > > > Eliot, thank you for the speed-up! I have uploaded Kernel-ct.1369 to the inbox to fix the regression in the simulator. > > > @Levente I don't see the need for mirror primitives here; the PrimitiveFailToken is a concept internal to the simulator and iiuc mirror primitives should only be used when dealing with objects from the *simulated* code. Am I > wrong? :-) Was the bug I tried to point out not obvious? #isArray is sent to a class which will never respond with true. Levente > > > Best, > > Christoph > > _________________________________________________________________________________________________________________________________________________________________________________________________________________________________ > Von: Squeak-dev im Auftrag von Levente Uzonyi > Gesendet: Donnerstag, 28. Januar 2021 15:56:07 > An: The general-purpose Squeak developers list > Betreff: Re: [squeak-dev] The Trunk: Kernel-eem.1366.mcz   > Hi Marcel, > > On Thu, 28 Jan 2021, Marcel Taeumel wrote: > > > Hi Levente. > > > I also wonder why you used #objectClass: there instead of #class in the > > previous version. Perhaps there was a good reason. > > Maybe because of ProtoObject (and proxies)? I think the long-term plan was to not treat #class as a special send anymore so that proxies can override that interface. > > In that case there are two problems with the rewrite. > > Btw, Eliot didn't mention it in the other thread, but #class is currently > a way to avoid suspension points, just like #==, #ifNil:ifNotNil:, > #caseOf:otherwise:, ifTrue:ifFalse:, etc. > > > Levente > > > > > Best, > > Marcel > > > >       Am 28.01.2021 13:46:12 schrieb Levente Uzonyi : > > > >       Hi Eliot, > > > >       On Wed, 27 Jan 2021, commits at source.squeak.org wrote: > > > >       > Eliot Miranda uploaded a new version of Kernel to project The Trunk: > >       > http://source.squeak.org/trunk/Kernel-eem.1366.mcz > >       > > >       > ==================== Summary ==================== > >       > > >       > Name: Kernel-eem.1366 > >       > Author: eem > >       > Time: 26 January 2021, 4:27:57.204259 pm > >       > UUID: 3a706d32-c2d6-416f-82c1-bbf735650385 > >       > Ancestors: Kernel-eem.1365 > >       > > >       > Slightly faster implementation of Context>>#isPrimFailToken:. > >       > Improve the comments in Context>>#isHandlerContext/#isUnwindContext. > >       > Nuke an obsolete method. > >       > > >       > =============== Diff against Kernel-eem.1365 =============== > >       > > >       > Item was changed: > >       > ----- Method: Context>>isHandlerContext (in category 'private-exceptions') ----- > >       > isHandlerContext > >       > + "Answer if the receiver is for a method that is marked as an exception handler. > >       > + BlockClosure>>#on:do: uses this primitive to identify itself to the VM > >       > + as an exception handler method, which the VM uses in primitive 197 > >       > + Context>>#findNextHandlerContextStarting, primitiveFindHandlerContext, > >       > + to accelerate the search for exception handlers." > >       > - "is this context for method that is marked?" > >       > ^method primitive = 199! > >       > > >       > Item was changed: > >       > ----- Method: Context>>isPrimFailToken: (in category 'private') ----- > >       > isPrimFailToken: anObject > >       > + ^(self objectClass: anObject) isArray > >       > - ^(self objectClass: anObject) == Array > > > >       I think you meant to write > > > >       ^(anObject isArray > > > >       I also wonder why you used #objectClass: there instead of #class in the > >       previous version. Perhaps there was a good reason. > > > > > >       Levente > > > >       > and: [anObject size = 2 > >       > + and: [(anObject at: 1) == PrimitiveFailToken]]! > >       > - and: [anObject first == PrimitiveFailToken]]! > >       > > >       > Item was changed: > >       > ----- Method: Context>>isUnwindContext (in category 'private-exceptions') ----- > >       > isUnwindContext > >       > + "Answer if the receiver is for a method that is marked as a non-local return/exception unwind protect. > >       > + BlockClosure>>#ensure: and BlockClosure>>#ifCurtailed: use this primitive to identify > >       > + themseves to the VM as unwind protect methods. The VM uses this in primitive 195 > >       > + Context>>#findNextUnwindContextUpTo:, primitiveFindNextUnwindContext, to > >       > + accelerate the search for unwind protects." > >       > - "is this context for method that is marked?" > >       > ^method primitive = 198! > >       > > >       > Item was removed: > >       > - ----- Method: Context>>tryPrimitiveFor:receiver:args: (in category 'private') ----- > >       > - tryPrimitiveFor: method receiver: receiver args: arguments > >       > - "If this method has a primitive index, then run the primitive and return its result. > >       > - Otherwise (and also if the primitive fails) return PrimitiveFailToken, > >       > - as an indication that the method should be activated and run as bytecodes." > >       > - | primIndex | > >       > - (primIndex := method primitive) = 0 ifTrue: [^{PrimitiveFailToken. nil}]. > >       > - ^ self doPrimitive: primIndex method: method receiver: receiver args: arguments! > > > > > > > > From leves at caesar.elte.hu Mon Feb 1 18:21:17 2021 From: leves at caesar.elte.hu (Levente Uzonyi) Date: Mon, 1 Feb 2021 19:21:17 +0100 (CET) Subject: [squeak-dev] The Trunk: Kernel-eem.1366.mcz In-Reply-To: <599ee95876bc41ab8f88f348d072f72a@student.hpi.uni-potsdam.de> References: , , <24f1800104c24bce9c173fb296a13f0b@student.hpi.uni-potsdam.de> <599ee95876bc41ab8f88f348d072f72a@student.hpi.uni-potsdam.de> Message-ID: On Mon, 1 Feb 2021, Thiede, Christoph wrote: > > Btw - independently of this change - it's a shame that we still need to nest #and: blocks just because #and: is inlined but #(and:){2,} are not. We should change this someday ... or just wait for Sista to arrive. :-) Or just remove #and:{2,} and be happy with #and:. Levente > > > Best, > > Christoph > > _________________________________________________________________________________________________________________________________________________________________________________________________________________________________ > Von: Thiede, Christoph > Gesendet: Montag, 1. Februar 2021 15:45:46 > An: The general-purpose Squeak developers list > Betreff: AW: [squeak-dev] The Trunk: Kernel-eem.1366.mcz   > > Hi all, > > > Eliot, thank you for the speed-up! I have uploaded Kernel-ct.1369 to the inbox to fix the regression in the simulator. > > > @Levente I don't see the need for mirror primitives here; the PrimitiveFailToken is a concept internal to the simulator and iiuc mirror primitives should only be used when dealing with objects from the *simulated* code. Am I > wrong? :-) > > > Best, > > Christoph > > _________________________________________________________________________________________________________________________________________________________________________________________________________________________________ > Von: Squeak-dev im Auftrag von Levente Uzonyi > Gesendet: Donnerstag, 28. Januar 2021 15:56:07 > An: The general-purpose Squeak developers list > Betreff: Re: [squeak-dev] The Trunk: Kernel-eem.1366.mcz   > Hi Marcel, > > On Thu, 28 Jan 2021, Marcel Taeumel wrote: > > > Hi Levente. > > > I also wonder why you used #objectClass: there instead of #class in the > > previous version. Perhaps there was a good reason. > > Maybe because of ProtoObject (and proxies)? I think the long-term plan was to not treat #class as a special send anymore so that proxies can override that interface. > > In that case there are two problems with the rewrite. > > Btw, Eliot didn't mention it in the other thread, but #class is currently > a way to avoid suspension points, just like #==, #ifNil:ifNotNil:, > #caseOf:otherwise:, ifTrue:ifFalse:, etc. > > > Levente > > > > > Best, > > Marcel > > > >       Am 28.01.2021 13:46:12 schrieb Levente Uzonyi : > > > >       Hi Eliot, > > > >       On Wed, 27 Jan 2021, commits at source.squeak.org wrote: > > > >       > Eliot Miranda uploaded a new version of Kernel to project The Trunk: > >       > http://source.squeak.org/trunk/Kernel-eem.1366.mcz > >       > > >       > ==================== Summary ==================== > >       > > >       > Name: Kernel-eem.1366 > >       > Author: eem > >       > Time: 26 January 2021, 4:27:57.204259 pm > >       > UUID: 3a706d32-c2d6-416f-82c1-bbf735650385 > >       > Ancestors: Kernel-eem.1365 > >       > > >       > Slightly faster implementation of Context>>#isPrimFailToken:. > >       > Improve the comments in Context>>#isHandlerContext/#isUnwindContext. > >       > Nuke an obsolete method. > >       > > >       > =============== Diff against Kernel-eem.1365 =============== > >       > > >       > Item was changed: > >       > ----- Method: Context>>isHandlerContext (in category 'private-exceptions') ----- > >       > isHandlerContext > >       > + "Answer if the receiver is for a method that is marked as an exception handler. > >       > + BlockClosure>>#on:do: uses this primitive to identify itself to the VM > >       > + as an exception handler method, which the VM uses in primitive 197 > >       > + Context>>#findNextHandlerContextStarting, primitiveFindHandlerContext, > >       > + to accelerate the search for exception handlers." > >       > - "is this context for method that is marked?" > >       > ^method primitive = 199! > >       > > >       > Item was changed: > >       > ----- Method: Context>>isPrimFailToken: (in category 'private') ----- > >       > isPrimFailToken: anObject > >       > + ^(self objectClass: anObject) isArray > >       > - ^(self objectClass: anObject) == Array > > > >       I think you meant to write > > > >       ^(anObject isArray > > > >       I also wonder why you used #objectClass: there instead of #class in the > >       previous version. Perhaps there was a good reason. > > > > > >       Levente > > > >       > and: [anObject size = 2 > >       > + and: [(anObject at: 1) == PrimitiveFailToken]]! > >       > - and: [anObject first == PrimitiveFailToken]]! > >       > > >       > Item was changed: > >       > ----- Method: Context>>isUnwindContext (in category 'private-exceptions') ----- > >       > isUnwindContext > >       > + "Answer if the receiver is for a method that is marked as a non-local return/exception unwind protect. > >       > + BlockClosure>>#ensure: and BlockClosure>>#ifCurtailed: use this primitive to identify > >       > + themseves to the VM as unwind protect methods. The VM uses this in primitive 195 > >       > + Context>>#findNextUnwindContextUpTo:, primitiveFindNextUnwindContext, to > >       > + accelerate the search for unwind protects." > >       > - "is this context for method that is marked?" > >       > ^method primitive = 198! > >       > > >       > Item was removed: > >       > - ----- Method: Context>>tryPrimitiveFor:receiver:args: (in category 'private') ----- > >       > - tryPrimitiveFor: method receiver: receiver args: arguments > >       > - "If this method has a primitive index, then run the primitive and return its result. > >       > - Otherwise (and also if the primitive fails) return PrimitiveFailToken, > >       > - as an indication that the method should be activated and run as bytecodes." > >       > - | primIndex | > >       > - (primIndex := method primitive) = 0 ifTrue: [^{PrimitiveFailToken. nil}]. > >       > - ^ self doPrimitive: primIndex method: method receiver: receiver args: arguments! > > > > > > > > From leves at caesar.elte.hu Mon Feb 1 18:21:51 2021 From: leves at caesar.elte.hu (Levente Uzonyi) Date: Mon, 1 Feb 2021 19:21:51 +0100 (CET) Subject: [squeak-dev] The Trunk: Kernel-eem.1366.mcz In-Reply-To: References: , <24f1800104c24bce9c173fb296a13f0b@student.hpi.uni-potsdam.de> Message-ID: Nvm. Just saw Kernel-ct.1369. Levente On Mon, 1 Feb 2021, Levente Uzonyi wrote: > Hi Chritoph, > > On Mon, 1 Feb 2021, Thiede, Christoph wrote: > >> >> Hi all, >> >> >> Eliot, thank you for the speed-up! I have uploaded Kernel-ct.1369 to the >> inbox to fix the regression in the simulator. >> >> >> @Levente I don't see the need for mirror primitives here; the >> PrimitiveFailToken is a concept internal to the simulator and iiuc mirror >> primitives should only be used when dealing with objects from the >> *simulated* code. Am I >> wrong? :-) > > Was the bug I tried to point out not obvious? #isArray is sent to a class > which will never respond with true. > > > Levente > >> >> >> Best, >> >> Christoph >> >> _________________________________________________________________________________________________________________________________________________________________________________________________________________________________ >> Von: Squeak-dev im Auftrag >> von Levente Uzonyi >> Gesendet: Donnerstag, 28. Januar 2021 15:56:07 >> An: The general-purpose Squeak developers list >> Betreff: Re: [squeak-dev] The Trunk: Kernel-eem.1366.mcz   >> Hi Marcel, >> >> On Thu, 28 Jan 2021, Marcel Taeumel wrote: >> >> > Hi Levente. >> > > I also wonder why you used #objectClass: there instead of #class in the >> > previous version. Perhaps there was a good reason. >> > Maybe because of ProtoObject (and proxies)? I think the long-term plan >> was to not treat #class as a special send anymore so that proxies can >> override that interface. >> >> In that case there are two problems with the rewrite. >> >> Btw, Eliot didn't mention it in the other thread, but #class is currently >> a way to avoid suspension points, just like #==, #ifNil:ifNotNil:, >> #caseOf:otherwise:, ifTrue:ifFalse:, etc. >> >> >> Levente >> >> > >> > Best, >> > Marcel >> > >> >       Am 28.01.2021 13:46:12 schrieb Levente Uzonyi >> : >> > >> >       Hi Eliot, >> > >> >       On Wed, 27 Jan 2021, commits at source.squeak.org wrote: >> > >> >       > Eliot Miranda uploaded a new version of Kernel to project The >> Trunk: >> >       > http://source.squeak.org/trunk/Kernel-eem.1366.mcz >> >       > >> >       > ==================== Summary ==================== >> >       > >> >       > Name: Kernel-eem.1366 >> >       > Author: eem >> >       > Time: 26 January 2021, 4:27:57.204259 pm >> >       > UUID: 3a706d32-c2d6-416f-82c1-bbf735650385 >> >       > Ancestors: Kernel-eem.1365 >> >       > >> >       > Slightly faster implementation of Context>>#isPrimFailToken:. >> >       > Improve the comments in >> Context>>#isHandlerContext/#isUnwindContext. >> >       > Nuke an obsolete method. >> >       > >> >       > =============== Diff against Kernel-eem.1365 =============== >> >       > >> >       > Item was changed: >> >       > ----- Method: Context>>isHandlerContext (in category >> 'private-exceptions') ----- >> >       > isHandlerContext >> >       > + "Answer if the receiver is for a method that is marked as an >> exception handler. >> >       > + BlockClosure>>#on:do: uses this primitive to identify itself to >> the VM >> >       > + as an exception handler method, which the VM uses in primitive >> 197 >> >       > + Context>>#findNextHandlerContextStarting, >> primitiveFindHandlerContext, >> >       > + to accelerate the search for exception handlers." >> >       > - "is this context for method that is marked?" >> >       > ^method primitive = 199! >> >       > >> >       > Item was changed: >> >       > ----- Method: Context>>isPrimFailToken: (in category 'private') >> ----- >> >       > isPrimFailToken: anObject >> >       > + ^(self objectClass: anObject) isArray >> >       > - ^(self objectClass: anObject) == Array >> > >> >       I think you meant to write >> > >> >       ^(anObject isArray >> > >> >       I also wonder why you used #objectClass: there instead of #class in >> the >> >       previous version. Perhaps there was a good reason. >> > >> > >> >       Levente >> > >> >       > and: [anObject size = 2 >> >       > + and: [(anObject at: 1) == PrimitiveFailToken]]! >> >       > - and: [anObject first == PrimitiveFailToken]]! >> >       > >> >       > Item was changed: >> >       > ----- Method: Context>>isUnwindContext (in category >> 'private-exceptions') ----- >> >       > isUnwindContext >> >       > + "Answer if the receiver is for a method that is marked as a >> non-local return/exception unwind protect. >> >       > + BlockClosure>>#ensure: and BlockClosure>>#ifCurtailed: use this >> primitive to identify >> >       > + themseves to the VM as unwind protect methods. The VM uses this >> in primitive 195 >> >       > + Context>>#findNextUnwindContextUpTo:, >> primitiveFindNextUnwindContext, to >> >       > + accelerate the search for unwind protects." >> >       > - "is this context for method that is marked?" >> >       > ^method primitive = 198! >> >       > >> >       > Item was removed: >> >       > - ----- Method: Context>>tryPrimitiveFor:receiver:args: (in >> category 'private') ----- >> >       > - tryPrimitiveFor: method receiver: receiver args: arguments >> >       > - "If this method has a primitive index, then run the primitive >> and return its result. >> >       > - Otherwise (and also if the primitive fails) return >> PrimitiveFailToken, >> >       > - as an indication that the method should be activated and run as >> bytecodes." >> >       > - | primIndex | >> >       > - (primIndex := method primitive) = 0 ifTrue: >> [^{PrimitiveFailToken. nil}]. >> >       > - ^ self doPrimitive: primIndex method: method receiver: receiver >> args: arguments! >> > >> > >> > >> > From eric.gade at gmail.com Mon Feb 1 18:57:42 2021 From: eric.gade at gmail.com (Eric Gade) Date: Mon, 1 Feb 2021 13:57:42 -0500 Subject: [squeak-dev] Unicode Ranges you might want to copy In-Reply-To: References: Message-ID: On Mon, Feb 1, 2021 at 10:52 AM Eliot Miranda wrote: > Hi Eric, > > Do you have any code for testing this, a workspace perhaps? If so, could > you post it here? > > Eliot > _,,,^..^,,,_ (phone) > > Eliot -- I'm having a problem tracking down any of the images I had when I was playing with this last year. However, some of my issue was documented in this mailing list exchange . Note that in my examples I'm using the Assurbanipal ttf font available here . My recollection is that the cuneiform (and perhaps other ancient script) fonts use unicode points that are higher than what Squeak's font handling is able to deal with. For example, all of the cuneiform stuff is from U+12000 to U+1254F. -- Eric -------------- next part -------------- An HTML attachment was scrubbed... URL: From gettimothy at zoho.com Mon Feb 1 19:31:39 2021 From: gettimothy at zoho.com (gettimothy) Date: Mon, 01 Feb 2021 14:31:39 -0500 Subject: [squeak-dev] Unicode Ranges you might want to copy In-Reply-To: References: <1775862c6d8.10f71a9b5728.3911329244202033832@zoho.com> , <1775e008814.10ffc1dcd21434.8448180592071211373@zoho.com> Message-ID: <1775f14439b.c920989110504.5506200508099756826@zoho.com> Hi Christoph I have looked at and added the class to my project notes. I noticed the Class comment does not provide ease of use of viewing the characters in a ByteString the way that Levente  demonstrated with the key in the association: (16r002FF0 asCharacter to: 16r002FFF asCharacter) -> 'Ideographic Description Characters' Its really handy for a quick way to see if the characters display. When you write "does not yet support UTF-16 characters, I presume you mean stuff like the isUppercaseCode method: isUppercaseCode: anInteger "Answer whether anInteger is the code of an uppercase letter." ^ 8r101 <= anInteger and: [anInteger <= 8r132]. anyway, thanks for pointing out the class to me. It may come in handy. cheers. ---- On Mon, 01 Feb 2021 09:36:35 -0500 Thiede, Christoph wrote ---- Hi Timothy, do you also know Unicode class and, in particular, its class variables and its testing selectors? Not sure whether this is on the same abstraction level as your work - just wanted to add this pointer. Also note that Unicode class's character classification does not yet support UTF-16 characters - I have added this to my todo-list some disgracefully long time ago [1] and not yet managed to return back to this issue (so sorry, Levente!). Best, Christoph [1] http://forum.world.st/Unicode-td5113495.html http://www.hpi.de/ Von: Squeak-dev im Auftrag von gettimothy via Squeak-dev Gesendet: Montag, 1. Februar 2021 15:30:29 An: mailto:eric.gade at gmail.com Cc: mailto:squeak-dev at lists.squeakfoundation.org Betreff: Re: [squeak-dev] Unicode Ranges you might want to copy   Hi Eric Thanks for the heads up! Doing some lite browsing on the matter, I found these resources.... https://unicode-table.com/en/#control-character  https://css-tricks.com/almanac/properties/u/unicode-range/  http://www.alanwood.net/unicode/alphabetic_presentation_forms.html That last one  looks very useful  and I will ve working through it. The middle one claims that fonts can be loaded dynamically when needed. An intersting thing is that the alan wood site displays the $ sign under the currency range, but the jgraphix  website does not! It is also somewhat apparent that  "like" ranges are not contigous. Thanjs again for your gelp! Cheers,   ---- On Mon, 01 Feb 2021 08:57:32 -0500mailto:eric.gade at gmail.com wrote ---- Hi Timothy, I spent several (fruitless) days last year trying to get cuneiform fonts to render properly in Squeak (see https://www.hethport.uni-wuerzburg.de/cuneifont/ for examples of the fonts). There does seem to be an issue with rendering glyphs above a certain code point from what I recall. I am definitely interested in your work and what you end up finding out. On Sun, Jan 31, 2021 at 7:20 AM gettimothy via Squeak-dev wrote: Hi Folks, You might find the below handy. Fwiw, I have coded the UnicodeRangeBrowser  SeasideApp to display all the below (it times out before all display, I will be doing refactor and more development). I am also coding a utility class to provide information such as below in a variety of ways. fwiw, here are my current todo notes for this font information. unifont provide link to the unicode spec. provide browser fonts list. provide squeak fonts list. provide phare fonts list ^self squeak fonts list: what are Variant Selectors ? show gaps in the ranges. provide a link(s) to required fonts that will make a range display. displays on: browser list, squeak, emacs, xterm... status bar...broken, partial, full. use cases for fonts pairs with xyz   example superscripts and subscripts The goal is to show what works and to find/test fonts that will support stuff. I am modelling the Seaside app on https://jrgraphix.net/research/unicode_blocks.php   But...for each unicode range, I intend to display smalltalk specific helpers on what/where to get fonts for both the browser side and the image side. --------------snip ------------------- (16r000020 asCharacter to: 16r00007F asCharacter) -> 'Basic Latin' (16r0000A0 asCharacter to: 16r0000FF asCharacter) -> 'Latin-1 Supplement' (16r000100 asCharacter to: 16r00017F asCharacter) -> 'Latin Extended-A' (16r000180 asCharacter to: 16r00024F asCharacter) -> 'Latin Extended-B' (16r000250 asCharacter to: 16r0002AF asCharacter) -> 'IPA Extensions' (16r0002B0 asCharacter to: 16r0002FF asCharacter) -> 'Spacing Modifier Letters' (16r000300 asCharacter to: 16r00036F asCharacter) -> 'Combining Diacritical Marks' (16r000370 asCharacter to: 16r0003FF asCharacter) -> 'Greek and Coptic' (16r000400 asCharacter to: 16r0004FF asCharacter) -> 'Cyrillic' (16r000500 asCharacter to: 16r00052F asCharacter) -> 'Cyrillic Supplementary' (16r000530 asCharacter to: 16r00058F asCharacter) -> 'Armenian' (16r000590 asCharacter to: 16r0005FF asCharacter) -> 'Hebrew' (16r000600 asCharacter to: 16r0006FF asCharacter) -> 'Arabic' (16r000700 asCharacter to: 16r00074F asCharacter) -> 'Syriac' (16r000780 asCharacter to: 16r0007BF asCharacter) -> 'Thaana' (16r000900 asCharacter to: 16r00097F asCharacter) -> 'Devanagari' (16r000980 asCharacter to: 16r0009FF asCharacter) -> 'Bengali' (16r000A00 asCharacter to: 16r000A7F asCharacter) -> 'Gurmukhi' (16r000A80 asCharacter to: 16r000AFF asCharacter) -> 'Gujarati' (16r000B00 asCharacter to: 16r000B7F asCharacter) -> 'Oriya' (16r000B80 asCharacter to: 16r000BFF asCharacter) -> 'Tamil' (16r000C00 asCharacter to: 16r000C7F asCharacter) -> 'Telugu' (16r000C80 asCharacter to: 16r000CFF asCharacter) -> 'Kannada' (16r000D00 asCharacter to: 16r000D7F asCharacter) -> 'Malayalam' (16r000D80 asCharacter to: 16r000DFF asCharacter) -> 'Sinhala' (16r000E00 asCharacter to: 16r000E7F asCharacter) -> 'Thai' (16r000E80 asCharacter to: 16r000EFF asCharacter) -> 'Lao' (16r000F00 asCharacter to: 16r000FFF asCharacter) -> 'Tibetan' (16r001000 asCharacter to: 16r00109F asCharacter) -> 'Myanmar' (16r0010A0 asCharacter to: 16r0010FF asCharacter) -> 'Georgian' (16r001100 asCharacter to: 16r0011FF asCharacter) -> 'Hangul Jamo' (16r001200 asCharacter to: 16r00137F asCharacter) -> 'Ethiopic' (16r0013A0 asCharacter to: 16r0013FF asCharacter) -> 'Cherokee' (16r001400 asCharacter to: 16r00167F asCharacter) -> 'Unified Canadian Aboriginal Syllabics' (16r001680 asCharacter to: 16r00169F asCharacter) -> 'Ogham' (16r0016A0 asCharacter to: 16r0016FF asCharacter) -> 'Runic' (16r001700 asCharacter to: 16r00171F asCharacter) -> 'Tagalog' (16r001720 asCharacter to: 16r00173F asCharacter) -> 'Hanunoo' (16r001740 asCharacter to: 16r00175F asCharacter) -> 'Buhid' (16r001760 asCharacter to: 16r00177F asCharacter) -> 'Tagbanwa' (16r001780 asCharacter to: 16r0017FF asCharacter) -> 'Khmer' (16r001800 asCharacter to: 16r0018AF asCharacter) -> 'Mongolian' (16r001900 asCharacter to: 16r00194F asCharacter) -> 'Limbu' (16r001950 asCharacter to: 16r00197F asCharacter) -> 'Tai Le' (16r0019E0 asCharacter to: 16r0019FF asCharacter) -> 'Khmer Symbols' (16r001D00 asCharacter to: 16r001D7F asCharacter) -> 'Phonetic Extensions' (16r001E00 asCharacter to: 16r001EFF asCharacter) -> 'Latin Extended Additional' (16r001F00 asCharacter to: 16r001FFF asCharacter) -> 'Greek Extended' (16r002000 asCharacter to: 16r00206F asCharacter) -> 'General Punctuation' (16r002070 asCharacter to: 16r00209F asCharacter) -> 'Superscripts and Subscripts' (16r0020A0 asCharacter to: 16r0020CF asCharacter) -> 'Currency Symbols' (16r0020D0 asCharacter to: 16r0020FF asCharacter) -> 'Combining Diacritical Marks for Symbols' (16r002100 asCharacter to: 16r00214F asCharacter) -> 'Letterlike Symbols' (16r002150 asCharacter to: 16r00218F asCharacter) -> 'Number Forms' (16r002190 asCharacter to: 16r0021FF asCharacter) -> 'Arrows' (16r002200 asCharacter to: 16r0022FF asCharacter) -> 'Mathematical Operators' (16r002300 asCharacter to: 16r0023FF asCharacter) -> 'Miscellaneous Technical' (16r002400 asCharacter to: 16r00243F asCharacter) -> 'Control Pictures' (16r002440 asCharacter to: 16r00245F asCharacter) -> 'Optical Character Recognition' (16r002460 asCharacter to: 16r0024FF asCharacter) -> 'Enclosed Alphanumerics' (16r002500 asCharacter to: 16r00257F asCharacter) -> 'Box Drawing' (16r002580 asCharacter to: 16r00259F asCharacter) -> 'Block Elements' (16r0025A0 asCharacter to: 16r0025FF asCharacter) -> 'Geometric Shapes' (16r002600 asCharacter to: 16r0026FF asCharacter) -> 'Miscellaneous Symbols' (16r002700 asCharacter to: 16r0027BF asCharacter) -> 'Dingbats' (16r0027C0 asCharacter to: 16r0027EF asCharacter) -> 'Miscellaneous Mathematical Symbols-A' (16r0027F0 asCharacter to: 16r0027FF asCharacter) -> 'Supplemental Arrows-A' (16r002800 asCharacter to: 16r0028FF asCharacter) -> 'Braille Patterns' (16r002900 asCharacter to: 16r00297F asCharacter) -> 'Supplemental Arrows-B' (16r002980 asCharacter to: 16r0029FF asCharacter) -> 'Miscellaneous Mathematical Symbols-B' (16r002A00 asCharacter to: 16r002AFF asCharacter) -> 'Supplemental Mathematical Operators' (16r002B00 asCharacter to: 16r002BFF asCharacter) -> 'Miscellaneous Symbols and Arrows' (16r002E80 asCharacter to: 16r002EFF asCharacter) -> 'CJK Radicals Supplement' (16r002F00 asCharacter to: 16r002FDF asCharacter) -> 'Kangxi Radicals' (16r002FF0 asCharacter to: 16r002FFF asCharacter) -> 'Ideographic Description Characters' (16r003000 asCharacter to: 16r00303F asCharacter) -> 'CJK Symbols and Punctuation' (16r003040 asCharacter to: 16r00309F asCharacter) -> 'Hiragana' (16r0030A0 asCharacter to: 16r0030FF asCharacter) -> 'Katakana' (16r003100 asCharacter to: 16r00312F asCharacter) -> 'Bopomofo' (16r003130 asCharacter to: 16r00318F asCharacter) -> 'Hangul Compatibility Jamo' (16r003190 asCharacter to: 16r00319F asCharacter) -> 'Kanbun' (16r0031A0 asCharacter to: 16r0031BF asCharacter) -> 'Bopomofo Extended' (16r0031F0 asCharacter to: 16r0031FF asCharacter) -> 'Katakana Phonetic Extensions' (16r003200 asCharacter to: 16r0032FF asCharacter) -> 'Enclosed CJK Letters and Months' (16r003300 asCharacter to: 16r0033FF asCharacter) -> 'CJK Compatibility' (16r003400 asCharacter to: 16r004DBF asCharacter) -> 'CJK Unified Ideographs Extension A' (16r004DC0 asCharacter to: 16r004DFF asCharacter) -> 'Yijing Hexagram Symbols' (16r004E00 asCharacter to: 16r009FFF asCharacter) -> 'CJK Unified Ideographs' (16r00A000 asCharacter to: 16r00A48F asCharacter) -> 'Yi Syllables' (16r00A490 asCharacter to: 16r00A4CF asCharacter) -> 'Yi Radicals' (16r00AC00 asCharacter to: 16r00D7AF asCharacter) -> 'Hangul Syllables' (16r00D800 asCharacter to: 16r00DB7F asCharacter) -> 'High Surrogates' (16r00DB80 asCharacter to: 16r00DBFF asCharacter) -> 'High Private Use Surrogates' (16r00DC00 asCharacter to: 16r00DFFF asCharacter) -> 'Low Surrogates' (16r00E000 asCharacter to: 16r00F8FF asCharacter) -> 'Private Use Area' (16r00F900 asCharacter to: 16r00FAFF asCharacter) -> 'CJK Compatibility Ideographs' (16r00FB00 asCharacter to: 16r00FB4F asCharacter) -> 'Alphabetic Presentation Forms' (16r00FB50 asCharacter to: 16r00FDFF asCharacter) -> 'Arabic Presentation Forms-A' (16r00FE00 asCharacter to: 16r00FE0F asCharacter) -> 'Variation Selectors' (16r00FE20 asCharacter to: 16r00FE2F asCharacter) -> 'Combining Half Marks' (16r00FE30 asCharacter to: 16r00FE4F asCharacter) -> 'CJK Compatibility Forms' (16r00FE50 asCharacter to: 16r00FE6F asCharacter) -> 'Small Form Variants' (16r00FE70 asCharacter to: 16r00FEFF asCharacter) -> 'Arabic Presentation Forms-B' (16r00FF00 asCharacter to: 16r00FFEF asCharacter) -> 'Halfwidth and Fullwidth Forms' (16r00FFF0 asCharacter to: 16r00FFFF asCharacter) -> 'Specials' (16r010000 asCharacter to: 16r01007F asCharacter) -> 'Linear B Syllabary' (16r010080 asCharacter to: 16r0100FF asCharacter) -> 'Linear B Ideograms' (16r010100 asCharacter to: 16r01013F asCharacter) -> 'Aegean Numbers' (16r010300 asCharacter to: 16r01032F asCharacter) -> 'Old Italic' (16r010330 asCharacter to: 16r01034F asCharacter) -> 'Gothic' (16r010380 asCharacter to: 16r01039F asCharacter) -> 'Ugaritic' (16r010400 asCharacter to: 16r01044F asCharacter) -> 'Deseret' (16r010450 asCharacter to: 16r01047F asCharacter) -> 'Shavian' (16r010480 asCharacter to: 16r0104AF asCharacter) -> 'Osmanya' (16r010800 asCharacter to: 16r01083F asCharacter) -> 'Cypriot Syllabary' (16r01D000 asCharacter to: 16r01D0FF asCharacter) -> 'Byzantine Musical Symbols' (16r01D100 asCharacter to: 16r01D1FF asCharacter) -> 'Musical Symbols' (16r01D300 asCharacter to: 16r01D35F asCharacter) -> 'Tai Xuan Jing Symbols' (16r01D400 asCharacter to: 16r01D7FF asCharacter) -> 'Mathematical Alphanumeric Symbols' (16r020000 asCharacter to: 16r02A6DF asCharacter) -> 'CJK Unified Ideographs Extension B' (16r02F800 asCharacter to: 16r02FA1F asCharacter) -> 'CJK Compatibility Ideographs Supplement' (16r0E0000 asCharacter to: 16r0E007F asCharacter) -> 'Tags' -- Eric -------------- next part -------------- An HTML attachment was scrubbed... URL: From Christoph.Thiede at student.hpi.uni-potsdam.de Mon Feb 1 21:28:31 2021 From: Christoph.Thiede at student.hpi.uni-potsdam.de (Thiede, Christoph) Date: Mon, 1 Feb 2021 21:28:31 +0000 Subject: [squeak-dev] The Trunk: Kernel-eem.1366.mcz In-Reply-To: References: , <24f1800104c24bce9c173fb296a13f0b@student.hpi.uni-potsdam.de> , Message-ID: Hi Levente, > Nvm. Just saw Kernel-ct.1369. No, now I would mind indeed :-) You're totally right, the following should be debuggable: Object newSubclass compile: 'isArray self error: #hacked'; new "through" I'm sorry for the hasty judgment! Maybe it is the best idea to revert to "(self objectClass: anObject) == Array"? Best, Christoph ________________________________ Von: Squeak-dev im Auftrag von Levente Uzonyi Gesendet: Montag, 1. Februar 2021 19:21:51 An: The general-purpose Squeak developers list Betreff: Re: [squeak-dev] The Trunk: Kernel-eem.1366.mcz Nvm. Just saw Kernel-ct.1369. Levente On Mon, 1 Feb 2021, Levente Uzonyi wrote: > Hi Chritoph, > > On Mon, 1 Feb 2021, Thiede, Christoph wrote: > >> >> Hi all, >> >> >> Eliot, thank you for the speed-up! I have uploaded Kernel-ct.1369 to the >> inbox to fix the regression in the simulator. >> >> >> @Levente I don't see the need for mirror primitives here; the >> PrimitiveFailToken is a concept internal to the simulator and iiuc mirror >> primitives should only be used when dealing with objects from the >> *simulated* code. Am I >> wrong? :-) > > Was the bug I tried to point out not obvious? #isArray is sent to a class > which will never respond with true. > > > Levente > >> >> >> Best, >> >> Christoph >> >> _________________________________________________________________________________________________________________________________________________________________________________________________________________________________ >> Von: Squeak-dev im Auftrag >> von Levente Uzonyi >> Gesendet: Donnerstag, 28. Januar 2021 15:56:07 >> An: The general-purpose Squeak developers list >> Betreff: Re: [squeak-dev] The Trunk: Kernel-eem.1366.mcz >> Hi Marcel, >> >> On Thu, 28 Jan 2021, Marcel Taeumel wrote: >> >> > Hi Levente. >> > > I also wonder why you used #objectClass: there instead of #class in the >> > previous version. Perhaps there was a good reason. >> > Maybe because of ProtoObject (and proxies)? I think the long-term plan >> was to not treat #class as a special send anymore so that proxies can >> override that interface. >> >> In that case there are two problems with the rewrite. >> >> Btw, Eliot didn't mention it in the other thread, but #class is currently >> a way to avoid suspension points, just like #==, #ifNil:ifNotNil:, >> #caseOf:otherwise:, ifTrue:ifFalse:, etc. >> >> >> Levente >> >> > >> > Best, >> > Marcel >> > >> > Am 28.01.2021 13:46:12 schrieb Levente Uzonyi >> : >> > >> > Hi Eliot, >> > >> > On Wed, 27 Jan 2021, commits at source.squeak.org wrote: >> > >> > > Eliot Miranda uploaded a new version of Kernel to project The >> Trunk: >> > > http://source.squeak.org/trunk/Kernel-eem.1366.mcz >> > > >> > > ==================== Summary ==================== >> > > >> > > Name: Kernel-eem.1366 >> > > Author: eem >> > > Time: 26 January 2021, 4:27:57.204259 pm >> > > UUID: 3a706d32-c2d6-416f-82c1-bbf735650385 >> > > Ancestors: Kernel-eem.1365 >> > > >> > > Slightly faster implementation of Context>>#isPrimFailToken:. >> > > Improve the comments in >> Context>>#isHandlerContext/#isUnwindContext. >> > > Nuke an obsolete method. >> > > >> > > =============== Diff against Kernel-eem.1365 =============== >> > > >> > > Item was changed: >> > > ----- Method: Context>>isHandlerContext (in category >> 'private-exceptions') ----- >> > > isHandlerContext >> > > + "Answer if the receiver is for a method that is marked as an >> exception handler. >> > > + BlockClosure>>#on:do: uses this primitive to identify itself to >> the VM >> > > + as an exception handler method, which the VM uses in primitive >> 197 >> > > + Context>>#findNextHandlerContextStarting, >> primitiveFindHandlerContext, >> > > + to accelerate the search for exception handlers." >> > > - "is this context for method that is marked?" >> > > ^method primitive = 199! >> > > >> > > Item was changed: >> > > ----- Method: Context>>isPrimFailToken: (in category 'private') >> ----- >> > > isPrimFailToken: anObject >> > > + ^(self objectClass: anObject) isArray >> > > - ^(self objectClass: anObject) == Array >> > >> > I think you meant to write >> > >> > ^(anObject isArray >> > >> > I also wonder why you used #objectClass: there instead of #class in >> the >> > previous version. Perhaps there was a good reason. >> > >> > >> > Levente >> > >> > > and: [anObject size = 2 >> > > + and: [(anObject at: 1) == PrimitiveFailToken]]! >> > > - and: [anObject first == PrimitiveFailToken]]! >> > > >> > > Item was changed: >> > > ----- Method: Context>>isUnwindContext (in category >> 'private-exceptions') ----- >> > > isUnwindContext >> > > + "Answer if the receiver is for a method that is marked as a >> non-local return/exception unwind protect. >> > > + BlockClosure>>#ensure: and BlockClosure>>#ifCurtailed: use this >> primitive to identify >> > > + themseves to the VM as unwind protect methods. The VM uses this >> in primitive 195 >> > > + Context>>#findNextUnwindContextUpTo:, >> primitiveFindNextUnwindContext, to >> > > + accelerate the search for unwind protects." >> > > - "is this context for method that is marked?" >> > > ^method primitive = 198! >> > > >> > > Item was removed: >> > > - ----- Method: Context>>tryPrimitiveFor:receiver:args: (in >> category 'private') ----- >> > > - tryPrimitiveFor: method receiver: receiver args: arguments >> > > - "If this method has a primitive index, then run the primitive >> and return its result. >> > > - Otherwise (and also if the primitive fails) return >> PrimitiveFailToken, >> > > - as an indication that the method should be activated and run as >> bytecodes." >> > > - | primIndex | >> > > - (primIndex := method primitive) = 0 ifTrue: >> [^{PrimitiveFailToken. nil}]. >> > > - ^ self doPrimitive: primIndex method: method receiver: receiver >> args: arguments! >> > >> > >> > >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Tue Feb 2 02:57:12 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Tue, 2 Feb 2021 02:57:12 0000 Subject: [squeak-dev] The Trunk: Kernel-eem.1367.mcz Message-ID: Eliot Miranda uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-eem.1367.mcz ==================== Summary ==================== Name: Kernel-eem.1367 Author: eem Time: 1 February 2021, 6:57:09.713484 pm UUID: def9aaa1-eb71-4da5-8f86-85856d9b88ad Ancestors: Kernel-eem.1366 Fix mistake in the previous commit. Thanks Levente! =============== Diff against Kernel-eem.1366 =============== Item was changed: ----- Method: Context>>isPrimFailToken: (in category 'private') ----- + isPrimFailToken: contextOrPrimFailToken + "Answer if contextOrPrimFailToken, which will either be a Context object or + a primitive fail token (a tuple of the PrimitiveFailToken unique object and + a primitive failure code), is the latter. This should only be used with the + (possibly indirect) results of Context>>doPrimitive:method:receiver:args:" + ^contextOrPrimFailToken isArray + and: [contextOrPrimFailToken size = 2 + and: [(contextOrPrimFailToken at: 1) == PrimitiveFailToken]]! - isPrimFailToken: anObject - ^(self objectClass: anObject) isArray - and: [anObject size = 2 - and: [(anObject at: 1) == PrimitiveFailToken]]! From eliot.miranda at gmail.com Tue Feb 2 03:12:51 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon, 1 Feb 2021 19:12:51 -0800 Subject: [squeak-dev] Cannot read 4.3 image on Raspberry Pi In-Reply-To: <1612166190-df0c69a5dbe963ffccc35a9360254e77@pckswarms.ch> References: <30761BA6E24B38D160E49291@chorder> <20210118141546.GA31888@shell.msen.com> <63BB2B023E075C08EF95DA13@chorder> <1612166190-df0c69a5dbe963ffccc35a9360254e77@pckswarms.ch> Message-ID: On Sun, Jan 31, 2021 at 11:56 PM Bruce O'Neel wrote: > Good news/bad news. > > The good news is that Pulse sound driver can be solved with: > > 1. apt install libpulse-dev > 2. Make sure you say yes to clean, and rebuild. > First, thank you Bruce! Second: $ git pull $ grep -i libpulse build.linux*/HowToBuild $ *PLEASE* (pretty please wit bells on, I'm *begging you*) make sure that build instructions are added to the various HowToBuild files. One cannot expect people to be able to build the VM if we don't maintain the documents. Further, having a discussion here is fine, but one should at least cc the opensmalltalk-vm / vm-dev list. That;'s the proper venue for discussing VM builds/bugs et al. > The bad news is that while sound might "work" in the sense that sounds > will now be produced we seem to have a problem with the sounds skipping and > having pops in them. That's still being worked on.... > > cheers > > bruce > > > > > *01 February 2021 08:36 Jim Rosenberg > > wrote:* > > > On Mon, Jan 18, 2021 at 07:07:25AM -0500, I wrote: > >> Ouch! I have a lot of artistic work which is developed in Squeak on > >> Linux -- currently only up to 4.3 (which is working fine for me, so I > >> haven't upgraded). I'm trying to run one of my 4.3 images on a > >> Raspberry Pi 3B+ which is at Raspbian 10 (buster), and with the current > >> armv6 squeak VM, getting the message > >> > >> This interpreter (vers. 6521) cannot read image file (vers. 6504). > >> > >> Suggestions? > > --On Monday, January 18, 2021 09:15:46 AM -0500 "David T. Lewis" > wrote: > > > If you do not mind installing development tools on your Raspberry Pi, > then > > the best thing to do is compile the VM yourself. Instructions for doing > > this are at http://wiki.squeak.org/squeak/6354 > > > > If you have any difficulty building your VM, please ask for help. And > > if it works without problems, please report back so we know. > > It built without a hitch, and worked fine with all but one of the images I > tested it on. The image that caused me trouble uses sound. Everything else > worked fine, but the default build seemed not to support sound at all. The > only drivers were vm-sound-null and vm-sound-custom. > > I've had no luck with Linux sound on my desktop using anything other than > vm-sound-pulse -- that works fine. squeak -h didn't show vm-sound-pulse as > an available driver oh the version I built on the Raspberry Pi, so I set > out to fix that. After installing the pulse development library, configure > found it, and now I have an image on which everything just works. Thanks > for the help!! > > lit-archive 82% squeak -version > 4.19.5-3796 #1 Wed 20 Jan 2021 08:45:38 AM EST /usr/bin/cc > Linux lit-archive 5.4.83-v7+ #1379 SMP Mon Dec 14 13:08:57 GMT 2020 armv7l > GNU/Linux > plugin path: /usr/local/lib/squeak/4.19.5-3796 [default: > /usr/local/lib/squeak/4.19.5-3796/] > > * * * > > > You can find a precompiled VM for ARM v61 at http://squeakvm.org/unix/ > > which may work, although it is out of date so I am not sure if it will > > run on your Pi. > > Results here are not so happy. The display driver is marked in red on that > web page as "experimental"; on my images it mangles bitmaps in SketchMorphs > in a way that is completely unacceptable. It looks almost as though there > was some kind of attempt to do after-the-fact anti-aliasing that just went > haywire on my graphics. > > -Thanks, Jim > > > > > -- _,,,^..^,,,_ best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: From Das.Linux at gmx.de Tue Feb 2 07:11:18 2021 From: Das.Linux at gmx.de (Tobias Pape) Date: Tue, 2 Feb 2021 08:11:18 +0100 Subject: [squeak-dev] Cannot read 4.3 image on Raspberry Pi In-Reply-To: References: <30761BA6E24B38D160E49291@chorder> <20210118141546.GA31888@shell.msen.com> <63BB2B023E075C08EF95DA13@chorder> <1612166190-df0c69a5dbe963ffccc35a9360254e77@pckswarms.ch> Message-ID: > On 2. Feb 2021, at 04:12, Eliot Miranda wrote: > > > > On Sun, Jan 31, 2021 at 11:56 PM Bruce O'Neel wrote: > Good news/bad news. > > The good news is that Pulse sound driver can be solved with: > > 1. apt install libpulse-dev > 2. Make sure you say yes to clean, and rebuild. > > > First, thank you Bruce! > > Second: > > $ git pull > $ grep -i libpulse build.linux*/HowToBuild > $ > > *PLEASE* (pretty please wit bells on, I'm *begging you*) make sure that build instructions are added to the various HowToBuild files. One cannot expect people to be able to build the VM if we don't maintain the documents. If we have more than one build-instruction document, we have too many. One and only one HowTo, INSTALL or the like in the main directory must suffice. Aint nobody read more, whether we insist or not. Preferably, also only one command (or command chain) to build should exist, but that's another story I'm not opening for debate here. :) -t > Further, having a discussion here is fine, but one should at least cc the opensmalltalk-vm / vm-dev list. That;'s the proper venue for discussing VM builds/bugs et al. > > > The bad news is that while sound might "work" in the sense that sounds will now be produced we seem to have a problem with the sounds skipping and having pops in them. That's still being worked on.... > > cheers > > bruce > > > > 01 February 2021 08:36 Jim Rosenberg wrote: > > On Mon, Jan 18, 2021 at 07:07:25AM -0500, I wrote: > >> Ouch! I have a lot of artistic work which is developed in Squeak on > >> Linux -- currently only up to 4.3 (which is working fine for me, so I > >> haven't upgraded). I'm trying to run one of my 4.3 images on a > >> Raspberry Pi 3B+ which is at Raspbian 10 (buster), and with the current > >> armv6 squeak VM, getting the message > >> > >> This interpreter (vers. 6521) cannot read image file (vers. 6504). > >> > >> Suggestions? > > --On Monday, January 18, 2021 09:15:46 AM -0500 "David T. Lewis" > wrote: > > > If you do not mind installing development tools on your Raspberry Pi, then > > the best thing to do is compile the VM yourself. Instructions for doing > > this are at http://wiki.squeak.org/squeak/6354 > > > > If you have any difficulty building your VM, please ask for help. And > > if it works without problems, please report back so we know. > > It built without a hitch, and worked fine with all but one of the images I > tested it on. The image that caused me trouble uses sound. Everything else > worked fine, but the default build seemed not to support sound at all. The > only drivers were vm-sound-null and vm-sound-custom. > > I've had no luck with Linux sound on my desktop using anything other than > vm-sound-pulse -- that works fine. squeak -h didn't show vm-sound-pulse as > an available driver oh the version I built on the Raspberry Pi, so I set > out to fix that. After installing the pulse development library, configure > found it, and now I have an image on which everything just works. Thanks > for the help!! > > lit-archive 82% squeak -version > 4.19.5-3796 #1 Wed 20 Jan 2021 08:45:38 AM EST /usr/bin/cc > Linux lit-archive 5.4.83-v7+ #1379 SMP Mon Dec 14 13:08:57 GMT 2020 armv7l > GNU/Linux > plugin path: /usr/local/lib/squeak/4.19.5-3796 [default: > /usr/local/lib/squeak/4.19.5-3796/] > > * * * > > > You can find a precompiled VM for ARM v61 at http://squeakvm.org/unix/ > > which may work, although it is out of date so I am not sure if it will > > run on your Pi. > > Results here are not so happy. The display driver is marked in red on that > web page as "experimental"; on my images it mangles bitmaps in SketchMorphs > in a way that is completely unacceptable. It looks almost as though there > was some kind of attempt to do after-the-fact anti-aliasing that just went > haywire on my graphics. > > -Thanks, Jim From eliot.miranda at gmail.com Tue Feb 2 07:25:56 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon, 1 Feb 2021 23:25:56 -0800 Subject: [squeak-dev] Cannot read 4.3 image on Raspberry Pi In-Reply-To: References: Message-ID: Hi Tobias, > On Feb 1, 2021, at 11:12 PM, Tobias Pape wrote: > >  > >> On 2. Feb 2021, at 04:12, Eliot Miranda wrote: >> >> >> >>> On Sun, Jan 31, 2021 at 11:56 PM Bruce O'Neel wrote: >>> Good news/bad news. >>> >>> The good news is that Pulse sound driver can be solved with: >>> >>> 1. apt install libpulse-dev >>> 2. Make sure you say yes to clean, and rebuild. >>> >>> >>> First, thank you Bruce! >>> >>> Second: >>> >>> $ git pull >>> $ grep -i libpulse build.linux*/HowToBuild >>> $ >>> >>> *PLEASE* (pretty please wit bells on, I'm *begging you*) make sure that build instructions are added to the various HowToBuild files. One cannot expect people to be able to build the VM if we don't maintain the documents. >> >> If we have more than one build-instruction document, we have too many. I disagree. We have one build reasons per platform that we build on. Every platform is different. There is a little duplication but the structure we have now means the build documents are situated in the most relevant place. >> One and only one HowTo, INSTALL or the like in the main directory must suffice. >> Aint nobody read more, whether we insist or not. >> >> Preferably, also only one command (or command chain) to build should exist, but that's another story I'm not opening for debate here. >> >> :) >> >> -t >> >> >>> Further, having a discussion here is fine, but one should at least cc the opensmalltalk-vm / vm-dev list. That;'s the proper venue for discussing VM builds/bugs et al. >>> >>> >>> The bad news is that while sound might "work" in the sense that sounds will now be produced we seem to have a problem with the sounds skipping and having pops in them. That's still being worked on.... >>> >>> cheers >>> >>> bruce >>> >>> >>> >>> 01 February 2021 08:36 Jim Rosenberg wrote: >>> On Mon, Jan 18, 2021 at 07:07:25AM -0500, I wrote: >>>> Ouch! I have a lot of artistic work which is developed in Squeak on >>>> Linux -- currently only up to 4.3 (which is working fine for me, so I >>>> haven't upgraded). I'm trying to run one of my 4.3 images on a >>>> Raspberry Pi 3B+ which is at Raspbian 10 (buster), and with the current >>>> armv6 squeak VM, getting the message >>>> >>>> This interpreter (vers. 6521) cannot read image file (vers. 6504). >>>> >>>> Suggestions? >> >> --On Monday, January 18, 2021 09:15:46 AM -0500 "David T. Lewis" >> wrote: >> >>> If you do not mind installing development tools on your Raspberry Pi, then >>> the best thing to do is compile the VM yourself. Instructions for doing >>> this are at http://wiki.squeak.org/squeak/6354 >>> >>> If you have any difficulty building your VM, please ask for help. And >>> if it works without problems, please report back so we know. >> >> It built without a hitch, and worked fine with all but one of the images I >> tested it on. The image that caused me trouble uses sound. Everything else >> worked fine, but the default build seemed not to support sound at all. The >> only drivers were vm-sound-null and vm-sound-custom. >> >> I've had no luck with Linux sound on my desktop using anything other than >> vm-sound-pulse -- that works fine. squeak -h didn't show vm-sound-pulse as >> an available driver oh the version I built on the Raspberry Pi, so I set >> out to fix that. After installing the pulse development library, configure >> found it, and now I have an image on which everything just works. Thanks >> for the help!! >> >> lit-archive 82% squeak -version >> 4.19.5-3796 #1 Wed 20 Jan 2021 08:45:38 AM EST /usr/bin/cc >> Linux lit-archive 5.4.83-v7+ #1379 SMP Mon Dec 14 13:08:57 GMT 2020 armv7l >> GNU/Linux >> plugin path: /usr/local/lib/squeak/4.19.5-3796 [default: >> /usr/local/lib/squeak/4.19.5-3796/] >> >> * * * >> >>> You can find a precompiled VM for ARM v61 at http://squeakvm.org/unix/ >>> which may work, although it is out of date so I am not sure if it will >>> run on your Pi. >> >> Results here are not so happy. The display driver is marked in red on that >> web page as "experimental"; on my images it mangles bitmaps in SketchMorphs >> in a way that is completely unacceptable. It looks almost as though there >> was some kind of attempt to do after-the-fact anti-aliasing that just went >> haywire on my graphics. >> >> -Thanks, Jim > > > > From Das.Linux at gmx.de Tue Feb 2 09:07:02 2021 From: Das.Linux at gmx.de (Tobias Pape) Date: Tue, 2 Feb 2021 10:07:02 +0100 Subject: [squeak-dev] Cannot read 4.3 image on Raspberry Pi In-Reply-To: References: Message-ID: <8EA29804-BE23-4186-884B-4D4E5D56AB50@gmx.de> > On 2. Feb 2021, at 08:25, Eliot Miranda wrote: > > Hi Tobias, > > >> On Feb 1, 2021, at 11:12 PM, Tobias Pape wrote: >> >>  >> >>> On 2. Feb 2021, at 04:12, Eliot Miranda wrote: >>> >>> >>> >>>> On Sun, Jan 31, 2021 at 11:56 PM Bruce O'Neel wrote: >>>> Good news/bad news. >>>> >>>> The good news is that Pulse sound driver can be solved with: >>>> >>>> 1. apt install libpulse-dev >>>> 2. Make sure you say yes to clean, and rebuild. >>>> >>>> >>>> First, thank you Bruce! >>>> >>>> Second: >>>> >>>> $ git pull >>>> $ grep -i libpulse build.linux*/HowToBuild >>>> $ >>>> >>>> *PLEASE* (pretty please wit bells on, I'm *begging you*) make sure that build instructions are added to the various HowToBuild files. One cannot expect people to be able to build the VM if we don't maintain the documents. >>> >>> If we have more than one build-instruction document, we have too many. > > I disagree. We have one build reasons per platform that we build on. Every platform is different. There is a little duplication but the structure we have now means the build documents are situated in the most relevant place. While it is true what you say, no-one is going to expect this dispersion or even read these infos. You can say that this is not proper, and you might be right, but people just won't do it. Best regards -tobias :) From commits at source.squeak.org Tue Feb 2 10:05:36 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Tue, 2 Feb 2021 10:05:36 0000 Subject: [squeak-dev] The Inbox: Compiler-mt.455.mcz Message-ID: A new version of Compiler was added to project The Inbox: http://source.squeak.org/inbox/Compiler-mt.455.mcz ==================== Summary ==================== Name: Compiler-mt.455 Author: mt Time: 2 February 2021, 11:05:35.301178 am UUID: 6907e7a1-ab73-dc41-a010-e73e20a90b84 Ancestors: Compiler-mt.454 Clarify meaning by renaming to . Also extend commentary. See http://forum.world.st/Trying-to-understand-unpreemptive-execution-valueNoContextSwitch-tp5126698p5126702.html =============== Diff against Compiler-mt.454 =============== Item was added: + ----- Method: Parser>>noContextSwitchOnActivation (in category 'pragmas - code evaluation') ----- + noContextSwitchOnActivation + "By adding this pragma to a method, it will not be preempt the current process on method activation if a higher-priority process is runnable. Once the method is running, preemption is still possible. -- Any numbered primitive without side effects will do here. Also see BlockClosure >> #valueNoContextSwitch." + + + "Note that primitive 123 once was primitiveValueUninteruptibly but is no longer in use." + self addPragma: (Pragma keyword: #primitive: arguments: #(123)). + + self advance. + ^ true! From commits at source.squeak.org Tue Feb 2 10:06:33 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Tue, 2 Feb 2021 10:06:33 0000 Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz Message-ID: A new version of Compiler was added to project The Inbox: http://source.squeak.org/inbox/Compiler-mt.456.mcz ==================== Summary ==================== Name: Compiler-mt.456 Author: mt Time: 2 February 2021, 11:06:33.099178 am UUID: 0558759c-0bf7-e946-8a65-c673c49d6c8f Ancestors: Compiler-mt.455 Forgot to remove old method. Sorry for the noise. =============== Diff against Compiler-mt.455 =============== Item was removed: - ----- Method: Parser>>noContextSwitch (in category 'pragmas - code evaluation') ----- - noContextSwitch - "By adding this pragma to a method, it will not be preempt the current process on method activation if a higher-priority process is runnable. Any numbered primitive without side effects will do here." - - - "Note that primitive 123 once was primitiveValueUninteruptibly but is no longer in use." - self addPragma: (Pragma keyword: #primitive: arguments: #(123)). - - self advance. - ^ true! From marcel.taeumel at hpi.de Tue Feb 2 10:23:28 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Tue, 2 Feb 2021 11:23:28 +0100 Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz In-Reply-To: References: Message-ID: Hi all! I would like to merge into Trunk. But I still need a nice test case. Should be independent from the JIT. Maybe a simple setter? foobar: value        instVar := value ... [ test instVar should be 42 already ] forkAt: current + 1. self foobar: 42. ?? Best, Marcel Am 02.02.2021 11:06:41 schrieb commits at source.squeak.org : A new version of Compiler was added to project The Inbox: http://source.squeak.org/inbox/Compiler-mt.456.mcz ==================== Summary ==================== Name: Compiler-mt.456 Author: mt Time: 2 February 2021, 11:06:33.099178 am UUID: 0558759c-0bf7-e946-8a65-c673c49d6c8f Ancestors: Compiler-mt.455 Forgot to remove old method. Sorry for the noise. =============== Diff against Compiler-mt.455 =============== Item was removed: - ----- Method: Parser>>noContextSwitch (in category 'pragmas - code evaluation') ----- - noContextSwitch - "By adding this pragma to a method, it will not be preempt the current process on method activation if a higher-priority process is runnable. Any numbered primitive without side effects will do here." - - - "Note that primitive 123 once was primitiveValueUninteruptibly but is no longer in use." - self addPragma: (Pragma keyword: #primitive: arguments: #(123)). - - self advance. - ^ true! -------------- next part -------------- An HTML attachment was scrubbed... URL: From marcel.taeumel at hpi.de Tue Feb 2 11:23:13 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Tue, 2 Feb 2021 12:23:13 +0100 Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz In-Reply-To: References: Message-ID: Ha! Tricky. I figured that #forkAt: will immediately run the process if its priority is higher than the current one: x := 0. [ x := 1 ] forkAt: 41. y := x == 1. "true :-)" However, I have no idea why the following happens: x := 0. [ [ x := 1 ] forkAt: 41 ] valueUnpreemptively. y := x == 1. "false :-(" Or this: x := 0. [ [ x := 1 ] forkAt: 41 ] valueUnpreemptively. Transcript showln: 'foo'. y := x == 1. "false :-(" I would expect that "Transcript showln: 'foo'" entails many suspension points. The following, however, works for me: x := 0. [ [ x := 1 ] forkAt: 41 ] valueUnpreemptively. ActiveWorld imageForm asMorph. y := x == 1. "true :-)" In any case, I have not yet found a way to test . Best, Marcel Am 02.02.2021 11:23:28 schrieb Marcel Taeumel : Hi all! I would like to merge into Trunk. But I still need a nice test case. Should be independent from the JIT. Maybe a simple setter? foobar: value        instVar := value ... [ test instVar should be 42 already ] forkAt: current + 1. self foobar: 42. ?? Best, Marcel Am 02.02.2021 11:06:41 schrieb commits at source.squeak.org : A new version of Compiler was added to project The Inbox: http://source.squeak.org/inbox/Compiler-mt.456.mcz ==================== Summary ==================== Name: Compiler-mt.456 Author: mt Time: 2 February 2021, 11:06:33.099178 am UUID: 0558759c-0bf7-e946-8a65-c673c49d6c8f Ancestors: Compiler-mt.455 Forgot to remove old method. Sorry for the noise. =============== Diff against Compiler-mt.455 =============== Item was removed: - ----- Method: Parser>>noContextSwitch (in category 'pragmas - code evaluation') ----- - noContextSwitch - "By adding this pragma to a method, it will not be preempt the current process on method activation if a higher-priority process is runnable. Any numbered primitive without side effects will do here." - - - "Note that primitive 123 once was primitiveValueUninteruptibly but is no longer in use." - self addPragma: (Pragma keyword: #primitive: arguments: #(123)). - - self advance. - ^ true! -------------- next part -------------- An HTML attachment was scrubbed... URL: From marcel.taeumel at hpi.de Tue Feb 2 11:37:10 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Tue, 2 Feb 2021 12:37:10 +0100 Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz In-Reply-To: References: Message-ID: Also, taking a closer look at #valueUnpreemptively, which I now use to schedule that higher-priority process in a test: [ [ result :=  value == 10 ] forkAt: 41 ] valueUnpreemptively. self setValue. self assert: result. Here is the problem: "result" is still undefined. That means that there is no suspension point when invoking #setValue. At least not my VM. setValue    value := 10. What would be a good implementation for #setValue to benefit from ? Best, Marcel Am 02.02.2021 12:23:13 schrieb Marcel Taeumel : Ha! Tricky. I figured that #forkAt: will immediately run the process if its priority is higher than the current one: x := 0. [ x := 1 ] forkAt: 41. y := x == 1. "true :-)" However, I have no idea why the following happens: x := 0. [ [ x := 1 ] forkAt: 41 ] valueUnpreemptively. y := x == 1. "false :-(" Or this: x := 0. [ [ x := 1 ] forkAt: 41 ] valueUnpreemptively. Transcript showln: 'foo'. y := x == 1. "false :-(" I would expect that "Transcript showln: 'foo'" entails many suspension points. The following, however, works for me: x := 0. [ [ x := 1 ] forkAt: 41 ] valueUnpreemptively. ActiveWorld imageForm asMorph. y := x == 1. "true :-)" In any case, I have not yet found a way to test . Best, Marcel Am 02.02.2021 11:23:28 schrieb Marcel Taeumel : Hi all! I would like to merge into Trunk. But I still need a nice test case. Should be independent from the JIT. Maybe a simple setter? foobar: value        instVar := value ... [ test instVar should be 42 already ] forkAt: current + 1. self foobar: 42. ?? Best, Marcel Am 02.02.2021 11:06:41 schrieb commits at source.squeak.org : A new version of Compiler was added to project The Inbox: http://source.squeak.org/inbox/Compiler-mt.456.mcz ==================== Summary ==================== Name: Compiler-mt.456 Author: mt Time: 2 February 2021, 11:06:33.099178 am UUID: 0558759c-0bf7-e946-8a65-c673c49d6c8f Ancestors: Compiler-mt.455 Forgot to remove old method. Sorry for the noise. =============== Diff against Compiler-mt.455 =============== Item was removed: - ----- Method: Parser>>noContextSwitch (in category 'pragmas - code evaluation') ----- - noContextSwitch - "By adding this pragma to a method, it will not be preempt the current process on method activation if a higher-priority process is runnable. Any numbered primitive without side effects will do here." - - - "Note that primitive 123 once was primitiveValueUninteruptibly but is no longer in use." - self addPragma: (Pragma keyword: #primitive: arguments: #(123)). - - self advance. - ^ true! -------------- next part -------------- An HTML attachment was scrubbed... URL: From gettimothy at zoho.com Tue Feb 2 11:48:30 2021 From: gettimothy at zoho.com (gettimothy) Date: Tue, 02 Feb 2021 06:48:30 -0500 Subject: [squeak-dev] First iteration of the UnicodeFonts utility is up at http://menmachinesmaterials.com/UnicodeRangeBrowser Message-ID: <17762929906.afbb3beb21184.1382805740767777831@zoho.com> http://menmachinesmaterials.com/UnicodeRangeBrowser next steps are to expand the individual font range displays to show info similar to http://www.alanwood.net/unicode/fonts_unix.html  and   http://www.alanwood.net/unicode/latin_1_supplement.html prettify the navigation a bit. for each font...test... does it appear in system/xterm/emacs? does it appear in Squeak/Pharo? does it appear in chrome/brave/edge... I guess I could add some forms for others to contribute...where to store the posts? in a class variable? anyhooo.... the purpose of this is to solidify my knowledge of fonts so that I can solve problems in my XTreams-Parsing project. By doing this, I can systematically eliminate unknown variables..hopefully. Let me know if you all want this submitted to monticello repo. cheers, t -------------- next part -------------- An HTML attachment was scrubbed... URL: From gettimothy at zoho.com Tue Feb 2 11:58:23 2021 From: gettimothy at zoho.com (gettimothy) Date: Tue, 02 Feb 2021 06:58:23 -0500 Subject: [squeak-dev] Unicode Ranges you might want to copy In-Reply-To: References: <1775862c6d8.10f71a9b5728.3911329244202033832@zoho.com> Message-ID: <177629ba343.11ab1094f21293.5347102493932469950@zoho.com> Either Levente or Christoph recommended something named Unifont. I just did a search http://unifoundry.com/unifont/  and it claims to cover all glyphs in True Type. I will be messing around with this next. Hi Timothy, I spent several (fruitless) days last year trying to get cuneiform fonts to render properly in Squeak (see https://www.hethport.uni-wuerzburg.de/cuneifont/ for examples of the fonts). There does seem to be an issue with rendering glyphs above a certain code point from what I recall. I am definitely interested in your work and what you end up finding out.  If you can find a character range, we can try to get them to appear in the browser. My Seaside is coded for UTF-8 . -------------- next part -------------- An HTML attachment was scrubbed... URL: From m at jaromir.net Tue Feb 2 13:14:03 2021 From: m at jaromir.net (jaromir) Date: Tue, 2 Feb 2021 07:14:03 -0600 (CST) Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz In-Reply-To: References: Message-ID: <1612271643148-0.post@n4.nabble.com> > However, I have no idea why the following happens: > > x := 0. > [ [ x := 1 ] forkAt: 41 ] valueUnpreemptively. > y := x == 1. "false :-(" > > > Or this: > > x := 0. > [ [ x := 1 ] forkAt: 41 ] valueUnpreemptively. > Transcript showln: 'foo'. > y := x == 1. "false :-(" The reason is the #yield primitive 167 - it doesn't reflect the change of priority as done in #valueUnpreemptively... Try to remove the primitive from #yield and then it works ok Regards, Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From marcel.taeumel at hpi.de Tue Feb 2 13:22:34 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Tue, 2 Feb 2021 14:22:34 +0100 Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz In-Reply-To: <1612271643148-0.post@n4.nabble.com> References: <1612271643148-0.post@n4.nabble.com> Message-ID: >  Try to remove the primitive from #yield and then it works ok Yes, removing the primitive form #yield will introduce one (or more) suspension points because of the (rather complex) fallback implementation. Yet, I cannot do that in a test. :-) Best, Marcel Am 02.02.2021 14:14:14 schrieb jaromir : > However, I have no idea why the following happens: > > x := 0. > [ [ x := 1 ] forkAt: 41 ] valueUnpreemptively. > y := x == 1. "false :-(" > > > Or this: > > x := 0. > [ [ x := 1 ] forkAt: 41 ] valueUnpreemptively. > Transcript showln: 'foo'. > y := x == 1. "false :-(" The reason is the #yield primitive 167 - it doesn't reflect the change of priority as done in #valueUnpreemptively... Try to remove the primitive from #yield and then it works ok Regards, Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From Christoph.Thiede at student.hpi.uni-potsdam.de Tue Feb 2 13:32:54 2021 From: Christoph.Thiede at student.hpi.uni-potsdam.de (Thiede, Christoph) Date: Tue, 2 Feb 2021 13:32:54 +0000 Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz In-Reply-To: References: <1612271643148-0.post@n4.nabble.com>, Message-ID: > Yet, I cannot do that in a test. :-) Hypothetically, you could use a mock environment and subclass ProcessorScheduler. But this would get too complex for a single test ... Do we have a good framework for such mocking experiments in Squeak? :-) self mock: #Processor with: MockProcessorWithoutYield new during: [ self doYourTestLogic]. or also: self mock: Processor class >> #yield with: (Processor class >> #yield) decompile withoutPrimitiveNode generate during: [ ...]. Best, Christoph ________________________________ Von: Squeak-dev im Auftrag von Taeumel, Marcel Gesendet: Dienstag, 2. Februar 2021 14:22:34 An: squeak-dev Betreff: Re: [squeak-dev] The Inbox: Compiler-mt.456.mcz > Try to remove the primitive from #yield and then it works ok Yes, removing the primitive form #yield will introduce one (or more) suspension points because of the (rather complex) fallback implementation. Yet, I cannot do that in a test. :-) Best, Marcel Am 02.02.2021 14:14:14 schrieb jaromir : > However, I have no idea why the following happens: > > x := 0. > [ [ x := 1 ] forkAt: 41 ] valueUnpreemptively. > y := x == 1. "false :-(" > > > Or this: > > x := 0. > [ [ x := 1 ] forkAt: 41 ] valueUnpreemptively. > Transcript showln: 'foo'. > y := x == 1. "false :-(" The reason is the #yield primitive 167 - it doesn't reflect the change of priority as done in #valueUnpreemptively... Try to remove the primitive from #yield and then it works ok Regards, Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From m at jaromir.net Tue Feb 2 13:49:31 2021 From: m at jaromir.net (jaromir) Date: Tue, 2 Feb 2021 07:49:31 -0600 (CST) Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz In-Reply-To: References: <1612271643148-0.post@n4.nabble.com> Message-ID: <1612273771242-0.post@n4.nabble.com> > > Try to remove the primitive from #yield and then it works ok > > Yes, removing the primitive form #yield will introduce one (or more) > suspension points because of the (rather complex) fallback implementation. > Yet, I cannot do that in a test. :-) Now I'm confused - it looks to me either yield primitive 167 or #valueUnpreemptively behave incorrectly because your example x := 0. [ [ x := 1 ] forkAt: 41 ] valueUnpreemptively. y := x == 1. should definitely return true. In case yield primitive works as intended, #valueUnpreemptively should change (replace Processor yield line to digest the change of priority) or vice versa - or am I missing something? J. -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From marcel.taeumel at hpi.de Tue Feb 2 13:56:09 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Tue, 2 Feb 2021 14:56:09 +0100 Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz In-Reply-To: <1612273771242-0.post@n4.nabble.com> References: <1612271643148-0.post@n4.nabble.com> <1612273771242-0.post@n4.nabble.com> Message-ID: > Now I'm confused - it looks to me either yield primitive 167 or #valueUnpreemptively behave incorrectly Hmm... I think that "Processor yield" should not only schedule the next runnable process at the same priority but also serve as a "classic" suspension point and consider higher-priority processes first. Not sure whether this is "by design" or actually a bug... most of the time, you would not need "Processor yield" to also look for interrupts. There are typically enough other suspension points. Hmmmm... Best, Marcel Am 02.02.2021 14:49:41 schrieb jaromir : > > Try to remove the primitive from #yield and then it works ok > > Yes, removing the primitive form #yield will introduce one (or more) > suspension points because of the (rather complex) fallback implementation. > Yet, I cannot do that in a test. :-) Now I'm confused - it looks to me either yield primitive 167 or #valueUnpreemptively behave incorrectly because your example x := 0. [ [ x := 1 ] forkAt: 41 ] valueUnpreemptively. y := x == 1. should definitely return true. In case yield primitive works as intended, #valueUnpreemptively should change (replace Processor yield line to digest the change of priority) or vice versa - or am I missing something? J. -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From m at jaromir.net Tue Feb 2 14:18:05 2021 From: m at jaromir.net (jaromir) Date: Tue, 2 Feb 2021 08:18:05 -0600 (CST) Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz In-Reply-To: References: <1612271643148-0.post@n4.nabble.com> <1612273771242-0.post@n4.nabble.com> Message-ID: <1612275485267-0.post@n4.nabble.com> > Not sure whether this is "by design" or actually a bug... most of the time, you would not need "Processor yield" to also look for interrupts. There are typically enough other suspension points. Hmmmm... Aaah, I guess I know what you mean - looking at the valueUnpreemptively method the Processor yield was meant to let the same priority preempted processes a chance to run but here we have a higher priority process scheduled and yield doesn't look there. And when you change `activeProcess priority: oldPriority` just like this there's a higher priority process scheduled while a lower priority process running! Funny, I thought that can't happen :D valueUnpreemptively | activeProcess oldPriority result | activeProcess := Processor activeProcess. oldPriority := activeProcess priority. activeProcess priority: Processor highestPriority. result := self ensure: [activeProcess priority: oldPriority]. "Yield after restoring priority to give the preempted processes a chance to run" Processor yield. "<-- replace by: [activeProcess resume] fork. activeProcess suspend." ^result I wanted to suggest replacing the yield as above but it may be a more general issue... J -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From marcel.taeumel at hpi.de Tue Feb 2 14:56:24 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Tue, 2 Feb 2021 15:56:24 +0100 Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz In-Reply-To: <1612275485267-0.post@n4.nabble.com> References: <1612271643148-0.post@n4.nabble.com> <1612273771242-0.post@n4.nabble.com> <1612275485267-0.post@n4.nabble.com> Message-ID: >  looking at the valueUnpreemptively > method the Processor yield was meant to let the same priority preempted > processes a chance to run Not quite. If you are at 40 and get boosted up to 80, there can be preempted processes at any other priority in between. I would expect that "Processor yield" accounts for that. Other processes running at 40 do not matter because we have cooperative schedulding at each priority. Best, Marcel Am 02.02.2021 15:18:15 schrieb jaromir : > Not sure whether this is "by design" or actually a bug... most of the time, you would not need "Processor yield" to also look for interrupts. There are typically enough other suspension points. Hmmmm... Aaah, I guess I know what you mean - looking at the valueUnpreemptively method the Processor yield was meant to let the same priority preempted processes a chance to run but here we have a higher priority process scheduled and yield doesn't look there. And when you change `activeProcess priority: oldPriority` just like this there's a higher priority process scheduled while a lower priority process running! Funny, I thought that can't happen :D valueUnpreemptively | activeProcess oldPriority result | activeProcess := Processor activeProcess. oldPriority := activeProcess priority. activeProcess priority: Processor highestPriority. result := self ensure: [activeProcess priority: oldPriority]. "Yield after restoring priority to give the preempted processes a chance to run" Processor yield. "<-- replace by: [activeProcess resume] fork. activeProcess suspend." ^result I wanted to suggest replacing the yield as above but it may be a more general issue... J -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From bruce.oneel at pckswarms.ch Tue Feb 2 16:23:34 2021 From: bruce.oneel at pckswarms.ch (Bruce O'Neel) Date: Tue, 02 Feb 2021 17:23:34 +0100 Subject: [squeak-dev] Cannot read 4.3 image on Raspberry Pi In-Reply-To: <1612166190-df0c69a5dbe963ffccc35a9360254e77@pckswarms.ch> References: <1612166190-df0c69a5dbe963ffccc35a9360254e77@pckswarms.ch> <63BB2B023E075C08EF95DA13@chorder> <30761BA6E24B38D160E49291@chorder> <20210118141546.GA31888@shell.msen.com> Message-ID: <1612283014-2df63a3918ef89f6ead13eead9057e01@pckswarms.ch> There are 3 axes at least here for linux 1. CPU (includes 32/64 bit) 2. OS 3. Distribution All three have to line up for someone to go from a git checkout to a build on an ARM or x86 linux version.  So my little hint works correctly on RaspberryPI OS and most other Debian based systems.  And not on others. Maybe we should separate out the build instructions into two files? The current build instructions file which references a pre-requisites file or files.  I don't like the additional complexity, but, I'd really like the files to be short.  I have found over the years that line 25 is the first line not read in the README.  For the few that will read the files you have to get all the important info in the first few lines of any instructions. -------------- next part -------------- An HTML attachment was scrubbed... URL: From m at jaromir.net Tue Feb 2 16:55:36 2021 From: m at jaromir.net (jaromir) Date: Tue, 2 Feb 2021 10:55:36 -0600 (CST) Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz In-Reply-To: References: <1612271643148-0.post@n4.nabble.com> <1612273771242-0.post@n4.nabble.com> <1612275485267-0.post@n4.nabble.com> Message-ID: <1612284936858-0.post@n4.nabble.com> > If you are at 40 and get boosted up to 80, there can be preempted processes at any other priority in between. I would expect that "Processor yield" accounts for that. Well, in that case #yield probably doesn't do that considering #yield's comment: "Give other Processes at the *current priority* a chance to run." J -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From Christoph.Thiede at student.hpi.uni-potsdam.de Tue Feb 2 17:36:08 2021 From: Christoph.Thiede at student.hpi.uni-potsdam.de (Thiede, Christoph) Date: Tue, 2 Feb 2021 17:36:08 +0000 Subject: [squeak-dev] Cannot read 4.3 image on Raspberry Pi In-Reply-To: <1612283014-2df63a3918ef89f6ead13eead9057e01@pckswarms.ch> References: <1612166190-df0c69a5dbe963ffccc35a9360254e77@pckswarms.ch> <63BB2B023E075C08EF95DA13@chorder> <30761BA6E24B38D160E49291@chorder> <20210118141546.GA31888@shell.msen.com>, <1612283014-2df63a3918ef89f6ead13eead9057e01@pckswarms.ch> Message-ID: <94b900b1ed89476aa043bbbd5a424889@student.hpi.uni-potsdam.de> My two cents on this debate: I think it has already proven in the past that self-explaining code is more efficient for the purpose of documentation than a long manual which (almost) no one is willing to read, especially, this fact has been proven in Smalltalk. Unlike plain English, code is not a redundant structure that can become obsolete, code can be tested automatically, code can be reused, and when decorated with a proper amount of explaining comments, code can also be easier to read than a long wall of text. In the era of IaC, we should apply the same pattern for the documentation of compile & build processes. This was also my motivation for https://github.com/LinqLover/squeak-raspi-docker. It could be a Dockerfile, a Vagrantfile, or maybe also a simple bash file - the main thing is to write something that can be automated in a CI. And when there are 2 times x times y build scripts, one could talk about refactoring these scripts in the same way we refactor Morphic code or Collections logic or whatever else. I could imagine this could be much more fun than asking developers to write walls of "unstructured data", i.e. text. :-) Best, Christoph ________________________________ Von: Squeak-dev im Auftrag von Bruce O'Neel Gesendet: Dienstag, 2. Februar 2021 17:23:34 An: bruce.oneel at pckswarms.ch; The general-purpose Squeak developers list Betreff: Re: [squeak-dev] Cannot read 4.3 image on Raspberry Pi There are 3 axes at least here for linux 1. CPU (includes 32/64 bit) 2. OS 3. Distribution All three have to line up for someone to go from a git checkout to a build on an ARM or x86 linux version. So my little hint works correctly on RaspberryPI OS and most other Debian based systems. And not on others. Maybe we should separate out the build instructions into two files? The current build instructions file which references a pre-requisites file or files. I don't like the additional complexity, but, I'd really like the files to be short. I have found over the years that line 25 is the first line not read in the README. For the few that will read the files you have to get all the important info in the first few lines of any instructions. 01 February 2021 08:56 "Bruce O'Neel" wrote: Good news/bad news. The good news is that Pulse sound driver can be solved with: 1. apt install libpulse-dev 2. Make sure you say yes to clean, and rebuild. The bad news is that while sound might "work" in the sense that sounds will now be produced we seem to have a problem with the sounds skipping and having pops in them. That's still being worked on.... cheers bruce 01 February 2021 08:36 Jim Rosenberg wrote: > On Mon, Jan 18, 2021 at 07:07:25AM -0500, I wrote: >> Ouch! I have a lot of artistic work which is developed in Squeak on >> Linux -- currently only up to 4.3 (which is working fine for me, so I >> haven't upgraded). I'm trying to run one of my 4.3 images on a >> Raspberry Pi 3B+ which is at Raspbian 10 (buster), and with the current >> armv6 squeak VM, getting the message >> >> This interpreter (vers. 6521) cannot read image file (vers. 6504). >> >> Suggestions? --On Monday, January 18, 2021 09:15:46 AM -0500 "David T. Lewis" wrote: > If you do not mind installing development tools on your Raspberry Pi, then > the best thing to do is compile the VM yourself. Instructions for doing > this are at http://wiki.squeak.org/squeak/6354 > > If you have any difficulty building your VM, please ask for help. And > if it works without problems, please report back so we know. It built without a hitch, and worked fine with all but one of the images I tested it on. The image that caused me trouble uses sound. Everything else worked fine, but the default build seemed not to support sound at all. The only drivers were vm-sound-null and vm-sound-custom. I've had no luck with Linux sound on my desktop using anything other than vm-sound-pulse -- that works fine. squeak -h didn't show vm-sound-pulse as an available driver oh the version I built on the Raspberry Pi, so I set out to fix that. After installing the pulse development library, configure found it, and now I have an image on which everything just works. Thanks for the help!! lit-archive 82% squeak -version 4.19.5-3796 #1 Wed 20 Jan 2021 08:45:38 AM EST /usr/bin/cc Linux lit-archive 5.4.83-v7+ #1379 SMP Mon Dec 14 13:08:57 GMT 2020 armv7l GNU/Linux plugin path: /usr/local/lib/squeak/4.19.5-3796 [default: /usr/local/lib/squeak/4.19.5-3796/] * * * > You can find a precompiled VM for ARM v61 at http://squeakvm.org/unix/ > which may work, although it is out of date so I am not sure if it will > run on your Pi. Results here are not so happy. The display driver is marked in red on that web page as "experimental"; on my images it mangles bitmaps in SketchMorphs in a way that is completely unacceptable. It looks almost as though there was some kind of attempt to do after-the-fact anti-aliasing that just went haywire on my graphics. -Thanks, Jim <> -------------- next part -------------- An HTML attachment was scrubbed... URL: From tim at rowledge.org Tue Feb 2 18:22:40 2021 From: tim at rowledge.org (tim Rowledge) Date: Tue, 2 Feb 2021 10:22:40 -0800 Subject: [squeak-dev] Cannot read 4.3 image on Raspberry Pi In-Reply-To: <8EA29804-BE23-4186-884B-4D4E5D56AB50@gmx.de> References: <8EA29804-BE23-4186-884B-4D4E5D56AB50@gmx.de> Message-ID: <4736437D-2366-4AD5-92CA-2C6B3ED082B3@rowledge.org> > On 2021-02-02, at 1:07 AM, Tobias Pape wrote: > > > While it is true what you say, no-one is going to expect this dispersion or even read these infos. > You can say that this is not proper, and you might be right, but people just won't do it. So the solution is to link them together in some manner, surely? We do really need the different details for the various types of vm & platforms. Would it be plausible to use Markdown format to link sections, or build a bundled doc? tim -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim Useful random insult:- Understands English as well as any parrot. From gettimothy at zoho.com Tue Feb 2 19:19:49 2021 From: gettimothy at zoho.com (gettimothy) Date: Tue, 02 Feb 2021 14:19:49 -0500 Subject: [squeak-dev] Morphic team, nice improvement during installer runs. The progress bar stays in top right... Message-ID: <177642fc86e.114e3871628639.4614723699233167822@zoho.com> Thanks all. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gettimothy at zoho.com Tue Feb 2 19:37:20 2021 From: gettimothy at zoho.com (gettimothy) Date: Tue, 02 Feb 2021 14:37:20 -0500 Subject: [squeak-dev] font dependent error message? More than 256 literals referenced. Message-ID: <177643fd364.1235f59d828867.4146533430626311588@zoho.com> Hi Folks "More than 256 literals referenced. You must split or otherwise simplify this method. The 257th literal is: 13055 ->"x Its funny, in one image, I have the method and all works fine. I spun up another image for Fonts work, installed the unifont and tried to us monticello to load the package and I get that message. The only difference I see is the installed/selected fonts. Is this assumption of mine true? -------------- next part -------------- An HTML attachment was scrubbed... URL: From gettimothy at zoho.com Tue Feb 2 19:49:06 2021 From: gettimothy at zoho.com (gettimothy) Date: Tue, 02 Feb 2021 14:49:06 -0500 Subject: [squeak-dev] With Unifont Russia Alphabet Comes to You! (or...some success with the font work) In-Reply-To: References: <1775862c6d8.10f71a9b5728.3911329244202033832@zoho.com> Message-ID: <177644a99fa.d996615429027.3350766649453911285@zoho.com> Hi folks. I am looking at the wide string for (16r000400  asCharacter to:  16r0004FF asCharacter)  and I can see Russian from my house! Very happy about this. Here is the process linux       download ttf font  example: http://unifoundry.com/unifont/       Copy your font files (.ttf and/or .otf) to their respective directories:       /usr/share/fonts/TTF       /usr/share/fonts/OTF       Run the following commands, with the directory where you copied the fonts as argument:       mkfontdir /usr/share/fonts/{TTF,OTF}       mkfontscale /usr/share/fonts/{TTF,OTF}       fc-cache -f -v  (i do this as root and as my normal user account)       Restart X.        in Squeak Apps -> Font Importer  (import the fonts into the image) World menu -> Appearance -> System Fonts  (blindly select one of the fonts you installed to see what sticks) Unfortunately, my mail client (see! now I know what to blame, yesterday, I had no clue) does not support cyrillic. My local instance of the UnicodeRangeBrowser displays the cyrillic in the browser and my workspace displays it. very good news! Ok...for UnicodeRangeBrowser...I need to expand it to keep tabs on what sticks. This means I have to create forms and such so others can add information if they wish. Then, for every Unicode Font Range, give instructions/fonts/steps to get things consistent from image to browser. Then...tests.... It MIGHT make sense to create UnicodeFontRange specific in-image tests.  i.e. loop through the characters and verify the integer = the displayed character. Maybe throw in some should: reason: 'font xyz not installed?" stuff. anyhoo, it feels good not to be flailing around. cheers. -------------- next part -------------- An HTML attachment was scrubbed... URL: From m at jaromir.net Tue Feb 2 21:59:21 2021 From: m at jaromir.net (Jaromir) Date: Tue, 2 Feb 2021 15:59:21 -0600 (CST) Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz In-Reply-To: <1612284936858-0.post@n4.nabble.com> References: <1612271643148-0.post@n4.nabble.com> <1612273771242-0.post@n4.nabble.com> <1612275485267-0.post@n4.nabble.com> <1612284936858-0.post@n4.nabble.com> Message-ID: <1612303161922-0.post@n4.nabble.com> Actually, I'd place the problem in Process>>#priority: method - it should make sure that if the active process downgrades it's priority below an existing runnable process, the active process will automatically be preempted - something like this (works for your examples): Process>>priority: anInteger "Set the receiver's priority to anInteger." (anInteger >= Processor lowestPriority and:[anInteger <= Processor highestPriority]) ifTrue: [ priority := anInteger. (self isActiveProcess and: [anInteger < Processor nextReadyProcess priority]) ifTrue: [ [self resume] fork. self suspend ] ] ifFalse: [self error: 'Invalid priority: ', anInteger printString] And then the #yield primitive can remain as it is :) J -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From m at jaromir.net Tue Feb 2 22:13:18 2021 From: m at jaromir.net (Jaromir) Date: Tue, 2 Feb 2021 16:13:18 -0600 (CST) Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz In-Reply-To: <1612303161922-0.post@n4.nabble.com> References: <1612271643148-0.post@n4.nabble.com> <1612273771242-0.post@n4.nabble.com> <1612275485267-0.post@n4.nabble.com> <1612284936858-0.post@n4.nabble.com> <1612303161922-0.post@n4.nabble.com> Message-ID: <1612303998037-0.post@n4.nabble.com> If you modify #priority behavior as per my previous message the #valueUnpreemptively can be simplified: valueUnpreemptively | activeProcess oldPriority | activeProcess := Processor activeProcess. oldPriority := activeProcess priority. activeProcess priority: Processor highestPriority. ^self ensure: [activeProcess priority: oldPriority]. -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From asqueaker at gmail.com Tue Feb 2 22:41:23 2021 From: asqueaker at gmail.com (Chris Muller) Date: Tue, 2 Feb 2021 16:41:23 -0600 Subject: [squeak-dev] Transcript losing output when #processPreemptionYields = true In-Reply-To: <1612160161284-0.post@n4.nabble.com> References: <1612114094246-0.post@n4.nabble.com> <1612116683800-0.post@n4.nabble.com> <0C26F716-F092-42C4-BE09-5D66690C0867@gmail.com> <1612160161284-0.post@n4.nabble.com> Message-ID: Hi Jaromir, I knew that I had some old code which dealt with this, which I looked up and found this comment I wrote years ago: _____ "In Feb, 2016, Eliot changed process scheduling from longest suspended process getting priority, to the prior process which was running when it was pre-empted by a higher-priority process. This means that rudimentary concurrency control can be implemented without Semaphores, but just by yielding at an appropriate time. The following sets it back to longest-waiting getting next run-priority." Smalltalk processPreemptionYields: true. _____ I prefer the legacy Smalltalk behavior, i.e., set to true, because you get concurrency across processes at equal priority, but I am looking forward to expert clarification on whether I'm running a "broken policy". I'm hoping Eliot only meant that in some specific usage context. If so, I'm not sure why we would've chosen to make the non-backward-compatible behavior the default. - Chris On Mon, Feb 1, 2021 at 12:16 AM jaromir wrote: > > processPreemptionYields = true is a clearly broken policy (as your > transcript bugs show) and is only supported for backwards compatibility. > > Thanks! May I ask why processPreemptionYields = true should be a broken > policy? The Transcript is broken, can be fixed and the bug disappears. I'd > say one's code should better be independent of the processPreemptionYields > setting anyway. Assuming the order of processes is always guaranteed by > processPreemptionYields = false may lead e.g. to using Processor yield > rather than semaphores to synchronize processes etc. (I try to test my code > against both settings to make sure it works) > > Thanks again, > Jaromir > > > > -- > Sent from: http://forum.world.st/Squeak-Dev-f45488.html > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lewis at mail.msen.com Tue Feb 2 22:47:07 2021 From: lewis at mail.msen.com (David T. Lewis) Date: Tue, 2 Feb 2021 17:47:07 -0500 Subject: [squeak-dev] font dependent error message? More than 256 literals referenced. In-Reply-To: <177643fd364.1235f59d828867.4146533430626311588@zoho.com> References: <177643fd364.1235f59d828867.4146533430626311588@zoho.com> Message-ID: <20210202224707.GA95307@shell.msen.com> On Tue, Feb 02, 2021 at 02:37:20PM -0500, gettimothy via Squeak-dev wrote: > Hi Folks > > "More than 256 literals referenced. > > You must split or otherwise simplify this method. > > The 257th literal is: 13055 ->"x > > > > Its funny, in one image, I have the method and all works fine. > > > > I spun up another image for Fonts work, installed the unifont and tried to us monticello to load the package and I get that message. > > > > The only difference I see is the installed/selected fonts. > > > > Is this assumption of mine true? > Try evaluating "CompiledCode useSista: true" in the image that is giving you problems. Afterwards your method will compile without error. The error that you are seeing is the result of a limitation of the traditional bytecode set used in Squeak. Eliot et al have provided the new Sista bytecode set that has a number of advantages, including this one. Squeak trunk has been using the Sista bytecode set for quite a while, but due to some glitches in the trunk update stream there are probably a few images (maybe including yours) that accidentally are using the other bytecode set. I think this will take care of your problem, but note that if you are writing something that needs to run on older images, you may want to reorganize your method so that it does not hit the old limit for literals. Dave From m at jaromir.net Tue Feb 2 23:21:23 2021 From: m at jaromir.net (Jaromir) Date: Tue, 2 Feb 2021 17:21:23 -0600 (CST) Subject: [squeak-dev] Transcript losing output when #processPreemptionYields = true In-Reply-To: References: <1612114094246-0.post@n4.nabble.com> <1612116683800-0.post@n4.nabble.com> <0C26F716-F092-42C4-BE09-5D66690C0867@gmail.com> <1612160161284-0.post@n4.nabble.com> Message-ID: <1612308083516-0.post@n4.nabble.com> Hi Chris, I've been trying to understand this dilemma and I too slightly incline towards 'true' - meaning the same priority processes do round robin when preempted. It makes the following example behave very 'naturally' – it lets a quicker process finish before a slower (independent) one: [ 50000 factorial. 'long computation finished' crTrace ] fork. [ 1+1. 'short computation finished' crTrace ] fork. 'test started' crTrace Output: test started short computation finished long computation finished However, people say Smalltalk is collaborative within priorities which wouldn't allow the above behavior. I personally would like to consider both ways equally 'correct' and stop labelling based on preemtive behavior. I even checked some other dialects and the vote looks like this: Squeak, VisualWorks = false Pharo, VisualAge = true I understand there may be technical problems due to complexity but the aim should be in my opinion to have it both ways. Thanks, Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From asqueaker at gmail.com Tue Feb 2 23:21:44 2021 From: asqueaker at gmail.com (Chris Muller) Date: Tue, 2 Feb 2021 17:21:44 -0600 Subject: [squeak-dev] Cannot read 4.3 image on Raspberry Pi In-Reply-To: <4736437D-2366-4AD5-92CA-2C6B3ED082B3@rowledge.org> References: <8EA29804-BE23-4186-884B-4D4E5D56AB50@gmx.de> <4736437D-2366-4AD5-92CA-2C6B3ED082B3@rowledge.org> Message-ID: It was only after 20 years of using Squeak that I was ever able to successfully build my first VM ever, just the other day, and only because the platform-specific instructions were good enough that even I was able to figure out the missing libraries myself. Whatever is being discussed here about the HowToBuild's, I hope it is not about taking it back to some "generic" instructions that require expert C++ development knowledge to be able to figure out. That's probably where the idea that "no one reads it" came from because, sure, if it targets a "members only" C++ experts audience that doesn't need documentation, it won't get read. Likewise, when non-experts (e.g., me) spend valuable time trying, but failing, to build, it also won't get read again for a long time, because it's safer to just keep scraping up pre-built binaries wherever they can find them, rather than risk wasting more time failing to build. Being able to build makes Squeak more valuable. Whatever the solution, I hope this usability will not regress. - Chris On Tue, Feb 2, 2021 at 12:22 PM tim Rowledge wrote: > > > > On 2021-02-02, at 1:07 AM, Tobias Pape wrote: > > > > > > While it is true what you say, no-one is going to expect this dispersion > or even read these infos. > > You can say that this is not proper, and you might be right, but people > just won't do it. > > So the solution is to link them together in some manner, surely? We do > really need the different details for the various types of vm & platforms. > > Would it be plausible to use Markdown format to link sections, or build a > bundled doc? > > tim > -- > tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim > Useful random insult:- Understands English as well as any parrot. > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From m at jaromir.net Wed Feb 3 11:54:54 2021 From: m at jaromir.net (Jaromir) Date: Wed, 3 Feb 2021 05:54:54 -0600 (CST) Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz In-Reply-To: <1612303998037-0.post@n4.nabble.com> References: <1612271643148-0.post@n4.nabble.com> <1612273771242-0.post@n4.nabble.com> <1612275485267-0.post@n4.nabble.com> <1612284936858-0.post@n4.nabble.com> <1612303161922-0.post@n4.nabble.com> <1612303998037-0.post@n4.nabble.com> Message-ID: <1612353294137-0.post@n4.nabble.com> Hi Marcel, same problem here: x := 0. [ [ x := 1 ] forkAt: 41 ] valueAt: 42. y := x == 1. "false :-(" And the same solution: fix Process>>priority: and simplify #valueAt: method. Regards, Jaromir BlockClosure>>valueAt: blockPriority "Evaluate the receiver (block), with another priority as the actual one and restore it afterwards. The caller should be careful with using higher priorities." | activeProcess result outsidePriority | activeProcess := Processor activeProcess. outsidePriority := activeProcess priority. activeProcess priority: blockPriority. result := self ensure: [activeProcess priority: outsidePriority]. * "Yield after restoring lower priority to give the preempted processes a chance to run." blockPriority > outsidePriority ifTrue: [Processor yield].* / "this part doesn't work and can be removed"/ ^ result -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From eliot.miranda at gmail.com Wed Feb 3 16:41:31 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed, 3 Feb 2021 08:41:31 -0800 Subject: [squeak-dev] Cannot read 4.3 image on Raspberry Pi In-Reply-To: <8EA29804-BE23-4186-884B-4D4E5D56AB50@gmx.de> References: <8EA29804-BE23-4186-884B-4D4E5D56AB50@gmx.de> Message-ID: <89F49C96-4D1E-45DD-A7B7-05155A7B13DD@gmail.com> Tobias, > On Feb 2, 2021, at 1:07 AM, Tobias Pape wrote: > >  > >> On 2. Feb 2021, at 08:25, Eliot Miranda wrote: >> >> Hi Tobias, >> >> >>>> On Feb 1, 2021, at 11:12 PM, Tobias Pape wrote: >>> >>>  >>> >>>> On 2. Feb 2021, at 04:12, Eliot Miranda wrote: >>>> >>>> >>>> >>>>> On Sun, Jan 31, 2021 at 11:56 PM Bruce O'Neel wrote: >>>>> Good news/bad news. >>>>> >>>>> The good news is that Pulse sound driver can be solved with: >>>>> >>>>> 1. apt install libpulse-dev >>>>> 2. Make sure you say yes to clean, and rebuild. >>>>> >>>>> >>>>> First, thank you Bruce! >>>>> >>>>> Second: >>>>> >>>>> $ git pull >>>>> $ grep -i libpulse build.linux*/HowToBuild >>>>> $ >>>>> >>>>> *PLEASE* (pretty please wit bells on, I'm *begging you*) make sure that build instructions are added to the various HowToBuild files. One cannot expect people to be able to build the VM if we don't maintain the documents. >>>> >>>> If we have more than one build-instruction document, we have too many. >> >> I disagree. We have one build reasons per platform that we build on. Every platform is different. There is a little duplication but the structure we have now means the build documents are situated in the most relevant place. > > While it is true what you say, no-one is going to expect this dispersion or even read these infos. > You can say that this is not proper, and you might be right, but people just won't do it. This is your projection. You do not know that this is the case. And it won’t be true of all people. Instead of being negative, encouraging others to do the right thing might improve things. > > Best regards > -tobias :) _,,,^..^,,,_ (phone) From eliot.miranda at gmail.com Wed Feb 3 16:50:15 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed, 3 Feb 2021 08:50:15 -0800 Subject: [squeak-dev] Cannot read 4.3 image on Raspberry Pi In-Reply-To: <1612283014-2df63a3918ef89f6ead13eead9057e01@pckswarms.ch> References: <1612283014-2df63a3918ef89f6ead13eead9057e01@pckswarms.ch> Message-ID: <98194934-9E21-4461-971C-81BC59AD4D42@gmail.com> Hi Bruce, > On Feb 2, 2021, at 8:24 AM, Bruce O'Neel wrote: > >  > > There are 3 axes at least here for linux > > 1. CPU (includes 32/64 bit) > 2. OS > 3. Distribution > > All three have to line up for someone to go from a git checkout to a build on an ARM or x86 linux version. So my little hint works correctly on RaspberryPI OS and most other Debian based systems. And not on others. > > Maybe we should separate out the build instructions into two files? > > The current build instructions file which references a pre-requisites file or files. > > I don't like the additional complexity, but, I'd really like the files to be short. I have found over the years that line 25 is the first line not read in the README. For the few that will read the files you have to get all the important info in the first few lines of any instructions. As Chris Muller’s message proves, the HowToBuild files are a viral resource. I agree that few will read something which isn’t useful. But the utility of the HowToBuild files is increased if we put the effort into maintaining them. Further, if they are useful we can draw more attention to them, and suggest strongly to people that they read beyond line 25. The alternative is having people trawl the web, email lists, etc for information that will inevitably be incoherent. Hence the alternative is having people fail to build the vm. And in the long term that will not contribute the the health and growth of the community. > 01 February 2021 08:56 "Bruce O'Neel" wrote: > Good news/bad news. > > The good news is that Pulse sound driver can be solved with: > > 1. apt install libpulse-dev > 2. Make sure you say yes to clean, and rebuild. > > The bad news is that while sound might "work" in the sense that sounds will now be produced we seem to have a problem with the sounds skipping and having pops in them. That's still being worked on.... > > cheers > > bruce > > > > 01 February 2021 08:36 Jim Rosenberg wrote: > > On Mon, Jan 18, 2021 at 07:07:25AM -0500, I wrote: > >> Ouch! I have a lot of artistic work which is developed in Squeak on > >> Linux -- currently only up to 4.3 (which is working fine for me, so I > >> haven't upgraded). I'm trying to run one of my 4.3 images on a > >> Raspberry Pi 3B+ which is at Raspbian 10 (buster), and with the current > >> armv6 squeak VM, getting the message > >> > >> This interpreter (vers. 6521) cannot read image file (vers. 6504). > >> > >> Suggestions? > > --On Monday, January 18, 2021 09:15:46 AM -0500 "David T. Lewis" > wrote: > > > If you do not mind installing development tools on your Raspberry Pi, then > > the best thing to do is compile the VM yourself. Instructions for doing > > this are at http://wiki.squeak.org/squeak/6354 > > > > If you have any difficulty building your VM, please ask for help. And > > if it works without problems, please report back so we know. > > It built without a hitch, and worked fine with all but one of the images I > tested it on. The image that caused me trouble uses sound. Everything else > worked fine, but the default build seemed not to support sound at all. The > only drivers were vm-sound-null and vm-sound-custom. > > I've had no luck with Linux sound on my desktop using anything other than > vm-sound-pulse -- that works fine. squeak -h didn't show vm-sound-pulse as > an available driver oh the version I built on the Raspberry Pi, so I set > out to fix that. After installing the pulse development library, configure > found it, and now I have an image on which everything just works. Thanks > for the help!! > > lit-archive 82% squeak -version > 4.19.5-3796 #1 Wed 20 Jan 2021 08:45:38 AM EST /usr/bin/cc > Linux lit-archive 5.4.83-v7+ #1379 SMP Mon Dec 14 13:08:57 GMT 2020 armv7l > GNU/Linux > plugin path: /usr/local/lib/squeak/4.19.5-3796 [default: > /usr/local/lib/squeak/4.19.5-3796/] > > * * * > > > You can find a precompiled VM for ARM v61 at http://squeakvm.org/unix/ > > which may work, although it is out of date so I am not sure if it will > > run on your Pi. > > Results here are not so happy. The display driver is marked in red on that > web page as "experimental"; on my images it mangles bitmaps in SketchMorphs > in a way that is completely unacceptable. It looks almost as though there > was some kind of attempt to do after-the-fact anti-aliasing that just went > haywire on my graphics. > > -Thanks, Jim > > > > <> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From gettimothy at zoho.com Wed Feb 3 19:33:21 2021 From: gettimothy at zoho.com (gettimothy) Date: Wed, 03 Feb 2021 14:33:21 -0500 Subject: [squeak-dev] font dependent error message? More than 256 literals referenced. In-Reply-To: <20210202224707.GA95307@shell.msen.com> References: <177643fd364.1235f59d828867.4146533430626311588@zoho.com> <20210202224707.GA95307@shell.msen.com> Message-ID: <17769628b2e.125c8842810513.7184263385940400563@zoho.com> Hi Dave. Try evaluating "CompiledCode useSista: true" in the image that is giving you problems. Afterwards your method will compile without error. The error that you are seeing is the result of a limitation of the traditional bytecode set used in Squeak. Eliot et al have provided the new Sista bytecode set that has a number of advantages, including this one. Squeak trunk has been using the Sista bytecode set for quite a while, but due to some glitches in the trunk update stream there are probably a few images (maybe including yours) that accidentally are using the other bytecode set. I think this will take care of your problem, but note that if you are writing something that needs to run on older images, you may want to reorganize your method so that it does not hit the old limit for literals. Dave Flawless Thank you. -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Thu Feb 4 02:38:15 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 4 Feb 2021 02:38:15 0000 Subject: [squeak-dev] The Trunk: Morphic-eem.1719.mcz Message-ID: Eliot Miranda uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-eem.1719.mcz ==================== Summary ==================== Name: Morphic-eem.1719 Author: eem Time: 3 February 2021, 6:38:11.11355 pm UUID: ffb981b1-7c53-4fbe-b6f4-4c8f27c79f5a Ancestors: Morphic-mt.1718 Make SearchBar>>#smartSearch:in: search existing browsers for a class name being searched for, bringing the first such browser to the front and selecting the class. This allows one to find classes in browsers either when one has very many, or when one is using multi-window browsers containing many many classes. =============== Diff against Morphic-mt.1718 =============== Item was added: + ----- Method: Browser>>displayClass: (in category '*Morphic-Menus-DockingBar-accessing') ----- + displayClass: aClass + "Assuming the receiver has answered true to isDisplayingClass:, come to the front and select the given class." + | index | + index := self multiWindowIndexForClassName: aClass. + index ~= 0 ifTrue: + [multiWindowState selectWindowIndex: index]. + self selectClass: aClass! Item was added: + ----- Method: Browser>>isDisplayingClass: (in category '*Morphic-Menus-DockingBar-accessing') ----- + isDisplayingClass: aClass + | className | + className := aClass name. + (self multiWindowIndexForClassName: className) ~= 0 ifTrue: [^true]. + ^selectedClassName = className! Item was added: + ----- Method: Browser>>multiWindowIndexForClassName: (in category '*Morphic-Menus-DockingBar-accessing') ----- + multiWindowIndexForClassName: className + "Answer the index of a browser displaying className in multiWindowState, if any. + Otherwise answer zero." + multiWindowState ifNil: [^0]. + multiWindowState models withIndexDo: + [:browser :index| + browser selectedClassName = className ifTrue: [^index]]. + ^0! Item was changed: ----- Method: SearchBar>>smartSearch:in: (in category 'searching') ----- smartSearch: text in: morph "Take the user input and perform an appropriate search" | input newContents | self removeResultsWidget. input := text asString ifEmpty:[^self]. self class useSmartSearch ifFalse: [^ ToolSet default browseMessageNames: input]. + (Symbol findInterned: input) ifNotNil: + [:symbol| input := symbol]. "If it is a global or a full class name, browse that class." + (Smalltalk bindingOf: input) ifNotNil: + [:assoc| | class | + class := (assoc value isBehavior ifTrue:[assoc value] ifFalse:[assoc value class]) theNonMetaClass. + Project current world submorphs do: + [:windowMorph| + (windowMorph isSystemWindow + and: [(windowMorph model isKindOf: Browser) + and: [windowMorph model isDisplayingClass: class]]) ifTrue: + [windowMorph beKeyWindow. + ^windowMorph model displayClass: class]]. + ^ToolSet browse: class selector: nil]. - (Smalltalk bindingOf: input) ifNotNil:[:assoc| | global | - global := assoc value. - ^ToolSet browse: (global isBehavior ifTrue:[global] ifFalse:[global class]) selector: nil]. "If it is a symbol and there are implementors of it, browse those implementors." Symbol hasInterned: input ifTrue: [:selector | (SystemNavigation new allImplementorsOf: selector) ifNotEmpty:[:list| ^SystemNavigation new browseMessageList: list name: 'Implementors of ' , input]]. "If it starts uppercase, browse classes if any. Otherwise, just search for messages." + input first isUppercase ifTrue: + [(UIManager default classFromPattern: input withCaption: '') + ifNotNil:[:aClass| ^ToolSet browse: aClass selector: nil]. + newContents := input, ' -- not found.'. + self searchTerm: newContents. + self selection: (input size+1 to: newContents size). + self currentHand newKeyboardFocus: morph textMorph. + ^ self]. + + "Default to browse message names..." + ToolSet default browseMessageNames: input! - input first isUppercase - ifTrue: [ - (UIManager default classFromPattern: input withCaption: '') - ifNotNil:[:aClass| ^ToolSet browse: aClass selector: nil] - ifNil: [ - newContents := input, ' -- not found.'. - self searchTerm: newContents. - self selection: (input size+1 to: newContents size). - self currentHand newKeyboardFocus: morph textMorph. - ^ self]] - ifFalse: [ - ToolSet default browseMessageNames: input].! From commits at source.squeak.org Thu Feb 4 02:42:00 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 4 Feb 2021 02:42:00 0000 Subject: [squeak-dev] The Trunk: Morphic-eem.1720.mcz Message-ID: Eliot Miranda uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-eem.1720.mcz ==================== Summary ==================== Name: Morphic-eem.1720 Author: eem Time: 3 February 2021, 6:41:54.512365 pm UUID: d5ad36ce-7228-4bbe-8c99-a5bcef5e9bef Ancestors: Morphic-eem.1719 Avoid Symbol interning dulication in SearchBar>>smartSearch:in: =============== Diff against Morphic-eem.1719 =============== Item was changed: ----- Method: SearchBar>>smartSearch:in: (in category 'searching') ----- smartSearch: text in: morph "Take the user input and perform an appropriate search" | input newContents | self removeResultsWidget. input := text asString ifEmpty:[^self]. self class useSmartSearch ifFalse: [^ ToolSet default browseMessageNames: input]. (Symbol findInterned: input) ifNotNil: [:symbol| input := symbol]. "If it is a global or a full class name, browse that class." (Smalltalk bindingOf: input) ifNotNil: [:assoc| | class | class := (assoc value isBehavior ifTrue:[assoc value] ifFalse:[assoc value class]) theNonMetaClass. Project current world submorphs do: [:windowMorph| (windowMorph isSystemWindow and: [(windowMorph model isKindOf: Browser) and: [windowMorph model isDisplayingClass: class]]) ifTrue: [windowMorph beKeyWindow. ^windowMorph model displayClass: class]]. ^ToolSet browse: class selector: nil]. "If it is a symbol and there are implementors of it, browse those implementors." + input isSymbol ifTrue: + [(SystemNavigation new allImplementorsOf: input) ifNotEmpty: + [:list| - Symbol hasInterned: input ifTrue: [:selector | - (SystemNavigation new allImplementorsOf: selector) ifNotEmpty:[:list| ^SystemNavigation new browseMessageList: list name: 'Implementors of ' , input]]. "If it starts uppercase, browse classes if any. Otherwise, just search for messages." input first isUppercase ifTrue: + [(UIManager default classFromPattern: input withCaption: '') ifNotNil: + [:aClass| ^ToolSet browse: aClass selector: nil]. - [(UIManager default classFromPattern: input withCaption: '') - ifNotNil:[:aClass| ^ToolSet browse: aClass selector: nil]. newContents := input, ' -- not found.'. self searchTerm: newContents. self selection: (input size+1 to: newContents size). self currentHand newKeyboardFocus: morph textMorph. ^ self]. "Default to browse message names..." ToolSet default browseMessageNames: input! From commits at source.squeak.org Thu Feb 4 02:52:31 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 4 Feb 2021 02:52:31 0000 Subject: [squeak-dev] The Trunk: Morphic-eem.1721.mcz Message-ID: Eliot Miranda uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-eem.1721.mcz ==================== Summary ==================== Name: Morphic-eem.1721 Author: eem Time: 3 February 2021, 6:52:27.309661 pm UUID: 3fa83dbf-de0f-4bb8-a461-57416e66b6cf Ancestors: Morphic-eem.1720 And make sure that we find the right model when searching for classes in multi-window browsers. =============== Diff against Morphic-eem.1720 =============== Item was changed: ----- Method: Browser>>displayClass: (in category '*Morphic-Menus-DockingBar-accessing') ----- displayClass: aClass "Assuming the receiver has answered true to isDisplayingClass:, come to the front and select the given class." | index | + index := self multiWindowIndexForClassName: aClass name. + index ~= 0 ifTrue: + [multiWindowState selectWindowIndex: index. + ^(multiWindowState models at: index) selectClass: aClass]. - index := self multiWindowIndexForClassName: aClass. - index ~= 0 ifTrue: - [multiWindowState selectWindowIndex: index]. self selectClass: aClass! From Christoph.Thiede at student.hpi.uni-potsdam.de Fri Feb 5 01:14:31 2021 From: Christoph.Thiede at student.hpi.uni-potsdam.de (Thiede, Christoph) Date: Fri, 5 Feb 2021 01:14:31 +0000 Subject: [squeak-dev] The Trunk: Morphic-eem.1719.mcz In-Reply-To: References: Message-ID: <804594dd36de4be1b92d4dbecaaeb973@student.hpi.uni-potsdam.de> Hi Eliot, could you please honor the "SystemWindow reuseWindows" here? I have turned that preference off in my image because I actually use to accept a class name multiple times in the search bar in order to open multiple windows - for instance, to view different protocols of the same class side-by-side. It would be great if this would work soon again ... :-) Best, Christoph ________________________________ Von: Squeak-dev im Auftrag von commits at source.squeak.org Gesendet: Donnerstag, 4. Februar 2021 03:38:15 An: squeak-dev at lists.squeakfoundation.org; packages at lists.squeakfoundation.org Betreff: [squeak-dev] The Trunk: Morphic-eem.1719.mcz Eliot Miranda uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-eem.1719.mcz ==================== Summary ==================== Name: Morphic-eem.1719 Author: eem Time: 3 February 2021, 6:38:11.11355 pm UUID: ffb981b1-7c53-4fbe-b6f4-4c8f27c79f5a Ancestors: Morphic-mt.1718 Make SearchBar>>#smartSearch:in: search existing browsers for a class name being searched for, bringing the first such browser to the front and selecting the class. This allows one to find classes in browsers either when one has very many, or when one is using multi-window browsers containing many many classes. =============== Diff against Morphic-mt.1718 =============== Item was added: + ----- Method: Browser>>displayClass: (in category '*Morphic-Menus-DockingBar-accessing') ----- + displayClass: aClass + "Assuming the receiver has answered true to isDisplayingClass:, come to the front and select the given class." + | index | + index := self multiWindowIndexForClassName: aClass. + index ~= 0 ifTrue: + [multiWindowState selectWindowIndex: index]. + self selectClass: aClass! Item was added: + ----- Method: Browser>>isDisplayingClass: (in category '*Morphic-Menus-DockingBar-accessing') ----- + isDisplayingClass: aClass + | className | + className := aClass name. + (self multiWindowIndexForClassName: className) ~= 0 ifTrue: [^true]. + ^selectedClassName = className! Item was added: + ----- Method: Browser>>multiWindowIndexForClassName: (in category '*Morphic-Menus-DockingBar-accessing') ----- + multiWindowIndexForClassName: className + "Answer the index of a browser displaying className in multiWindowState, if any. + Otherwise answer zero." + multiWindowState ifNil: [^0]. + multiWindowState models withIndexDo: + [:browser :index| + browser selectedClassName = className ifTrue: [^index]]. + ^0! Item was changed: ----- Method: SearchBar>>smartSearch:in: (in category 'searching') ----- smartSearch: text in: morph "Take the user input and perform an appropriate search" | input newContents | self removeResultsWidget. input := text asString ifEmpty:[^self]. self class useSmartSearch ifFalse: [^ ToolSet default browseMessageNames: input]. + (Symbol findInterned: input) ifNotNil: + [:symbol| input := symbol]. "If it is a global or a full class name, browse that class." + (Smalltalk bindingOf: input) ifNotNil: + [:assoc| | class | + class := (assoc value isBehavior ifTrue:[assoc value] ifFalse:[assoc value class]) theNonMetaClass. + Project current world submorphs do: + [:windowMorph| + (windowMorph isSystemWindow + and: [(windowMorph model isKindOf: Browser) + and: [windowMorph model isDisplayingClass: class]]) ifTrue: + [windowMorph beKeyWindow. + ^windowMorph model displayClass: class]]. + ^ToolSet browse: class selector: nil]. - (Smalltalk bindingOf: input) ifNotNil:[:assoc| | global | - global := assoc value. - ^ToolSet browse: (global isBehavior ifTrue:[global] ifFalse:[global class]) selector: nil]. "If it is a symbol and there are implementors of it, browse those implementors." Symbol hasInterned: input ifTrue: [:selector | (SystemNavigation new allImplementorsOf: selector) ifNotEmpty:[:list| ^SystemNavigation new browseMessageList: list name: 'Implementors of ' , input]]. "If it starts uppercase, browse classes if any. Otherwise, just search for messages." + input first isUppercase ifTrue: + [(UIManager default classFromPattern: input withCaption: '') + ifNotNil:[:aClass| ^ToolSet browse: aClass selector: nil]. + newContents := input, ' -- not found.'. + self searchTerm: newContents. + self selection: (input size+1 to: newContents size). + self currentHand newKeyboardFocus: morph textMorph. + ^ self]. + + "Default to browse message names..." + ToolSet default browseMessageNames: input! - input first isUppercase - ifTrue: [ - (UIManager default classFromPattern: input withCaption: '') - ifNotNil:[:aClass| ^ToolSet browse: aClass selector: nil] - ifNil: [ - newContents := input, ' -- not found.'. - self searchTerm: newContents. - self selection: (input size+1 to: newContents size). - self currentHand newKeyboardFocus: morph textMorph. - ^ self]] - ifFalse: [ - ToolSet default browseMessageNames: input].! -------------- next part -------------- An HTML attachment was scrubbed... URL: From marcel.taeumel at hpi.de Fri Feb 5 08:08:44 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Fri, 5 Feb 2021 09:08:44 +0100 Subject: [squeak-dev] The Trunk: Morphic-eem.1719.mcz In-Reply-To: <804594dd36de4be1b92d4dbecaaeb973@student.hpi.uni-potsdam.de> References: <804594dd36de4be1b92d4dbecaaeb973@student.hpi.uni-potsdam.de> Message-ID: > could you please honor the "SystemWindow reuseWindows" here? +1 This is a regression. If there is an exact match and there is already a window open with that object, nothing will happen, except for that window coming to front. On a big screen, one cannot even notice that. Still, not even sure that this would be the wanted behavior for reuseWindows being true. It only works if you type the full name into the search bar. I would expect that it should work also when you select the match from the list of multiple matches. :-) Best, Marcel Am 05.02.2021 02:14:41 schrieb Thiede, Christoph : Hi Eliot, could you please honor the "SystemWindow reuseWindows" here? I have turned that preference off in my image because I actually use to accept a class name multiple times in the search bar in order to open multiple windows - for instance, to view different protocols of the same class side-by-side. It would be great if this would work soon again ... :-) Best, Christoph Von: Squeak-dev im Auftrag von commits at source.squeak.org Gesendet: Donnerstag, 4. Februar 2021 03:38:15 An: squeak-dev at lists.squeakfoundation.org; packages at lists.squeakfoundation.org Betreff: [squeak-dev] The Trunk: Morphic-eem.1719.mcz   Eliot Miranda uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-eem.1719.mcz [http://source.squeak.org/trunk/Morphic-eem.1719.mcz] ==================== Summary ==================== Name: Morphic-eem.1719 Author: eem Time: 3 February 2021, 6:38:11.11355 pm UUID: ffb981b1-7c53-4fbe-b6f4-4c8f27c79f5a Ancestors: Morphic-mt.1718 Make SearchBar>>#smartSearch:in: search existing browsers for a class name being searched for, bringing the first such browser to the front and selecting the class.  This allows one to find classes in browsers either when one has very many, or when one is using multi-window browsers containing many many classes. =============== Diff against Morphic-mt.1718 =============== Item was added: + ----- Method: Browser>>displayClass: (in category '*Morphic-Menus-DockingBar-accessing') ----- + displayClass: aClass +        "Assuming the receiver has answered true to isDisplayingClass:, come to the front and select the given class." +        | index | +        index := self multiWindowIndexForClassName: aClass. +        index  ~= 0 ifTrue: +                [multiWindowState selectWindowIndex: index]. +        self selectClass: aClass! Item was added: + ----- Method: Browser>>isDisplayingClass: (in category '*Morphic-Menus-DockingBar-accessing') ----- + isDisplayingClass: aClass +        | className | +        className := aClass name. +        (self multiWindowIndexForClassName: className) ~= 0 ifTrue: [^true]. +        ^selectedClassName = className! Item was added: + ----- Method: Browser>>multiWindowIndexForClassName: (in category '*Morphic-Menus-DockingBar-accessing') ----- + multiWindowIndexForClassName: className +        "Answer the index of a browser displaying className in multiWindowState, if any. +         Otherwise answer zero." +        multiWindowState ifNil: [^0]. +        multiWindowState models withIndexDo: +                [:browser :index| +                browser selectedClassName = className ifTrue: [^index]]. +        ^0! Item was changed:   ----- Method: SearchBar>>smartSearch:in: (in category 'searching') -----   smartSearch: text in: morph          "Take the user input and perform an appropriate search"          | input newContents |          self removeResultsWidget.          input := text asString ifEmpty:[^self].          self class useSmartSearch ifFalse: [^ ToolSet default browseMessageNames: input].   +        (Symbol findInterned: input) ifNotNil: +                [:symbol| input := symbol].          "If it is a global or a full class name, browse that class." +        (Smalltalk bindingOf: input) ifNotNil: +                [:assoc| | class | +                class := (assoc value isBehavior ifTrue:[assoc value] ifFalse:[assoc value class]) theNonMetaClass. +                Project current world submorphs do: +                        [:windowMorph| +                         (windowMorph isSystemWindow +                          and: [(windowMorph model isKindOf: Browser) +                          and: [windowMorph model isDisplayingClass: class]]) ifTrue: +                                [windowMorph beKeyWindow. +                                 ^windowMorph model displayClass: class]]. +                ^ToolSet browse: class selector: nil]. -        (Smalltalk bindingOf: input) ifNotNil:[:assoc| | global | -                global := assoc value. -                ^ToolSet browse: (global isBehavior ifTrue:[global] ifFalse:[global class]) selector: nil].                   "If it is a symbol and there are implementors of it, browse those implementors."          Symbol hasInterned: input ifTrue: [:selector |                  (SystemNavigation new allImplementorsOf: selector) ifNotEmpty:[:list|                          ^SystemNavigation new                                  browseMessageList: list                                  name: 'Implementors of ' , input]].            "If it starts uppercase, browse classes if any. Otherwise, just search for messages." +        input first isUppercase ifTrue: +                [(UIManager default classFromPattern: input withCaption: '') +                        ifNotNil:[:aClass| ^ToolSet browse: aClass selector: nil]. +                newContents := input, ' -- not found.'. +                self searchTerm: newContents. +                self selection: (input size+1 to: newContents size). +                self currentHand newKeyboardFocus: morph textMorph. +                ^ self]. + +        "Default to browse message names..." +        ToolSet default browseMessageNames: input! -        input first isUppercase -                ifTrue: [ -                        (UIManager default classFromPattern: input withCaption: '') -                                ifNotNil:[:aClass| ^ToolSet browse: aClass selector: nil] -                                ifNil: [ -                                        newContents := input, ' -- not found.'. -                                        self searchTerm: newContents. -                                        self selection: (input size+1 to: newContents size). -                                        self currentHand newKeyboardFocus: morph textMorph. -                                        ^ self]] -                ifFalse: [ -                        ToolSet default browseMessageNames: input].! -------------- next part -------------- An HTML attachment was scrubbed... URL: From asqueaker at gmail.com Fri Feb 5 21:19:13 2021 From: asqueaker at gmail.com (Chris Muller) Date: Fri, 5 Feb 2021 15:19:13 -0600 Subject: [squeak-dev] The Trunk: Morphic-eem.1719.mcz In-Reply-To: <804594dd36de4be1b92d4dbecaaeb973@student.hpi.uni-potsdam.de> References: <804594dd36de4be1b92d4dbecaaeb973@student.hpi.uni-potsdam.de> Message-ID: Hi Christoph! I thought this feature seemed reminiscent of Reuse Windows as well. The method to hook in each Model subclass (as needed) is #representsSameBrowseeAs:. Looking at that, you can see that simply making your code pane temporarily dirty, an additional window will be spawned. I mention that because Reuse Windows is fantastic and I hate to see your experience with it ruined over something so trivial. :) You do also have the green duplicate halo. People are happy to use "non-standard" UI features in other IDE's, but there seems to be an aversion to people using halos in Squeak. I could be wrong about that, but I find the duplicate halo useful quite often. - Chris On Thu, Feb 4, 2021 at 7:14 PM Thiede, Christoph < Christoph.Thiede at student.hpi.uni-potsdam.de> wrote: > Hi Eliot, > > > could you please honor the "SystemWindow reuseWindows" here? I have > turned that preference off in my image because I actually use to accept a > class name multiple times in the search bar in order to open multiple > windows - for instance, to view different protocols of the same > class side-by-side. It would be great if this would work soon again ... :-) > > > Best, > > Christoph > ------------------------------ > *Von:* Squeak-dev im > Auftrag von commits at source.squeak.org > *Gesendet:* Donnerstag, 4. Februar 2021 03:38:15 > *An:* squeak-dev at lists.squeakfoundation.org; > packages at lists.squeakfoundation.org > *Betreff:* [squeak-dev] The Trunk: Morphic-eem.1719.mcz > > Eliot Miranda uploaded a new version of Morphic to project The Trunk: > http://source.squeak.org/trunk/Morphic-eem.1719.mcz > > ==================== Summary ==================== > > Name: Morphic-eem.1719 > Author: eem > Time: 3 February 2021, 6:38:11.11355 pm > UUID: ffb981b1-7c53-4fbe-b6f4-4c8f27c79f5a > Ancestors: Morphic-mt.1718 > > Make SearchBar>>#smartSearch:in: search existing browsers for a class name > being searched for, bringing the first such browser to the front and > selecting the class. This allows one to find classes in browsers either > when one has very many, or when one is using multi-window browsers > containing many many classes. > > =============== Diff against Morphic-mt.1718 =============== > > Item was added: > + ----- Method: Browser>>displayClass: (in category > '*Morphic-Menus-DockingBar-accessing') ----- > + displayClass: aClass > + "Assuming the receiver has answered true to isDisplayingClass:, > come to the front and select the given class." > + | index | > + index := self multiWindowIndexForClassName: aClass. > + index ~= 0 ifTrue: > + [multiWindowState selectWindowIndex: index]. > + self selectClass: aClass! > > Item was added: > + ----- Method: Browser>>isDisplayingClass: (in category > '*Morphic-Menus-DockingBar-accessing') ----- > + isDisplayingClass: aClass > + | className | > + className := aClass name. > + (self multiWindowIndexForClassName: className) ~= 0 ifTrue: > [^true]. > + ^selectedClassName = className! > > Item was added: > + ----- Method: Browser>>multiWindowIndexForClassName: (in category > '*Morphic-Menus-DockingBar-accessing') ----- > + multiWindowIndexForClassName: className > + "Answer the index of a browser displaying className in > multiWindowState, if any. > + Otherwise answer zero." > + multiWindowState ifNil: [^0]. > + multiWindowState models withIndexDo: > + [:browser :index| > + browser selectedClassName = className ifTrue: [^index]]. > + ^0! > > Item was changed: > ----- Method: SearchBar>>smartSearch:in: (in category 'searching') ----- > smartSearch: text in: morph > "Take the user input and perform an appropriate search" > | input newContents | > self removeResultsWidget. > input := text asString ifEmpty:[^self]. > self class useSmartSearch ifFalse: [^ ToolSet default > browseMessageNames: input]. > > + (Symbol findInterned: input) ifNotNil: > + [:symbol| input := symbol]. > "If it is a global or a full class name, browse that class." > + (Smalltalk bindingOf: input) ifNotNil: > + [:assoc| | class | > + class := (assoc value isBehavior ifTrue:[assoc value] > ifFalse:[assoc value class]) theNonMetaClass. > + Project current world submorphs do: > + [:windowMorph| > + (windowMorph isSystemWindow > + and: [(windowMorph model isKindOf: Browser) > + and: [windowMorph model isDisplayingClass: > class]]) ifTrue: > + [windowMorph beKeyWindow. > + ^windowMorph model displayClass: class]]. > + ^ToolSet browse: class selector: nil]. > - (Smalltalk bindingOf: input) ifNotNil:[:assoc| | global | > - global := assoc value. > - ^ToolSet browse: (global isBehavior ifTrue:[global] > ifFalse:[global class]) selector: nil]. > > "If it is a symbol and there are implementors of it, browse those > implementors." > Symbol hasInterned: input ifTrue: [:selector | > (SystemNavigation new allImplementorsOf: selector) > ifNotEmpty:[:list| > ^SystemNavigation new > browseMessageList: list > name: 'Implementors of ' , input]]. > > "If it starts uppercase, browse classes if any. Otherwise, just > search for messages." > + input first isUppercase ifTrue: > + [(UIManager default classFromPattern: input withCaption: > '') > + ifNotNil:[:aClass| ^ToolSet browse: aClass > selector: nil]. > + newContents := input, ' -- not found.'. > + self searchTerm: newContents. > + self selection: (input size+1 to: newContents size). > + self currentHand newKeyboardFocus: morph textMorph. > + ^ self]. > + > + "Default to browse message names..." > + ToolSet default browseMessageNames: input! > - input first isUppercase > - ifTrue: [ > - (UIManager default classFromPattern: input > withCaption: '') > - ifNotNil:[:aClass| ^ToolSet browse: > aClass selector: nil] > - ifNil: [ > - newContents := input, ' -- not > found.'. > - self searchTerm: newContents. > - self selection: (input size+1 to: > newContents size). > - self currentHand > newKeyboardFocus: morph textMorph. > - ^ self]] > - ifFalse: [ > - ToolSet default browseMessageNames: input].! > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Sat Feb 6 04:25:20 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sat, 6 Feb 2021 04:25:20 0000 Subject: [squeak-dev] The Trunk: System-cmm.1214.mcz Message-ID: Chris Muller uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-cmm.1214.mcz ==================== Summary ==================== Name: System-cmm.1214 Author: cmm Time: 5 February 2021, 10:09:05.179247 pm UUID: d6f968d9-a638-42ef-89ef-d37af0f31ffd Ancestors: System-mt.1213 Patch the patcher. Smalltalk run: permits the patching of a production system without having to resort to running a custom image, but when the patch.st file has read-only status in the OS, FileStream class>>#fileNamed:do: can't open it, because it tries to open for read/write. But rather htan signal an error, it silently does nothing (wow), leaving the system unpatched. Patch files can and should be read-only anyway, so use DirectoryEntryFile>>#readStreamDo:. =============== Diff against System-mt.1213 =============== Item was changed: ----- Method: SmalltalkImage>>patchSystem (in category 'command line') ----- patchSystem 'patch.st' asDirectoryEntry ifNotNil: [ : patchEntry | patchEntry modificationTime > Smalltalk imageName asDirectoryEntry modificationTime ifTrue: [ Notification signal: 'Patching system...'. + patchEntry readStreamDo: [ : stream | stream fileIn ] ] - FileStream - fileNamed: 'patch.st' - do: - [ : stream | stream fileIn ] ] ifFalse: [ self error: 'patch.st file is older than the image file. Aborting.' ] ]! From tim at rowledge.org Sat Feb 6 05:15:01 2021 From: tim at rowledge.org (tim Rowledge) Date: Fri, 5 Feb 2021 21:15:01 -0800 Subject: [squeak-dev] The Trunk: System-cmm.1214.mcz In-Reply-To: References: Message-ID: <1900AC74-9909-4316-9693-84B27FFF8CC6@rowledge.org> Ah, that reminds me of a related issue I've been meaning to bring up for , oy, 6 years. Last time I tried, it was not possible to load code into a system with no changes file because of an issue to do with the method tail - the bit where we keep the source details. Has that been solved? tim -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim Strange OpCodes: CM: Circulate Memory From m at jaromir.net Sat Feb 6 08:37:56 2021 From: m at jaromir.net (Jaromir) Date: Sat, 6 Feb 2021 02:37:56 -0600 (CST) Subject: [squeak-dev] Process >> priority: behavior grossly incorrect, Transcript losing output Message-ID: <1612600676425-0.post@n4.nabble.com> In the following example higher priority process keeps waiting in the ProcessorScheduler queue until lower priority process suspends! Transcript flush; cr. *Processor activeProcess priority: 42. [ Transcript nextPut: $A ] forkAt: 41. Processor activeProcess priority: 40.* Transcript nextPut: $B; flush. 1000 factorial. Transcript nextPut: $C; flush. 1000 factorial. Transcript nextPut: $D; flush. 10 milliSeconds wait. "suspends the active process" Transcript nextPut: $E; flush. Answers: BCDAE BCDAE BCDE "here A even lost!" BCDAE BCDAE BCDAE BCDAE BCDAE Increasing the lenght of computation by doing 20000 factorial shows interrupts work and suspend the rogue process: BCDAE BACDE BCADE BCDE "A lost again" BACDE BCDAE BCDAE Reason: the #priority: method won't make sure the active process doesn't jump over a scheduled process when lowering it's priority - as a result the active process will continue running until it suspends and won't let the higher priority process a chance to run. priority: anInteger "Set the receiver's priority to anInteger." (anInteger >= Processor lowestPriority and:[anInteger <= Processor highestPriority]) ifTrue: [priority := anInteger] ifFalse: [self error: 'Invalid priority: ', anInteger printString] Proposed solution: priority: anInteger "Set the receiver's priority to anInteger." (anInteger >= Processor lowestPriority and:[anInteger <= Processor highestPriority]) ifTrue: [ priority := anInteger. *(self isActiveProcess and: [anInteger < Processor nextReadyProcess priority]) ifTrue: [ [self resume] fork. self suspend ] ]* ifFalse: [self error: 'Invalid priority: ', anInteger printString] The problem with this solution is the #nextReadyProcess may get interrupted in the middle which may make it's answer usless. So I guess either this whole method should run as a primitive or in the interim, always force the active process suspend momentarily to let ProcessorScheduler do the job: priority: anInteger "Set the receiver's priority to anInteger." (anInteger >= Processor lowestPriority and:[anInteger <= Processor highestPriority]) ifTrue: [ priority := anInteger. *self isActiveProcess ifTrue: [ [self resume] fork. self suspend ] ]* ifFalse: [self error: 'Invalid priority: ', anInteger printString] Impact: at least two methods use this type of priority switching: #valueUnpreemptively and #valueAt: and their behavior is impacted the same way. Transcript flush; cr. *[ [ Transcript nextPut: $A ] forkAt: 41. ] valueUnpreemptively.* Transcript nextPut: $B; flush. 20000 factorial. Transcript nextPut: $C; flush. 20000 factorial. Transcript nextPut: $D; flush. 10 milliSeconds wait. Transcript nextPut: $E; flush. Answers again: BCDAE BCDAE BCDE BCADE BCDAE BCADE BCDAE BCDE BCDAE BACDE On top of that Transcript loses some output intermittently - I'm not sure if it's related or a separate issue. Image ----- C:\Users\mail\Squeak\Squeak6.0alpha-20182-64bit-superFRESH\Squeak6.0alpha-20182-64bit.image Squeak6.0alpha latest update: #20182 with all default settings including: Smalltalk vm processPreemptionYields = false TranscriptStream forceUpdate = true Related discussion: http://forum.world.st/The-Inbox-Compiler-mt-456-mcz-td5126723.html -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From gettimothy at zoho.com Sat Feb 6 14:29:41 2021 From: gettimothy at zoho.com (gettimothy) Date: Sat, 06 Feb 2021 09:29:41 -0500 Subject: [squeak-dev] interesting slowness (not important, just an FYI) Message-ID: <17777bf98d4.f034827449640.1173019270683908797@zoho.com> Hi Folks. I am in the process of verifying what Unifont stuff appears in squeak/xterm and in web on Brave (chromium) / Edge (runs on Linux now) per: http://menmachinesmaterials.com/UnicodeRangeBrowser Ok, on the Squeak side, I am doing a mass Do on the following: (16r000020  asCharacter to:16r00007F asCharacter) editWithLabel:'Basic Latin'. (16r0000A0  asCharacter to:16r0000FF asCharacter) editWithLabel:'Latin-1 Supplement'. (16r000100  asCharacter to:16r00017F asCharacter) editWithLabel:'Latin Extended-A'. (16r000180  asCharacter to:16r00024F asCharacter) editWithLabel:'Latin Extended-B'. (16r000250  asCharacter to:16r0002AF asCharacter) editWithLabel:'IPA Extensions'. (16r0002B0  asCharacter to:16r0002FF asCharacter) editWithLabel:'Spacing Modifier Letters'. (16r000300  asCharacter to:16r00036F asCharacter) editWithLabel:'Combining Diacritical Marks'. (16r000370  asCharacter to:16r0003FF asCharacter) editWithLabel:'Greek and Coptic'. (16r000400  asCharacter to:16r0004FF asCharacter) editWithLabel:'Cyrillic'. (16r000500  asCharacter to:16r00052F asCharacter) editWithLabel:'Cyrillic Supplementary'. (16r000530  asCharacter to:16r00058F asCharacter) editWithLabel:'Armenian'. (16r000590  asCharacter to:16r0005FF asCharacter) editWithLabel:'Hebrew' . (16r000600  asCharacter to:16r0006FF asCharacter) editWithLabel:'Arabic' . (16r000700  asCharacter to:16r00074F asCharacter) editWithLabel:'Syriac' . (16r000780  asCharacter to:16r0007BF asCharacter) editWithLabel:'Thaana' . (16r000900  asCharacter to:16r00097F asCharacter) editWithLabel:'Devanagari'. (16r000980  asCharacter to:16r0009FF asCharacter) editWithLabel:'Bengali'. (16r000A00  asCharacter to:16r000A7F asCharacter) editWithLabel:'Gurmukhi'. (16r000A80  asCharacter to:16r000AFF asCharacter) editWithLabel:'Gujarati'. (16r000B00  asCharacter to:16r000B7F asCharacter) editWithLabel:'Oriya'. (16r000B80  asCharacter to:16r000BFF asCharacter) editWithLabel:'Tamil'. (16r000C00  asCharacter to:16r000C7F asCharacter) editWithLabel:'Telugu'. (16r000C80  asCharacter to:16r000CFF asCharacter) editWithLabel:'Kannada'. (16r000D00  asCharacter to:16r000D7F asCharacter) editWithLabel:'Malayalam'. (16r000D80  asCharacter to:16r000DFF asCharacter) editWithLabel:'Sinhala'. (16r000E00  asCharacter to:16r000E7F asCharacter) editWithLabel:'Thai'. (16r000E80  asCharacter to:16r000EFF asCharacter) editWithLabel:'Lao'. (16r000F00  asCharacter to:16r000FFF asCharacter) editWithLabel:'Tibetan'. (16r001000  asCharacter to:16r00109F asCharacter) editWithLabel:'Myanmar'. (16r0010A0  asCharacter to:16r0010FF asCharacter) editWithLabel:'Georgian'. (16r001100  asCharacter to:16r0011FF asCharacter) editWithLabel:'Hangul Jamo'. (16r001200  asCharacter to:16r00137F asCharacter) editWithLabel:'Ethiopic'. (16r0013A0  asCharacter to:16r0013FF asCharacter) editWithLabel:'Cherokee'. (16r001400  asCharacter to:16r00167F asCharacter) editWithLabel:'Unified Canadian Aboriginal Syllabics'. (16r001680  asCharacter to:16r00169F asCharacter) editWithLabel:'Ogham'. (16r0016A0  asCharacter to:16r0016FF asCharacter) editWithLabel:'Runic'. (16r001700  asCharacter to:16r00171F asCharacter) editWithLabel:'Tagalog'. (16r001720  asCharacter to:16r00173F asCharacter) editWithLabel:'Hanunoo'. (16r001740  asCharacter to:16r00175F asCharacter) editWithLabel:'Buhid'. (16r001760  asCharacter to:16r00177F asCharacter) editWithLabel:'Tagbanwa'. (16r001780  asCharacter to:16r0017FF asCharacter) editWithLabel:'Khmer'. (16r001800  asCharacter to:16r0018AF asCharacter) editWithLabel:'Mongolian'. (16r001900  asCharacter to:16r00194F asCharacter) editWithLabel:'Limbu'. (16r001950  asCharacter to:16r00197F asCharacter) editWithLabel:'Tai Le'. (16r0019E0  asCharacter to:16r0019FF asCharacter) editWithLabel:'Khmer Symbols'. (16r001D00  asCharacter to:16r001D7F asCharacter) editWithLabel:'Phonetic Extensions'. (16r001E00  asCharacter to:16r001EFF asCharacter) editWithLabel:'Latin Extended Additional'. (16r001F00  asCharacter to:16r001FFF asCharacter) editWithLabel:'Greek Extended'. (16r002000  asCharacter to:16r00206F asCharacter) editWithLabel:'General Punctuation'. (16r002070  asCharacter to:16r00209F asCharacter) editWithLabel:'Superscripts and Subscripts'. (16r0020A0  asCharacter to:16r0020CF asCharacter) editWithLabel:'Currency Symbols'. (16r0020D0  asCharacter to:16r0020FF asCharacter) editWithLabel:'Combining Diacritical Marks for Symbols'. (16r002100  asCharacter to:16r00214F asCharacter) editWithLabel:'Letterlike Symbols'. (16r002150  asCharacter to:16r00218F asCharacter) editWithLabel:'Number Forms'. (16r002190  asCharacter to:16r0021FF asCharacter) editWithLabel:'Arrows'. (16r002200  asCharacter to:16r0022FF asCharacter) editWithLabel:'Mathematical Operators'. (16r002300  asCharacter to:16r0023FF asCharacter) editWithLabel:'Miscellaneous Technical'. (16r002400  asCharacter to:16r00243F asCharacter) editWithLabel:'Control Pictures'. (16r002440  asCharacter to:16r00245F asCharacter) editWithLabel:'Optical Character Recognition'. (16r002460  asCharacter to:16r0024FF asCharacter) editWithLabel:'Enclosed Alphanumerics'. (16r002500  asCharacter to:16r00257F asCharacter) editWithLabel:'Box Drawing'. (16r002580  asCharacter to:16r00259F asCharacter) editWithLabel:'Block Elements'. (16r0025A0  asCharacter to:16r0025FF asCharacter) editWithLabel:'Geometric Shapes'. (16r002600  asCharacter to:16r0026FF asCharacter) editWithLabel:'Miscellaneous Symbols'. (16r002700  asCharacter to:16r0027BF asCharacter) editWithLabel:'Dingbats'. (16r0027C0  asCharacter to:16r0027EF asCharacter) editWithLabel:'Miscellaneous Mathematical Symbols-A'. (16r0027F0  asCharacter to:16r0027FF asCharacter) editWithLabel:'Supplemental Arrows-A'. (16r002800  asCharacter to:16r0028FF asCharacter) editWithLabel:'Braille Patterns'. (16r002900  asCharacter to:16r00297F asCharacter) editWithLabel:'Supplemental Arrows-B'. (16r002980  asCharacter to:16r0029FF asCharacter) editWithLabel:'Miscellaneous Mathematical Symbols-B'. (16r002A00  asCharacter to:16r002AFF asCharacter) editWithLabel:'Supplemental Mathematical Operators'. (16r002B00  asCharacter to:16r002BFF asCharacter) editWithLabel:'Miscellaneous Symbols and Arrows'. (16r002E80  asCharacter to:16r002EFF asCharacter) editWithLabel:'CJK Radicals Supplement'. (16r002F00  asCharacter to:16r002FDF asCharacter) editWithLabel:'Kangxi Radicals'. (16r002FF0  asCharacter to:16r002FFF asCharacter) editWithLabel:'Ideographic Description Characters'. (16r003000  asCharacter to:16r00303F asCharacter) editWithLabel:'CJK Symbols and Punctuation'. (16r003040  asCharacter to:16r00309F asCharacter) editWithLabel:'Hiragana'. (16r0030A0  asCharacter to:16r0030FF asCharacter) editWithLabel:'Katakana'. (16r003100  asCharacter to:16r00312F asCharacter) editWithLabel:'Bopomofo'. (16r003130  asCharacter to:16r00318F asCharacter) editWithLabel:'Hangul Compatibility Jamo'. (16r003190  asCharacter to:16r00319F asCharacter) editWithLabel:'Kanbun'. (16r0031A0  asCharacter to:16r0031BF asCharacter) editWithLabel:'Bopomofo Extended'. (16r0031F0  asCharacter to:16r0031FF asCharacter) editWithLabel:'Katakana Phonetic Extensions'. (16r003200  asCharacter to:16r0032FF asCharacter) editWithLabel:'Enclosed CJK Letters and Months'. (16r003300  asCharacter to:16r0033FF asCharacter) editWithLabel:'CJK Compatibility'. (16r003400  asCharacter to:16r004DBF asCharacter) editWithLabel:'CJK Unified Ideographs Extension A'. (16r004DC0  asCharacter to:16r004DFF asCharacter) editWithLabel:'Yijing Hexagram Symbols'. (16r004E00  asCharacter to:16r009FFF asCharacter) editWithLabel:'CJK Unified Ideographs'. (16r00A000  asCharacter to:16r00A48F asCharacter) editWithLabel:'Yi Syllables'. (16r00A490  asCharacter to:16r00A4CF asCharacter) editWithLabel:'Yi Radicals'. (16r00AC00  asCharacter to:16r00D7AF asCharacter) editWithLabel:'Hangul Syllables'. (16r00D800  asCharacter to:16r00DB7F asCharacter) editWithLabel:'High Surrogates'. (16r00DB80  asCharacter to:16r00DBFF asCharacter) editWithLabel:'High Private Use Surrogates'. (16r00DC00  asCharacter to:16r00DFFF asCharacter) editWithLabel:'Low Surrogates'. (16r00E000  asCharacter to:16r00F8FF asCharacter) editWithLabel:'Private Use Area'. (16r00F900  asCharacter to:16r00FAFF asCharacter) editWithLabel:'CJK Compatibility Ideographs'. (16r00FB00  asCharacter to:16r00FB4F asCharacter) editWithLabel:'Alphabetic Presentation Forms'. (16r00FB50  asCharacter to:16r00FDFF asCharacter) editWithLabel:'Arabic Presentation Forms-A'. (16r00FE00  asCharacter to:16r00FE0F asCharacter) editWithLabel:'Variation Selectors'. (16r00FE20  asCharacter to:16r00FE2F asCharacter) editWithLabel:'Combining Half Marks'. (16r00FE30  asCharacter to:16r00FE4F asCharacter) editWithLabel:'CJK Compatibility Forms'. (16r00FE50  asCharacter to:16r00FE6F asCharacter) editWithLabel:'Small Form Variants'. (16r00FE70  asCharacter to:16r00FEFF asCharacter) editWithLabel:'Arabic Presentation Forms-B'. (16r00FF00  asCharacter to:16r00FFEF asCharacter) editWithLabel:'Halfwidth and Fullwidth Forms'. (16r00FFF0  asCharacter to:16r00FFFF asCharacter) editWithLabel:'Specials'. (16r010000  asCharacter to:16r01007F asCharacter) editWithLabel:'Linear B Syllabary'. (16r010080  asCharacter to:16r0100FF asCharacter) editWithLabel:'Linear B Ideograms'. (16r010100  asCharacter to:16r01013F asCharacter) editWithLabel:'Aegean Numbers'. (16r010300  asCharacter to:16r01032F asCharacter) editWithLabel:'Old Italic'. (16r010330  asCharacter to:16r01034F asCharacter) editWithLabel:'Gothic'. (16r010380  asCharacter to:16r01039F asCharacter) editWithLabel:'Ugaritic'. (16r010400  asCharacter to:16r01044F asCharacter) editWithLabel:'Deseret'. (16r010450  asCharacter to:16r01047F asCharacter) editWithLabel:'Shavian'. (16r010480  asCharacter to:16r0104AF asCharacter) editWithLabel:'Osmanya'. (16r010800  asCharacter to:16r01083F asCharacter) editWithLabel:'Cypriot Syllabary'. (16r01D000  asCharacter to:16r01D0FF asCharacter) editWithLabel:'Byzantine Musical Symbols'. (16r01D100  asCharacter to:16r01D1FF asCharacter) editWithLabel:'Musical Symbols'. (16r01D300  asCharacter to:16r01D35F asCharacter) editWithLabel:'Tai Xuan Jing Symbols'. (16r01D400  asCharacter to:16r01D7FF asCharacter) editWithLabel:'Mathematical Alphanumeric Symbols'. (16r020000  asCharacter to:16r02A6DF asCharacter) editWithLabel:'CJK Unified Ideographs Extension B'. (16r02F800  asCharacter to:16r02FA1F asCharacter) editWithLabel:'CJK Compatibility Ideographs Supplement'. (16r0E0000  asCharacter to:16r0E007F asCharacter) editWithLabel:'Tags'. When I do it en-masse, Squeak slows to a crawl.  I am going to give it a few hours to see what happens...Workspaces are starting to appear. The limited number of individual doits work as fast as always. just a heads up, nothing to get concerned about. cordially, t -------------- next part -------------- An HTML attachment was scrubbed... URL: From lewis at mail.msen.com Sat Feb 6 15:51:25 2021 From: lewis at mail.msen.com (David T. Lewis) Date: Sat, 6 Feb 2021 10:51:25 -0500 Subject: [squeak-dev] MCM configuration versioning active on source.squeak.org Message-ID: <20210206155125.GA21716@shell.msen.com> The source.squeak.org server now has MonticelloConfigurations-dtl.161 installed, so both squeaksource.com and source.squeak.org will now save MCM configurations with comments and version information. It may be necessary to do MCFileBasedRepository flushAllCaches in your image, but afterwards the version information will be present for newly saved MCM configs. Try browsing update-dtl.483.mcm for an example. See MonticelloConfigurations-dtl.161 for details: Name: MonticelloConfigurations-dtl.161 Time: 9 May 2020, 10:22:36.276105 am A MCConfigurationExtended is a configuration with author initials, timestamp, UUID identifier, comment, and a list of prior versions. Its external storage format is organized for compatibility with MCConfiguration, such that an image wtih support for only MCConfiguration can use configurations saved from a MCConfigurationExtended. The intended use is to enable documentation of configuration maps, and to allow modifications to a configuration map without loss of version history. When editing an MCConfiguration, a copyForEdit of the configuration is modfied, leaving the prior configuration in the version history. When saving an edited version, an editor window allows a version comment to be entered for the new configuration. Version history for a saved MCConfiguration is trimmed to a maximum of 10 prior versions to maintain reasonable storage size. Full version history can be reconstructed based on the UUID identifiers. MCConfigurationBrowser provides a "Versions" button to open an explorer on the version history of a configuration. No other support for browsing version history and comments is provided. MCConfigurationExtended is fully backward compatible such that saved versions will be rendered as simple MCConfiguration without version history in an image that lacks support for the extended format. A SqueakSource server must have this update applied before it can render a saved MCConfigurationExtended. From gettimothy at zoho.com Sat Feb 6 16:29:47 2021 From: gettimothy at zoho.com (gettimothy) Date: Sat, 06 Feb 2021 11:29:47 -0500 Subject: [squeak-dev] interesting slowness (not important, just an FYI) In-Reply-To: <17777bf98d4.f034827449640.1173019270683908797@zoho.com> References: <17777bf98d4.f034827449640.1173019270683908797@zoho.com> Message-ID: <177782d8e7c.ac6f17ab50499.931291489568652147@zoho.com> I narrowed it down to one range... (16r010000  asCharacter to:16r01007F asCharacter) editWithLabel:'Linear B Syllabary'. This is with the various Unifont installed. It displays pretty well in the browser I can inspect the WideString by inspecting (16r010000  asCharacter to:16r01007F asCharacter) When I click on "self" of the inspector, the image freezes up. hmmmm. Well, I can click through the individual elements and see if they match with what is displayed on the web page and then find the element that hangs the image and voila--theoretically speaking of course. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gettimothy at zoho.com Sat Feb 6 17:15:07 2021 From: gettimothy at zoho.com (gettimothy) Date: Sat, 06 Feb 2021 12:15:07 -0500 Subject: [squeak-dev] interesting slowness (not important, just an FYI) In-Reply-To: <177782d8e7c.ac6f17ab50499.931291489568652147@zoho.com> References: <17777bf98d4.f034827449640.1173019270683908797@zoho.com> <177782d8e7c.ac6f17ab50499.931291489568652147@zoho.com> Message-ID: <17778571062.10d70b9a650834.2104914185316614021@zoho.com> TTCFontDescription at: 65537  is throwing an Error: subscript is out of bounds: 65537. So, that is where I investigate next. back later. ---- On Sat, 06 Feb 2021 11:29:47 -0500 gettimothy via Squeak-dev wrote ---- I narrowed it down to one range... (16r010000  asCharacter to:16r01007F asCharacter) editWithLabel:'Linear B Syllabary'. This is with the various Unifont installed. It displays pretty well in the browser I can inspect the WideString by inspecting (16r010000  asCharacter to:16r01007F asCharacter) When I click on "self" of the inspector, the image freezes up. hmmmm. Well, I can click through the individual elements and see if they match with what is displayed on the web page and then find the element that hangs the image and voila--theoretically speaking of course. -------------- next part -------------- An HTML attachment was scrubbed... URL: From m at jaromir.net Sat Feb 6 17:17:50 2021 From: m at jaromir.net (Jaromir) Date: Sat, 6 Feb 2021 11:17:50 -0600 (CST) Subject: [squeak-dev] SharedQueue bug in #nextOrNilSuchThat Message-ID: <1612631870105-0.post@n4.nabble.com> Test for SharedQueue >> nextOrNilSuchThat fails due to incorrect implementation of #nextOrNilSuchThat - I at least assume the semantics should be the same as for SharedQueue2 and satisfy the test (i.e. pick one item, leave the rest be). I propose this correction to #nextOrNilSuchThat (the original one skipped AND DISCARDED all items before the item found): nextOrNilSuchThat: aBlock "Answer the next object that satisfies aBlock, skipping any intermediate objects. If no object has been sent, answer and leave me intact. NOTA BENE: aBlock MUST NOT contain a non-local return (^)." ^accessProtect critical: [ | value readPos | value := nil. readPos := readPosition. [ readPos < writePosition and: [ value isNil ] ] whileTrue: [ value := contentsArray at: readPos. readPos := readPos + 1. (aBlock value: value) ifFalse: [ value := nil ] ifTrue: [ readSynch waitIfLocked: [ ^nil ]. "We found the value, but someone else booked it." *readPos-1 to: readPosition+1 by: -1 do: [ :j | contentsArray at: j put: (contentsArray at: j-1) ]. contentsArray at: readPosition put: nil. readPosition := readPosition+1 *] ]. value ]. Is this the right way to propose changes and fixes? Thanks Cheers, Jaromir Tested at Squeak6.0alpha-20182-64bit.image -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From eric.gade at gmail.com Sat Feb 6 18:21:06 2021 From: eric.gade at gmail.com (Eric Gade) Date: Sat, 6 Feb 2021 13:21:06 -0500 Subject: [squeak-dev] interesting slowness (not important, just an FYI) In-Reply-To: <17778571062.10d70b9a650834.2104914185316614021@zoho.com> References: <17777bf98d4.f034827449640.1173019270683908797@zoho.com> <177782d8e7c.ac6f17ab50499.931291489568652147@zoho.com> <17778571062.10d70b9a650834.2104914185316614021@zoho.com> Message-ID: Hi Tim, On Sat, Feb 6, 2021 at 12:15 PM gettimothy via Squeak-dev < squeak-dev at lists.squeakfoundation.org> wrote: > > TTCFontDescription at: 65537 is throwing an Error: subscript is out of > bounds: 65537. > > > So, that is where I investigate next. > This is the same issue I had last year. I am not sure my diagnosis was correct (see this thread , especially the final message), but from what I recall TTF uses so-called GSUB records to render code points above 65536 or something, and that the implementation of TTF in Squeak is not set up to handle such records. I might be wrong about that though. -- Eric -------------- next part -------------- An HTML attachment was scrubbed... URL: From lewis at mail.msen.com Sat Feb 6 18:43:27 2021 From: lewis at mail.msen.com (David T. Lewis) Date: Sat, 6 Feb 2021 13:43:27 -0500 Subject: [squeak-dev] interesting slowness (not important, just an FYI) In-Reply-To: <17778571062.10d70b9a650834.2104914185316614021@zoho.com> References: <17777bf98d4.f034827449640.1173019270683908797@zoho.com> <177782d8e7c.ac6f17ab50499.931291489568652147@zoho.com> <17778571062.10d70b9a650834.2104914185316614021@zoho.com> Message-ID: <20210206184327.GA45534@shell.msen.com> On Sat, Feb 06, 2021 at 12:15:07PM -0500, gettimothy via Squeak-dev wrote: > TTCFontDescription at: 65537?? is throwing an Error: subscript is out of bounds: 65537. > > > So, that is where I investigate next. > > > back later. > > > > ---- On Sat, 06 Feb 2021 11:29:47 -0500 gettimothy via Squeak-dev wrote ---- > > > I narrowed it down to one range... > > > > > > (16r010000?? asCharacter to:16r01007F asCharacter) editWithLabel:'Linear B Syllabary'. > It's probably just a cut an paste thing in your email, but look for a hidden unprintable character after the 16r010000 in your code. My ascii email client is showing something there, but it is not visible when I look at your message on gmail. iDave From gettimothy at zoho.com Sat Feb 6 19:40:12 2021 From: gettimothy at zoho.com (gettimothy) Date: Sat, 06 Feb 2021 14:40:12 -0500 Subject: [squeak-dev] interesting slowness (not important, just an FYI) In-Reply-To: <20210206184327.GA45534@shell.msen.com> References: <17777bf98d4.f034827449640.1173019270683908797@zoho.com> <177782d8e7c.ac6f17ab50499.931291489568652147@zoho.com> <17778571062.10d70b9a650834.2104914185316614021@zoho.com> <20210206184327.GA45534@shell.msen.com> Message-ID: <17778dbe28f.11251ddf147390.7866410713744860368@zoho.com> Will do later tonight. Thx ---- On Sat, 06 Feb 2021 13:43:27 -0500 lewis at mail.msen.com wrote ---- On Sat, Feb 06, 2021 at 12:15:07PM -0500, gettimothy via Squeak-dev wrote: > TTCFontDescription at: 65537?? is throwing an Error: subscript is out of bounds: 65537. > > > So, that is where I investigate next. > > > back later. > > > > ---- On Sat, 06 Feb 2021 11:29:47 -0500 gettimothy via Squeak-dev wrote ---- > > > I narrowed it down to one range... > > > > > > (16r010000?? asCharacter to:16r01007F asCharacter) editWithLabel:'Linear B Syllabary'. > It's probably just a cut an paste thing in your email, but look for a hidden unprintable character after the 16r010000 in your code. My ascii email client is showing something there, but it is not visible when I look at your message on gmail. iDave -------------- next part -------------- An HTML attachment was scrubbed... URL: From gettimothy at zoho.com Sat Feb 6 19:44:06 2021 From: gettimothy at zoho.com (gettimothy) Date: Sat, 06 Feb 2021 14:44:06 -0500 Subject: [squeak-dev] interesting slowness (not important, just an FYI) In-Reply-To: References: <17777bf98d4.f034827449640.1173019270683908797@zoho.com> <177782d8e7c.ac6f17ab50499.931291489568652147@zoho.com> <17778571062.10d70b9a650834.2104914185316614021@zoho.com> Message-ID: <17778df73e4.10cafab3947264.1571029226711511454@zoho.com> Hi Eric I will read later tonight, thx. If you have time, what is "the font stack" in Squeak? I know via the font import tool that 'something' is stored in image. how do we view that something? The TTC stack....is that the intermediarry between the in image font something and the tools that want to use it? Thx for your time ---- On Sat, 06 Feb 2021 13:21:06 -0500 eric.gade at gmail.com wrote ---- Hi Tim, On Sat, Feb 6, 2021 at 12:15 PM gettimothy via Squeak-dev wrote: TTCFontDescription at: 65537  is throwing an Error: subscript is out of bounds: 65537. So, that is where I investigate next.   This is the same issue I had last year. I am not sure my diagnosis was correct (see this thread, especially the final message), but from what I recall TTF uses so-called GSUB records to render code points above 65536 or something, and that the implementation of TTF in Squeak is not set up to handle such records. I might be wrong about that though. -- Eric -------------- next part -------------- An HTML attachment was scrubbed... URL: From eric.gade at gmail.com Sat Feb 6 21:12:43 2021 From: eric.gade at gmail.com (Eric Gade) Date: Sat, 6 Feb 2021 16:12:43 -0500 Subject: [squeak-dev] interesting slowness (not important, just an FYI) In-Reply-To: <17778df73e4.10cafab3947264.1571029226711511454@zoho.com> References: <17777bf98d4.f034827449640.1173019270683908797@zoho.com> <177782d8e7c.ac6f17ab50499.931291489568652147@zoho.com> <17778571062.10d70b9a650834.2104914185316614021@zoho.com> <17778df73e4.10cafab3947264.1571029226711511454@zoho.com> Message-ID: Hi Tim, On Sat, Feb 6, 2021 at 2:44 PM gettimothy wrote: > > If you have time, what is "the font stack" in Squeak? > > I know via the font import tool that 'something' is stored in image. > how do we view that something? > > The TTC stack....is that the intermediarry between the in image font > something and the tools that want to use it? > > Thx for your time > I am really not familiar enough with it all to say anything definitively, and I don't know as much about fonts generally as I should. My understanding is that the "normal" fonts are StrikeFonts, which is a bitmap font format (I think?) The TTC stuff is a kind of extension of the default font management classes, but I'm not exactly sure how they fit together. As you've probably found, poking around those classes and trying to piece together what's happening takes a lot of time. Sorry if this is not much help! -- Eric -------------- next part -------------- An HTML attachment was scrubbed... URL: From lewis at mail.msen.com Sat Feb 6 22:04:54 2021 From: lewis at mail.msen.com (David T. Lewis) Date: Sat, 6 Feb 2021 17:04:54 -0500 Subject: [squeak-dev] SharedQueue bug in #nextOrNilSuchThat In-Reply-To: <1612631870105-0.post@n4.nabble.com> References: <1612631870105-0.post@n4.nabble.com> Message-ID: <20210206220454.GA74893@shell.msen.com> On Sat, Feb 06, 2021 at 11:17:50AM -0600, Jaromir wrote: > Test for SharedQueue >> nextOrNilSuchThat fails due to incorrect > implementation of #nextOrNilSuchThat - I at least assume the semantics > should be the same as for SharedQueue2 and satisfy the test (i.e. pick one > item, leave the rest be). > > I propose this correction to #nextOrNilSuchThat (the original one skipped > AND DISCARDED all items before the item found): > > nextOrNilSuchThat: aBlock > "Answer the next object that satisfies aBlock, skipping any intermediate > objects. > If no object has been sent, answer and leave me intact. > NOTA BENE: aBlock MUST NOT contain a non-local return (^)." > > ^accessProtect critical: [ > | value readPos | > value := nil. > readPos := readPosition. > [ readPos < writePosition and: [ value isNil ] ] whileTrue: [ > value := contentsArray at: readPos. > readPos := readPos + 1. > (aBlock value: value) > ifFalse: [ value := nil ] > ifTrue: [ > readSynch waitIfLocked: [ ^nil ]. "We found the value, but someone else > booked it." > *readPos-1 to: readPosition+1 by: -1 do: [ :j | contentsArray at: j > put: (contentsArray at: j-1) ]. > contentsArray at: readPosition put: nil. > readPosition := readPosition+1 *] ]. > value ]. > > > Is this the right way to propose changes and fixes? Thanks Hi Jaromir, Yes it is perfectly fine to post suggestions to the list like this, especially if you are asking for discussion of ideas like this. Please also read about the contribution process here: https://squeak.org/development_process/ If you have a specific change or improvement to contribute, it is good to publish your change to the inbox, and then discuss it here on the list also. Dave From m at jaromir.net Sat Feb 6 22:32:18 2021 From: m at jaromir.net (Jaromir) Date: Sat, 6 Feb 2021 16:32:18 -0600 (CST) Subject: [squeak-dev] SharedQueue bug in #nextOrNilSuchThat In-Reply-To: <20210206220454.GA74893@shell.msen.com> References: <1612631870105-0.post@n4.nabble.com> <20210206220454.GA74893@shell.msen.com> Message-ID: <1612650738380-0.post@n4.nabble.com> Perfect, thanks, Dave. I'll try the Inbox then to see how it works. Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From gettimothy at zoho.com Sun Feb 7 08:19:00 2021 From: gettimothy at zoho.com (gettimothy) Date: Sun, 07 Feb 2021 03:19:00 -0500 Subject: [squeak-dev] interesting slowness (not important, just an FYI) In-Reply-To: References: <17777bf98d4.f034827449640.1173019270683908797@zoho.com> <177782d8e7c.ac6f17ab50499.931291489568652147@zoho.com> <17778571062.10d70b9a650834.2104914185316614021@zoho.com> <17778df73e4.10cafab3947264.1571029226711511454@zoho.com> Message-ID: <1777b929740.f6cf3bda55754.8448902585526523764@zoho.com> Thx Eric. I will continue to poke. I will keep you informed as I find stuff. cheers, t ---- On Sat, 06 Feb 2021 16:12:43 -0500 Eric Gade wrote ---- Hi Tim, On Sat, Feb 6, 2021 at 2:44 PM gettimothy wrote: If you have time, what is "the font stack" in Squeak? I know via the font import tool that 'something' is stored in image. how do we view that something? The TTC stack....is that the intermediarry between the in image font something and the tools that want to use it? Thx for your time I am really not familiar enough with it all to say anything definitively, and I don't know as much about fonts generally as I should. My understanding is that the "normal" fonts are StrikeFonts, which is a bitmap font format (I think?) The TTC stuff is a kind of extension of the default font management classes, but I'm not exactly sure how they fit together. As you've probably found, poking around those classes and trying to piece together what's happening takes a lot of time. Sorry if this is not much help! -- Eric -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Sun Feb 7 08:42:11 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sun, 7 Feb 2021 08:42:11 0000 Subject: [squeak-dev] The Inbox: Collections-jar.924.mcz Message-ID: A new version of Collections was added to project The Inbox: http://source.squeak.org/inbox/Collections-jar.924.mcz ==================== Summary ==================== Name: Collections-jar.924 Author: jar Time: 7 February 2021, 9:42:07.649004 am UUID: 073b26bc-8e5e-ba41-9aac-9d424bbe6848 Ancestors: Collections-dtl.923 Fixes SharedQueue >> nextOrNilSuchThat bug to pass the existing test =============== Diff against Collections-dtl.923 =============== Item was changed: ----- Method: SharedQueue>>nextOrNilSuchThat: (in category 'accessing') ----- nextOrNilSuchThat: aBlock "Answer the next object that satisfies aBlock, skipping any intermediate objects. If no object has been sent, answer and leave me intact. NOTA BENE: aBlock MUST NOT contain a non-local return (^)." ^accessProtect critical: [ | value readPos | value := nil. readPos := readPosition. [ readPos < writePosition and: [ value isNil ] ] whileTrue: [ value := contentsArray at: readPos. readPos := readPos + 1. (aBlock value: value) ifFalse: [ value := nil ] ifTrue: [ readSynch waitIfLocked: [ ^nil ]. "We found the value, but someone else booked it." + readPos-1 to: readPosition+1 by: -1 do: [ :j | contentsArray at: j put: (contentsArray at: j-1) ]. + contentsArray at: readPosition put: nil. + readPosition := readPosition+1 ] ]. - readPosition to: readPos - 1 do: [ :j | contentsArray at: j put: nil ]. - readPosition := readPos ] ]. value ]. "=== q := SharedQueue new. 1 to: 10 do: [ :i | q nextPut: i]. c := OrderedCollection new. [ v := q nextOrNilSuchThat: [ :e | e odd]. v notNil ] whileTrue: [ c add: {v. q size} ]. {c. q} explore ==="! From gettimothy at zoho.com Sun Feb 7 10:45:26 2021 From: gettimothy at zoho.com (gettimothy) Date: Sun, 07 Feb 2021 05:45:26 -0500 Subject: [squeak-dev] More Fonts digging In-Reply-To: <17778df73e4.10cafab3947264.1571029226711511454@zoho.com> References: <17777bf98d4.f034827449640.1173019270683908797@zoho.com> <177782d8e7c.ac6f17ab50499.931291489568652147@zoho.com> <17778571062.10d70b9a650834.2104914185316614021@zoho.com> <17778df73e4.10cafab3947264.1571029226711511454@zoho.com> Message-ID: <1777c18a808.e1f7ea6e56316.6819799799866604262@zoho.com> Hi Eric. I am building a Dia diagram of the Font's stuff and beginning to get some insights. It looks like TTFontDescription is the holder of the glyphs for a font that is stored in squeak. (memory? image?). There is a parallel construct TTFileDescription that does similar stuff, but off of the file system. Let's stick with TTFontDescription.... Browse TTFontDescription class  and trow in an "inspect" as below.... descriptionNamed: descriptionName Descriptions inspect. ^ Descriptions detect: [:f | f first name = descriptionName] ifNone: [Default]. I added that Descriptions inspect. It shows a Set. Browsing that set, I was able to pick one of the entries in the Set.  The entries are very important as they hold the guts of the fonts.: TTFontDescription. Pick one in the entries in the set and send it the message 'first name' You can then plug that into the descriptionNamed and see the TTFontDescription (There is a similar class TTFileDescription) I have Unifont installed so I send the message: TTFontDescription descriptionNamed:'Unifont' per the name gleaned from above. In the TTCFontDescription, there is a glyphTable and a bunch of glyphs. So, this looks like the bloody guts where the error occurs...maybe. Investigating this, I learned something. Glyphs are not "Pictures" that are plopped into a space on a "screen" rather, they are instructions for drawing a figure. How it is done, I do not know yet. cheers, t -------------- next part -------------- An HTML attachment was scrubbed... URL: From lewis at mail.msen.com Sun Feb 7 15:31:12 2021 From: lewis at mail.msen.com (David T. Lewis) Date: Sun, 7 Feb 2021 10:31:12 -0500 Subject: [squeak-dev] The Inbox: Collections-jar.924.mcz In-Reply-To: References: Message-ID: <20210207153112.GA28116@shell.msen.com> This looks good to me, and it fixes the failing test. Note that none of the historical versions of SharedQueue>>nextOrNilSuchThat: pass the test, but the issue became visible after CollectionsTests-eem.342 last September when the existing test for SharedQueue2 was applied to SharedQueue as well. It would be good if Levente or Nicolas can review this, but +1 from me. Thanks Jaromir for putting this in the inbox :-) Dave On Sun, Feb 07, 2021 at 08:42:11AM +0000, commits at source.squeak.org wrote: > A new version of Collections was added to project The Inbox: > http://source.squeak.org/inbox/Collections-jar.924.mcz > > ==================== Summary ==================== > > Name: Collections-jar.924 > Author: jar > Time: 7 February 2021, 9:42:07.649004 am > UUID: 073b26bc-8e5e-ba41-9aac-9d424bbe6848 > Ancestors: Collections-dtl.923 > > Fixes SharedQueue >> nextOrNilSuchThat bug to pass the existing test > > =============== Diff against Collections-dtl.923 =============== > > Item was changed: > ----- Method: SharedQueue>>nextOrNilSuchThat: (in category 'accessing') ----- > nextOrNilSuchThat: aBlock > "Answer the next object that satisfies aBlock, skipping any intermediate objects. > If no object has been sent, answer and leave me intact. > NOTA BENE: aBlock MUST NOT contain a non-local return (^)." > > ^accessProtect critical: [ > | value readPos | > value := nil. > readPos := readPosition. > [ readPos < writePosition and: [ value isNil ] ] whileTrue: [ > value := contentsArray at: readPos. > readPos := readPos + 1. > (aBlock value: value) > ifFalse: [ value := nil ] > ifTrue: [ > readSynch waitIfLocked: [ ^nil ]. "We found the value, but someone else booked it." > + readPos-1 to: readPosition+1 by: -1 do: [ :j | contentsArray at: j put: (contentsArray at: j-1) ]. > + contentsArray at: readPosition put: nil. > + readPosition := readPosition+1 ] ]. > - readPosition to: readPos - 1 do: [ :j | contentsArray at: j put: nil ]. > - readPosition := readPos ] ]. > value ]. > "=== > q := SharedQueue new. > 1 to: 10 do: [ :i | q nextPut: i]. > c := OrderedCollection new. > [ > v := q nextOrNilSuchThat: [ :e | e odd]. > v notNil > ] whileTrue: [ > c add: {v. q size} > ]. > {c. q} explore > ==="! > > From giovanni at corriga.net Sun Feb 7 22:13:09 2021 From: giovanni at corriga.net (Giovanni Corriga) Date: Sun, 7 Feb 2021 22:13:09 +0000 Subject: [squeak-dev] UK Smalltalk User Group meeting - Wednesday February 24th Message-ID: The next meeting of the UK Smalltalk User Group will be on Wednesday, February 24th. Christian Haider will guide us in a tour of the Amber dialect of Smalltalk and its Silk web framework. In his own words... Amber [1], created by Nicolas Petton, is a Smalltalk implemented in JavaScript running in a web browser. Silk [2], written by the Amber maintainer Herby Vojčík, is a web framework in Amber. I was looking for a good solution for the web for a long time. At the last ESUG, I was bugging everybody about a Smalltalk in the browser, because I decided to redo the frontend of my current project [3] in Smalltalk instead of JavaScript. There were some developments, but only Amber was available. So I tried it for real on a little side project [4] to see if this route is viable - spoiler: it is! Silk, the web framework, caught my attention and I fell in love with it. Silk is very simple, straight forward and powerful, just the properties I love Smalltalk for. A Silk is basically a facade for a DOM node in the browser allowing the programmer to build up and manipulate the DOM in a direct way. Silk is so easy and intuitive that it never stood in the way and just worked. So, I could just concentrate on the complexities of the web (and the app). In this presentation I will walk you through the setup, show you the Amber tools and explore what you can do with Silk. I will try to justify my enthusiasm and appreciation for Silk :-). About me: My name is Christian Haider [5] and I use Smalltalk since the mid-90s. Fortunately, I earn my living with Smalltalk and use it on a daily bases (mostly VisualWorks). I like programming UIs and graphics. My largest open source contribution is a PDF library [6], the most significant one is Values [7]. [1] https://amber-lang.net/ [2] https://smalltalkrenaissance.wordpress.com/2015/06/29/silk-is-just-too-flexible/ [3] https://unsere-gelder.de/ (in German) [4] https://covidcrt.uber.space/ (sources at https://github.com/ChristianHaider/CoViD19UI) [5] https://christianhaider.de/ (in German) [6] https://wiki.pdftalk.de/doku.php [7] https://wiki.pdftalk.de/doku.php?id=complexvalues Given the current COVID-19 restrictions, this will be an online meeting from home. If you'd like to join us, please sign up in advance on the meeting's Meetup page ( https://www.meetup.com/UKSTUG/events/cbklbryccdbgc/ ) to receive the meeting details. Don’t forget to bring your laptop and drinks! * * -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Mon Feb 8 19:25:23 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Mon, 8 Feb 2021 19:25:23 0000 Subject: [squeak-dev] The Inbox: CollectionsTests-jar.349.mcz Message-ID: A new version of CollectionsTests was added to project The Inbox: http://source.squeak.org/inbox/CollectionsTests-jar.349.mcz ==================== Summary ==================== Name: CollectionsTests-jar.349 Author: jar Time: 8 February 2021, 8:25:19.407373 pm UUID: f484ba2b-2035-b046-9222-c3e4e42a7ad4 Ancestors: CollectionsTests-ul.348 Test to show differing SharedQueue and SharedQueue2 semantics =============== Diff against CollectionsTests-ul.348 =============== Item was added: + ----- Method: AbstractSharedQueueTest>>testContention2 (in category 'tests') ----- + testContention2 + "and here's a test case that distunguishes SharedQueue from SharedQueue2 semantics: + SharedQueue2 produces a sequence #(5 10 15) while SharedQueue produces #(5 15 10)" + + | q r1 r2 r3 | + q := self queueClass new. + + [ r1 := q next. q nextPut: 15. r3 := q next ] fork. + [ r2 := q next ] fork. + + Processor yield. "let the above two threads block" + + q nextPut: 5. + Processor yield. "let the first thread above proceed" + + q nextPut: 10. + Processor yield. "let the unfinished thread above finish" + + q class = SharedQueue2 ifTrue: [ + self assert: 5 equals: r1. + self assert: 10 equals: r2. + self assert: 15 equals: r3. + self assert: nil equals: q nextOrNil ]. + + q class = SharedQueue ifTrue: [ + self assert: 5 equals: r1. + self assert: 15 equals: r2. + self assert: 10 equals: r3. + self assert: nil equals: q nextOrNil ]. + + "SharedQueue2 implementation using a Monitor checks the queue for available data while + the SharedQueue implementation based on a Semaphore checks for excessSignals > 0, + which results in these two different outcomes"! From m at jaromir.net Mon Feb 8 19:27:27 2021 From: m at jaromir.net (Jaromir) Date: Mon, 8 Feb 2021 13:27:27 -0600 (CST) Subject: [squeak-dev] The Inbox: CollectionsTests-jar.349.mcz In-Reply-To: References: Message-ID: <1612812447102-0.post@n4.nabble.com> I propose a test to show the semantics of the two implementations of shared queue ended up slightly different: SharedQueue2 implementation using the Monitor checks the queue for available data while the SharedQueue implementation based on the Semaphore checks for excessSignals > 0, which results in these two different outcomes of the test: SharedQueue2 produces a sequence #(5 10 15) while SharedQueue produces #(5 15 10) for the same code. Regards, Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From commits at source.squeak.org Mon Feb 8 21:03:04 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Mon, 8 Feb 2021 21:03:04 0000 Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz Message-ID: A new version of Kernel was added to project The Inbox: http://source.squeak.org/inbox/Kernel-jar.1368.mcz ==================== Summary ==================== Name: Kernel-jar.1368 Author: jar Time: 8 February 2021, 10:03:00.688403 pm UUID: 095338a7-d694-3e4c-97dd-1f33e4d08156 Ancestors: Kernel-eem.1367 Fix incorrect #priority: behavior blocking higher priority processes =============== Diff against Kernel-eem.1367 =============== Item was changed: ----- Method: Process>>priority: (in category 'accessing') ----- priority: anInteger "Set the receiver's priority to anInteger." (anInteger >= Processor lowestPriority and:[anInteger <= Processor highestPriority]) + ifTrue: [ + priority := anInteger. + self isActiveProcess ifTrue: [ [ ] forkAt: Processor highestPriority] ] - ifTrue: [priority := anInteger] ifFalse: [self error: 'Invalid priority: ', anInteger printString]! From commits at source.squeak.org Mon Feb 8 21:06:11 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Mon, 8 Feb 2021 21:06:11 0000 Subject: [squeak-dev] The Inbox: KernelTests-jar.393.mcz Message-ID: A new version of KernelTests was added to project The Inbox: http://source.squeak.org/inbox/KernelTests-jar.393.mcz ==================== Summary ==================== Name: KernelTests-jar.393 Author: jar Time: 8 February 2021, 10:06:09.126403 pm UUID: af94938b-d43a-b94c-b306-922ab65afb78 Ancestors: KernelTests-eem.392 Test for Process>>priority: related to fix Kernel-jar.1368 =============== Diff against KernelTests-eem.392 =============== Item was added: + ----- Method: ProcessTest>>testPriority (in category 'tests') ----- + testPriority + "test whether #priority: preempts active process to allow higher priority processes run" + + | val oldPriority | + val := nil. + oldPriority := Processor activePriority. + Processor activeProcess priority: oldPriority + 2. + [ val := false ] forkAt: oldPriority + 1. + [ val := true ] forkAt: oldPriority. + Processor activeProcess priority: oldPriority. + self assert: val equals: Smalltalk vm processPreemptionYields! From m at jaromir.net Mon Feb 8 21:13:42 2021 From: m at jaromir.net (Jaromir) Date: Mon, 8 Feb 2021 15:13:42 -0600 (CST) Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: References: Message-ID: <1612818822033-0.post@n4.nabble.com> I propose the following change for consideration / discussion: modify Process>>#priority behavior so that it guarantees no higher priority processes remain waiting before active process continues at a lower priority. The proposed fix only affects active process priority changes. Replacing the method by a primitive may also be considered. Impact: #valueUnpreemptively and #valueAt: methods are currently affected by the #priority:'s incorrect behavior and need to be amended in any case. This fix would cover both of them. If this fix is accepted the two methods should remove `Processor yield` line which is not working anyway. Related issue with examples: http://forum.world.st/Process-gt-gt-priority-behavior-grossly-incorrect-Transcript-losing-output-td5126836.html Test: KernelTests-jar.393 (The Inbox) ``` testPriority "test whether #priority: preempts active process to allow higher priority processes run" | val oldPriority | val := nil. oldPriority := Processor activePriority. Processor activeProcess priority: oldPriority + 2. [ val := false ] forkAt: oldPriority + 1. [ val := true ] forkAt: oldPriority. Processor activeProcess priority: oldPriority. self assert: val equals: Smalltalk vm processPreemptionYields ``` The test respects the current setting of #processPreemptionYields. -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From m at jaromir.net Mon Feb 8 22:32:27 2021 From: m at jaromir.net (Jaromir) Date: Mon, 8 Feb 2021 16:32:27 -0600 (CST) Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: <1612818822033-0.post@n4.nabble.com> References: <1612818822033-0.post@n4.nabble.com> Message-ID: <1612823547920-0.post@n4.nabble.com> For some reason the proposed fix also fixes the Transcript losing output intermittently problem mentioned in http://forum.world.st/Process-gt-gt-priority-behavior-grossly-incorrect-Transcript-losing-output-td5126836.html => it looks like the current #priority bug influences also Transcript behavior and who knows what else... -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From leves at caesar.elte.hu Tue Feb 9 12:54:33 2021 From: leves at caesar.elte.hu (Levente Uzonyi) Date: Tue, 9 Feb 2021 13:54:33 +0100 (CET) Subject: [squeak-dev] The Inbox: Collections-jar.924.mcz In-Reply-To: <20210207153112.GA28116@shell.msen.com> References: <20210207153112.GA28116@shell.msen.com> Message-ID: Hi David, On Sun, 7 Feb 2021, David T. Lewis wrote: > This looks good to me, and it fixes the failing test. > > Note that none of the historical versions of SharedQueue>>nextOrNilSuchThat: > pass the test, but the issue became visible after CollectionsTests-eem.342 > last September when the existing test for SharedQueue2 was applied to > SharedQueue as well. > > It would be good if Levente or Nicolas can review this, but +1 from me. The fix looks right in the sense that it does what the test case requires. But it may affect the way events are processed. The only sender of this method is EventSensor which may rely on the current behavior. So, I would like someone who understands how EventSensor works confirm that the change is okay before pushing it to the Trunk. Levente > > Thanks Jaromir for putting this in the inbox :-) > > Dave > > > On Sun, Feb 07, 2021 at 08:42:11AM +0000, commits at source.squeak.org wrote: >> A new version of Collections was added to project The Inbox: >> http://source.squeak.org/inbox/Collections-jar.924.mcz >> >> ==================== Summary ==================== >> >> Name: Collections-jar.924 >> Author: jar >> Time: 7 February 2021, 9:42:07.649004 am >> UUID: 073b26bc-8e5e-ba41-9aac-9d424bbe6848 >> Ancestors: Collections-dtl.923 >> >> Fixes SharedQueue >> nextOrNilSuchThat bug to pass the existing test >> >> =============== Diff against Collections-dtl.923 =============== >> >> Item was changed: >> ----- Method: SharedQueue>>nextOrNilSuchThat: (in category 'accessing') ----- >> nextOrNilSuchThat: aBlock >> "Answer the next object that satisfies aBlock, skipping any intermediate objects. >> If no object has been sent, answer and leave me intact. >> NOTA BENE: aBlock MUST NOT contain a non-local return (^)." >> >> ^accessProtect critical: [ >> | value readPos | >> value := nil. >> readPos := readPosition. >> [ readPos < writePosition and: [ value isNil ] ] whileTrue: [ >> value := contentsArray at: readPos. >> readPos := readPos + 1. >> (aBlock value: value) >> ifFalse: [ value := nil ] >> ifTrue: [ >> readSynch waitIfLocked: [ ^nil ]. "We found the value, but someone else booked it." >> + readPos-1 to: readPosition+1 by: -1 do: [ :j | contentsArray at: j put: (contentsArray at: j-1) ]. >> + contentsArray at: readPosition put: nil. >> + readPosition := readPosition+1 ] ]. >> - readPosition to: readPos - 1 do: [ :j | contentsArray at: j put: nil ]. >> - readPosition := readPos ] ]. >> value ]. >> "=== >> q := SharedQueue new. >> 1 to: 10 do: [ :i | q nextPut: i]. >> c := OrderedCollection new. >> [ >> v := q nextOrNilSuchThat: [ :e | e odd]. >> v notNil >> ] whileTrue: [ >> c add: {v. q size} >> ]. >> {c. q} explore >> ==="! >> >> From marcel.taeumel at hpi.de Tue Feb 9 16:43:52 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Tue, 9 Feb 2021 17:43:52 +0100 Subject: [squeak-dev] Squeak Winter Demos, 2021/03/06, 3 p.m. - 6 p.m. CET, virtual Message-ID: Dear Squeakers, Smalltalkers, and friends of object-oriented, interactive programming environments! We hope that you are doing well in these difficult times. Please take care of yourself and your peers. We cordially invite you to the “Squeak Winter Demos”, which are organized by the club of German-speaking Squeakers (“Squeak Deutschland e.V.”). We are going to fill that meeting with exciting talks, demos, and discussions. You want to attend or have more questions? Maybe even a proposal for a demo/talk/discussion? Feel free to talk to us so that we can better include your idea in the schedule. Since we want to keep the meeting as flexible as possible, every speaker should plan for about 20 minutes. When? Saturday, March 6, 2021, 3 p.m. to 6 p.m. CET (6 a.m. to 9 a.m. PST) Where? The event will take place as a Zoom call. You need a webcam (maybe with a microphone) and a recent Web browser such as Firefox, Chrome, Edge, or Safari. Alternatively, you can download an app for your operating system via https://zoom.us/download [https://zoom.us/download]. We will share the login data for the virtual meeting here on the day of the event. What will happen? We are currently in the process of planning talks and demos. Feel free to contribute with a short demo or experience report yourself – even on the fly if you want to! We welcome non-members to the meeting. :) Here is a preliminary agenda: * Like the Babylonias: Programming with Examples * Fast and colorful: OpenGL in Squeak * Use the Entire Canvas: Block-based Programming * Spot off, Morph on: Squeak Game Showcase 2020 * It’s Broken! How to debug the debugger =) * Social Media? A Telegram Bot for Squeak … and those who find the time but are not so fluent in German: We always welcome non-German-speaking Squeakers, too! We suppose that you will understand the live demonstrations anyway. :) We will be able to translate technical details or questions into English as well. Stay healthy. Best, Marcel Taeumel --- Squeak Deutschland e.V. c/o Freudenberg, Potsdamer Str. 3a 39114 Magdeburg (GERMANY) E-Mail: info at squeak-ev.de [mailto:info at squeak-ev.de] Internet: http://www.squeak.de/squeakev [http://www.squeak.de/squeakev] -------------- next part -------------- An HTML attachment was scrubbed... URL: From karlramberg at gmail.com Tue Feb 9 21:39:36 2021 From: karlramberg at gmail.com (karl ramberg) Date: Tue, 9 Feb 2021 22:39:36 +0100 Subject: [squeak-dev] Squeak Winter Demos, 2021/03/06, 3 p.m. - 6 p.m. CET, virtual In-Reply-To: References: Message-ID: Cool :-D Best, Karl On Tue, Feb 9, 2021 at 5:44 PM Marcel Taeumel wrote: > *Dear Squeakers, Smalltalkers, and friends of object-oriented, interactive > programming environments!* > > We hope that you are doing well in these difficult times. Please take care > of yourself and your peers. > > We cordially invite you to the “Squeak Winter Demos”, which are organized > by the club of German-speaking Squeakers (“Squeak Deutschland e.V.”). We > are going to fill that meeting with exciting talks, demos, and discussions. > > You want to attend or have more questions? Maybe even a proposal for a > demo/talk/discussion? Feel free to talk to us so that we can better include > your idea in the schedule. Since we want to keep the meeting as flexible as > possible, every speaker should plan for about 20 minutes. > > *When?* > > Saturday, March 6, 2021, 3 p.m. to 6 p.m. CET (6 a.m. to 9 a.m. PST) > > *Where?* > > The event will take place as a Zoom call. You need a webcam (maybe with a > microphone) and a recent Web browser such as Firefox, Chrome, Edge, or > Safari. Alternatively, you can download an app for your operating system > via https://zoom.us/download. > > We will share the login data for the virtual meeting here on the day of > the event. > > *What will happen?* > > We are currently in the process of planning talks and demos. Feel free to > contribute with a short demo or experience report yourself – even on the > fly if you want to! We welcome non-members to the meeting. :) > > Here is a preliminary agenda: > > - Like the Babylonias: Programming with Examples > - Fast and colorful: OpenGL in Squeak > - Use the Entire Canvas: Block-based Programming > - Spot off, Morph on: Squeak Game Showcase 2020 > - It’s Broken! How to debug the debugger =) > - Social Media? A Telegram Bot for Squeak > > … and those who find the time but are not so fluent in German: We always > welcome non-German-speaking Squeakers, too! We suppose that you will > understand the live demonstrations anyway. :) We will be able to translate > technical details or questions into English as well. > > Stay healthy. > Best, > Marcel Taeumel > > --- > Squeak Deutschland e.V. > c/o Freudenberg, Potsdamer Str. 3a > 39114 Magdeburg (GERMANY) > > E-Mail: info at squeak-ev.de > Internet: http://www.squeak.de/squeakev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lewis at mail.msen.com Wed Feb 10 05:55:57 2021 From: lewis at mail.msen.com (David T. Lewis) Date: Wed, 10 Feb 2021 00:55:57 -0500 Subject: [squeak-dev] The Inbox: Collections-jar.924.mcz In-Reply-To: References: <20210207153112.GA28116@shell.msen.com> Message-ID: <20210210055557.GA84178@shell.msen.com> On Tue, Feb 09, 2021 at 01:54:33PM +0100, Levente Uzonyi wrote: > Hi David, > > On Sun, 7 Feb 2021, David T. Lewis wrote: > > >This looks good to me, and it fixes the failing test. > > > >Note that none of the historical versions of > >SharedQueue>>nextOrNilSuchThat: > >pass the test, but the issue became visible after CollectionsTests-eem.342 > >last September when the existing test for SharedQueue2 was applied to > >SharedQueue as well. > > > >It would be good if Levente or Nicolas can review this, but +1 from me. > > The fix looks right in the sense that it does what the test case requires. > But it may affect the way events are processed. > The only sender of this method is EventSensor which may rely on the > current behavior. > So, I would like someone who understands how EventSensor works confirm > that the change is okay before pushing it to the Trunk. > Agreed, although I would say that if no further comments show up after a couple of days, we should move it to trunk anyway. The reason I say this is that the only sender is part of the Etoys package, that that sender is part of SugarLauncher. That means that nobody is actually using it in Squeak today. The unit test shows an actual error condition (not a failed test expectation). Earlier method versions show a test failure (not error) so indeed there has been some change to the behavior over time. So indeed additional review would be welcome. Let's wait a few days and if no objections move it to trunk. Dave From eliot.miranda at gmail.com Wed Feb 10 16:13:14 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed, 10 Feb 2021 08:13:14 -0800 Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: <1612823547920-0.post@n4.nabble.com> References: <1612823547920-0.post@n4.nabble.com> Message-ID: <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> Hi Jaromir, > On Feb 8, 2021, at 2:32 PM, Jaromir wrote: > > For some reason the proposed fix also fixes the Transcript losing output > intermittently problem mentioned in > http://forum.world.st/Process-gt-gt-priority-behavior-grossly-incorrect-Transcript-losing-output-td5126836.html > => it looks like the current #priority bug influences also Transcript > behavior and who knows what else... That’s a good catch. What if instead of the fork you simply use yield? yield is now implemented as a primitive so it is far faster than creating a new process and resuming it. I’ll take a look at the yield primitive today and make sure it handles this use case. It’s great to have your insight and energy looking at this. Thank you!! Eliot _,,,^..^,,,_ (phone) From m at jaromir.net Wed Feb 10 18:30:53 2021 From: m at jaromir.net (Jaromir) Date: Wed, 10 Feb 2021 12:30:53 -0600 (CST) Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> References: <1612818822033-0.post@n4.nabble.com> <1612823547920-0.post@n4.nabble.com> <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> Message-ID: <1612981853325-0.post@n4.nabble.com> > What if instead of the fork you simply use yield? yield is now implemented as a primitive so it is far faster than creating a new process and resuming it. Hi, thanks for your encouragement! I did try to use #yield but the primitive seems to check only the active priority queue (and assumes it can't even happen that higher priority processes are waiting while a lower priority process is active - which is probably a reasonable assumption - if it weren't for the #priority: behavior). So I guess either #priority: or #yield should be modified. Thanks, Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From tim at rowledge.org Wed Feb 10 18:55:24 2021 From: tim at rowledge.org (tim Rowledge) Date: Wed, 10 Feb 2021 10:55:24 -0800 Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: <1612981853325-0.post@n4.nabble.com> References: <1612818822033-0.post@n4.nabble.com> <1612823547920-0.post@n4.nabble.com> <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> <1612981853325-0.post@n4.nabble.com> Message-ID: > On 2021-02-10, at 10:30 AM, Jaromir wrote: > I did try to use #yield but the primitive > seems to check only the active priority queue (and assumes it can't even > happen that higher priority processes are waiting while a lower priority > process is active - which is probably a reasonable assumption - if it > weren't for the #priority: behavior). So I guess either #priority: or #yield > should be modified. That doesn't seem right; the primitiveYield carefully transfers control to the result of `wakeHighestPriority()` which is certainly *meant* to find the highest priority process that is runnable. It's what I wrote the original version to do nearly 20 years ago.. tim -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim Hackers have kernel knowledge. From leves at caesar.elte.hu Wed Feb 10 19:10:51 2021 From: leves at caesar.elte.hu (Levente Uzonyi) Date: Wed, 10 Feb 2021 20:10:51 +0100 (CET) Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: References: <1612818822033-0.post@n4.nabble.com> <1612823547920-0.post@n4.nabble.com> <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> <1612981853325-0.post@n4.nabble.com> Message-ID: On Wed, 10 Feb 2021, tim Rowledge wrote: > > >> On 2021-02-10, at 10:30 AM, Jaromir wrote: >> I did try to use #yield but the primitive >> seems to check only the active priority queue (and assumes it can't even >> happen that higher priority processes are waiting while a lower priority >> process is active - which is probably a reasonable assumption - if it >> weren't for the #priority: behavior). So I guess either #priority: or #yield >> should be modified. > > That doesn't seem right; the primitiveYield carefully transfers control to the result of `wakeHighestPriority()` which is certainly *meant* to find the highest priority process that is runnable. It's what I wrote the original version to do nearly 20 years ago.. The problem is that when you change the priority via #priority:, the process will not be placed to the list corresponding to the new priority. Also, #yield is not optimal, because it will #yield instead of just keep running the current process with the new priority. IMO, the right solution is to create a new primitive if we want to support on-the-fly priority changes. Levente > > > tim > -- > tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim > Hackers have kernel knowledge. From m at jaromir.net Wed Feb 10 19:27:11 2021 From: m at jaromir.net (Jaromir) Date: Wed, 10 Feb 2021 13:27:11 -0600 (CST) Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: References: <1612818822033-0.post@n4.nabble.com> <1612823547920-0.post@n4.nabble.com> <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> <1612981853325-0.post@n4.nabble.com> Message-ID: <1612985231265-0.post@n4.nabble.com> > the right solution is to create a new primitive if we want to support on-the-fly priority changes. The system already does on-the-fly priority changes - implementing #valueUnpreemptively and #valueAt: - but they're actually not working properly due to this #priority: issue - they're trying to use #yield after changing the priority down but that really doesn't do anything. Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From eliot.miranda at gmail.com Wed Feb 10 19:35:34 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed, 10 Feb 2021 11:35:34 -0800 Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: <1612985231265-0.post@n4.nabble.com> References: <1612818822033-0.post@n4.nabble.com> <1612823547920-0.post@n4.nabble.com> <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> <1612981853325-0.post@n4.nabble.com> <1612985231265-0.post@n4.nabble.com> Message-ID: On Wed, Feb 10, 2021 at 11:27 AM Jaromir wrote: > > the right solution is to create a new primitive if we want to support > on-the-fly priority changes. > > The system already does on-the-fly priority changes - implementing > #valueUnpreemptively and #valueAt: - but they're actually not working > properly due to this #priority: issue - they're trying to use #yield after > changing the priority down but that really doesn't do anything. > So it seems to me that updating the yield primitive to "do the right thing" is a good way to go. Agreed? If so, I should be able to get to that very soon. _,,,^..^,,,_ best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: From leves at caesar.elte.hu Wed Feb 10 19:54:38 2021 From: leves at caesar.elte.hu (Levente Uzonyi) Date: Wed, 10 Feb 2021 20:54:38 +0100 (CET) Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: References: <1612818822033-0.post@n4.nabble.com> <1612823547920-0.post@n4.nabble.com> <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> <1612981853325-0.post@n4.nabble.com> <1612985231265-0.post@n4.nabble.com> Message-ID: On Wed, 10 Feb 2021, Eliot Miranda wrote: > > > On Wed, Feb 10, 2021 at 11:27 AM Jaromir wrote: > > the right solution is to create a new primitive if we want to support > on-the-fly priority changes. > > The system already does on-the-fly priority changes - implementing > #valueUnpreemptively and #valueAt: - but they're actually not working > properly due to this #priority: issue - they're trying to use #yield after > changing the priority down but that really doesn't do anything. > > > So it seems to me that updating the yield primitive to "do the right thing" is a good way to go.  Agreed?  If so, I should be able to get to that very soon. I think it's not. Let's say the priority of process p is 30, I want to increase it to 40 and then do something at that priority. #yield will stop the process and put it at the end of the list of processes with 40 priority (I think the current implementation doesn't check for priority changes and puts the process on the list of its earlier priority). So, with yield, p will have to wait until all other 40 priority processes finish their job or yield instead of just continuing as the active process. Levente > _,,,^..^,,,_ > best, Eliot > > From m at jaromir.net Wed Feb 10 20:01:22 2021 From: m at jaromir.net (Jaromir) Date: Wed, 10 Feb 2021 14:01:22 -0600 (CST) Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: References: <1612818822033-0.post@n4.nabble.com> <1612823547920-0.post@n4.nabble.com> <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> <1612981853325-0.post@n4.nabble.com> <1612985231265-0.post@n4.nabble.com> Message-ID: <1612987282218-0.post@n4.nabble.com> I may be completely off but let me ask you this: How a process coming down from a higher priority should be treated: (A) as a 'regular' process trying to run at a given priority - i.e. send it to the back of the queue (B) as a sort of 'privileged' process deserving the front of the queue, as if previously 'preempted' by itself Now, as I can see only two usage examples - #valueUnpreemptively and #valueAt, the question is how are these two supposed to work ideally? At the moment they behave - or rather were supposed to I guess - like (A) and changing #yield implementation and using it in the #priority: method would preserve the (A) behavior. However, I wouldn't rule out behavior (B) because it would provide a nice choice based on #processPreemptionYields setting: - for `false` (default) the active process wouldn't yield and "stay" at the front of the queue and - for `true` the active process would yield and go to the end of the queue. For this scenario something like`[ ] forkAt: Processor highestPriority` in the #priority would provide such behavior. To illustrate such scenario I propose the following test: - currently it fails as the val assignment never happens... testPriority "test whether #priority: preempts active process to allow higher priority processes run; #priority behavior reflects the processPreemptionYields setting - for false (default) the active process gets to the front of the queue while for true it goes to the end" | val oldPriority | val := nil. oldPriority := Processor activePriority. Processor activeProcess priority: oldPriority + 2. [ val := false ] forkAt: oldPriority + 1. [ val := true ] forkAt: oldPriority. Processor activeProcess priority: oldPriority. self assert: val equals: Smalltalk vm processPreemptionYields Sorry for the lengthy message... Thanks -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From eliot.miranda at gmail.com Wed Feb 10 20:06:13 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed, 10 Feb 2021 12:06:13 -0800 Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: References: <1612818822033-0.post@n4.nabble.com> <1612823547920-0.post@n4.nabble.com> <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> <1612981853325-0.post@n4.nabble.com> <1612985231265-0.post@n4.nabble.com> Message-ID: Hi Levente, On Wed, Feb 10, 2021 at 11:54 AM Levente Uzonyi wrote: > On Wed, 10 Feb 2021, Eliot Miranda wrote: > > > > > > > On Wed, Feb 10, 2021 at 11:27 AM Jaromir wrote: > > > the right solution is to create a new primitive if we want to > support > > on-the-fly priority changes. > > > > The system already does on-the-fly priority changes - implementing > > #valueUnpreemptively and #valueAt: - but they're actually not > working > > properly due to this #priority: issue - they're trying to use > #yield after > > changing the priority down but that really doesn't do anything. > > > > > > So it seems to me that updating the yield primitive to "do the right > thing" is a good way to go. Agreed? If so, I should be able to get to > that very soon. > > I think it's not. Let's say the priority of process p is 30, I want to > increase it to 40 and then do something at that priority. > #yield will stop the process and put it at the end of the list of > processes with 40 priority (I think the current implementation doesn't > check for priority changes and puts the process on the list of its > earlier priority). > So, with yield, p will have to wait until all other 40 priority processes > finish their job or yield instead of just continuing as the active > process. > But if that's the behaviour you want you can either - set the priority, do the processing, and then invoke yield - do the processing and then set the priority and then yield, right? We're not tying assigning to priority to the yield primitive, right? These are still distinct operations. I'm simply suggesting that the yield primitive take into account the receiver's priority, which it currently doesn't do. > > Levente > > > _,,,^..^,,,_ > > best, Eliot > > > > > -- _,,,^..^,,,_ best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: From m at jaromir.net Wed Feb 10 23:07:39 2021 From: m at jaromir.net (Jaromir) Date: Wed, 10 Feb 2021 17:07:39 -0600 (CST) Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: References: <1612818822033-0.post@n4.nabble.com> <1612823547920-0.post@n4.nabble.com> <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> <1612981853325-0.post@n4.nabble.com> <1612985231265-0.post@n4.nabble.com> Message-ID: <1612998459789-0.post@n4.nabble.com> Hi, I sense a few different approaches here: - fix #yield and leave #priority be as it is - fix #yield and use it to fix #priority - fix #yield and fix #priority independently of each other (my preference) best, Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From leves at caesar.elte.hu Wed Feb 10 23:40:56 2021 From: leves at caesar.elte.hu (Levente Uzonyi) Date: Thu, 11 Feb 2021 00:40:56 +0100 (CET) Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: References: <1612818822033-0.post@n4.nabble.com> <1612823547920-0.post@n4.nabble.com> <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> <1612981853325-0.post@n4.nabble.com> <1612985231265-0.post@n4.nabble.com> Message-ID: Hi Eliot, On Wed, 10 Feb 2021, Eliot Miranda wrote: > Hi Levente, > > On Wed, Feb 10, 2021 at 11:54 AM Levente Uzonyi wrote: > On Wed, 10 Feb 2021, Eliot Miranda wrote: > > > > > > > On Wed, Feb 10, 2021 at 11:27 AM Jaromir wrote: > >       > the right solution is to create a new primitive if we want to support > >       on-the-fly priority changes. > > > >       The system already does on-the-fly priority changes - implementing > >       #valueUnpreemptively and #valueAt: - but they're actually not working > >       properly due to this #priority: issue - they're trying to use #yield after > >       changing the priority down but that really doesn't do anything. > > > > > > So it seems to me that updating the yield primitive to "do the right thing" is a good way to go.  Agreed?  If so, I should be able to get to that very soon. > > I think it's not. Let's say the priority of process p is 30, I want to > increase it to 40 and then do something at that priority. > #yield will stop the process and put it at the end of the list of > processes with 40 priority (I think the current implementation doesn't > check for priority changes and puts the process on the list of its > earlier priority). > So, with yield, p will have to wait until all other 40 priority processes > finish their job or yield instead of just continuing as the active > process. > > > But if that's the behaviour you want you can either > - set the priority, do the processing, and then invoke yield > - do the processing and then set the priority and then yield, right? > > We're not tying assigning to priority to the yield primitive, right?  These are still distinct operations.  I'm simply suggesting that the yield primitive take into account the receiver's priority, which it currently doesn't do. The current issue is that when a process's priority is decreased, e.g. from 42 to 40, and there's a process waiting to be executed at priority 41, then that process will not be activated but the process with priority 40 will keep on running. And, even yielding after the priority decrease doesn't help now. IMO, the ideal solution would be to 1. Make sure that #yield lets all existing higher priority processes run besides all the same priority processes. 2. When #priority: is sent to the active process to decrease its priority, then that process should a) should keep running without interruption if there's no higher priority processes awaiting execution than the new priority b) should be suspended if there are higher priority processes ready to run, and it should be resumed once all higher priority processes are suspended or terminated. Only fixing #yield does not help with the requirements in point 2. Levente > > > > Levente > > > _,,,^..^,,,_ > > best, Eliot > > > > > > > > -- > _,,,^..^,,,_ > best, Eliot > > From kksubbu.ml at gmail.com Thu Feb 11 05:48:01 2021 From: kksubbu.ml at gmail.com (K K Subbu) Date: Thu, 11 Feb 2021 11:18:01 +0530 Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: References: <1612818822033-0.post@n4.nabble.com> <1612823547920-0.post@n4.nabble.com> <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> <1612981853325-0.post@n4.nabble.com> <1612985231265-0.post@n4.nabble.com> Message-ID: On 11/02/21 5:10 am, Levente Uzonyi wrote: > IMO, the ideal solution would be to > 1. Make sure that #yield lets all existing higher priority processes run > besides all the same priority processes all existing *equal* or higher priority ... yield just surrenders the time slot ahead of its expiry. The active process is moved to the back of its priority queue for #reschedule. > 2. When #priority: is sent to the active process to decrease its > priority, then that process should >     a) should keep running without interruption if there's no higher > priority processes awaiting execution than the new priority >     b) should be suspended if there are higher priority processes ready > to run, and it should be resumed once all higher priority processes are > suspended or terminated. Rescheduling logic should be separated from priority setting logic. #priority: should simply switch the process from its existing priority queue to the back of the new priority queue and then #reschedule. #yield reduces to setting a process to its current priority. It gives an opportunity for rescheduling. #reschedule logic should pick the next process to run. If this happens to be same as active process, no further change is required. Otherwise, the active process is suspended and the new process resumed. The third case when rescheduling is requested is by an async event like timer, interrupt, input etc. Here if the active process has exhausted its time slice, then it should be forced to #yield (fair share policy). Rescheduling a process is quite tricky. The working priority used in scheduling decisions could be different from that of a process's priority setting. Sometimes, a process (A) could be holding a mutex on which a higher priority process (H) is blocked. In this case, A's working priority is the highest priority of its waiters. HTH .. Subbu From eliot.miranda at gmail.com Thu Feb 11 07:02:42 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed, 10 Feb 2021 23:02:42 -0800 Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: References: <1612818822033-0.post@n4.nabble.com> <1612823547920-0.post@n4.nabble.com> <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> <1612981853325-0.post@n4.nabble.com> <1612985231265-0.post@n4.nabble.com> Message-ID: Hi Levente, On Wed, Feb 10, 2021 at 3:41 PM Levente Uzonyi wrote: > Hi Eliot, > > On Wed, 10 Feb 2021, Eliot Miranda wrote: > > > Hi Levente, > > > > On Wed, Feb 10, 2021 at 11:54 AM Levente Uzonyi > wrote: > > On Wed, 10 Feb 2021, Eliot Miranda wrote: > > > > > > > > > > > On Wed, Feb 10, 2021 at 11:27 AM Jaromir wrote: > > > > the right solution is to create a new primitive if we > want to support > > > on-the-fly priority changes. > > > > > > The system already does on-the-fly priority changes - > implementing > > > #valueUnpreemptively and #valueAt: - but they're actually > not working > > > properly due to this #priority: issue - they're trying to > use #yield after > > > changing the priority down but that really doesn't do > anything. > > > > > > > > > So it seems to me that updating the yield primitive to "do the > right thing" is a good way to go. Agreed? If so, I should be able to get > to that very soon. > > > > I think it's not. Let's say the priority of process p is 30, I > want to > > increase it to 40 and then do something at that priority. > > #yield will stop the process and put it at the end of the list of > > processes with 40 priority (I think the current implementation > doesn't > > check for priority changes and puts the process on the list of its > > earlier priority). > > So, with yield, p will have to wait until all other 40 priority > processes > > finish their job or yield instead of just continuing as the active > > process. > > > > > > But if that's the behaviour you want you can either > > - set the priority, do the processing, and then invoke yield > > - do the processing and then set the priority and then yield, right? > > > > We're not tying assigning to priority to the yield primitive, right? > These are still distinct operations. I'm simply suggesting that the yield > primitive take into account the receiver's priority, which it currently > doesn't do. > > The current issue is that when a process's priority is decreased, e.g. > from 42 to 40, and there's a process waiting to be executed at priority > 41, then that process will not be activated but the process with priority > 40 will keep on running. > And, even yielding after the priority decrease doesn't help now. > > IMO, the ideal solution would be to > 1. Make sure that #yield lets all existing higher priority processes run > besides all the same priority processes. > Agreed. This means that yield should check to see if there is a runnable process at higher priority than the current process. It doesn't do this. It merely checks if there are processes at the same priority as the receiver. > 2. When #priority: is sent to the active process to decrease its priority, > then that process should > a) should keep running without interruption if there's no higher > priority processes awaiting execution than the new priority > b) should be suspended if there are higher priority processes > ready to run, and it should be resumed once all higher priority processes > are suspended or terminated. > > Only fixing #yield does not help with the requirements in point 2. > Ah, yes, I see. That's tricky. "Fixing" yield to ensure that the highest priority process is runnable and using it in Process>>priority: would have the unwanted side-effect of yielding. So we may need another primitive. A primitive that answered the highest runnable priority process would work. Then we could write Process>>priority: anInteger priority := anInteger. ProcessorScheduler highestPriorityRunnableProcess priority > priority ifTrue: [self yield] That would be OK right? Levente > > > > > > > > > Levente > > > > > _,,,^..^,,,_ > > > best, Eliot > > > > > > > > > > > > > > -- > > _,,,^..^,,,_ > > best, Eliot > > > > > -- _,,,^..^,,,_ best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Thu Feb 11 08:14:08 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 11 Feb 2021 08:14:08 0000 Subject: [squeak-dev] The Trunk: SUnit-nice.124.mcz Message-ID: Nicolas Cellier uploaded a new version of SUnit to project The Trunk: http://source.squeak.org/trunk/SUnit-nice.124.mcz ==================== Summary ==================== Name: SUnit-nice.124 Author: nice Time: 11 February 2021, 9:14:06.179764 am UUID: f1c47b72-13f3-4690-86c9-b76f3cae6e04 Ancestors: SUnit-pre.123 Use lines rather than subStrings: {Character cr} This is what lines is made for; it is fast and also work whatever CRLF zoo. =============== Diff against SUnit-pre.123 =============== Item was changed: ----- Method: SUnitExtensionsTest>>testAutoAssertFalse (in category 'tests') ----- testAutoAssertFalse | booleanCondition | self assert: self isLogging. self should: [ self assert: 1 = 2 description: 'self assert: 1 = 2' ] raise: TestResult failure. + booleanCondition := (self stream contents lines) last = 'self assert: 1 = 2'. - booleanCondition := (self stream contents subStrings: {Character cr}) last = 'self assert: 1 = 2'. self assert: booleanCondition! Item was changed: ----- Method: SUnitExtensionsTest>>testAutoDenyFalse (in category 'tests') ----- testAutoDenyFalse | booleanCondition | self assert: self isLogging. self should: [ self deny: 1 = 1 description: 'self deny: 1 = 1'.] raise: TestResult failure. + booleanCondition := (self stream contents lines) last = 'self deny: 1 = 1'. - booleanCondition := (self stream contents subStrings: {Character cr}) last = 'self deny: 1 = 1'. self assert: booleanCondition! From commits at source.squeak.org Thu Feb 11 08:30:12 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 11 Feb 2021 08:30:12 0000 Subject: [squeak-dev] The Trunk: Kernel-nice.1368.mcz Message-ID: Nicolas Cellier uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-nice.1368.mcz ==================== Summary ==================== Name: Kernel-nice.1368 Author: nice Time: 11 February 2021, 9:30:07.084854 am UUID: b086833d-ece4-4372-b252-87d2caa59193 Ancestors: Kernel-eem.1367 Rescue setting of Processor highestPriority: anInteger There was a double problem: 1) if reducing the priority, then anyProcessesAbove: did behave as noProcessAbove: because (select:) isEmpty <=> noneSatisfy: It should have been (reject:) empty or (select:) notEmpty, but we have anySatisfy: for expressing this intention 2) if increasing the priority, then the loop did overwrite the last LinkedList in the quiescentProcessLists Those LinkedList are mostly empty in my own image, and we never change the highestPriority, so the bug was probably benign... =============== Diff against Kernel-eem.1367 =============== Item was changed: ----- Method: ProcessorScheduler>>anyProcessesAbove: (in category 'private') ----- anyProcessesAbove: highestPriority + "Do any (sub) instances of Process exist with higher priorities?" - "Do any instances of Process exist with higher priorities?" + ^(Process allSubInstances anySatisfy: [:aProcess | + aProcess priority > highestPriority])! - ^(Process allSubInstances select: [:aProcess | - aProcess priority > highestPriority]) isEmpty - "If anyone ever makes a subclass of Process, be sure to use allSubInstances."! Item was changed: ----- Method: ProcessorScheduler>>highestPriority: (in category 'accessing') ----- highestPriority: newHighestPriority "Change the number of priority levels currently available for use." | newProcessLists | (quiescentProcessLists size > newHighestPriority and: [self anyProcessesAbove: newHighestPriority]) ifTrue: [self error: 'There are processes with priority higher than ' ,newHighestPriority printString]. newProcessLists := Array new: newHighestPriority. + 1 to: (quiescentProcessLists size min: newProcessLists size) do: - 1 to: ((quiescentProcessLists size) min: (newProcessLists size)) do: [:priority | newProcessLists at: priority put: (quiescentProcessLists at: priority)]. + quiescentProcessLists size + 1 to: newProcessLists size do: - (quiescentProcessLists size max: 1) to: newProcessLists size do: [:priority | newProcessLists at: priority put: LinkedList new]. quiescentProcessLists := newProcessLists! From m at jaromir.net Thu Feb 11 09:27:11 2021 From: m at jaromir.net (Jaromir) Date: Thu, 11 Feb 2021 03:27:11 -0600 (CST) Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: References: <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> <1612981853325-0.post@n4.nabble.com> <1612985231265-0.post@n4.nabble.com> Message-ID: <1613035631768-0.post@n4.nabble.com> Hi, > The current issue is that when a process's priority is decreased, e.g. > from 42 to 40, and there's a process waiting to be executed at priority > 41, then that process will not be activated but the process with priority > 40 will keep on running. > And, even yielding after the priority decrease doesn't help now. > > IMO, the ideal solution would be to > 1. Make sure that #yield lets all existing higher priority processes run > besides all the same priority processes. > 2. When #priority: is sent to the active process to decrease its priority, > then that process should > a) should keep running without interruption if there's no higher > priority processes awaiting execution than the new priority > b) should be suspended if there are higher priority processes > ready to run, and it should be resumed once all higher priority processes > are suspended or terminated. (b) is still unclear to me: if you decrease an active process's priority from 42 to 40 and there's a process waiting at 41, AND there's another process waiting at 40 then: the active process should suspend, the process at 41 should run and then what: resume your original process or run the other waiting process at 40 first? > Ah, yes, I see. That's tricky. "Fixing" yield to ensure that the highest > priority process is runnable and using it in Process>>priority: would have > the unwanted side-effect of yielding. So we may need another primitive. > A primitive that answered the highest runnable priority process would > work. Then we could write > > Process>>priority: anInteger > priority := anInteger. > ProcessorScheduler highestPriorityRunnableProcess priority > priority > ifTrue: > [self yield] > > That would be OK right? If the process should run before other processes waiting at its new (decreased) priority then #yield would still send the process to the end of the 40 queue, right? Btw, there's already a #nextReadyProcess method available but non-primitive so understand it's not usable for the above purpose as such. The condition above should apply to the active process only, is that right? Process>>priority: anInteger priority := anInteger. self isActiveProcess and: [Processor nextReadyProcess priority > priority] ifTrue: ... best, Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From gettimothy at zoho.com Thu Feb 11 18:41:49 2021 From: gettimothy at zoho.com (gettimothy) Date: Thu, 11 Feb 2021 13:41:49 -0500 Subject: [squeak-dev] correct form for Problem With Blocks Message-ID: <177926639dc.126c5423a22931.4400491071187392019@zoho.com> Hi Folks, I am importing my grammar/xtreams parsing work into its own image so that I can change my system fonts without making my other projects look funky with the chages. The base image is: Image ----- /home/wm/usr/src/smalltalk/squeak6.0alpha/shared/Squeak6.0alpha-19802-64bit.image Squeak6.0alpha latest update: #20147 to the latest: /home/wm/Squeak/images/WikitextParser/WikitextParser.image Squeak6.0alpha latest update: #20188 During the import of my work, I ran into this issue regarding Store Into in a block: http://forum.world.st/Cuis-problem-with-blocks-td1047783.html#a1049556 The parser is looking for patterns of  (10e2)e2....i.e.  exponential notation of unknown length, i.e. per the comment on Collection inject: into:  accumulate a running value... Per the email chain referenced, the "Allow block argument assignment" is allowed in the former, and not allowed in the latest, which is cool with me, but... My question is "what is the generic form" that I can use to duplicate the behaviour I want? Here is the original method with the bad store into: Float: first exponent: pairs   "Float <- ( Number / Group / Function ) (''e'' ( Number / Group / Function ))+" |result|   result := pairs inject: first                         into: [ :base  :pair |                                     (pair first = 'e')                                                ifTrue: [                                                             (pair last abs > 1)                                                                   ifTrue:[ base := Float readFrom: ((base asString) , 'e', (pair last asString))]                                                                   ifFalse:[ base := (base * (10 raisedTo:(pair last) ))]]]. transcripton ifTrue:[Transcript show:'Float ' , (result asFloat); cr. ]. ^ result asFloat Here is my "hack" to fix it , (I create a tmp variable outside the block to use in place of the "base"): Float: first exponent: pairs   "Float <- ( Number / Group / Function ) (''e'' ( Number / Group / Function ))+" |result tmp|         result := pairs inject: first                               into: [ :base  :pair |                                           (pair first = 'e')                                                 ifTrue: [                                                       (pair last abs > 1)                                                             ifTrue:[tmp := base.                                                                         tmp := Float readFrom: ((tmp asString) , 'e', (pair last asString))]                                                                         tmp := Float readFrom: ((tmp asString) , 'e', (pair last asString)).                                                                         tmp]                                                             ifFalse:[tmp := base.                                                                         tmp := (tmp * (10 raisedTo:(pair last) ))]]].                                                                         tmp := (tmp * (10 raisedTo:(pair last) )).                                                                         tmp]]]. transcripton ifTrue:[Transcript show:'Float ' , (result asFloat); cr. ]. ^ result asFloat I got a bad feeling about this one. Is there a general form for this ? My brain is a bit foggy from working the graveyard shift so what would be obvious while in normal conditions , is not obvious today. Thanks for you time. -------------- next part -------------- An HTML attachment was scrubbed... URL: From leves at caesar.elte.hu Thu Feb 11 19:24:33 2021 From: leves at caesar.elte.hu (Levente Uzonyi) Date: Thu, 11 Feb 2021 20:24:33 +0100 (CET) Subject: [squeak-dev] The Inbox: Kernel-jar.1368.mcz In-Reply-To: References: <1612818822033-0.post@n4.nabble.com> <1612823547920-0.post@n4.nabble.com> <21B6F9A2-68A3-4543-A2F8-BD8C2F9BBF24@gmail.com> <1612981853325-0.post@n4.nabble.com> <1612985231265-0.post@n4.nabble.com> Message-ID: Hi Eliot, On Wed, 10 Feb 2021, Eliot Miranda wrote: > Hi Levente, > > On Wed, Feb 10, 2021 at 3:41 PM Levente Uzonyi wrote: > Hi Eliot, > > On Wed, 10 Feb 2021, Eliot Miranda wrote: > > > Hi Levente, > > > > On Wed, Feb 10, 2021 at 11:54 AM Levente Uzonyi wrote: > >       On Wed, 10 Feb 2021, Eliot Miranda wrote: > > > >       > > >       > > >       > On Wed, Feb 10, 2021 at 11:27 AM Jaromir wrote: > >       >       > the right solution is to create a new primitive if we want to support > >       >       on-the-fly priority changes. > >       > > >       >       The system already does on-the-fly priority changes - implementing > >       >       #valueUnpreemptively and #valueAt: - but they're actually not working > >       >       properly due to this #priority: issue - they're trying to use #yield after > >       >       changing the priority down but that really doesn't do anything. > >       > > >       > > >       > So it seems to me that updating the yield primitive to "do the right thing" is a good way to go.  Agreed?  If so, I should be able to get to that very soon. > > > >       I think it's not. Let's say the priority of process p is 30, I want to > >       increase it to 40 and then do something at that priority. > >       #yield will stop the process and put it at the end of the list of > >       processes with 40 priority (I think the current implementation doesn't > >       check for priority changes and puts the process on the list of its > >       earlier priority). > >       So, with yield, p will have to wait until all other 40 priority processes > >       finish their job or yield instead of just continuing as the active > >       process. > > > > > > But if that's the behaviour you want you can either > > - set the priority, do the processing, and then invoke yield > > - do the processing and then set the priority and then yield, right? > > > > We're not tying assigning to priority to the yield primitive, right?  These are still distinct operations.  I'm simply suggesting that the yield primitive take into account the receiver's priority, which it currently doesn't do. > > The current issue is that when a process's priority is decreased, e.g. > from 42 to 40, and there's a process waiting to be executed at priority > 41, then that process will not be activated but the process with priority > 40 will keep on running. > And, even yielding after the priority decrease doesn't help now. > > IMO, the ideal solution would be to > 1. Make sure that #yield lets all existing higher priority processes run > besides all the same priority processes. > > > Agreed.  This means that yield should check to see if there is a runnable process at higher priority than the current process.  It doesn't do this.  It merely checks if there are processes at the same priority as the receiver. #yield doesn't check for higher priorities because no higher priority process should ever be ready to run when #yield is sent. The problem only occurs when the active process's priority is decreased and there is a higher priority process awaiting execution. So, IMO, the right solution is to create a new primitive to set the process priority. When it is changing the active processes priority and the priority is decreased then look for higher priority processes awaiting execution. In other cases, just set the value of the instance variable. Levente > 2. When #priority: is sent to the active process to decrease its priority, > then that process should >         a) should keep running without interruption if there's no higher > priority processes awaiting execution than the new priority >         b) should be suspended if there are higher priority processes > ready to run, and it should be resumed once all higher priority processes > are suspended or terminated. > > Only fixing #yield does not help with the requirements in point 2. > > > Ah, yes, I see. That's tricky.  "Fixing" yield to ensure that the highest priority process is runnable and using it in Process>>priority: would have the unwanted side-effect of yielding.  So we may need another primitive.  A primitive that answered the highest runnable priority process would work.  Then we could > write > > Process>>priority: anInteger >     priority := anInteger. >     ProcessorScheduler highestPriorityRunnableProcess priority > priority ifTrue: >         [self yield] > > That would be OK right? > > Levente > > > > > > > > >       Levente > > > >       > _,,,^..^,,,_ > >       > best, Eliot > >       > > >       > > > > > > > > > -- > > _,,,^..^,,,_ > > best, Eliot > > > > > > > > -- > _,,,^..^,,,_ > best, Eliot > > From leves at caesar.elte.hu Thu Feb 11 19:29:38 2021 From: leves at caesar.elte.hu (Levente Uzonyi) Date: Thu, 11 Feb 2021 20:29:38 +0100 (CET) Subject: [squeak-dev] correct form for Problem With Blocks In-Reply-To: <177926639dc.126c5423a22931.4400491071187392019@zoho.com> References: <177926639dc.126c5423a22931.4400491071187392019@zoho.com> Message-ID: Hi Tim, On Thu, 11 Feb 2021, gettimothy via Squeak-dev wrote: > Hi Folks, > > I am importing my grammar/xtreams parsing work into its own image so that I can change my system fonts without making my other projects look funky with the chages. > > The base image is: > > > Image > ----- > /home/wm/usr/src/smalltalk/squeak6.0alpha/shared/Squeak6.0alpha-19802-64bit.image > Squeak6.0alpha > latest update: #20147 > > to the latest: > > /home/wm/Squeak/images/WikitextParser/WikitextParser.image > Squeak6.0alpha > latest update: #20188 > > During the import of my work, I ran into this issue regarding Store Into in a block: > > > http://forum.world.st/Cuis-problem-with-blocks-td1047783.html#a1049556 > > > The parser is looking for patterns of  (10e2)e2....i.e.  exponential notation of unknown length, i.e. per the comment on Collection inject: into:  accumulate a running value... > > > > Per the email chain referenced, the "Allow block argument assignment" is allowed in the former, and not allowed in the latest, which is cool with me, but... > > My question is "what is the generic form" that I can use to duplicate the behaviour I want? > Here is the original method with the bad store into: > Float: first exponent: pairs >   > > "Float <- ( Number / Group / Function ) (''e'' ( Number / Group / Function ))+" > > |result| >   result := pairs inject: first >                         into: [ :base  :pair | >                                     (pair first = 'e') >                                                ifTrue: [ >                                                             (pair last abs > 1) >                                                                   ifTrue:[ base := Float readFrom: ((base asString) , 'e', (pair last asString))] >                                                                   ifFalse:[ base := (base * (10 raisedTo:(pair last) ))]]]. That makes no sense. I can't even fathom how it works. #inject:into:'s second argument, the block, must return the computed value. Currently that block returns the value assigned to base when pair first = 'e' and nil otherwise. So, if it works correctly now, which is doubtful, then just remove the assignments to base from the block and it should just work. > > transcripton ifTrue:[Transcript show:'Float ' , (result asFloat); cr. ]. > > > ^ result asFloat > > > > > Here is my "hack" to fix it , (I create a tmp variable outside the block to use in place of the "base"): > > > Float: first exponent: pairs >   > > "Float <- ( Number / Group / Function ) (''e'' ( Number / Group / Function ))+" > > |result tmp| >         result := pairs inject: first >                               into: [ :base  :pair | >                                           (pair first = 'e') >                                                 ifTrue: [ >                                                       (pair last abs > 1) >                                                             ifTrue:[tmp := base. >                                                                         tmp := Float readFrom: ((tmp asString) , 'e', (pair last asString))] >                                                                         tmp := Float readFrom: ((tmp asString) , 'e', (pair last asString)). >                                                                         tmp] >                                                             ifFalse:[tmp := base. >                                                                         tmp := (tmp * (10 raisedTo:(pair last) ))]]]. >                                                                         tmp := (tmp * (10 raisedTo:(pair last) )). >                                                                         tmp]]]. Those parentheses don't look well balanced, but anyway, there's no need to use tmp, especially not one at the outer scope. Levente > > transcripton ifTrue:[Transcript show:'Float ' , (result asFloat); cr. ]. > > > ^ result asFloat > > > I got a bad feeling about this one. > > > Is there a general form for this ? > > > My brain is a bit foggy from working the graveyard shift so what would be obvious while in normal conditions , is not obvious today. > > > Thanks for you time. > > > > > From jrmaffeo at gmail.com Fri Feb 12 04:59:45 2021 From: jrmaffeo at gmail.com (John-Reed Maffeo) Date: Thu, 11 Feb 2021 21:59:45 -0700 Subject: [squeak-dev] Syntax Error window locks up image Message-ID: What causes a window like this to appear? Why does it lock up the image? The problem occurred in an image that was running unattended using #Delay to run a method every hour. The application is in development but it has been running on schedule for a month or so without any problems. I do save and restart the image occasionally. -- jrm -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: SqueakSyntaxError.png Type: image/png Size: 104248 bytes Desc: not available URL: From marcel.taeumel at hpi.de Fri Feb 12 08:33:09 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Fri, 12 Feb 2021 09:33:09 +0100 Subject: [squeak-dev] Syntax Error window locks up image In-Reply-To: References: Message-ID: Hi John-Reed, can you tell us more about that method your are running every hour? Syntax errors are as tricky as debuggers. They actually use a debugger internally to interrupt the current (i.e. the compiler's/parser's) control flow and offer interactive means to fix syntax to then continue compilation. Considering interactive syntax correction, I am not sure whether compilation is safe in processes other than the UI process. Did you try hitting [CMD]+[Dot] in that case? Best, Marcel Am 12.02.2021 06:00:11 schrieb John-Reed Maffeo : What causes a window like this to appear? Why does it lock up the image? The problem occurred in an image that was running unattended using #Delay to run a method every hour. The application is in development but it has been running on schedule for a month or so without any problems. I do save and restart the image occasionally. -- jrm -------------- next part -------------- An HTML attachment was scrubbed... URL: From tim at rowledge.org Fri Feb 12 18:02:16 2021 From: tim at rowledge.org (tim Rowledge) Date: Fri, 12 Feb 2021 10:02:16 -0800 Subject: [squeak-dev] Syntax Error window locks up image In-Reply-To: References: Message-ID: <943B0443-DB5F-454B-BEF8-79890749DB80@rowledge.org> > On 2021-02-12, at 12:33 AM, Marcel Taeumel wrote: > > Hi John-Reed, > > can you tell us more about that method your are running every hour? My first thought on seeing the screenshot was that the source file is mucked up somehow; looks like it was trying to compile some part of the method header that ought to be ignored. I remember in the far distant past having problems of that sort when Windows got its nsty little fingers in the pie and converted Rc to CRLF and thus broke all the source pointers. tim -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim Useful random insult:- A room temperature IQ. From commits at source.squeak.org Fri Feb 12 23:32:38 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 12 Feb 2021 23:32:38 0000 Subject: [squeak-dev] The Trunk: Kernel-dtl.1369.mcz Message-ID: David T. Lewis uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-dtl.1369.mcz ==================== Summary ==================== Name: Kernel-dtl.1369 Author: dtl Time: 12 February 2021, 6:32:35.918542 pm UUID: 3968e898-9e0c-4f26-a331-74c2353b7e99 Ancestors: Kernel-nice.1368, Kernel-ct.1368 merge Kernel-ct.1368 =============== Diff against Kernel-nice.1368 =============== Item was changed: ----- Method: Process>>longPrintOn: (in category 'printing') ----- longPrintOn: stream | ctxt | super printOn: stream. + stream + nextPut: $(; + nextPutAll: self name; + nextPut: $). stream cr. ctxt := self suspendedContext. [ctxt == nil] whileFalse: [ stream space. ctxt printOn: stream. stream cr. ctxt := ctxt sender. ]. ! Item was changed: ----- Method: Process>>printOn: (in category 'printing') ----- printOn: aStream super printOn: aStream. + aStream + nextPut: $(; + nextPutAll: self name; + nextPut: $). aStream nextPutAll: ' in '. suspendedContext printOn: aStream! From commits at source.squeak.org Fri Feb 12 23:33:59 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 12 Feb 2021 23:33:59 0000 Subject: [squeak-dev] The Trunk: Kernel-ct.1368.mcz Message-ID: David T. Lewis uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-ct.1368.mcz ==================== Summary ==================== Name: Kernel-ct.1368 Author: ct Time: 24 January 2021, 3:19:48.003384 pm UUID: c62a6062-b240-9149-a2ed-78fdc1079dfd Ancestors: Kernel-mt.1364 Proposal: Always include process name into its print string. This facilitates debugging/inspecting of multiprocess scenarios. =============== Diff against Kernel-mt.1364 =============== Item was changed: ----- Method: Process>>longPrintOn: (in category 'printing') ----- longPrintOn: stream | ctxt | super printOn: stream. + stream + nextPut: $(; + nextPutAll: self name; + nextPut: $). stream cr. ctxt := self suspendedContext. [ctxt == nil] whileFalse: [ stream space. ctxt printOn: stream. stream cr. ctxt := ctxt sender. ]. ! Item was changed: ----- Method: Process>>printOn: (in category 'printing') ----- printOn: aStream super printOn: aStream. + aStream + nextPut: $(; + nextPutAll: self name; + nextPut: $). aStream nextPutAll: ' in '. suspendedContext printOn: aStream! From commits at source.squeak.org Sat Feb 13 03:54:37 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sat, 13 Feb 2021 03:54:37 0000 Subject: [squeak-dev] The Trunk: Collections-jar.924.mcz Message-ID: David T. Lewis uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-jar.924.mcz ==================== Summary ==================== Name: Collections-jar.924 Author: jar Time: 7 February 2021, 9:42:07.649004 am UUID: 073b26bc-8e5e-ba41-9aac-9d424bbe6848 Ancestors: Collections-dtl.923 Fixes SharedQueue >> nextOrNilSuchThat bug to pass the existing test =============== Diff against Collections-dtl.923 =============== Item was changed: ----- Method: SharedQueue>>nextOrNilSuchThat: (in category 'accessing') ----- nextOrNilSuchThat: aBlock "Answer the next object that satisfies aBlock, skipping any intermediate objects. If no object has been sent, answer and leave me intact. NOTA BENE: aBlock MUST NOT contain a non-local return (^)." ^accessProtect critical: [ | value readPos | value := nil. readPos := readPosition. [ readPos < writePosition and: [ value isNil ] ] whileTrue: [ value := contentsArray at: readPos. readPos := readPos + 1. (aBlock value: value) ifFalse: [ value := nil ] ifTrue: [ readSynch waitIfLocked: [ ^nil ]. "We found the value, but someone else booked it." + readPos-1 to: readPosition+1 by: -1 do: [ :j | contentsArray at: j put: (contentsArray at: j-1) ]. + contentsArray at: readPosition put: nil. + readPosition := readPosition+1 ] ]. - readPosition to: readPos - 1 do: [ :j | contentsArray at: j put: nil ]. - readPosition := readPos ] ]. value ]. "=== q := SharedQueue new. 1 to: 10 do: [ :i | q nextPut: i]. c := OrderedCollection new. [ v := q nextOrNilSuchThat: [ :e | e odd]. v notNil ] whileTrue: [ c add: {v. q size} ]. {c. q} explore ==="! From commits at source.squeak.org Sat Feb 13 03:54:49 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sat, 13 Feb 2021 03:54:49 0000 Subject: [squeak-dev] The Trunk: CollectionsTests-jar.349.mcz Message-ID: David T. Lewis uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-jar.349.mcz ==================== Summary ==================== Name: CollectionsTests-jar.349 Author: jar Time: 8 February 2021, 8:25:19.407373 pm UUID: f484ba2b-2035-b046-9222-c3e4e42a7ad4 Ancestors: CollectionsTests-ul.348 Test to show differing SharedQueue and SharedQueue2 semantics =============== Diff against CollectionsTests-ul.348 =============== Item was added: + ----- Method: AbstractSharedQueueTest>>testContention2 (in category 'tests') ----- + testContention2 + "and here's a test case that distunguishes SharedQueue from SharedQueue2 semantics: + SharedQueue2 produces a sequence #(5 10 15) while SharedQueue produces #(5 15 10)" + + | q r1 r2 r3 | + q := self queueClass new. + + [ r1 := q next. q nextPut: 15. r3 := q next ] fork. + [ r2 := q next ] fork. + + Processor yield. "let the above two threads block" + + q nextPut: 5. + Processor yield. "let the first thread above proceed" + + q nextPut: 10. + Processor yield. "let the unfinished thread above finish" + + q class = SharedQueue2 ifTrue: [ + self assert: 5 equals: r1. + self assert: 10 equals: r2. + self assert: 15 equals: r3. + self assert: nil equals: q nextOrNil ]. + + q class = SharedQueue ifTrue: [ + self assert: 5 equals: r1. + self assert: 15 equals: r2. + self assert: 10 equals: r3. + self assert: nil equals: q nextOrNil ]. + + "SharedQueue2 implementation using a Monitor checks the queue for available data while + the SharedQueue implementation based on a Semaphore checks for excessSignals > 0, + which results in these two different outcomes"! From m at jaromir.net Sat Feb 13 11:55:20 2021 From: m at jaromir.net (Jaromir) Date: Sat, 13 Feb 2021 05:55:20 -0600 (CST) Subject: [squeak-dev] #ifCurtailed - why the "complete := true" line? Message-ID: <1613217320055-0.post@n4.nabble.com> Hi, I can't figure this one out - is the value of /complete / in #ifCurtailed method used somewhere? Very confusing ;) Thanks a lot! Jaromir ifCurtailed: aBlock | complete result | result := self valueNoContextSwitch. complete := true. ^result -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From lecteur at zogotounga.net Sat Feb 13 11:57:15 2021 From: lecteur at zogotounga.net (=?UTF-8?Q?St=c3=a9phane_Rollandin?=) Date: Sat, 13 Feb 2021 12:57:15 +0100 Subject: [squeak-dev] Rectangle>>merging: does not accepts Sets anymore Message-ID: Hello all, I just noticed that Rectangle class>>#merging: now (well, since summer 2020) uses #first and so does not allow its argument to be a Set anymore. Is that the intended behavior? Stef From lecteur at zogotounga.net Sat Feb 13 14:34:40 2021 From: lecteur at zogotounga.net (=?UTF-8?Q?St=c3=a9phane_Rollandin?=) Date: Sat, 13 Feb 2021 15:34:40 +0100 Subject: [squeak-dev] Float32Array weirdness Message-ID: Hello all, In the latest trunk image, #at:put: in Float32Array seems to miss the fractional part: | floatArray | (floatArray := Float32Array new: 4) at: 2 put: 2.3. floatArray ==> a Float32Array(0.0 2.0 0.0 0.0) Stef From Das.Linux at gmx.de Sat Feb 13 14:36:52 2021 From: Das.Linux at gmx.de (Tobias Pape) Date: Sat, 13 Feb 2021 15:36:52 +0100 Subject: [squeak-dev] #ifCurtailed - why the "complete := true" line? In-Reply-To: <1613217320055-0.post@n4.nabble.com> References: <1613217320055-0.post@n4.nabble.com> Message-ID: <7D2C3606-AC65-4C79-8EC3-72C8C292B482@gmx.de> Hi > On 13. Feb 2021, at 12:55, Jaromir wrote: > > Hi, > I can't figure this one out - is the value of /complete / in #ifCurtailed > method used somewhere? > Very confusing ;) Thanks a lot! > Jaromir > > ifCurtailed: aBlock > | complete result | > > result := self valueNoContextSwitch. > complete := true. > ^result Yes. But first thing to notice is that #ensure: uses the same primitive and the same names and oder of local variables. In both methods, the comment states: " The VM uses prim 198 in a context's method as the mark for an ensure:/ifCurtailed: activation" But more so: Look at Context>>unwindTo: unwindTo: aContext | ctx unwindBlock | ctx := self. [(ctx := ctx findNextUnwindContextUpTo: aContext) isNil] whileFalse: [ (ctx tempAt: 2) ifNil:[ ctx tempAt: 2 put: true. unwindBlock := ctx tempAt: 1. unwindBlock value] ]. In a Context, that is the "running" form of a Block, tempAt: 1 is the argument of #ifCurtailed:/#ensure:. and tempAt: 2 is "completed". So: the context will be marked as being completed either via #ifCurtailed: directly or via #unwindTo:. However, in #ensure: ensure: aBlock | complete returnValue | returnValue := self valueNoContextSwitch. complete ifNil:[ complete := true. aBlock value. ]. ^ returnValue The aBlock will only be run if the action was not completed yet. "complete" can be set from the outside as can be seen in #unwindTo:. It is also visible, that #unwindTo: and #ensure: have a similar structure, but #unwindTo: operates on the data structure of the "running" code. See also in Context: #restart #resume: #resume:through: or Process>>#terminate. I hope this helps :) Best regards -Tobias From nicolas.cellier.aka.nice at gmail.com Sat Feb 13 15:16:54 2021 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Sat, 13 Feb 2021 16:16:54 +0100 Subject: [squeak-dev] Float32Array weirdness In-Reply-To: References: Message-ID: Hi Stef, it's a VM problem that has been solved already. It works OK with latest VM. Le sam. 13 févr. 2021 à 15:34, Stéphane Rollandin a écrit : > > Hello all, > > In the latest trunk image, #at:put: in Float32Array seems to miss the > fractional part: > > | floatArray | > (floatArray := Float32Array new: 4) at: 2 put: 2.3. > floatArray > > ==> a Float32Array(0.0 2.0 0.0 0.0) > > > Stef > From lewis at mail.msen.com Sat Feb 13 15:18:02 2021 From: lewis at mail.msen.com (David T. Lewis) Date: Sat, 13 Feb 2021 10:18:02 -0500 Subject: [squeak-dev] Float32Array weirdness In-Reply-To: References: Message-ID: <20210213151802.GA34279@shell.msen.com> On Sat, Feb 13, 2021 at 03:34:40PM +0100, St??phane Rollandin wrote: > Hello all, > > In the latest trunk image, #at:put: in Float32Array seems to miss the > fractional part: > > | floatArray | > (floatArray := Float32Array new: 4) at: 2 put: 2.3. > floatArray > > ==> a Float32Array(0.0 2.0 0.0 0.0) > I cannot reproduce. I am on linux, and I get this: ==> a Float32Array(0.0 2.299999952316284 0.0 0.0) Dave From lewis at mail.msen.com Sat Feb 13 15:41:46 2021 From: lewis at mail.msen.com (David T. Lewis) Date: Sat, 13 Feb 2021 10:41:46 -0500 Subject: [squeak-dev] Rectangle>>merging: does not accepts Sets anymore In-Reply-To: References: Message-ID: <20210213154146.GA36611@shell.msen.com> On Sat, Feb 13, 2021 at 12:57:15PM +0100, St??phane Rollandin wrote: > Hello all, > > I just noticed that Rectangle class>>#merging: now (well, since summer > 2020) uses #first and so does not allow its argument to be a Set > anymore. Is that the intended behavior? > Hi Stef, The change was introduced here: Name: Graphics-kfr.436 Author: kfr Time: 22 August 2020, 11:47:40.557622 am I wanted to subclass Rectangle with a instance variable to carry some state, but these methodes indirected to Point>>corner: so it broke the override and returned a ordinary Rectangle instead of my fancy new subclass SuperRectangle Updated to use #first to get the first element and #allButFirstDo: to iterate over the rest. (Suggested by Levente Uzonyi) Two methods are affected, #merging: and #encompassing: I don't have an easy way to verify, but it looks like adding #asArray might resolve the issue for Sets (e.g. listOfRects asArray in #merging:). Can you check and see if that is what is needed? I do not know if this would be a proper fix but it would at least clarify the problem. Thanks, Dave From nicolas.cellier.aka.nice at gmail.com Sat Feb 13 15:55:49 2021 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Sat, 13 Feb 2021 16:55:49 +0100 Subject: [squeak-dev] Rectangle>>merging: does not accepts Sets anymore In-Reply-To: <20210213154146.GA36611@shell.msen.com> References: <20210213154146.GA36611@shell.msen.com> Message-ID: We could use anyOne instead of first; and do: instead of allButFirstDo: Iterating twice on anyOne is really benign... Le sam. 13 févr. 2021 à 16:41, David T. Lewis a écrit : > > On Sat, Feb 13, 2021 at 12:57:15PM +0100, St??phane Rollandin wrote: > > Hello all, > > > > I just noticed that Rectangle class>>#merging: now (well, since summer > > 2020) uses #first and so does not allow its argument to be a Set > > anymore. Is that the intended behavior? > > > > Hi Stef, > > The change was introduced here: > > Name: Graphics-kfr.436 > Author: kfr > Time: 22 August 2020, 11:47:40.557622 am > > I wanted to subclass Rectangle with a instance variable to carry some > state, but these methodes indirected to Point>>corner: so it broke the > override and returned a ordinary Rectangle instead of my fancy new > subclass SuperRectangle > > Updated to use #first to get the first element and #allButFirstDo: > to iterate over the rest. (Suggested by Levente Uzonyi) > > Two methods are affected, #merging: and #encompassing: > > I don't have an easy way to verify, but it looks like adding #asArray > might resolve the issue for Sets (e.g. listOfRects asArray in #merging:). > Can you check and see if that is what is needed? > > I do not know if this would be a proper fix but it would at least > clarify the problem. > > Thanks, > > Dave > > From commits at source.squeak.org Sat Feb 13 16:04:59 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sat, 13 Feb 2021 16:04:59 0000 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz Message-ID: Nicolas Cellier uploaded a new version of Graphics to project The Inbox: http://source.squeak.org/inbox/Graphics-nice.446.mcz ==================== Summary ==================== Name: Graphics-nice.446 Author: nice Time: 13 February 2021, 5:04:52.453325 pm UUID: d13c1db2-370f-4fa6-b7ae-e6766bf0c8fb Ancestors: Graphics-dtl.445 Let Rectangle merging:/encompassing: an unordered collection. =============== Diff against Graphics-dtl.445 =============== Item was changed: ----- Method: Rectangle class>>encompassing: (in category 'instance creation') ----- encompassing: listOfPoints "A number of callers of encompass: should use this method." | topLeft bottomRight | + topLeft := bottomRight := listOfPoints anyOne. + listOfPoints do: - topLeft := bottomRight := listOfPoints first. - listOfPoints allButFirstDo: [:p |topLeft := topLeft min: p. + bottomRight := bottomRight max: p]. - bottomRight := bottomRight max: p]. ^self origin: topLeft corner: bottomRight ! Item was changed: ----- Method: Rectangle class>>merging: (in category 'instance creation') ----- merging: listOfRects "A number of callers of merge: should use this method." + | aRectangle bottomRight topLeft | + aRectangle := listOfRects anyOne. + topLeft := aRectangle topLeft. + bottomRight := aRectangle bottomRight. - | bottomRight topLeft | - topLeft := listOfRects first topLeft. - bottomRight := listOfRects first bottomRight. listOfRects + do: [:r | topLeft := topLeft min: r topLeft. - allButFirstDo: [:r | topLeft := topLeft min: r topLeft. bottomRight := bottomRight max: r bottomRight]. ^self origin: topLeft corner: bottomRight. ! From lecteur at zogotounga.net Sat Feb 13 16:44:10 2021 From: lecteur at zogotounga.net (=?UTF-8?Q?St=c3=a9phane_Rollandin?=) Date: Sat, 13 Feb 2021 17:44:10 +0100 Subject: [squeak-dev] Float32Array weirdness In-Reply-To: References: Message-ID: > Hi Stef, > it's a VM problem that has been solved already. It works OK with latest VM. Ah ok, thanks. It would be good to update the VM coming with trunk images then (they are from March 3rd) Stef From lecteur at zogotounga.net Sat Feb 13 16:45:19 2021 From: lecteur at zogotounga.net (=?UTF-8?Q?St=c3=a9phane_Rollandin?=) Date: Sat, 13 Feb 2021 17:45:19 +0100 Subject: [squeak-dev] Float32Array weirdness In-Reply-To: <20210213151802.GA34279@shell.msen.com> References: <20210213151802.GA34279@shell.msen.com> Message-ID: <8886299d-6de3-d474-7988-8a72cff28877@zogotounga.net> > I cannot reproduce. I am on linux, and I get this: > > ==> a Float32Array(0.0 2.299999952316284 0.0 0.0) I forgot to mention I'm on Windows, sorry about that. Stef From lecteur at zogotounga.net Sat Feb 13 16:49:57 2021 From: lecteur at zogotounga.net (=?UTF-8?Q?St=c3=a9phane_Rollandin?=) Date: Sat, 13 Feb 2021 17:49:57 +0100 Subject: [squeak-dev] Rectangle>>merging: does not accepts Sets anymore In-Reply-To: References: <20210213154146.GA36611@shell.msen.com> Message-ID: >> I don't have an easy way to verify, but it looks like adding #asArray >> might resolve the issue for Sets (e.g. listOfRects asArray in #merging:). Yes it would, but at a cost that I would better avoid (both in term of performance and GC), since #merging: is a pretty fundamental method for computational geometry. Best, Stef From jrmaffeo at gmail.com Sat Feb 13 16:58:26 2021 From: jrmaffeo at gmail.com (John-Reed Maffeo) Date: Sat, 13 Feb 2021 09:58:26 -0700 Subject: [squeak-dev] Syntax Error window locks up image In-Reply-To: References: Message-ID: CMD]+[Dot] interrupt was the first thing I tried. At this point it is not repeatable so I don't think there is anything I can do other that keep an eye out for it. the method that is run every hour is setup to run a method to do some work and then spawn a block with an hour delay which runs the method again when the delay elapses. -jrm On Fri, Feb 12, 2021 at 1:33 AM Marcel Taeumel wrote: > Hi John-Reed, > > can you tell us more about that method your are running every hour? > > Syntax errors are as tricky as debuggers. They actually use a debugger > internally to interrupt the current (i.e. the compiler's/parser's) control > flow and offer interactive means to fix syntax to then continue compilation. > > Considering interactive syntax correction, I am not sure whether > compilation is safe in processes other than the UI process. > > Did you try hitting [CMD]+[Dot] in that case? > > Best, > Marcel > > Am 12.02.2021 06:00:11 schrieb John-Reed Maffeo : > What causes a window like this to appear? > Why does it lock up the image? > The problem occurred in an image that was running unattended using #Delay > to run a method every hour. The application is in development but it has > been running on schedule for a month or so without any problems. > > I do save and restart the image occasionally. > > -- > jrm > > > -- John-Reed Maffeo -------------- next part -------------- An HTML attachment was scrubbed... URL: From eliot.miranda at gmail.com Sat Feb 13 16:59:54 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sat, 13 Feb 2021 08:59:54 -0800 Subject: [squeak-dev] The Trunk: Kernel-ct.1368.mcz In-Reply-To: References: Message-ID: <5AC68202-9597-4C01-A48D-52C8FFA73CCA@gmail.com> I disagree with this. Only certain processes are named. Including the destiny name of unnamed processes just introduces noise. By all means include the name of named processes, but please *don’t* add verbosity where it is unhelpful. _,,,^..^,,,_ (phone) > On Feb 12, 2021, at 3:34 PM, commits at source.squeak.org wrote: > > David T. Lewis uploaded a new version of Kernel to project The Trunk: > http://source.squeak.org/trunk/Kernel-ct.1368.mcz > > ==================== Summary ==================== > > Name: Kernel-ct.1368 > Author: ct > Time: 24 January 2021, 3:19:48.003384 pm > UUID: c62a6062-b240-9149-a2ed-78fdc1079dfd > Ancestors: Kernel-mt.1364 > > Proposal: Always include process name into its print string. This facilitates debugging/inspecting of multiprocess scenarios. > > =============== Diff against Kernel-mt.1364 =============== > > Item was changed: > ----- Method: Process>>longPrintOn: (in category 'printing') ----- > longPrintOn: stream > > | ctxt | > super printOn: stream. > + stream > + nextPut: $(; > + nextPutAll: self name; > + nextPut: $). > stream cr. > ctxt := self suspendedContext. > [ctxt == nil] whileFalse: [ > stream space. > ctxt printOn: stream. > stream cr. > ctxt := ctxt sender. > ]. > ! > > Item was changed: > ----- Method: Process>>printOn: (in category 'printing') ----- > printOn: aStream > > super printOn: aStream. > + aStream > + nextPut: $(; > + nextPutAll: self name; > + nextPut: $). > aStream nextPutAll: ' in '. > suspendedContext printOn: aStream! > > From Christoph.Thiede at student.hpi.uni-potsdam.de Sat Feb 13 17:45:11 2021 From: Christoph.Thiede at student.hpi.uni-potsdam.de (Thiede, Christoph) Date: Sat, 13 Feb 2021 17:45:11 +0000 Subject: [squeak-dev] The Trunk: Kernel-ct.1368.mcz In-Reply-To: <5AC68202-9597-4C01-A48D-52C8FFA73CCA@gmail.com> References: , <5AC68202-9597-4C01-A48D-52C8FFA73CCA@gmail.com> Message-ID: <4d59ca8bdb344d8d83a233120f37dce4@student.hpi.uni-potsdam.de> Hi Eliot, we already discussed this below my inbox proposal, but I still think that "destiny name of unnamed processed" is more than noise. It is still helpful to compare the identities of two process instances by taking a short look at their print strings ... Best, Christoph ________________________________ Von: Squeak-dev im Auftrag von Eliot Miranda Gesendet: Samstag, 13. Februar 2021 17:59:54 An: squeak-dev at lists.squeakfoundation.org Betreff: Re: [squeak-dev] The Trunk: Kernel-ct.1368.mcz I disagree with this. Only certain processes are named. Including the destiny name of unnamed processes just introduces noise. By all means include the name of named processes, but please *don’t* add verbosity where it is unhelpful. _,,,^..^,,,_ (phone) > On Feb 12, 2021, at 3:34 PM, commits at source.squeak.org wrote: > > David T. Lewis uploaded a new version of Kernel to project The Trunk: > http://source.squeak.org/trunk/Kernel-ct.1368.mcz > > ==================== Summary ==================== > > Name: Kernel-ct.1368 > Author: ct > Time: 24 January 2021, 3:19:48.003384 pm > UUID: c62a6062-b240-9149-a2ed-78fdc1079dfd > Ancestors: Kernel-mt.1364 > > Proposal: Always include process name into its print string. This facilitates debugging/inspecting of multiprocess scenarios. > > =============== Diff against Kernel-mt.1364 =============== > > Item was changed: > ----- Method: Process>>longPrintOn: (in category 'printing') ----- > longPrintOn: stream > > | ctxt | > super printOn: stream. > + stream > + nextPut: $(; > + nextPutAll: self name; > + nextPut: $). > stream cr. > ctxt := self suspendedContext. > [ctxt == nil] whileFalse: [ > stream space. > ctxt printOn: stream. > stream cr. > ctxt := ctxt sender. > ]. > ! > > Item was changed: > ----- Method: Process>>printOn: (in category 'printing') ----- > printOn: aStream > > super printOn: aStream. > + aStream > + nextPut: $(; > + nextPutAll: self name; > + nextPut: $). > aStream nextPutAll: ' in '. > suspendedContext printOn: aStream! > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lewis at mail.msen.com Sat Feb 13 18:04:07 2021 From: lewis at mail.msen.com (David T. Lewis) Date: Sat, 13 Feb 2021 13:04:07 -0500 Subject: [squeak-dev] The Trunk: Kernel-ct.1368.mcz In-Reply-To: <5AC68202-9597-4C01-A48D-52C8FFA73CCA@gmail.com> References: <5AC68202-9597-4C01-A48D-52C8FFA73CCA@gmail.com> Message-ID: <20210213180407.GA58985@shell.msen.com> I'll revert if it is not a good thing to do. To me it seems both useful and harmless. Dave On Sat, Feb 13, 2021 at 08:59:54AM -0800, Eliot Miranda wrote: > I disagree with this. Only certain processes are named. Including the destiny name of unnamed processes just introduces noise. By all means include the name of named processes, but please *don???t* add verbosity where it is unhelpful. > > _,,,^..^,,,_ (phone) > > > On Feb 12, 2021, at 3:34 PM, commits at source.squeak.org wrote: > > > > ???David T. Lewis uploaded a new version of Kernel to project The Trunk: > > http://source.squeak.org/trunk/Kernel-ct.1368.mcz > > > > ==================== Summary ==================== > > > > Name: Kernel-ct.1368 > > Author: ct > > Time: 24 January 2021, 3:19:48.003384 pm > > UUID: c62a6062-b240-9149-a2ed-78fdc1079dfd > > Ancestors: Kernel-mt.1364 > > > > Proposal: Always include process name into its print string. This facilitates debugging/inspecting of multiprocess scenarios. > > > > =============== Diff against Kernel-mt.1364 =============== > > > > Item was changed: > > ----- Method: Process>>longPrintOn: (in category 'printing') ----- > > longPrintOn: stream > > > > | ctxt | > > super printOn: stream. > > + stream > > + nextPut: $(; > > + nextPutAll: self name; > > + nextPut: $). > > stream cr. > > ctxt := self suspendedContext. > > [ctxt == nil] whileFalse: [ > > stream space. > > ctxt printOn: stream. > > stream cr. > > ctxt := ctxt sender. > > ]. > > ! > > > > Item was changed: > > ----- Method: Process>>printOn: (in category 'printing') ----- > > printOn: aStream > > > > super printOn: aStream. > > + aStream > > + nextPut: $(; > > + nextPutAll: self name; > > + nextPut: $). > > aStream nextPutAll: ' in '. > > suspendedContext printOn: aStream! > > > > > From m at jaromir.net Sat Feb 13 19:22:14 2021 From: m at jaromir.net (Jaromir) Date: Sat, 13 Feb 2021 13:22:14 -0600 (CST) Subject: [squeak-dev] #ifCurtailed - why the "complete := true" line? In-Reply-To: <1613217320055-0.post@n4.nabble.com> References: <1613217320055-0.post@n4.nabble.com> Message-ID: <1613244134994-0.post@n4.nabble.com> Hi Tobias, >> Hi, >> I can't figure this one out - is the value of /complete / in #ifCurtailed >> method used somewhere? > Yes. That’s a great help, thanks! So I understand “complete” marks contexts that have already been processed (unwound) during an abnormal return (in #resume:through:) or, in case of a normal return it just marks normal completion of #ensure/#ifCurtailed. Just to be sure: there’s a close interplay between e.g. #ensure and #resume:through: but NO interplay between #ensure and #ifCurtailed, right? And finally, is there a simple example where “complete” plays a role? It seems to me that if #resume:through: unwinds contexts it never gets to unwind the same context twice and if the #ensure protected block returns normally no unwinding even happens. I tried to remove “complete” from the #ensure/#ifCurtailed code and all my naive examples work as before :) > But first thing to notice is that #ensure: uses the same primitive and the > same names and oder of local variables. > > In both methods, the comment states: > " The VM uses prim 198 in a context's method as the mark for an > ensure:/ifCurtailed: activation" > > But more so: > > Look at Context>>unwindTo: > > unwindTo: aContext > > ​ | ctx unwindBlock | > ​ ctx := self. > ​ [(ctx := ctx findNextUnwindContextUpTo: aContext) isNil] whileFalse: > [ > ​ (ctx tempAt: 2) ifNil:[ > ​ ctx tempAt: 2 put: true. > ​ unwindBlock := ctx tempAt: 1. > ​ unwindBlock value] > ​ ]. > > In a Context, that is the "running" form of a Block, tempAt: 1 is the > argument of #ifCurtailed:/#ensure:. > and tempAt: 2 is "completed". So: the context will be marked as being > completed either via #ifCurtailed: directly or via #unwindTo:. However, > in #ensure: > > ensure: aBlock > | complete returnValue | > > returnValue := self valueNoContextSwitch. > complete ifNil:[ > complete := true. > aBlock value. > ]. > ^ returnValue > > The aBlock will only be run if the action was not completed yet. Now this confused me: if the protected block returns normally, that means no unwinding has happened and thus “complete” must be nil and aBlock will always be evaluated. Conversely, if the protected block returned abnormally I thought it meant the process would never reach the condition and the aBlock would never be run here (but on the unwind path instead). Where am I wrong? (I used this to explore: [x := thisContext sender explore. ^1] ensure: [x explore] ) Thanks again! Jaromir > "complete" can be set from the outside as can be seen in #unwindTo:. > It is also visible, that #unwindTo: and #ensure: have a similar structure, > but #unwindTo: operates on the data structure of the "running" code. > > See also in Context: #restart #resume: #resume:through: or > Process>>#terminate. > > I hope this helps :) > > Best regards > -Tobias -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From leves at caesar.elte.hu Sat Feb 13 21:12:39 2021 From: leves at caesar.elte.hu (Levente Uzonyi) Date: Sat, 13 Feb 2021 22:12:39 +0100 (CET) Subject: [squeak-dev] The Trunk: CollectionsTests-jar.349.mcz In-Reply-To: References: Message-ID: Hi David, While these tests pass now and document something about shared queues, I don't think we should have them in the Trunk. I prefer the design-by-contract approach for tests where there are actual requirements to be satisfied by the subject of the tests to make them pass. These tests do not describe such requirements, so if the implementations change, they'll start failing, which some may interpret wrongly as actual errors. Another problem with them is that people may feel like they can relying on the behavior described by these tests since there are tests for them. Levente On Sat, 13 Feb 2021, commits at source.squeak.org wrote: > David T. Lewis uploaded a new version of CollectionsTests to project The Trunk: > http://source.squeak.org/trunk/CollectionsTests-jar.349.mcz > > ==================== Summary ==================== > > Name: CollectionsTests-jar.349 > Author: jar > Time: 8 February 2021, 8:25:19.407373 pm > UUID: f484ba2b-2035-b046-9222-c3e4e42a7ad4 > Ancestors: CollectionsTests-ul.348 > > Test to show differing SharedQueue and SharedQueue2 semantics > > =============== Diff against CollectionsTests-ul.348 =============== > > Item was added: > + ----- Method: AbstractSharedQueueTest>>testContention2 (in category 'tests') ----- > + testContention2 > + "and here's a test case that distunguishes SharedQueue from SharedQueue2 semantics: > + SharedQueue2 produces a sequence #(5 10 15) while SharedQueue produces #(5 15 10)" > + > + | q r1 r2 r3 | > + q := self queueClass new. > + > + [ r1 := q next. q nextPut: 15. r3 := q next ] fork. > + [ r2 := q next ] fork. > + > + Processor yield. "let the above two threads block" > + > + q nextPut: 5. > + Processor yield. "let the first thread above proceed" > + > + q nextPut: 10. > + Processor yield. "let the unfinished thread above finish" > + > + q class = SharedQueue2 ifTrue: [ > + self assert: 5 equals: r1. > + self assert: 10 equals: r2. > + self assert: 15 equals: r3. > + self assert: nil equals: q nextOrNil ]. > + > + q class = SharedQueue ifTrue: [ > + self assert: 5 equals: r1. > + self assert: 15 equals: r2. > + self assert: 10 equals: r3. > + self assert: nil equals: q nextOrNil ]. > + > + "SharedQueue2 implementation using a Monitor checks the queue for available data while > + the SharedQueue implementation based on a Semaphore checks for excessSignals > 0, > + which results in these two different outcomes"! From lewis at mail.msen.com Sat Feb 13 21:49:17 2021 From: lewis at mail.msen.com (David T. Lewis) Date: Sat, 13 Feb 2021 16:49:17 -0500 Subject: [squeak-dev] The Trunk: CollectionsTests-jar.349.mcz In-Reply-To: References: Message-ID: <20210213214917.GA89495@shell.msen.com> Hi Levente, You are right. I removed the test from trunk. The AbstractSharedQueueTest>>testContention2 test in CollectionsTests-jar.349 is a useful description of the current behavior, so may want to refer to that if the differences cause problems. Sorry for the noise. Dave On Sat, Feb 13, 2021 at 10:12:39PM +0100, Levente Uzonyi wrote: > Hi David, > > While these tests pass now and document something about shared queues, I > don't think we should have them in the Trunk. > I prefer the design-by-contract approach for tests where there are > actual requirements to be satisfied by the subject of the tests to make > them pass. > These tests do not describe such requirements, so if the implementations > change, they'll start failing, which some may interpret wrongly as actual > errors. > Another problem with them is that people may feel like they can relying on > the behavior described by these tests since there are tests for them. > > > Levente > > On Sat, 13 Feb 2021, commits at source.squeak.org wrote: > > >David T. Lewis uploaded a new version of CollectionsTests to project The > >Trunk: > >http://source.squeak.org/trunk/CollectionsTests-jar.349.mcz > > > >==================== Summary ==================== > > > >Name: CollectionsTests-jar.349 > >Author: jar > >Time: 8 February 2021, 8:25:19.407373 pm > >UUID: f484ba2b-2035-b046-9222-c3e4e42a7ad4 > >Ancestors: CollectionsTests-ul.348 > > > >Test to show differing SharedQueue and SharedQueue2 semantics > > > >=============== Diff against CollectionsTests-ul.348 =============== > > > >Item was added: > >+ ----- Method: AbstractSharedQueueTest>>testContention2 (in category > >'tests') ----- > >+ testContention2 > >+ "and here's a test case that distunguishes SharedQueue from > >SharedQueue2 semantics: > >+ SharedQueue2 produces a sequence #(5 10 15) while SharedQueue > >produces #(5 15 10)" > >+ > >+ | q r1 r2 r3 | > >+ q := self queueClass new. > >+ > >+ [ r1 := q next. q nextPut: 15. r3 := q next ] fork. > >+ [ r2 := q next ] fork. > >+ > >+ Processor yield. "let the above two threads block" > >+ > >+ q nextPut: 5. > >+ Processor yield. "let the first thread above proceed" > >+ > >+ q nextPut: 10. > >+ Processor yield. "let the unfinished thread above finish" > >+ > >+ q class = SharedQueue2 ifTrue: [ > >+ self assert: 5 equals: r1. > >+ self assert: 10 equals: r2. > >+ self assert: 15 equals: r3. > >+ self assert: nil equals: q nextOrNil ]. > >+ > >+ q class = SharedQueue ifTrue: [ > >+ self assert: 5 equals: r1. > >+ self assert: 15 equals: r2. > >+ self assert: 10 equals: r3. > >+ self assert: nil equals: q nextOrNil ]. > >+ > >+ "SharedQueue2 implementation using a Monitor checks the queue for > >available data while + the SharedQueue implementation based on a Semaphore > >checks for excessSignals > 0, + which results in these two different > >outcomes"! > From gettimothy at zoho.com Sun Feb 14 14:21:55 2021 From: gettimothy at zoho.com (gettimothy) Date: Sun, 14 Feb 2021 09:21:55 -0500 Subject: [squeak-dev] correct form for Problem With Blocks Message-ID: <177a0eb5dab.ffedfef8528.2383924643943088178@zoho.com> Hi Levente, Thank you for your reply. That makes no sense. I can't even fathom how it works. #inject:into:'s second argument, the block, must return the computed value. Currently that block returns the value assigned to base when pair first = 'e' and nil otherwise. So, if it works correctly now, which is doubtful, then just remove the assignments to base from the block and it should just work. I did, it does. thx. Fwiw, here are the tests I have for this rule ...It might make things clearer on what it is meant to accomplish.  The pattern is borrowed from some Algebraic PEG grammar I found on the net. The purpose is to support some PHP-isms in the wikitext grammar...basically PHP version of callbacks given a pattern. testFloat "Float <-  Multiplicand  (''e'' Multiplicand)+" | n output actor | actor := PEGWikiMediaGeneratorTables new. actor transcripton: false.  "disable tracing to Transcript" n := '-2.3e-4'. output := parser parse: 'Negation' stream: n reading actor: actor. self assert: (output = -0.00023 ). n := '6e2e3'. output := parser parse: 'Float' stream: n reading actor: actor. self assert: (output = 600000.0) . n := '2e3'. output := parser parse: 'Float' stream: n reading actor: actor. self assert: (output = 2000) . n := '-2.3e-4'. output := parser parse: 'Negation' stream: n reading actor: actor. self assert: (output = -0.00023 ). n := '(trunc2)e(trunc-3)'. output := parser parse: 'Float' stream: n reading actor: actor. self assert: (output = 0.002) . n := '(trunc2)e(trunc0)'. output := parser parse: 'Float' stream: n reading actor: actor. self assert: (output = 2) . n := '(trunc2)e(trunc18)'. output := parser parse: 'Float' stream: n reading actor: actor.  self assert: (output = 2.0e18) . n := '(trunc2)e(trunc19)'. output := parser parse: 'Float' stream: n reading actor: actor. self assert: (output = 2.0e19) . n := '6e(5-2)'. output := parser parse: 'Float' stream: n reading actor: actor. self assert: (output = 6000.0) . n := '(5-2)e-2'. output := parser parse: 'Float' stream: n reading actor: actor. self assert: (output = 0.03) . n := '6e(5-2)e-2'. output := parser parse: 'Float' stream: n reading actor: actor. self assert: (output = 60) . n := '5.0e-324'.  "(Float fmin) * (Float fmax)" output := parser parse: 'Operation' stream: n reading actor: actor. self assert: (output = (Float fmin) ) . -------------- next part -------------- An HTML attachment was scrubbed... URL: From stes at telenet.be Mon Feb 15 07:25:27 2021 From: stes at telenet.be (stes@PANDORA.BE) Date: Mon, 15 Feb 2021 08:25:27 +0100 (CET) Subject: [squeak-dev] Building UnicodePlugin on ARM64 Message-ID: <1225488599.6405541.1613373927641.JavaMail.zimbra@telenet.be> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 > Notice how it does not have the -I/usr/lib/aarch64-linux-gnu/glib-2.0/include path I've now added to > acinclude.m4 Makefile.inc I think this is because the configure script needs to be rebuilt. > The obvious question is what the 'proper' way to solve this is. > I had the vague idea floating around the back of my skull that the > 'configure' script stuff built itself from things like the acinclude.m4 fragments - > and it certainly seems to include exactly the text from the original acinclude file. Yes this is true. Something like 'autoconf' or perhaps 'autoreconf' to generate the configure script. As the README in the plugin directory for UnicodePlugin indicates, an approach may be (it is a possibility) to use "pkg-config" Assuming that pkgconfig on your system gives some results such as: # pkg-config --cflags glib-2.0 # PKG_CONFIG_PATH=/usr/lib/64/pkgconfig pkg-config --cflags glib-2.0 it may be able to find the required --cflags using pkg-config However I can imagine that approach has its own disadvantages. My understanding is that historically pkg-config was used, and that the opensmalltalk-vm team wants to migrate/move away from pkg-config. If I'm not mistaken the Squeak VM "Classic" (squeak-4) uses the approach, with cmake/pkg-config. Squeak VM classic (in subversion) uses pkg-config. The GNU configure script could use also the same approach using: PKG_CHECK_MODULES(UNICODE_PLUGIN,[glib-2.0 pangocairo],,AC_PLUGIN_DISABLE) AC_SUBST(UNICODE_PLUGIN_CFLAGS) AC_SUBST(UNICODE_PLUGIN_LIBS) However I agree that no approach is without faults, they all have their own advantages and disadvantages, I suppose. Currently on Solaris 11.4 I just disable the UnicodePlugin, as it used to build fine for GNOME 2 (on OpenIndiana with MATE or Solaris 11.3), but not on GNOME 3 with 64bit (Solaris 11.4) for me. Provided I reconfigure with the right path to #include, UnicodePlugin builds, on Solaris 11.4 as well. This is basically unrelated to Solaris 11.3 or Solaris 11.4 etc. It is just where Linux/Unix distributions (or operating systems in general), put their #include files and the configuration tools to figure out the settings. Regards, David Stes -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQEcBAEBCAAGBQJgKiHRAAoJEAwpOKXMq1Maxw4H/29SCg+YABqmJhd3s4LhCmnt 9fp2ogOTGFWdj4OXeBTDG0QnqTwEuJWLAruispEMiwtCoFWFoJKzpHt0yW78VjEu vhivE/TmOVPYPAzzU1DwSjttGP5XOpul3Pl9kAZvXXR2bNece93FqKBb+6Kjb47Z aRch60dw+XXc+ZoaxnUl4DOw5qKQQJLNq/tFIfKcYN3ZHuwUi2NGxPXtoxy9fsDY z5hBVE3aj58X1kKyFJs9wvT2uJG8VdQReAjSHYxOxRXJaQCPhzaSMnN14KKmvGyr GnakeHLgrUKyldvvv0FFj4u9kioYJKknRndS1tSkxbrVF1KUbrpHKrv4teDliYA= =+siH -----END PGP SIGNATURE----- From asqueaker at gmail.com Mon Feb 15 22:36:51 2021 From: asqueaker at gmail.com (Chris Muller) Date: Mon, 15 Feb 2021 16:36:51 -0600 Subject: [squeak-dev] Rectangle>>merging: does not accepts Sets anymore In-Reply-To: References: <20210213154146.GA36611@shell.msen.com> Message-ID: On Sat, Feb 13, 2021 at 10:50 AM Stéphane Rollandin wrote: > >> I don't have an easy way to verify, but it looks like adding #asArray > >> might resolve the issue for Sets (e.g. listOfRects asArray in > #merging:). > > Yes it would, but at a cost that I would better avoid (both in term of > performance and GC), since #merging: is a pretty fundamental method for computational geometry. > In which case you should make use of #quickMerge: then. -------------- next part -------------- An HTML attachment was scrubbed... URL: From asqueaker at gmail.com Mon Feb 15 23:01:37 2021 From: asqueaker at gmail.com (Chris Muller) Date: Mon, 15 Feb 2021 17:01:37 -0600 Subject: [squeak-dev] The Trunk: Kernel-ct.1368.mcz In-Reply-To: <5AC68202-9597-4C01-A48D-52C8FFA73CCA@gmail.com> References: <5AC68202-9597-4C01-A48D-52C8FFA73CCA@gmail.com> Message-ID: On Sat, Feb 13, 2021 at 11:00 AM Eliot Miranda wrote: > I disagree with this. Only certain processes are named. Including the > destiny name of unnamed processes just introduces noise. By all means > include the name of named processes, but please *don’t* add verbosity where > it is unhelpful. > +1. You are so right. Assigning a *name* for human consumption establishes the intent of the human's desire to utilize its #name as the basis for its consumption. If specific identity distinction is needed, then set it as part of its name, but we should not include arbitrary attributes in its #printString. If such additional identity attributes are needed, they should be consumed by sending the appropriate messages from the appropriate places (UI). In fact, I would recommend taking this concept one step further by, when a name for human consumption is explicitly set, consider it an indication that the "type" (e.g., class), is not really germaine to its #printString, either. Skip the super call. Alternatively, the name accessors could be changed to ^ name value so that a Block could be assigned (e.g., dynamic name). - Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: From lewis at mail.msen.com Mon Feb 15 23:39:07 2021 From: lewis at mail.msen.com (David T. Lewis) Date: Mon, 15 Feb 2021 18:39:07 -0500 Subject: [squeak-dev] The Trunk: Kernel-ct.1368.mcz In-Reply-To: References: <5AC68202-9597-4C01-A48D-52C8FFA73CCA@gmail.com> Message-ID: <20210215233907.GA35939@shell.msen.com> On Mon, Feb 15, 2021 at 05:01:37PM -0600, Chris Muller wrote: > On Sat, Feb 13, 2021 at 11:00 AM Eliot Miranda > wrote: > > > I disagree with this. Only certain processes are named. Including the > > destiny name of unnamed processes just introduces noise. By all means > > include the name of named processes, but please *don???t* add verbosity where > > it is unhelpful. > > > > +1. You are so right. Assigning a *name* for human consumption > establishes the intent of the human's desire to utilize its #name as the > basis for its consumption. If specific identity distinction is > needed, then set it as part of its name, but we should not include > arbitrary attributes in its #printString. If such additional identity > attributes are needed, they should be consumed by sending the appropriate > messages from the appropriate places (UI). > Eliot and Chris both think that this was a bad idea. I don't understand the objection, but if no one speaks up in support of it, I will revert the merge in a day or two. Dave > In fact, I would recommend taking this concept one step further by, when a > name for human consumption is explicitly set, consider it an indication > that the "type" (e.g., class), is not really germaine to its #printString, > either. Skip the super call. > > Alternatively, the name accessors could be changed to > > ^ name value > > so that a Block could be assigned (e.g., dynamic name). > > - Chris > From ma.chris.m at gmail.com Tue Feb 16 04:54:44 2021 From: ma.chris.m at gmail.com (Chris Muller) Date: Mon, 15 Feb 2021 22:54:44 -0600 Subject: [squeak-dev] The Trunk: Kernel-ct.1368.mcz In-Reply-To: <20210215233907.GA35939@shell.msen.com> References: <5AC68202-9597-4C01-A48D-52C8FFA73CCA@gmail.com> <20210215233907.GA35939@shell.msen.com> Message-ID: Hi Dave, thanks for your efforts in keeping the improvements flowing. For this, would you please consider Kernel-cmm.1370 (or an improved version of it based on your and others' review), instead of merely reverting Christoph's version to the prior state? Eliot and I both expressed that the name is a good thing for the #printString, when it's set. This is an attempt to capture the intent of Christoph's idea, which was good. Thanks, Chris On Mon, Feb 15, 2021 at 5:39 PM David T. Lewis wrote: > On Mon, Feb 15, 2021 at 05:01:37PM -0600, Chris Muller wrote: > > On Sat, Feb 13, 2021 at 11:00 AM Eliot Miranda > > wrote: > > > > > I disagree with this. Only certain processes are named. Including the > > > destiny name of unnamed processes just introduces noise. By all means > > > include the name of named processes, but please *don???t* add > verbosity where > > > it is unhelpful. > > > > > > > +1. You are so right. Assigning a *name* for human consumption > > establishes the intent of the human's desire to utilize its #name as the > > basis for its consumption. If specific identity distinction is > > needed, then set it as part of its name, but we should not include > > arbitrary attributes in its #printString. If such additional identity > > attributes are needed, they should be consumed by sending the appropriate > > messages from the appropriate places (UI). > > > > Eliot and Chris both think that this was a bad idea. I don't understand > the objection, but if no one speaks up in support of it, I will revert > the merge in a day or two. > > Dave > > > > In fact, I would recommend taking this concept one step further by, when > a > > name for human consumption is explicitly set, consider it an indication > > that the "type" (e.g., class), is not really germaine to its > #printString, > > either. Skip the super call. > > > > Alternatively, the name accessors could be changed to > > > > ^ name value > > > > so that a Block could be assigned (e.g., dynamic name). > > > > - Chris > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Tue Feb 16 04:59:51 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Tue, 16 Feb 2021 04:59:51 0000 Subject: [squeak-dev] The Inbox: Kernel-cmm.1370.mcz Message-ID: Chris Muller uploaded a new version of Kernel to project The Inbox: http://source.squeak.org/inbox/Kernel-cmm.1370.mcz ==================== Summary ==================== Name: Kernel-cmm.1370 Author: cmm Time: 15 February 2021, 10:43:35.519565 pm UUID: d974937b-c8d9-44a1-bbb0-9c233146b528 Ancestors: Kernel-dtl.1369 Let Processes identify themselves by a dynamic #name in their #printString IF they were so intentionally named, otherwise, the classic generic printString (which indicates its current Context). =============== Diff against Kernel-dtl.1369 =============== Item was changed: ----- Method: Process>>longPrintOn: (in category 'printing') ----- + longPrintOn: stream - longPrintOn: stream - | ctxt | + self printOn: stream. - super printOn: stream. - stream - nextPut: $(; - nextPutAll: self name; - nextPut: $). stream cr. ctxt := self suspendedContext. + [ ctxt == nil ] whileFalse: + [ stream space. - [ctxt == nil] whileFalse: [ - stream space. ctxt printOn: stream. stream cr. + ctxt := ctxt sender ]! - ctxt := ctxt sender. - ]. - ! Item was changed: ----- Method: Process>>printOn: (in category 'printing') ----- + printOn: aStream + self name value + ifNil: + [ super printOn: aStream. + aStream nextPutAll: ' in '. + self suspendedContext printOn: aStream ] + ifNotNil: + [ : nm | aStream nextPutAll: nm ]! - printOn: aStream - - super printOn: aStream. - aStream - nextPut: $(; - nextPutAll: self name; - nextPut: $). - aStream nextPutAll: ' in '. - suspendedContext printOn: aStream! From commits at source.squeak.org Sat Feb 13 21:37:18 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sat, 13 Feb 2021 21:37:18 0000 Subject: [squeak-dev] The Trunk: CollectionsTests-dtl.350.mcz Message-ID: David T. Lewis uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-dtl.350.mcz ==================== Summary ==================== Name: CollectionsTests-dtl.350 Author: dtl Time: 13 February 2021, 4:37:17.676276 pm UUID: c4060470-23b9-4b11-a961-41baeb166af8 Ancestors: CollectionsTests-ul.348 Do not include new test from CollectionsTests-jar.349 because it documents existing behavior that may not necessarily be the expected behavior. Discussion at http://lists.squeakfoundation.org/pipermail/squeak-dev/2021-February/213918.html =============== Diff against CollectionsTests-ul.348 =============== From asqueaker at gmail.com Tue Feb 16 06:00:29 2021 From: asqueaker at gmail.com (Chris Muller) Date: Tue, 16 Feb 2021 00:00:29 -0600 Subject: [squeak-dev] The Inbox: Kernel-cmm.1370.mcz In-Reply-To: References: Message-ID: Replaced by cmm-1371. On Mon, Feb 15, 2021 at 10:59 PM wrote: > Chris Muller uploaded a new version of Kernel to project The Inbox: > http://source.squeak.org/inbox/Kernel-cmm.1370.mcz > > ==================== Summary ==================== > > Name: Kernel-cmm.1370 > Author: cmm > Time: 15 February 2021, 10:43:35.519565 pm > UUID: d974937b-c8d9-44a1-bbb0-9c233146b528 > Ancestors: Kernel-dtl.1369 > > Let Processes identify themselves by a dynamic #name in their #printString > IF they were so intentionally named, otherwise, the classic generic > printString (which indicates its current Context). > > =============== Diff against Kernel-dtl.1369 =============== > > Item was changed: > ----- Method: Process>>longPrintOn: (in category 'printing') ----- > + longPrintOn: stream > - longPrintOn: stream > - > | ctxt | > + self printOn: stream. > - super printOn: stream. > - stream > - nextPut: $(; > - nextPutAll: self name; > - nextPut: $). > stream cr. > ctxt := self suspendedContext. > + [ ctxt == nil ] whileFalse: > + [ stream space. > - [ctxt == nil] whileFalse: [ > - stream space. > ctxt printOn: stream. > stream cr. > + ctxt := ctxt sender ]! > - ctxt := ctxt sender. > - ]. > - ! > > Item was changed: > ----- Method: Process>>printOn: (in category 'printing') ----- > + printOn: aStream > + self name value > + ifNil: > + [ super printOn: aStream. > + aStream nextPutAll: ' in '. > + self suspendedContext printOn: aStream ] > + ifNotNil: > + [ : nm | aStream nextPutAll: nm ]! > - printOn: aStream > - > - super printOn: aStream. > - aStream > - nextPut: $(; > - nextPutAll: self name; > - nextPut: $). > - aStream nextPutAll: ' in '. > - suspendedContext printOn: aStream! > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From asqueaker at gmail.com Tue Feb 16 06:04:11 2021 From: asqueaker at gmail.com (Chris Muller) Date: Tue, 16 Feb 2021 00:04:11 -0600 Subject: [squeak-dev] slow uploads Message-ID: Is anyone else experiencing slow upload speed saving to the inbox? -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Tue Feb 16 06:07:41 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Tue, 16 Feb 2021 06:07:41 0000 Subject: [squeak-dev] The Inbox: Kernel-cmm.1371.mcz Message-ID: Chris Muller uploaded a new version of Kernel to project The Inbox: http://source.squeak.org/inbox/Kernel-cmm.1371.mcz ==================== Summary ==================== Name: Kernel-cmm.1371 Author: cmm Time: 15 February 2021, 11:51:24.851653 pm UUID: 4a74e7a0-6654-491e-8a64-685c44d6fb63 Ancestors: Kernel-dtl.1369 Let Processes identify themselves by a dynamic #name in their #printString IF they were so intentionally named, otherwise, the classic generic printString indicating its current Context. =============== Diff against Kernel-dtl.1369 =============== Item was changed: ----- Method: Process>>longPrintOn: (in category 'printing') ----- + longPrintOn: stream - longPrintOn: stream - | ctxt | + self printOn: stream. - super printOn: stream. - stream - nextPut: $(; - nextPutAll: self name; - nextPut: $). stream cr. ctxt := self suspendedContext. + [ ctxt == nil ] whileFalse: + [ stream space. - [ctxt == nil] whileFalse: [ - stream space. ctxt printOn: stream. stream cr. + ctxt := ctxt sender ]! - ctxt := ctxt sender. - ]. - ! Item was changed: ----- Method: Process>>name (in category 'accessing') ----- name + ^ name value + ifNil: [ self hash asString forceTo: 5 paddingStartWith: $ ]! - - ^name ifNil: [ self hash asString forceTo: 5 paddingStartWith: $ ]! Item was changed: ----- Method: Process>>printOn: (in category 'printing') ----- + printOn: aStream + self name + ifNil: + [ super printOn: aStream. + aStream nextPutAll: ' in '. + self suspendedContext printOn: aStream ] + ifNotNil: + [ : nm | aStream nextPutAll: nm ]! - printOn: aStream - - super printOn: aStream. - aStream - nextPut: $(; - nextPutAll: self name; - nextPut: $). - aStream nextPutAll: ' in '. - suspendedContext printOn: aStream! From Das.Linux at gmx.de Tue Feb 16 06:25:19 2021 From: Das.Linux at gmx.de (Tobias Pape) Date: Tue, 16 Feb 2021 07:25:19 +0100 Subject: [squeak-dev] The Trunk: Kernel-ct.1368.mcz In-Reply-To: <20210215233907.GA35939@shell.msen.com> References: <5AC68202-9597-4C01-A48D-52C8FFA73CCA@gmail.com> <20210215233907.GA35939@shell.msen.com> Message-ID: Hi > On 16. Feb 2021, at 00:39, David T. Lewis wrote: > > On Mon, Feb 15, 2021 at 05:01:37PM -0600, Chris Muller wrote: >> On Sat, Feb 13, 2021 at 11:00 AM Eliot Miranda >> wrote: >> >>> I disagree with this. Only certain processes are named. Including the >>> destiny name of unnamed processes just introduces noise. By all means >>> include the name of named processes, but please *don???t* add verbosity where >>> it is unhelpful. >>> >> >> +1. You are so right. Assigning a *name* for human consumption >> establishes the intent of the human's desire to utilize its #name as the >> basis for its consumption. If specific identity distinction is >> needed, then set it as part of its name, but we should not include >> arbitrary attributes in its #printString. If such additional identity >> attributes are needed, they should be consumed by sending the appropriate >> messages from the appropriate places (UI). >> > > Eliot and Chris both think that this was a bad idea. I don't understand > the objection, but if no one speaks up in support of it, I will revert > the merge in a day or two. I'd like to retain the synthetic name. It certainly helps people like me who read and write with a voice in their head. Best -Tobias From lecteur at zogotounga.net Tue Feb 16 08:41:43 2021 From: lecteur at zogotounga.net (=?UTF-8?Q?St=c3=a9phane_Rollandin?=) Date: Tue, 16 Feb 2021 09:41:43 +0100 Subject: [squeak-dev] Rectangle>>merging: does not accepts Sets anymore In-Reply-To: References: <20210213154146.GA36611@shell.msen.com> Message-ID: <6e3752ad-d63b-930e-6c38-7ac80776751d@zogotounga.net> > In which case you should make use of #quickMerge: then. Thanks! I was not aware of this one. Stef From commits at source.squeak.org Tue Feb 16 09:10:51 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Tue, 16 Feb 2021 09:10:51 0000 Subject: [squeak-dev] The Trunk: Morphic-mt.1722.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.1722.mcz ==================== Summary ==================== Name: Morphic-mt.1722 Author: mt Time: 16 February 2021, 10:10:46.500005 am UUID: 5d63cf8f-7e43-4f77-8ab3-fb3239223af2 Ancestors: Morphic-eem.1721 Minor tweaks to icon cache in LazyList: - Flag missing icons with #none to avoid repeated model access - Support no-icon separator items, thus avoiding minor visual glitch (e.g., in Git Browser's list of branches) Note that it felt right to format #iconExtent this way to emphasize the ordered variations of lazy init. =) =============== Diff against Morphic-eem.1721 =============== Item was changed: ----- Method: LazyListMorph>>icon: (in category 'list access - cached') ----- icon: row + "Answer a cached form from the model at a specific row. By flagging nil-icons with #none, only try to fetch an icon once from the model until next #listChanged. Also do inst-var access on listIcons here to initialize it as late as possible." - "Do inst-var access on listIcons here to initialize it as late as possible." self listSource canHaveIcons ifFalse: [^ nil]. listIcons ifNil: [listIcons := Array new: self getListSize]. + + ^ (listIcons at: row) + ifNotNil: [:iconOrNone | iconOrNone == #none ifFalse: [iconOrNone]] + ifNil: [ + | icon | + icon := (self getListIcon: row) ifNotNil: [:form | form scaleIconToDisplay]. + "Update cache for uniform icon extent." + iconExtent ifNil: [iconExtent := icon ifNotNil: [icon extent]]. + listIcons at: row put: (icon ifNil: [#none]). + icon]! - - ^ (listIcons at: row) ifNil: [ - | icon | - icon := (self getListIcon: row) ifNotNil: [:form | form scaleIconToDisplay]. - "Update cache for uniform icon extent." - iconExtent ifNil: [iconExtent := icon ifNotNil: [icon extent]]. - listIcons at: row put: icon. - icon]! Item was changed: ----- Method: LazyListMorph>>iconExtent (in category 'layout') ----- iconExtent + "Answers the uniform icon extent for this lazy list based on sample icons from the list source." + | listSize | + iconExtent ifNil: [ + + self listSource canHaveIcons + ifFalse: [^ iconExtent := 0 at 0]. + + (listSize := self getListSize) = 0 + ifTrue: [^ iconExtent := ((14 at 14) * RealEstateAgent scaleFactor) truncated]. + + (self icon: (2 min: listSize)) "mt: Use second item bc. first one might be visual separator w/o icon." + ifNil: [^ iconExtent := 0 at 0] + ifNotNil: [:form | ^ iconExtent := form extent]]. + + ^ iconExtent! - ^ iconExtent ifNil: [ - self getListSize = 0 - ifTrue: [((14 at 14) * RealEstateAgent scaleFactor) truncated] - ifFalse: [(self icon: 1) ifNil: [0 at 0] ifNotNil: [:form | form extent]]]! From marcel.taeumel at hpi.de Tue Feb 16 11:58:38 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Tue, 16 Feb 2021 12:58:38 +0100 Subject: [squeak-dev] The Trunk: Kernel-ct.1368.mcz In-Reply-To: References: <5AC68202-9597-4C01-A48D-52C8FFA73CCA@gmail.com> <20210215233907.GA35939@shell.msen.com> Message-ID: Hmm... this change would certainly be in line with what "Morph new printString" looks like. :-) I recall a not-too-distant discussion about adding the hash to any object's printOn:.  http://forum.world.st/Object-gt-gt-printOn-refined-td5117573.html Best, Marcel Am 16.02.2021 07:25:32 schrieb Tobias Pape : Hi > On 16. Feb 2021, at 00:39, David T. Lewis wrote: > > On Mon, Feb 15, 2021 at 05:01:37PM -0600, Chris Muller wrote: >> On Sat, Feb 13, 2021 at 11:00 AM Eliot Miranda >> wrote: >> >>> I disagree with this. Only certain processes are named. Including the >>> destiny name of unnamed processes just introduces noise. By all means >>> include the name of named processes, but please *don???t* add verbosity where >>> it is unhelpful. >>> >> >> +1. You are so right. Assigning a *name* for human consumption >> establishes the intent of the human's desire to utilize its #name as the >> basis for its consumption. If specific identity distinction is >> needed, then set it as part of its name, but we should not include >> arbitrary attributes in its #printString. If such additional identity >> attributes are needed, they should be consumed by sending the appropriate >> messages from the appropriate places (UI). >> > > Eliot and Chris both think that this was a bad idea. I don't understand > the objection, but if no one speaks up in support of it, I will revert > the merge in a day or two. I'd like to retain the synthetic name. It certainly helps people like me who read and write with a voice in their head. Best -Tobias -------------- next part -------------- An HTML attachment was scrubbed... URL: From lecteur at zogotounga.net Tue Feb 16 12:30:40 2021 From: lecteur at zogotounga.net (=?UTF-8?Q?St=c3=a9phane_Rollandin?=) Date: Tue, 16 Feb 2021 13:30:40 +0100 Subject: [squeak-dev] WarpBlt geometry puzzle Message-ID: <0f9e31d1-770b-879a-c602-9ef81e77e981@zogotounga.net> Hello all, I can't figure this out: Given an instance of WarpBlt, what is the formula giving the destination of a specific original point? I only need one point (for the record, the offset of a Form to be rotated and magnified). The code in WarpBlt works incrementaly by running over all original points. At the moment I can get the result by hacking into that loop, but it is slow and ugly. There has to be a direct formula, but I can't find it. Any idea? Stef From lecteur at zogotounga.net Tue Feb 16 12:35:05 2021 From: lecteur at zogotounga.net (=?UTF-8?Q?St=c3=a9phane_Rollandin?=) Date: Tue, 16 Feb 2021 13:35:05 +0100 Subject: [squeak-dev] WarpBlt geometry puzzle In-Reply-To: <0f9e31d1-770b-879a-c602-9ef81e77e981@zogotounga.net> References: <0f9e31d1-770b-879a-c602-9ef81e77e981@zogotounga.net> Message-ID: > The code in WarpBlt works incrementaly by > running over all original points. Should read: by running over all destination points From m at jaromir.net Tue Feb 16 13:05:11 2021 From: m at jaromir.net (Jaromir) Date: Tue, 16 Feb 2021 07:05:11 -0600 (CST) Subject: [squeak-dev] #valueWithExit inconsistency (?) Message-ID: <1613480711312-0.post@n4.nabble.com> Current implementation of #valueWithExit seems a bit inconsistent in its return value: it returns either nil (if the receiver exited using the exit block) or the receiver. Would it be worth modifying it to always return nil? (there are no senders anyway) valueWithExit - self value: [ ^nil ] + ^self value: [ ^nil ] Or using a nice complementary method #valueWithExit: valueWithExit: aBlock self value: [^aBlock value]. ^aBlock value valueWithExit ^self valueWithExit: [nil] Thanks ----- Jaromir ^[^ -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From marcel.taeumel at hpi.de Tue Feb 16 14:54:50 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Tue, 16 Feb 2021 15:54:50 +0100 Subject: [squeak-dev] Syntax Error window locks up image In-Reply-To: References: Message-ID: > the method that is run every hour is setup to run a method to > do some work and then spawn a block with an hour delay > which runs the method again when the delay elapses. Ah, so you do not compile code in that method. Hmm... Am 13.02.2021 17:58:50 schrieb John-Reed Maffeo : CMD]+[Dot] interrupt was the first thing I tried. At this point it is not repeatable so I don't think there is anything I can do other that keep an eye out for it. the method that is run every hour is setup to run a method to do some work and then spawn a block with an hour delay which runs the method again when the delay elapses. -jrm On Fri, Feb 12, 2021 at 1:33 AM Marcel Taeumel wrote: Hi John-Reed, can you tell us more about that method your are running every hour? Syntax errors are as tricky as debuggers. They actually use a debugger internally to interrupt the current (i.e. the compiler's/parser's) control flow and offer interactive means to fix syntax to then continue compilation. Considering interactive syntax correction, I am not sure whether compilation is safe in processes other than the UI process. Did you try hitting [CMD]+[Dot] in that case? Best, Marcel Am 12.02.2021 06:00:11 schrieb John-Reed Maffeo : What causes a window like this to appear? Why does it lock up the image? The problem occurred in an image that was running unattended using #Delay to run a method every hour. The application is in development but it has been running on schedule for a month or so without any problems. I do save and restart the image occasionally. -- jrm -- John-Reed Maffeo -------------- next part -------------- An HTML attachment was scrubbed... URL: From marcel.taeumel at hpi.de Tue Feb 16 15:08:29 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Tue, 16 Feb 2021 16:08:29 +0100 Subject: [squeak-dev] Syntax Error window locks up image In-Reply-To: References: Message-ID: I just noticed "Squeak 5.2" in that screenshot. Yes, we fixed that issue in 5.3 and restart all those processes through the release builder. That particular compiled method in the screenshot was apparently very old and out-of-sync with the .sources file. http://forum.world.st/The-Trunk-Kernel-mt-1211-mcz-td5093956.html http://forum.world.st/The-Trunk-Kernel-eem-1273-mcz-td5105160.html Best, Marcel Am 16.02.2021 15:54:50 schrieb Marcel Taeumel : > the method that is run every hour is setup to run a method to > do some work and then spawn a block with an hour delay > which runs the method again when the delay elapses. Ah, so you do not compile code in that method. Hmm... Am 13.02.2021 17:58:50 schrieb John-Reed Maffeo : CMD]+[Dot] interrupt was the first thing I tried. At this point it is not repeatable so I don't think there is anything I can do other that keep an eye out for it. the method that is run every hour is setup to run a method to do some work and then spawn a block with an hour delay which runs the method again when the delay elapses. -jrm On Fri, Feb 12, 2021 at 1:33 AM Marcel Taeumel wrote: Hi John-Reed, can you tell us more about that method your are running every hour? Syntax errors are as tricky as debuggers. They actually use a debugger internally to interrupt the current (i.e. the compiler's/parser's) control flow and offer interactive means to fix syntax to then continue compilation. Considering interactive syntax correction, I am not sure whether compilation is safe in processes other than the UI process. Did you try hitting [CMD]+[Dot] in that case? Best, Marcel Am 12.02.2021 06:00:11 schrieb John-Reed Maffeo : What causes a window like this to appear? Why does it lock up the image? The problem occurred in an image that was running unattended using #Delay to run a method every hour. The application is in development but it has been running on schedule for a month or so without any problems. I do save and restart the image occasionally. -- jrm -- John-Reed Maffeo -------------- next part -------------- An HTML attachment was scrubbed... URL: From leves at caesar.elte.hu Tue Feb 16 15:38:01 2021 From: leves at caesar.elte.hu (Levente Uzonyi) Date: Tue, 16 Feb 2021 16:38:01 +0100 (CET) Subject: [squeak-dev] Rectangle>>merging: does not accepts Sets anymore In-Reply-To: References: <20210213154146.GA36611@shell.msen.com> Message-ID: On Mon, 15 Feb 2021, Chris Muller wrote: > On Sat, Feb 13, 2021 at 10:50 AM Stéphane Rollandin wrote: > >> I don't have an easy way to verify, but it looks like adding #asArray > >> might resolve the issue for Sets (e.g. listOfRects asArray in #merging:). > > Yes it would, but at a cost that I would better avoid (both in term of > performance and GC), since #merging: is a pretty fundamental method for  > > computational geometry. > > > In which case you should make use of #quickMerge: then. > > I don't think that's a good idea. It'll still create lots of garbage when merging more than two rectangles. Levente From eliot.miranda at gmail.com Tue Feb 16 17:52:46 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue, 16 Feb 2021 09:52:46 -0800 Subject: [squeak-dev] The Trunk: Kernel-ct.1368.mcz In-Reply-To: References: Message-ID: <62D57601-A773-4387-BDF5-7BBEC9F46EE9@gmail.com> Hi All, one thing people may be missing here is that identity hashes are not unique. Just because two objects have the same identity hash does not imply they are the same object. In V3 the identityHash field is 11 bits and identity hash’s range from 0 to 2,047. In Spur the identityHash field is 22 bits and identity hash’s range from 1 to 4,194,303. With the 64-bit system one can easily create 4 million instances of some class and in doing so create two distinct objects with the same identityHash. Including the identityHash in basic print strings, at least for me, carries a false implication that the identityHash uniquely identifies an object. It does not. _,,,^..^,,,_ (phone) > On Feb 16, 2021, at 3:58 AM, Marcel Taeumel wrote: > >  > Hmm... this change would certainly be in line with what "Morph new printString" looks like. :-) I recall a not-too-distant discussion about adding the hash to any object's printOn:. > > http://forum.world.st/Object-gt-gt-printOn-refined-td5117573.html > > Best, > Marcel >> Am 16.02.2021 07:25:32 schrieb Tobias Pape : >> >> Hi >> >> > On 16. Feb 2021, at 00:39, David T. Lewis wrote: >> > >> > On Mon, Feb 15, 2021 at 05:01:37PM -0600, Chris Muller wrote: >> >> On Sat, Feb 13, 2021 at 11:00 AM Eliot Miranda >> >> wrote: >> >> >> >>> I disagree with this. Only certain processes are named. Including the >> >>> destiny name of unnamed processes just introduces noise. By all means >> >>> include the name of named processes, but please *don???t* add verbosity where >> >>> it is unhelpful. >> >>> >> >> >> >> +1. You are so right. Assigning a *name* for human consumption >> >> establishes the intent of the human's desire to utilize its #name as the >> >> basis for its consumption. If specific identity distinction is >> >> needed, then set it as part of its name, but we should not include >> >> arbitrary attributes in its #printString. If such additional identity >> >> attributes are needed, they should be consumed by sending the appropriate >> >> messages from the appropriate places (UI). >> >> >> > >> > Eliot and Chris both think that this was a bad idea. I don't understand >> > the objection, but if no one speaks up in support of it, I will revert >> > the merge in a day or two. >> >> I'd like to retain the synthetic name. >> It certainly helps people like me who read and write with a voice in their head. >> >> Best >> -Tobias >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From Das.Linux at gmx.de Tue Feb 16 18:08:03 2021 From: Das.Linux at gmx.de (Tobias Pape) Date: Tue, 16 Feb 2021 19:08:03 +0100 Subject: [squeak-dev] The Trunk: Kernel-ct.1368.mcz In-Reply-To: <62D57601-A773-4387-BDF5-7BBEC9F46EE9@gmail.com> References: <62D57601-A773-4387-BDF5-7BBEC9F46EE9@gmail.com> Message-ID: > On 16. Feb 2021, at 18:52, Eliot Miranda wrote: > > Hi All, > > one thing people may be missing here is that identity hashes are not unique. Just because two objects have the same identity hash does not imply they are the same object. In V3 the identityHash field is 11 bits and identity hash’s range from 0 to 2,047. In Spur the identityHash field is 22 bits and identity hash’s range from 1 to 4,194,303. With the 64-bit system one can easily create 4 million instances of some class and in doing so create two distinct objects with the same identityHash. Including the identityHash in basic print strings, at least for me, carries a false implication that the identityHash uniquely identifies an object. It does not. It's merely about having a few of them processes and having a quick glance on them and discerning them without much effort. The code by Christoph provides that and helps. Let's keep it that way. -t From vanessa at codefrau.net Wed Feb 17 01:24:34 2021 From: vanessa at codefrau.net (Vanessa Freudenberg) Date: Tue, 16 Feb 2021 17:24:34 -0800 Subject: [squeak-dev] Rectangle>>merging: does not accepts Sets anymore In-Reply-To: References: <20210213154146.GA36611@shell.msen.com> Message-ID: On Sat, Feb 13, 2021 at 7:56 AM Nicolas Cellier < nicolas.cellier.aka.nice at gmail.com> wrote: > We could use anyOne instead of first; and do: instead of allButFirstDo: > Iterating twice on anyOne is really benign... > +1 - Vanessa - -------------- next part -------------- An HTML attachment was scrubbed... URL: From m at jaromir.net Wed Feb 17 08:07:20 2021 From: m at jaromir.net (Jaromir) Date: Wed, 17 Feb 2021 02:07:20 -0600 (CST) Subject: [squeak-dev] Class MessageTally not initialized in 6.0 images Message-ID: <1613549240462-0.post@n4.nabble.com> Hi, I've noticed the the MessageTally class is not initialized in 6.0 images (my latest is Squeak6.0alpha-20194-64bit.image) -> as a result ShowProcesses = nil and spyOn fails. Tried MessageTally initialize and then it indeed works. Please help me understand how this works: the downloaded image normally contains all classes initialized. What causes that a class becomes uninitialized? Thanks and regards, ----- Jaromir ^[^ -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From commits at source.squeak.org Wed Feb 17 14:42:22 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Wed, 17 Feb 2021 14:42:22 0000 Subject: [squeak-dev] The Trunk: System-mt.1215.mcz Message-ID: Marcel Taeumel uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-mt.1215.mcz ==================== Summary ==================== Name: System-mt.1215 Author: mt Time: 17 February 2021, 3:42:18.125168 pm UUID: 5c7faa4b-79dd-c14c-a76e-2d1f9baec59d Ancestors: System-cmm.1214 Fixes a regression caused by not-too-distant change in ReleaseBuilder to reset all pragma preferences in CI. Thanks to Jaromir for pointing this out! =============== Diff against System-cmm.1214 =============== Item was changed: ----- Method: MessageTally class>>showProcesses (in category 'defaults') ----- showProcesses "Indicates whether to show each process separately or cumulatively. For example, compare the spy results of the following with both values: [1000 timesRepeat: [3.14159 printString. Processor yield]] fork. [1000 timesRepeat: [30 factorial. Processor yield]] fork. [1000 timesRepeat: [30 factorial. Processor yield]] fork. MessageTally spyAllOn: [ (Delay forMilliseconds: 100) wait] " + ^ShowProcesses ifNil: [true]! - ^ShowProcesses! From marcel.taeumel at hpi.de Wed Feb 17 14:42:47 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Wed, 17 Feb 2021 15:42:47 +0100 Subject: [squeak-dev] Class MessageTally not initialized in 6.0 images In-Reply-To: <1613549240462-0.post@n4.nabble.com> References: <1613549240462-0.post@n4.nabble.com> Message-ID: Thanks! Fixed in System-mt.1215 Best, Marcel Am 17.02.2021 09:07:30 schrieb Jaromir : Hi, I've noticed the the MessageTally class is not initialized in 6.0 images (my latest is Squeak6.0alpha-20194-64bit.image) -> as a result ShowProcesses = nil and spyOn fails. Tried MessageTally initialize and then it indeed works. Please help me understand how this works: the downloaded image normally contains all classes initialized. What causes that a class becomes uninitialized? Thanks and regards, ----- Jaromir ^[^ -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Wed Feb 17 14:46:16 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Wed, 17 Feb 2021 14:46:16 0000 Subject: [squeak-dev] The Trunk: EToys-mt.420.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-mt.420.mcz ==================== Summary ==================== Name: EToys-mt.420 Author: mt Time: 17 February 2021, 3:46:09.320168 pm UUID: 6869819a-56f8-9042-aa5d-33f1522d7376 Ancestors: EToys-dtl.419 Removes some long-read-and-replaced code. =============== Diff against EToys-dtl.419 =============== Item was removed: - ----- Method: HaloMorph>>addSmallHandle:on:send:to: (in category '*Etoys-Squeakland-private') ----- - addSmallHandle: handleSpec on: eventName send: selector to: recipient - "Add a handle within the halo box as per the haloSpec, and set it up to respond to the given event by sending the given selector to the given recipient. Return the handle. This is the 5/17/04 version of HaloMorph>>addHandle:on:send:to:" - - | handle aPoint iconName colorToUse | - aPoint := self positionIn: haloBox horizontalPlacement: handleSpec horizontalPlacement verticalPlacement: handleSpec verticalPlacement. - handle := EllipseMorph - newBounds: (Rectangle center: aPoint extent: self handleSize asPoint) - color: (colorToUse := Color colorFrom: handleSpec color). - handle borderColor: colorToUse muchDarker. - self addMorph: handle. - (iconName := handleSpec iconSymbol) ifNotNil: - [ | form | - form := ScriptingSystem formAtKey: iconName. - form ifNotNil: - [handle addMorphCentered: (ImageMorph new - image: form; - color: colorToUse makeForegroundColor; - lock)]]. - handle on: #mouseUp send: #endInteraction: to: self. - handle on: eventName send: selector to: recipient. - self isMagicHalo ifTrue:[ - handle on: #mouseEnter send: #handleEntered to: self. - handle on: #mouseLeave send: #handleLeft to: self]. - handle setBalloonText: (target balloonHelpTextForHandle: handle) translated. - ^ handle - ! Item was removed: - ----- Method: HaloMorph>>dragTarget: (in category '*Etoys-Squeakland-events') ----- - dragTarget: event - "Begin dragging the target" - - | thePoint | - event controlKeyPressed ifTrue: [^self growTarget: event]. - growingOrRotating := false. - innerTarget aboutToBeBrownDragged. - self setProperty: #conclusionSelector toValue: #brownDragConcluded. - thePoint := target point: event position - positionOffset from: owner. - target setConstrainedPosition: thePoint hangOut: true. - event hand newMouseFocus: self! Item was removed: - ----- Method: HaloMorph>>growTarget: (in category '*Etoys-Squeakland-events') ----- - growTarget: event - "Begin resizing the target" - growingOrRotating := true. - positionOffset := event position. - originalExtent := target extent. - self removeAllHandlesBut: nil. - event hand newMouseFocus: self. - event hand addMouseListener: self. "add handles back on mouse-up"! Item was removed: - ----- Method: HaloMorph>>highlight:handleName:state: (in category '*Etoys-Squeakland-private') ----- - highlight: handle handleName: handleName state: state - "Change color of handles. Need refactoring later..." - | form highlightName | - handle class == ThreePhaseButtonMorph - ifTrue: [form := ScriptingSystem formPressedAtKey: handleName. - state == #on - ifTrue: [highlightName := (handleName , 'Highlighted') asSymbol. - form := ScriptingSystem formAtKey: highlightName. - form - ifNil: [ScriptingSystem saveForm: (form := (ScriptingSystem formAtKey: handleName) - blendColor: (Color white alpha: 0.5)) colorReduced atKey: highlightName]]. - handle offImage: form. - handle pressedImage: form. - ^ self]. - handleName == #'Halo-Rot' - ifTrue: [state == #on - ifTrue: [handle color: Color lightBlue] - ifFalse: [handle color: Color blue]. - handle - submorphsDo: [:m | m color: handle color makeForegroundColor]]. - handleName == #'Halo-Scale' - ifTrue: [state == #on - ifTrue: [handle color: Color yellow] - ifFalse: [handle color: Color orange]]! From commits at source.squeak.org Wed Feb 17 16:05:38 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Wed, 17 Feb 2021 16:05:38 0000 Subject: [squeak-dev] The Trunk: ReleaseBuilder-mt.215.mcz Message-ID: Marcel Taeumel uploaded a new version of ReleaseBuilder to project The Trunk: http://source.squeak.org/trunk/ReleaseBuilder-mt.215.mcz ==================== Summary ==================== Name: ReleaseBuilder-mt.215 Author: mt Time: 17 February 2021, 5:05:37.202893 pm UUID: 8fccf536-9495-3d4a-a67d-720286012aca Ancestors: ReleaseBuilder-mt.214 Always use dialog interface that supports #valueSupplyingAnswer for scripts. =============== Diff against ReleaseBuilder-mt.214 =============== Item was changed: ----- Method: ReleaseBuilder class>>assureReleaseRepositoryReadAccess: (in category 'manual') ----- assureReleaseRepositoryReadAccess: repo self releaseLocally ifTrue: [ (FileDirectory on: repo description) assureExistence. ^ true]. [repo allFileNames] on: NetworkError do: [ + self + inform: ('Release Builder - Manual Step Required\\Please create the release repository:\{1}\...and ensure that you have global read access to it.' withCRs + format: {repo description}). - UserDialogBoxMorph - inform: ('Please create the release repository:\{1}\...and ensure that you have global read access to it.' withCRs - format: {repo description}) title: 'Release Builder - Manual Step Required'. ^ false]. ^ true! From commits at source.squeak.org Wed Feb 17 16:08:26 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Wed, 17 Feb 2021 16:08:26 0000 Subject: [squeak-dev] The Trunk: SystemReporter-mt.49.mcz Message-ID: Marcel Taeumel uploaded a new version of SystemReporter to project The Trunk: http://source.squeak.org/trunk/SystemReporter-mt.49.mcz ==================== Summary ==================== Name: SystemReporter-mt.49 Author: mt Time: 17 February 2021, 5:08:25.667893 pm UUID: 29b81ef5-5233-3c4f-981d-2c8205f4ce49 Ancestors: SystemReporter-eem.48 Adds report about "Image Packages" to help organize all code artifacts in your personal working image. =============== Diff against SystemReporter-eem.48 =============== Item was changed: ----- Method: SystemReporter>>initialize (in category 'initialize-release') ----- initialize self add: #'Contributors' method: #reportContributors; add: #Image method: #reportImage; add: #'Image Parameters' method: #reportImageParameters; add: #'Image Sources' method: #reportSources; add: #'Image Preferences' method: #reportPreferences; + add: #'Image Packages' method: #reportImagePackages; add: #'MC Repositories' method: #reportRepositories; add: #'MC Working Copies' method: #reportWorkingCopies; add: #'VM General' method: #reportVM; add: #'VM Options' method: #reportVMOptions; add: #'VM Modules' method: #reportModules; add: #'VM Parameters' method: #reportVMParameters; add: #'VM Stats' method: #reportVMStats. Smalltalk os platformName = 'Win32' ifTrue: [ self add: #'VM Configuration' method: #reportWin32VMConfig. ]. self add: #'OS General' method: #reportOS. Smalltalk os platformName = 'Win32' ifTrue: [ self add: #'OS Details' method: #reportWin32OSDetails; add: #'Hardware Details' method: #reportWin32HardwareDetails; add: #'GFX Hardware Details' method: #reportWin32GFXDetails. ]. Smalltalk os osVersion = 'linux' ifTrue: [ self add: #'OS Details' method: #reportLinuxOSDetails ]. self add: #'Tiny Benchmarks' method: #reportTinyBenchmarks; add: #'Space Analysis' method: #reportSpaceAnalysis; add: #'SUnit' method: #reportTestRunner; add: #'Debug Log' method: #reportDebugLog. categoriesSelected := Set with: #Image with: #'VM General'. self updateReport ! Item was added: + ----- Method: SystemReporter>>reportImagePackages: (in category 'reporting') ----- + reportImagePackages: aStream + + | organizer trunk treated inbox release releaseRepo attribute others | + organizer := PackageOrganizer default. + + self header: 'System Categories with Unknown Package' on: aStream. + SystemOrganization categories + select: [:category | (organizer packageOfSystemCategory: category ifNone: []) isNil] + thenDo: [:category | aStream nextPutAll: category; cr]. + + aStream cr. + self header: 'Packages with Only Cache Repository' on: aStream. + organizer packages + select: [:package | + | repos | + repos := package mcPackage workingCopy repositoryGroup repositories. + repos size = 1 and: [repos first == MCRepository packageCache]] + thenDo: [:package | aStream nextPutAll: package mcPackage workingCopy description; cr]. + + aStream cr. + self header: 'Official Packages' on: aStream. + others := OrderedCollection new. + trunk := MCRepository trunk allVersionNames. + inbox := MCRepository inbox allVersionNames. + treated := MCRepository treated allVersionNames. + releaseRepo := [[ReleaseBuilder releaseRepository] valueSupplyingAnswer: {'*'. true}] on: ReleaseBuilderFailed do: [:ex | nil]. + release := releaseRepo ifNotNil: [:repo | repo allVersionNames] ifNil: [#()]. + + (organizer packages sorted: [:a :b | a packageName <= b packageName]) + collect: [:package | package mcPackage workingCopy] + thenDo: [:workingCopy | | version repo | + version := workingCopy ancestry ancestors ifNotEmpty: [:a | a first]. + version ifNotNil: [version := version name]. + attribute := TextEmphasis normal. + (release includes: version) + ifTrue: [repo := releaseRepo] + ifFalse: [(trunk includes: version) + ifTrue: [repo := MCRepository trunk] + ifFalse: [(inbox includes: version) + ifTrue: [repo := MCRepository inbox. attribute := TextEmphasis bold] + ifFalse: [(treated includes: version) + ifTrue: [repo := treated. attribute := TextColor gray] + ifFalse: [others add: workingCopy]]]. + repo ifNotNil: [ "Only official packages here." + aStream withAttribute: attribute do: [ + aStream + nextPutAll: workingCopy description; + nextPutAll: ' --- '; + nextPutAll: repo description; cr]]]]. + + aStream cr. + self header: 'Other Packages' on: aStream. + others + select: [:workingCopy | workingCopy repositoryGroup repositories size > 1] + thenDo: [:workingCopy | + aStream + nextPutAll: workingCopy description; + nextPutAll: ' --- '; + nextPutAll: workingCopy repositoryGroup repositories second description; cr] + ! From marcel.taeumel at hpi.de Wed Feb 17 16:08:58 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Wed, 17 Feb 2021 17:08:58 +0100 Subject: [squeak-dev] The Trunk: SystemReporter-mt.49.mcz In-Reply-To: References: Message-ID: Am 17.02.2021 17:08:34 schrieb commits at source.squeak.org : Marcel Taeumel uploaded a new version of SystemReporter to project The Trunk: http://source.squeak.org/trunk/SystemReporter-mt.49.mcz ==================== Summary ==================== Name: SystemReporter-mt.49 Author: mt Time: 17 February 2021, 5:08:25.667893 pm UUID: 29b81ef5-5233-3c4f-981d-2c8205f4ce49 Ancestors: SystemReporter-eem.48 Adds report about "Image Packages" to help organize all code artifacts in your personal working image. =============== Diff against SystemReporter-eem.48 =============== Item was changed: ----- Method: SystemReporter>>initialize (in category 'initialize-release') ----- initialize self add: #'Contributors' method: #reportContributors; add: #Image method: #reportImage; add: #'Image Parameters' method: #reportImageParameters; add: #'Image Sources' method: #reportSources; add: #'Image Preferences' method: #reportPreferences; + add: #'Image Packages' method: #reportImagePackages; add: #'MC Repositories' method: #reportRepositories; add: #'MC Working Copies' method: #reportWorkingCopies; add: #'VM General' method: #reportVM; add: #'VM Options' method: #reportVMOptions; add: #'VM Modules' method: #reportModules; add: #'VM Parameters' method: #reportVMParameters; add: #'VM Stats' method: #reportVMStats. Smalltalk os platformName = 'Win32' ifTrue: [ self add: #'VM Configuration' method: #reportWin32VMConfig. ]. self add: #'OS General' method: #reportOS. Smalltalk os platformName = 'Win32' ifTrue: [ self add: #'OS Details' method: #reportWin32OSDetails; add: #'Hardware Details' method: #reportWin32HardwareDetails; add: #'GFX Hardware Details' method: #reportWin32GFXDetails. ]. Smalltalk os osVersion = 'linux' ifTrue: [ self add: #'OS Details' method: #reportLinuxOSDetails ]. self add: #'Tiny Benchmarks' method: #reportTinyBenchmarks; add: #'Space Analysis' method: #reportSpaceAnalysis; add: #'SUnit' method: #reportTestRunner; add: #'Debug Log' method: #reportDebugLog. categoriesSelected := Set with: #Image with: #'VM General'. self updateReport ! Item was added: + ----- Method: SystemReporter>>reportImagePackages: (in category 'reporting') ----- + reportImagePackages: aStream + + | organizer trunk treated inbox release releaseRepo attribute others | + organizer := PackageOrganizer default. + + self header: 'System Categories with Unknown Package' on: aStream. + SystemOrganization categories + select: [:category | (organizer packageOfSystemCategory: category ifNone: []) isNil] + thenDo: [:category | aStream nextPutAll: category; cr]. + + aStream cr. + self header: 'Packages with Only Cache Repository' on: aStream. + organizer packages + select: [:package | + | repos | + repos := package mcPackage workingCopy repositoryGroup repositories. + repos size = 1 and: [repos first == MCRepository packageCache]] + thenDo: [:package | aStream nextPutAll: package mcPackage workingCopy description; cr]. + + aStream cr. + self header: 'Official Packages' on: aStream. + others := OrderedCollection new. + trunk := MCRepository trunk allVersionNames. + inbox := MCRepository inbox allVersionNames. + treated := MCRepository treated allVersionNames. + releaseRepo := [[ReleaseBuilder releaseRepository] valueSupplyingAnswer: {'*'. true}] on: ReleaseBuilderFailed do: [:ex | nil]. + release := releaseRepo ifNotNil: [:repo | repo allVersionNames] ifNil: [#()]. + + (organizer packages sorted: [:a :b | a packageName + collect: [:package | package mcPackage workingCopy] + thenDo: [:workingCopy | | version repo | + version := workingCopy ancestry ancestors ifNotEmpty: [:a | a first]. + version ifNotNil: [version := version name]. + attribute := TextEmphasis normal. + (release includes: version) + ifTrue: [repo := releaseRepo] + ifFalse: [(trunk includes: version) + ifTrue: [repo := MCRepository trunk] + ifFalse: [(inbox includes: version) + ifTrue: [repo := MCRepository inbox. attribute := TextEmphasis bold] + ifFalse: [(treated includes: version) + ifTrue: [repo := treated. attribute := TextColor gray] + ifFalse: [others add: workingCopy]]]. + repo ifNotNil: [ "Only official packages here." + aStream withAttribute: attribute do: [ + aStream + nextPutAll: workingCopy description; + nextPutAll: ' --- '; + nextPutAll: repo description; cr]]]]. + + aStream cr. + self header: 'Other Packages' on: aStream. + others + select: [:workingCopy | workingCopy repositoryGroup repositories size > 1] + thenDo: [:workingCopy | + aStream + nextPutAll: workingCopy description; + nextPutAll: ' --- '; + nextPutAll: workingCopy repositoryGroup repositories second description; cr] + ! -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image.png Type: image/png Size: 124530 bytes Desc: not available URL: From marcel.taeumel at hpi.de Wed Feb 17 16:14:52 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Wed, 17 Feb 2021 17:14:52 +0100 Subject: [squeak-dev] The Trunk: SystemReporter-mt.49.mcz In-Reply-To: References: Message-ID: I wanted to figure out which inbox code I already loaded into my image. Am 17.02.2021 17:08:58 schrieb Marcel Taeumel : Am 17.02.2021 17:08:34 schrieb commits at source.squeak.org : Marcel Taeumel uploaded a new version of SystemReporter to project The Trunk: http://source.squeak.org/trunk/SystemReporter-mt.49.mcz ==================== Summary ==================== Name: SystemReporter-mt.49 Author: mt Time: 17 February 2021, 5:08:25.667893 pm UUID: 29b81ef5-5233-3c4f-981d-2c8205f4ce49 Ancestors: SystemReporter-eem.48 Adds report about "Image Packages" to help organize all code artifacts in your personal working image. =============== Diff against SystemReporter-eem.48 =============== Item was changed: ----- Method: SystemReporter>>initialize (in category 'initialize-release') ----- initialize self add: #'Contributors' method: #reportContributors; add: #Image method: #reportImage; add: #'Image Parameters' method: #reportImageParameters; add: #'Image Sources' method: #reportSources; add: #'Image Preferences' method: #reportPreferences; + add: #'Image Packages' method: #reportImagePackages; add: #'MC Repositories' method: #reportRepositories; add: #'MC Working Copies' method: #reportWorkingCopies; add: #'VM General' method: #reportVM; add: #'VM Options' method: #reportVMOptions; add: #'VM Modules' method: #reportModules; add: #'VM Parameters' method: #reportVMParameters; add: #'VM Stats' method: #reportVMStats. Smalltalk os platformName = 'Win32' ifTrue: [ self add: #'VM Configuration' method: #reportWin32VMConfig. ]. self add: #'OS General' method: #reportOS. Smalltalk os platformName = 'Win32' ifTrue: [ self add: #'OS Details' method: #reportWin32OSDetails; add: #'Hardware Details' method: #reportWin32HardwareDetails; add: #'GFX Hardware Details' method: #reportWin32GFXDetails. ]. Smalltalk os osVersion = 'linux' ifTrue: [ self add: #'OS Details' method: #reportLinuxOSDetails ]. self add: #'Tiny Benchmarks' method: #reportTinyBenchmarks; add: #'Space Analysis' method: #reportSpaceAnalysis; add: #'SUnit' method: #reportTestRunner; add: #'Debug Log' method: #reportDebugLog. categoriesSelected := Set with: #Image with: #'VM General'. self updateReport ! Item was added: + ----- Method: SystemReporter>>reportImagePackages: (in category 'reporting') ----- + reportImagePackages: aStream + + | organizer trunk treated inbox release releaseRepo attribute others | + organizer := PackageOrganizer default. + + self header: 'System Categories with Unknown Package' on: aStream. + SystemOrganization categories + select: [:category | (organizer packageOfSystemCategory: category ifNone: []) isNil] + thenDo: [:category | aStream nextPutAll: category; cr]. + + aStream cr. + self header: 'Packages with Only Cache Repository' on: aStream. + organizer packages + select: [:package | + | repos | + repos := package mcPackage workingCopy repositoryGroup repositories. + repos size = 1 and: [repos first == MCRepository packageCache]] + thenDo: [:package | aStream nextPutAll: package mcPackage workingCopy description; cr]. + + aStream cr. + self header: 'Official Packages' on: aStream. + others := OrderedCollection new. + trunk := MCRepository trunk allVersionNames. + inbox := MCRepository inbox allVersionNames. + treated := MCRepository treated allVersionNames. + releaseRepo := [[ReleaseBuilder releaseRepository] valueSupplyingAnswer: {'*'. true}] on: ReleaseBuilderFailed do: [:ex | nil]. + release := releaseRepo ifNotNil: [:repo | repo allVersionNames] ifNil: [#()]. + + (organizer packages sorted: [:a :b | a packageName + collect: [:package | package mcPackage workingCopy] + thenDo: [:workingCopy | | version repo | + version := workingCopy ancestry ancestors ifNotEmpty: [:a | a first]. + version ifNotNil: [version := version name]. + attribute := TextEmphasis normal. + (release includes: version) + ifTrue: [repo := releaseRepo] + ifFalse: [(trunk includes: version) + ifTrue: [repo := MCRepository trunk] + ifFalse: [(inbox includes: version) + ifTrue: [repo := MCRepository inbox. attribute := TextEmphasis bold] + ifFalse: [(treated includes: version) + ifTrue: [repo := treated. attribute := TextColor gray] + ifFalse: [others add: workingCopy]]]. + repo ifNotNil: [ "Only official packages here." + aStream withAttribute: attribute do: [ + aStream + nextPutAll: workingCopy description; + nextPutAll: ' --- '; + nextPutAll: repo description; cr]]]]. + + aStream cr. + self header: 'Other Packages' on: aStream. + others + select: [:workingCopy | workingCopy repositoryGroup repositories size > 1] + thenDo: [:workingCopy | + aStream + nextPutAll: workingCopy description; + nextPutAll: ' --- '; + nextPutAll: workingCopy repositoryGroup repositories second description; cr] + ! -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image.png Type: image/png Size: 124530 bytes Desc: not available URL: From commits at source.squeak.org Wed Feb 17 16:48:48 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Wed, 17 Feb 2021 16:48:48 0000 Subject: [squeak-dev] The Trunk: Kernel-mt.1370.mcz Message-ID: Marcel Taeumel uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-mt.1370.mcz ==================== Summary ==================== Name: Kernel-mt.1370 Author: mt Time: 17 February 2021, 5:48:45.447426 pm UUID: fe073783-4c0c-e345-aebe-4ea80f101f00 Ancestors: Kernel-dtl.1369 Adds commentary for #valueWithExit. =============== Diff against Kernel-dtl.1369 =============== Item was changed: ----- Method: BlockClosure>>valueWithExit (in category 'evaluating') ----- + valueWithExit + "Provides an exit block to the receiver. Use it to break out of the control flow with an early return. For example: + [:exit | 1 to: 10 do: [:each | each > 5 ifTrue: [exit value]]] valueWithExit" - valueWithExit self value: [ ^nil ]! From marcel.taeumel at hpi.de Wed Feb 17 16:52:22 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Wed, 17 Feb 2021 17:52:22 +0100 Subject: [squeak-dev] #valueWithExit inconsistency (?) In-Reply-To: <1613480711312-0.post@n4.nabble.com> References: <1613480711312-0.post@n4.nabble.com> Message-ID: Hi Jaromir. I added commentary via Kernel-mt.1370. I don't think that the (outer block's) return value should ever be used in this construct. It is more like a #detect: but without meaningful return values. http://forum.world.st/explicit-return-from-a-block-tp51833.html http://forum.world.st/The-Trunk-Kernel-ul-519-mcz-td3077583.html I don't suppose it is idiomatic Smalltalk: "...but actually, I never had any reason to use this except when porting algorithms from Fortran or C... " Best, Marcel Am 16.02.2021 14:05:23 schrieb Jaromir : Current implementation of #valueWithExit seems a bit inconsistent in its return value: it returns either nil (if the receiver exited using the exit block) or the receiver. Would it be worth modifying it to always return nil? (there are no senders anyway) valueWithExit - self value: [ ^nil ] + ^self value: [ ^nil ] Or using a nice complementary method #valueWithExit: valueWithExit: aBlock self value: [^aBlock value]. ^aBlock value valueWithExit ^self valueWithExit: [nil] Thanks ----- Jaromir ^[^ -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Wed Feb 17 16:56:32 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Wed, 17 Feb 2021 16:56:32 0000 Subject: [squeak-dev] The Trunk: Kernel-mt.1371.mcz Message-ID: Marcel Taeumel uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-mt.1371.mcz ==================== Summary ==================== Name: Kernel-mt.1371 Author: mt Time: 17 February 2021, 5:56:29.152426 pm UUID: 1e5b05c3-feb7-e945-a253-3218ee358e74 Ancestors: Kernel-mt.1370 Extracts better examples for #valueWithExit from squeak-dev mailing list. =============== Diff against Kernel-mt.1370 =============== Item was changed: ----- Method: BlockClosure>>valueWithExit (in category 'evaluating') ----- valueWithExit + "Provides an exit block to the receiver. Use it to break out of the control flow with an early return. Examples below. + [:break | 1 to: 10 do: [:each | each > 5 ifTrue: [break value]]] valueWithExit. + 1 to: 10 do: [:each | [:continue | each > 5 ifTrue: [continue value]] valueWithExit]." - "Provides an exit block to the receiver. Use it to break out of the control flow with an early return. For example: - [:exit | 1 to: 10 do: [:each | each > 5 ifTrue: [exit value]]] valueWithExit" self value: [ ^nil ]! From marcel.taeumel at hpi.de Wed Feb 17 16:59:52 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Wed, 17 Feb 2021 17:59:52 +0100 Subject: [squeak-dev] Float32Array weirdness In-Reply-To: References: Message-ID: Hi Stef. > Ah ok, thanks. It would be good to update the VM coming with trunk > images then (they are from March 3rd) We chose to not bundle bleeding-edge VMs with Trunk bundles as a safety net. But you are right. Such a fix might justify updating the VM used for Trunk bundles. Best, Marcel Am 13.02.2021 17:44:18 schrieb Stéphane Rollandin : > Hi Stef, > it's a VM problem that has been solved already. It works OK with latest VM. Ah ok, thanks. It would be good to update the VM coming with trunk images then (they are from March 3rd) Stef -------------- next part -------------- An HTML attachment was scrubbed... URL: From marcel.taeumel at hpi.de Wed Feb 17 17:04:01 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Wed, 17 Feb 2021 18:04:01 +0100 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: Hmm... looking at performance ... why not just add #asSequenceableCollection, which would only impact Set arguments? As a programmer, I do not want to choose between #merge: and #quickMerge:. Or similar. :-) Best, Marcel Am 13.02.2021 17:05:07 schrieb commits at source.squeak.org : Nicolas Cellier uploaded a new version of Graphics to project The Inbox: http://source.squeak.org/inbox/Graphics-nice.446.mcz ==================== Summary ==================== Name: Graphics-nice.446 Author: nice Time: 13 February 2021, 5:04:52.453325 pm UUID: d13c1db2-370f-4fa6-b7ae-e6766bf0c8fb Ancestors: Graphics-dtl.445 Let Rectangle merging:/encompassing: an unordered collection. =============== Diff against Graphics-dtl.445 =============== Item was changed: ----- Method: Rectangle class>>encompassing: (in category 'instance creation') ----- encompassing: listOfPoints "A number of callers of encompass: should use this method." | topLeft bottomRight | + topLeft := bottomRight := listOfPoints anyOne. + listOfPoints do: - topLeft := bottomRight := listOfPoints first. - listOfPoints allButFirstDo: [:p |topLeft := topLeft min: p. + bottomRight := bottomRight max: p]. - bottomRight := bottomRight max: p]. ^self origin: topLeft corner: bottomRight ! Item was changed: ----- Method: Rectangle class>>merging: (in category 'instance creation') ----- merging: listOfRects "A number of callers of merge: should use this method." + | aRectangle bottomRight topLeft | + aRectangle := listOfRects anyOne. + topLeft := aRectangle topLeft. + bottomRight := aRectangle bottomRight. - | bottomRight topLeft | - topLeft := listOfRects first topLeft. - bottomRight := listOfRects first bottomRight. listOfRects + do: [:r | topLeft := topLeft min: r topLeft. - allButFirstDo: [:r | topLeft := topLeft min: r topLeft. bottomRight := bottomRight max: r bottomRight]. ^self origin: topLeft corner: bottomRight. ! -------------- next part -------------- An HTML attachment was scrubbed... URL: From leves at caesar.elte.hu Wed Feb 17 17:26:53 2021 From: leves at caesar.elte.hu (Levente Uzonyi) Date: Wed, 17 Feb 2021 18:26:53 +0100 (CET) Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: On Wed, 17 Feb 2021, Marcel Taeumel wrote: > Hmm... looking at performance ... why not just add #asSequenceableCollection, which would only impact Set arguments? I don't think we have such method. Adding one would raise the usual question: should it create a new collection or return self if self already to the requested collection kind? IIRC currently the only outlier is #asOrderedCollection which always creates a copy when the receiver is an OrderedCollection, and that property is being relied on, so it can't be changed... > As a programmer, I do not want to choose between #merge: and #quickMerge:. Or similar. :-) IMO, we simply need one quick solution. If you have a Set, you may need that help from the library even more. #quickMerge: is only good for merging two rectangles. It does not solve the GC issue #merge: has. Levente > > Best, > Marcel > > Am 13.02.2021 17:05:07 schrieb commits at source.squeak.org : > > Nicolas Cellier uploaded a new version of Graphics to project The Inbox: > http://source.squeak.org/inbox/Graphics-nice.446.mcz > > ==================== Summary ==================== > > Name: Graphics-nice.446 > Author: nice > Time: 13 February 2021, 5:04:52.453325 pm > UUID: d13c1db2-370f-4fa6-b7ae-e6766bf0c8fb > Ancestors: Graphics-dtl.445 > > Let Rectangle merging:/encompassing: an unordered collection. > > =============== Diff against Graphics-dtl.445 =============== > > Item was changed: > ----- Method: Rectangle class>>encompassing: (in category 'instance creation') ----- > encompassing: listOfPoints > "A number of callers of encompass: should use this method." > | topLeft bottomRight | > + topLeft := bottomRight := listOfPoints anyOne. > + listOfPoints do: > - topLeft := bottomRight := listOfPoints first. > - listOfPoints allButFirstDo: > [:p |topLeft := topLeft min: p. > + bottomRight := bottomRight max: p]. > - bottomRight := bottomRight max: p]. > ^self origin: topLeft corner: bottomRight > ! > > Item was changed: > ----- Method: Rectangle class>>merging: (in category 'instance creation') ----- > merging: listOfRects > "A number of callers of merge: should use this method." > + | aRectangle bottomRight topLeft | > + aRectangle := listOfRects anyOne. > + topLeft := aRectangle topLeft. > + bottomRight := aRectangle bottomRight. > - | bottomRight topLeft | > - topLeft := listOfRects first topLeft. > - bottomRight := listOfRects first bottomRight. > listOfRects > + do: [:r | topLeft := topLeft min: r topLeft. > - allButFirstDo: [:r | topLeft := topLeft min: r topLeft. > bottomRight := bottomRight max: r bottomRight]. > ^self origin: topLeft corner: bottomRight. > ! > > > > From eliot.miranda at gmail.com Wed Feb 17 17:37:36 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed, 17 Feb 2021 09:37:36 -0800 Subject: [squeak-dev] #valueWithExit inconsistency (?) In-Reply-To: References: <1613480711312-0.post@n4.nabble.com> Message-ID: On Wed, Feb 17, 2021 at 8:52 AM Marcel Taeumel wrote: > Hi Jaromir. > > I added commentary via Kernel-mt.1370. I don't think that the (outer > block's) return value should ever be used in this construct. It is more > like a #detect: but without meaningful return values. > > http://forum.world.st/explicit-return-from-a-block-tp51833.html > http://forum.world.st/The-Trunk-Kernel-ul-519-mcz-td3077583.html > > I don't suppose it is idiomatic Smalltalk: "...but actually, I never had > any reason to use this except when porting algorithms from Fortran or > C... " > But there's a bug. It should at least answer the result of value:. I'm going to change it. > Best, > Marcel > > Am 16.02.2021 14:05:23 schrieb Jaromir : > Current implementation of #valueWithExit seems a bit inconsistent in its > return value: it returns either nil (if the receiver exited using the exit > block) or the receiver. > > Would it be worth modifying it to always return nil? (there are no senders > anyway) > > valueWithExit > - self value: [ ^nil ] > + ^self value: [ ^nil ] > > Or using a nice complementary method #valueWithExit: > > valueWithExit: aBlock > self value: [^aBlock value]. > ^aBlock value > > valueWithExit > ^self valueWithExit: [nil] > > Thanks > > > > ----- > Jaromir > ^[^ > -- > Sent from: http://forum.world.st/Squeak-Dev-f45488.html > > > -- _,,,^..^,,,_ best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Wed Feb 17 17:43:28 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Wed, 17 Feb 2021 17:43:28 0000 Subject: [squeak-dev] The Trunk: Kernel-eem.1372.mcz Message-ID: Eliot Miranda uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-eem.1372.mcz ==================== Summary ==================== Name: Kernel-eem.1372 Author: eem Time: 17 February 2021, 9:43:25.718097 am UUID: 925aae94-6b62-4770-b21d-499dd106ba6d Ancestors: Kernel-mt.1371 BlockClosure>>valueWithExit really should return the value of the block if exit is not taken. =============== Diff against Kernel-mt.1371 =============== Item was changed: ----- Method: BlockClosure>>valueWithExit (in category 'evaluating') ----- valueWithExit "Provides an exit block to the receiver. Use it to break out of the control flow with an early return. Examples below. [:break | 1 to: 10 do: [:each | each > 5 ifTrue: [break value]]] valueWithExit. 1 to: 10 do: [:each | [:continue | each > 5 ifTrue: [continue value]] valueWithExit]." + ^self value: [ ^nil ]! - self value: [ ^nil ]! From m at jaromir.net Wed Feb 17 19:17:44 2021 From: m at jaromir.net (Jaromir) Date: Wed, 17 Feb 2021 13:17:44 -0600 (CST) Subject: [squeak-dev] #valueWithExit inconsistency (?) In-Reply-To: References: <1613480711312-0.post@n4.nabble.com> Message-ID: <1613589464510-0.post@n4.nabble.com> Hi, thanks for your feedback! I'm by no means advocating for using returns from blocks :) I just found it useful in understanding the local vs. non-local returns... e.g. in this example the return value is useful: "find max value before nil and return its square" | supplier max maxSquared | supplier := {3 . 2 . 5 . 1 . nil . 6} readStream. maxSquared := [:exitBlock | | value | max := 0. [supplier atEnd] whileFalse: [ value := supplier next. value ifNil: [exitBlock value]. max := max max: value] ] valueWithExit: [max squared]. "more code" Transcript show: maxSquared ----- Jaromir ^[^ -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From m at jaromir.net Wed Feb 17 20:44:46 2021 From: m at jaromir.net (Jaromir) Date: Wed, 17 Feb 2021 14:44:46 -0600 (CST) Subject: [squeak-dev] Class MessageTally not initialized in 6.0 images In-Reply-To: References: <1613549240462-0.post@n4.nabble.com> Message-ID: <1613594686471-0.post@n4.nabble.com> Marcel, unfortunately initializing ShowProcesses in an accessor won't help; #spyOn: accesses the ShowProcesses variable directly... I still wonder why initializing via the class #initialize doesn't work. Thanks, ----- Jaromir ^[^ -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From asqueaker at gmail.com Wed Feb 17 23:32:20 2021 From: asqueaker at gmail.com (Chris Muller) Date: Wed, 17 Feb 2021 17:32:20 -0600 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: This is what I would do: merging: listOfRects "A number of callers of merge: should use this method." ^ listOfRects inject: (self origin: Float infinity @ Float infinity corner: Float infinity negated @ Float infinity negated) into: [ : rect : each | rect quickMerge: each ] With #quickMerge:, you're only creating a new Rectangle when it needed to grow to accomodate the current element, but many of the elements might fit completely, resulting in no additional instantiation. Do an analysis of how many temporary Point objects we create -- hint: it's a ton -- and my own attempts to optimize that in my Kml framework were not fruitful (e.g., ~1%), with a trade-off of duplicating implementation across multiple methods and making the system's code harder to read and understand and maintain. - Chris On Wed, Feb 17, 2021 at 11:27 AM Levente Uzonyi wrote: > On Wed, 17 Feb 2021, Marcel Taeumel wrote: > > > Hmm... looking at performance ... why not just add > #asSequenceableCollection, which would only impact Set arguments? > > I don't think we have such method. Adding one would raise the usual > question: should it create a new collection or return self if self > already to the requested collection kind? > IIRC currently the only outlier is #asOrderedCollection which always > creates a copy when the receiver is an OrderedCollection, and that > property is being relied on, so it can't be changed... > > > As a programmer, I do not want to choose between #merge: and > #quickMerge:. Or similar. :-) > > IMO, we simply need one quick solution. If you have a Set, you may need > that help from the library even more. > #quickMerge: is only good for merging two rectangles. It does not solve > the GC issue #merge: has. > > > Levente > > > > > Best, > > Marcel > > > > Am 13.02.2021 17:05:07 schrieb commits at source.squeak.org < > commits at source.squeak.org>: > > > > Nicolas Cellier uploaded a new version of Graphics to project The > Inbox: > > http://source.squeak.org/inbox/Graphics-nice.446.mcz > > > > ==================== Summary ==================== > > > > Name: Graphics-nice.446 > > Author: nice > > Time: 13 February 2021, 5:04:52.453325 pm > > UUID: d13c1db2-370f-4fa6-b7ae-e6766bf0c8fb > > Ancestors: Graphics-dtl.445 > > > > Let Rectangle merging:/encompassing: an unordered collection. > > > > =============== Diff against Graphics-dtl.445 =============== > > > > Item was changed: > > ----- Method: Rectangle class>>encompassing: (in category > 'instance creation') ----- > > encompassing: listOfPoints > > "A number of callers of encompass: should use this method." > > | topLeft bottomRight | > > + topLeft := bottomRight := listOfPoints anyOne. > > + listOfPoints do: > > - topLeft := bottomRight := listOfPoints first. > > - listOfPoints allButFirstDo: > > [:p |topLeft := topLeft min: p. > > + bottomRight := bottomRight max: p]. > > - bottomRight := bottomRight max: p]. > > ^self origin: topLeft corner: bottomRight > > ! > > > > Item was changed: > > ----- Method: Rectangle class>>merging: (in category 'instance > creation') ----- > > merging: listOfRects > > "A number of callers of merge: should use this method." > > + | aRectangle bottomRight topLeft | > > + aRectangle := listOfRects anyOne. > > + topLeft := aRectangle topLeft. > > + bottomRight := aRectangle bottomRight. > > - | bottomRight topLeft | > > - topLeft := listOfRects first topLeft. > > - bottomRight := listOfRects first bottomRight. > > listOfRects > > + do: [:r | topLeft := topLeft min: r topLeft. > > - allButFirstDo: [:r | topLeft := topLeft min: r topLeft. > > bottomRight := bottomRight max: r bottomRight]. > > ^self origin: topLeft corner: bottomRight. > > ! > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jrmaffeo at gmail.com Thu Feb 18 00:14:11 2021 From: jrmaffeo at gmail.com (John-Reed Maffeo) Date: Wed, 17 Feb 2021 17:14:11 -0700 Subject: [squeak-dev] Syntax Error window locks up image In-Reply-To: References: Message-ID: Marcel, Thanks! -jrm On Tue, Feb 16, 2021 at 8:08 AM Marcel Taeumel wrote: > I just noticed "Squeak 5.2" in that screenshot. Yes, we fixed that issue > in 5.3 and restart all those processes through the release builder. That > particular compiled method in the screenshot was apparently very old and > out-of-sync with the .sources file. > > http://forum.world.st/The-Trunk-Kernel-mt-1211-mcz-td5093956.html > http://forum.world.st/The-Trunk-Kernel-eem-1273-mcz-td5105160.html > > Best, > Marcel > > Am 16.02.2021 15:54:50 schrieb Marcel Taeumel : > > the method that is run every hour is setup to run a method to > > do some work and then spawn a block with an hour delay > > which runs the method again when the delay elapses. > > Ah, so you do not compile code in that method. Hmm... > > Am 13.02.2021 17:58:50 schrieb John-Reed Maffeo : > CMD]+[Dot] interrupt was the first thing I tried. > > At this point it is not repeatable so I don't think there is anything I > can do other that keep an eye out for it. > > the method that is run every hour is setup to run a method to do some work > and then spawn a block with an hour delay which runs the method again when > the delay elapses. > -jrm > > On Fri, Feb 12, 2021 at 1:33 AM Marcel Taeumel > wrote: > >> Hi John-Reed, >> >> can you tell us more about that method your are running every hour? >> >> Syntax errors are as tricky as debuggers. They actually use a debugger >> internally to interrupt the current (i.e. the compiler's/parser's) control >> flow and offer interactive means to fix syntax to then continue compilation. >> >> Considering interactive syntax correction, I am not sure whether >> compilation is safe in processes other than the UI process. >> >> Did you try hitting [CMD]+[Dot] in that case? >> >> Best, >> Marcel >> >> Am 12.02.2021 06:00:11 schrieb John-Reed Maffeo : >> What causes a window like this to appear? >> Why does it lock up the image? >> The problem occurred in an image that was running unattended using #Delay >> to run a method every hour. The application is in development but it has >> been running on schedule for a month or so without any problems. >> >> I do save and restart the image occasionally. >> >> -- >> jrm >> >> >> > > -- > John-Reed Maffeo > > > -- John-Reed Maffeo -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Thu Feb 18 08:16:21 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 08:16:21 0000 Subject: [squeak-dev] The Trunk: System-mt.1216.mcz Message-ID: Marcel Taeumel uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-mt.1216.mcz ==================== Summary ==================== Name: System-mt.1216 Author: mt Time: 18 February 2021, 9:16:17.196751 am UUID: 70862cfd-0be1-453a-b6af-8697996913ba Ancestors: System-mt.1215 Replaces direct access to class var with accessor to make resetting of pragma preference work. =============== Diff against System-mt.1215 =============== Item was changed: ----- Method: MessageTally class>>initialize (in category 'class initialization') ----- initialize "MessageTally initialize" - "By default, show each process separately" - ShowProcesses ifNil: [ShowProcesses := true]. Smalltalk addToShutDownList: self after: Delay; "i.e. convert to relative times & stats after Delay sleeps." addToStartUpList: self before: Delay "i.e. convert back to absolute stats before Delay wakes."! Item was changed: ----- Method: MessageTally class>>spyOn: (in category 'spying') ----- spyOn: aBlock "Spy on aBlock, in the current process. Can include or not statistics on other processes in the report. [1000 timesRepeat: [ 100 timesRepeat: [120 factorial]. (Delay forMilliseconds: 10) wait ]] forkAt: 45 named: '45'. MessageTally spyOn: [10000 timesRepeat: [1.23 printString]] " + ^self spyOn: aBlock reportOtherProcesses: self showProcesses! - ^self spyOn: aBlock reportOtherProcesses: ShowProcesses! Item was changed: ----- Method: MessageTally class>>spyOnProcess:forMilliseconds: (in category 'spying') ----- spyOnProcess: aProcess forMilliseconds: msecDuration " Spy on aProcess for a certain amount of time | p1 p2 | p1 := [100000 timesRepeat: [3.14159 printString. Processor yield]] newProcess. p2 := [100000 timesRepeat: [3.14159 printString. Processor yield]] newProcess. p1 resume. p2 resume. (Delay forMilliseconds: 100) wait. MessageTally spyOnProcess: p1 forMilliseconds: 1000 " ^self spyOnProcess: aProcess forMilliseconds: msecDuration + reportOtherProcesses: self showProcesses - reportOtherProcesses: ShowProcesses ! From marcel.taeumel at hpi.de Thu Feb 18 08:17:59 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Thu, 18 Feb 2021 09:17:59 +0100 Subject: [squeak-dev] Class MessageTally not initialized in 6.0 images In-Reply-To: <1613594686471-0.post@n4.nabble.com> References: <1613549240462-0.post@n4.nabble.com> <1613594686471-0.post@n4.nabble.com> Message-ID: Hi Jaromir, ah, thanks again. I fixed it in System-mt.1216. > I still wonder why initializing via the class #initialize doesn't work. Because a class-side #initialize will only be called when its code changes, which does not happen automatically for release building / CI. Best, Marcel Am 17.02.2021 21:44:54 schrieb Jaromir : Marcel, unfortunately initializing ShowProcesses in an accessor won't help; #spyOn: accesses the ShowProcesses variable directly... I still wonder why initializing via the class #initialize doesn't work. Thanks, ----- Jaromir ^[^ -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Thu Feb 18 09:39:50 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 09:39:50 0000 Subject: [squeak-dev] The Trunk: System-mt.1217.mcz Message-ID: Marcel Taeumel uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-mt.1217.mcz ==================== Summary ==================== Name: System-mt.1217 Author: mt Time: 18 February 2021, 10:39:44.603465 am UUID: d3cc5ff1-d4e9-274f-b695-caa62309d8cf Ancestors: System-mt.1216 Maps "MPW" initials to "Marcel Weiher" =============== Diff against System-mt.1216 =============== Item was changed: ----- Method: SystemNavigation class>>privateAuthorsRaw (in category 'class initialization') ----- (excessive size, no diff calculated) Item was changed: + (PackageInfo named: 'System') postscript: 'SystemNavigation initializeAuthors.....'! - (PackageInfo named: 'System') postscript: 'SystemNavigation initializeAuthors....'! From commits at source.squeak.org Thu Feb 18 10:19:54 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 10:19:54 0000 Subject: [squeak-dev] The Trunk: Tools-mt.1025.mcz Message-ID: Marcel Taeumel uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-mt.1025.mcz ==================== Summary ==================== Name: Tools-mt.1025 Author: mt Time: 18 February 2021, 11:19:50.596465 am UUID: 3a18ed90-267b-f545-86b6-a8edb2631a80 Ancestors: Tools-mt.1024 Add scoping and inverted lookup to dependency browser. I am using it for "DependencyBrowser openInvertedOn: #(EToys)" =============== Diff against Tools-mt.1024 =============== Item was changed: CodeHolder subclass: #DependencyBrowser + instanceVariableNames: 'packageList packageDeps packageDepsList classDeps classDepsList classList messageList packageListIndex packageDepsIndex classDepsIndex classListIndex messageListIndex autoSelectString windowTitle' - instanceVariableNames: 'packageList packageDeps packageDepsList classDeps classDepsList classList messageList packageListIndex packageDepsIndex classDepsIndex classListIndex messageListIndex autoSelectString' classVariableNames: '' poolDictionaries: '' category: 'Tools-Browser'! !DependencyBrowser commentStamp: 'fbs 5/6/2011 11:29' prior: 0! A simple dependency browser showing five panes: [1]: Packages: The list of available packages in the system. [2]: Package Dependencies: The dependent packages of the currently selected package. [3]: Class Dependencies: The classes causing the dependencies. [4]: Class List: The classes introducing the dependencies. [5]: Messages: The messages introducing the dependencies.! Item was added: + ----- Method: DependencyBrowser class>>openInvertedOn: (in category 'opening') ----- + openInvertedOn: requiredPackageNames + "DependencyBrowser openInvertedOn: #(Monticello)" + + | model | + model := self new. + ^ ToolBuilder open: ( + model + packageList: (model packageList select: [:packageName | + model computePackageDependencies: packageName. + model packageDeps includesAnyOf: requiredPackageNames]); + windowTitle: ('Dependency Browser (inverted on {1})' format: {requiredPackageNames}); + yourself) + ! Item was added: + ----- Method: DependencyBrowser class>>openOn: (in category 'opening') ----- + openOn: packageNames + "DependencyBrowser openOn: #(Morphic EToys)" + + ^ ToolBuilder open: (self new + packageList: packageNames; + windowTitle: 'Dependency Browser (on selected packages)'; + yourself)! Item was added: + ----- Method: DependencyBrowser>>packageList: (in category 'package list') ----- + packageList: somePackageNames + + packageList := somePackageNames. + self packageListIndex: 0.! Item was added: + ----- Method: DependencyBrowser>>windowTitle (in category 'accessing') ----- + windowTitle + + ^ windowTitle ifNil: ['Dependency Browser']! Item was added: + ----- Method: DependencyBrowser>>windowTitle: (in category 'accessing') ----- + windowTitle: aString + + windowTitle := aString. + self changed: #windowTitle.! From marcel.taeumel at hpi.de Thu Feb 18 10:20:41 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Thu, 18 Feb 2021 11:20:41 +0100 Subject: [squeak-dev] The Trunk: Tools-mt.1025.mcz In-Reply-To: References: Message-ID: Am 18.02.2021 11:20:04 schrieb commits at source.squeak.org : Marcel Taeumel uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-mt.1025.mcz ==================== Summary ==================== Name: Tools-mt.1025 Author: mt Time: 18 February 2021, 11:19:50.596465 am UUID: 3a18ed90-267b-f545-86b6-a8edb2631a80 Ancestors: Tools-mt.1024 Add scoping and inverted lookup to dependency browser. I am using it for "DependencyBrowser openInvertedOn: #(EToys)" =============== Diff against Tools-mt.1024 =============== Item was changed: CodeHolder subclass: #DependencyBrowser + instanceVariableNames: 'packageList packageDeps packageDepsList classDeps classDepsList classList messageList packageListIndex packageDepsIndex classDepsIndex classListIndex messageListIndex autoSelectString windowTitle' - instanceVariableNames: 'packageList packageDeps packageDepsList classDeps classDepsList classList messageList packageListIndex packageDepsIndex classDepsIndex classListIndex messageListIndex autoSelectString' classVariableNames: '' poolDictionaries: '' category: 'Tools-Browser'! !DependencyBrowser commentStamp: 'fbs 5/6/2011 11:29' prior: 0! A simple dependency browser showing five panes: [1]: Packages: The list of available packages in the system. [2]: Package Dependencies: The dependent packages of the currently selected package. [3]: Class Dependencies: The classes causing the dependencies. [4]: Class List: The classes introducing the dependencies. [5]: Messages: The messages introducing the dependencies.! Item was added: + ----- Method: DependencyBrowser class>>openInvertedOn: (in category 'opening') ----- + openInvertedOn: requiredPackageNames + "DependencyBrowser openInvertedOn: #(Monticello)" + + | model | + model := self new. + ^ ToolBuilder open: ( + model + packageList: (model packageList select: [:packageName | + model computePackageDependencies: packageName. + model packageDeps includesAnyOf: requiredPackageNames]); + windowTitle: ('Dependency Browser (inverted on {1})' format: {requiredPackageNames}); + yourself) + ! Item was added: + ----- Method: DependencyBrowser class>>openOn: (in category 'opening') ----- + openOn: packageNames + "DependencyBrowser openOn: #(Morphic EToys)" + + ^ ToolBuilder open: (self new + packageList: packageNames; + windowTitle: 'Dependency Browser (on selected packages)'; + yourself)! Item was added: + ----- Method: DependencyBrowser>>packageList: (in category 'package list') ----- + packageList: somePackageNames + + packageList := somePackageNames. + self packageListIndex: 0.! Item was added: + ----- Method: DependencyBrowser>>windowTitle (in category 'accessing') ----- + windowTitle + + ^ windowTitle ifNil: ['Dependency Browser']! Item was added: + ----- Method: DependencyBrowser>>windowTitle: (in category 'accessing') ----- + windowTitle: aString + + windowTitle := aString. + self changed: #windowTitle.! -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image.png Type: image/png Size: 127537 bytes Desc: not available URL: From commits at source.squeak.org Thu Feb 18 13:15:45 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:15:45 0000 Subject: [squeak-dev] The Trunk: EToys-ct.402.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-ct.402.mcz ==================== Summary ==================== Name: EToys-ct.402 Author: ct Time: 24 August 2020, 8:22:21.479269 pm UUID: 8b6598bf-158f-a74f-a399-f82c39269bdc Ancestors: EToys-eem.400 Fixes EToys fences for players within flexshells by subtracting transformations. =============== Diff against EToys-eem.400 =============== Item was changed: ----- Method: Player>>forward: (in category 'scripts-standard') ----- forward: dist "Move forward (viz. in the direction of my heading) by the given amount" | rho radians delta didStray p aCostume aPlayfield | (aCostume := self costume) isInWorld ifFalse: [^ self]. aCostume isWorldOrHandMorph ifTrue: [^ self]. aCostume owner isHandMorph ifTrue: [^ self]. + - rho := (aCostume asNumber: dist) asFloat. + radians := (self getHeadingUnrounded asFloat - 90) degreesToRadians. - radians := (self getHeadingUnrounded asFloat - 90.0) degreesToRadians. delta := (radians cos @ radians sin) * rho. + + (aPlayfield := aCostume pasteUpMorph) fenceEnabled ifTrue: [ + | playfieldBounds costumeBounds | + playfieldBounds := aPlayfield boundsInWorld. + costumeBounds := aCostume boundsInWorld. + (playfieldBounds containsRect: costumeBounds) ifFalse: [ + "If I stray out of the bounds of my playfield, pull me back, but without changing my heading as bounce would. Do nothing if bounce has already corrected the direction." - - (aPlayfield := aCostume pasteUpMorph) fenceEnabled ifTrue: - [(aPlayfield bounds containsRect: aCostume bounds) ifFalse: - ["If I stray out of the bounds of my playfield, pull me back, but - without changing my heading as bounce would. Do nothing if - bounce has already corrected the direction." didStray := false. + ((costumeBounds left < playfieldBounds left and: [delta x < 0]) + or: [costumeBounds right > playfieldBounds right and: [delta x > 0]]) + ifTrue: [ + delta := delta x negated @ delta y. + didStray := true]. + ((costumeBounds top < playfieldBounds top and: [delta y < 0]) + or: [costumeBounds bottom > playfieldBounds bottom and: [delta y > 0]]) + ifTrue: [ + delta := delta x @ delta y negated. + didStray := true]. + (didStray and: [Preferences fenceSoundEnabled]) ifTrue: [ + aCostume makeFenceSound]]]. + - ((aCostume left < aPlayfield left and: [delta x < 0]) or: - [aCostume right > aPlayfield right and: [delta x > 0]]) ifTrue: - [delta := delta x negated @ delta y. - didStray := true]. - ((aCostume top < aPlayfield top and: [delta y < 0]) or: - [aCostume bottom > aPlayfield bottom and: [delta y > 0]]) ifTrue: - [delta := delta x @ delta y negated. - didStray := true]. - (didStray and: [Preferences fenceSoundEnabled]) ifTrue: [aCostume makeFenceSound]]]. - "use and record the fractional position" p := aCostume referencePosition + delta. + aCostume referencePosition: p.! - aCostume referencePosition: p! From commits at source.squeak.org Thu Feb 18 13:15:56 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:15:56 0000 Subject: [squeak-dev] The Trunk: EToys-ct.403.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-ct.403.mcz ==================== Summary ==================== Name: EToys-ct.403 Author: ct Time: 16 September 2020, 9:28:21.732871 pm UUID: da566a07-8012-ee4b-88d6-58f224234d76 Ancestors: EToys-eem.400 Fixes an AssertionFailure concerning #doLayoutAgain when a particular arrangement of EToys tiles is laid out. TileMorph wants to change its owner's layout policy if that is a TilePadMorph as soon as it is embedded into that. However, the wrong hook was chosen for this. #ownerChanged is signaled whenever the owner has changed its layout. Instead, #noteNewOner: is signaled whenever the receiver is embedded into a new owner. Note that this practice of lazy layout modification is still suspect from my perspective, but at least it works again. Pooh, this one was really hard to find. Thanks a lot to Marcel (mt) and the MessageSendRecorder for their important help! ;-) =============== Diff against EToys-eem.400 =============== Item was added: + ----- Method: TileMorph>>noteNewOwner: (in category 'change reporting') ----- + noteNewOwner: ownerMorph + + super noteNewOwner: ownerMorph. + + ((ownerMorph isKindOf: TilePadMorph) + and: [ownerMorph layoutPolicy isNil]) + ifTrue: [ + ownerMorph + layoutPolicy: TableLayout new; + hResizing: #shrinkWrap; + vResizing: #spaceFill].! Item was removed: - ----- Method: TileMorph>>ownerChanged (in category 'change reporting') ----- - ownerChanged - super ownerChanged. - (owner class == TilePadMorph and:[owner layoutPolicy isNil]) ifTrue:[ - owner layoutPolicy: TableLayout new. - owner hResizing: #shrinkWrap. - owner vResizing: #spaceFill ].! From commits at source.squeak.org Thu Feb 18 13:16:08 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:16:08 0000 Subject: [squeak-dev] The Trunk: EToys-ct.405.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-ct.405.mcz ==================== Summary ==================== Name: EToys-ct.405 Author: ct Time: 17 September 2020, 12:12:06.449813 pm UUID: db0ca850-9a21-1849-b3e2-bd9ce983b266 Ancestors: EToys-eem.400 Adds WatchMorph example method. This commit is part of reconstruction of Objectland (also known as "The Worlds of Squeak"). For more information, see: http://forum.world.st/The-Inbox-MorphicExtras-ct-267-mcz-td5104764.html =============== Diff against EToys-eem.400 =============== Item was added: + ----- Method: WatchMorph class>>example (in category 'examples') ----- + example + "WatchMorph example openInWorld" + + ^ (WatchMorph + fontName: #BitstreamVeraSerif + bgColor: Color lightGray + centerColor: Color red paler) + handsColor: Color grape; + toggleRoman; + yourself! From commits at source.squeak.org Thu Feb 18 13:16:16 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:16:16 0000 Subject: [squeak-dev] The Trunk: EToys-ct.406.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-ct.406.mcz ==================== Summary ==================== Name: EToys-ct.406 Author: ct Time: 17 September 2020, 12:23:18.233813 pm UUID: 0b76e3b6-1567-c542-8350-de5b7a28fcf2 Ancestors: EToys-eem.400 Minor Tetris refactorings. Expose action selectors for game control as part of the public Tetris protocol. This will be used to play/pause a tetris game from the outside. Recategorize some methods. This commit is part of reconstruction of Objectland (also known as "The Worlds of Squeak"). For more information, see: http://forum.world.st/The-Inbox-MorphicExtras-ct-267-mcz-td5104764.html =============== Diff against EToys-eem.400 =============== Item was changed: + ----- Method: Tetris class>>colors (in category 'constants') ----- - ----- Method: Tetris class>>colors (in category 'as yet unclassified') ----- colors ^{ Color r: 0.5 g: 0 b: 0. Color r: 0 g: 0.5 b: 0. Color r: 0 g: 0 b: 0.5. Color r: 0.5 g: 0.5 b: 0. Color r: 0.5 g: 0 b: 0.5. Color r: 0 g: 0.5 b: 0.5 } ! Item was changed: ----- Method: Tetris>>makeGameControls (in category 'initialization') ----- makeGameControls ^ self rowForButtons addMorph: (self buildButtonTarget: self label: 'Quit' translated selector: #delete help: 'quit' translated); addMorph: (self + buildButtonTarget: self - buildButtonTarget: board label: 'Pause' translated selector: #pause help: 'pause' translated); addMorph: (self + buildButtonTarget: self - buildButtonTarget: board label: 'New game' translated selector: #newGame help: 'new game' translated)! Item was added: + ----- Method: Tetris>>newGame (in category 'actions') ----- + newGame + + board newGame.! Item was added: + ----- Method: Tetris>>pause (in category 'actions') ----- + pause + + board pause.! Item was changed: + ----- Method: TetrisBlock class>>flipShapes: (in category 'support') ----- - ----- Method: TetrisBlock class>>flipShapes: (in category 'as yet unclassified') ----- flipShapes: anArray ^OrderedCollection new add: anArray; add: (anArray collect: [ :each | each y negated @ each x]); add: (anArray collect: [ :each | each x negated @ each y negated]); add: (anArray collect: [ :each | each y @ each x negated]); yourself ! Item was changed: + ----- Method: TetrisBlock class>>shapeChoices (in category 'constants') ----- - ----- Method: TetrisBlock class>>shapeChoices (in category 'as yet unclassified') ----- shapeChoices ^ ShapeChoices ifNil: [ ShapeChoices := { { { 0 @ 0 . 1 @ 0 . 0 @ 1 . 1 @ 1 } }. "square - one is sufficient here" self flipShapes: { 0 @ 0 . -1 @ 0 . 1 @ 0 . 0 @ -1 }. "T" { { 0 @ 0 . -1 @ 0 . 1 @ 0 . 2 @ 0 }. { 0 @ 0 . 0 @ -1 . 0 @ 1 . 0 @ 2 } "long - two are sufficient here" }. self flipShapes: { 0 @ 0 . 0 @ -1 . 0 @ 1 . 1 @ 1 }. "L" self flipShapes: { 0 @ 0 . 0 @ -1 . 0 @ 1 . -1 @ 1 }. "inverted L" self flipShapes: { 0 @ 0 . -1 @ 0 . 0 @ -1 . 1 @ -1 }. "S" self flipShapes: { 0 @ 0 . 1 @ 0 . 0 @ -1 . -1 @ -1 } "Z" }. ] ! Item was changed: + ----- Method: TetrisBoard>>cellSize (in category 'accessing') ----- - ----- Method: TetrisBoard>>cellSize (in category 'as yet unclassified') ----- cellSize ^12 at 12! Item was changed: + ----- Method: TetrisBoard>>originForCell: (in category 'accessing') ----- - ----- Method: TetrisBoard>>originForCell: (in category 'as yet unclassified') ----- originForCell: aPoint ^aPoint - (1 at 1) * self cellSize + self position ! From commits at source.squeak.org Thu Feb 18 13:16:23 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:16:23 0000 Subject: [squeak-dev] The Trunk: EToys-ct.407.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-ct.407.mcz ==================== Summary ==================== Name: EToys-ct.407 Author: ct Time: 17 September 2020, 12:38:51.188813 pm UUID: 1ba5c4b2-8ee7-dd46-9d86-5a7526c91629 Ancestors: EToys-eem.400 Activates Shout styling in EToys MethodMorph. Also includes recategorization of some selectors. Is the reference from EToys to ToolBuilder-Morphic okay? The dependency already existed before. =============== Diff against EToys-eem.400 =============== Item was changed: + PluggableTextMorphPlus subclass: #MethodMorph - PluggableTextMorph subclass: #MethodMorph instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Etoys-Scripting'! Item was changed: + ----- Method: MethodMorph class>>defaultNameStemForInstances (in category 'constants') ----- - ----- Method: MethodMorph class>>defaultNameStemForInstances (in category 'as yet unclassified') ----- defaultNameStemForInstances ^ 'Method' translatedNoop! Item was changed: ----- Method: MethodMorph>>initialize (in category 'initialization') ----- initialize "initialize the state of the receiver" super initialize. + self useDefaultStyler.! - ! Item was changed: + ----- Method: MethodMorph>>installRollBackButtons: (in category 'initialization') ----- - ----- Method: MethodMorph>>installRollBackButtons: (in category 'as yet unclassified') ----- installRollBackButtons: target | mine | "If I don't already have such a button, put one in at the upper right. Set its target to the furtherest enclosing book. Send chooseAndRevertToVersion when clicked. Stay in place via scrollBar install." mine := self submorphNamed: #chooseAndRevertToVersion ifNone: [nil]. mine ifNil: [mine := SimpleButtonMorph new. "mine height: mine height - 2." mine label: 'Roll Back'; cornerStyle: #square. mine color: Color white; borderColor: Color black. mine actionSelector: #chooseAndRevertToVersion. mine align: mine topRight with: (self findA: ScrollBar) topLeft +(1 at 1). self addMorphFront: mine. mine height: mine height - 5 "14"]. mine target: target.! Item was added: + ----- Method: MethodMorph>>okToStyle (in category 'testing') ----- + okToStyle + + styler ifNil: [^ false]. + styler + classOrMetaClass: self model selectedClassOrMetaClass; + environment: self model environment. + ^ true! From commits at source.squeak.org Thu Feb 18 13:16:31 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:16:31 0000 Subject: [squeak-dev] The Trunk: EToys-ct.408.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-ct.408.mcz ==================== Summary ==================== Name: EToys-ct.408 Author: ct Time: 17 September 2020, 12:48:54.350813 pm UUID: c530407c-bee4-a54c-8781-1ba7af10c1c1 Ancestors: EToys-eem.400 Improves MovingEyeMorph support for custom colors. =============== Diff against EToys-eem.400 =============== Item was added: + ----- Method: MovingEyeMorph class>>color:irisColor: (in category 'instance creation') ----- + color: aColor irisColor: anotherColor + + ^ self new color: aColor irisColor: anotherColor! Item was changed: ----- Method: MovingEyeMorph>>color: (in category 'accessing') ----- color: aColor super color: aColor. "Migrate old instances." inner color: Color transparent. + self keepIrisVisible.! - "Keep iris visible." - aColor = iris color - ifTrue: [iris borderWidth: 1; borderColor: aColor negated] - ifFalse: [iris borderWidth: 0].! Item was added: + ----- Method: MovingEyeMorph>>color:irisColor: (in category 'accessing') ----- + color: aColor irisColor: anotherColor + + self color: aColor. + self irisColor: anotherColor.! Item was added: + ----- Method: MovingEyeMorph>>defaultBorderWidth (in category 'accessing') ----- + defaultBorderWidth + + ^ 0! Item was changed: ----- Method: MovingEyeMorph>>irisColor: (in category 'accessing') ----- irisColor: aColor iris color: aColor. + self keepIrisVisible.! - "Keep iris visible." - aColor = self color - ifTrue: [iris borderWidth: 1; borderColor: aColor negated] - ifFalse: [iris borderWidth: 0].! Item was added: + ----- Method: MovingEyeMorph>>keepIrisVisible (in category 'private') ----- + keepIrisVisible + + self color = self irisColor + ifTrue: [ + iris borderWidth: 1; + borderColor: self color makeForegroundColor] + ifFalse: [ + iris borderWidth: 0].! From commits at source.squeak.org Thu Feb 18 13:19:08 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:19:08 0000 Subject: [squeak-dev] The Trunk: Compiler-ct.450.mcz Message-ID: Marcel Taeumel uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler-ct.450.mcz ==================== Summary ==================== Name: Compiler-ct.450 Author: ct Time: 24 October 2020, 12:16:36.359256 am UUID: ea5bdd56-7ceb-ae4f-a2d7-1b9d11cda893 Ancestors: Compiler-ct.449 Implements #environment on SyntaxErrorNotification. Sorry I hit the Accept button to soon... =============== Diff against Compiler-tobe.448 =============== Item was added: + ----- Method: CompilationCue>>source: (in category 'accessing') ----- + source: aString + + source := aString. + sourceStream := source readStream.! Item was changed: ----- Method: Parser>>notify:at: (in category 'error handling') ----- notify: string at: location | messageText | messageText := '"' , string , ' ->"'. cue requestor isNil ifTrue: [ | notification | (encoder == self or: [encoder isNil]) ifTrue: [^ self fail "failure setting up syntax error"]. (notification := SyntaxErrorNotification + cue: (cue copy + source: (source contents asText + copyReplaceFrom: location + to: location - 1 + with: messageText); + yourself) - inClass: encoder classEncoding - withCode: (source contents asText - copyReplaceFrom: location - to: location - 1 - with: messageText) doitFlag: doitFlag errorMessage: string location: location) signal. notification tryNewSourceIfAvailable] ifFalse: [cue requestor notify: messageText at: location in: source]. ^ self fail! Item was changed: Error subclass: #SyntaxErrorNotification + instanceVariableNames: 'cue doitFlag errorMessage location newSource' - instanceVariableNames: 'inClass code doitFlag errorMessage location newSource' classVariableNames: '' poolDictionaries: '' category: 'Compiler-Exceptions'! + !SyntaxErrorNotification commentStamp: 'ct 10/24/2020 00:01' prior: 0! - !SyntaxErrorNotification commentStamp: 'nice 9/18/2013 22:16' prior: 0! A SyntaxErrorNotification is an Exception occuring when compiling a Smalltalk source code with incorrect syntax. Note that in interactive mode, this exception is not raised because the Compiler will interact directly with source code editor. The defaultAction is to raise a SyntaxError pop up window so as to enable interactive handling even in non interactive mode. Instance Variables + cue: - category: - code: doitFlag: errorMessage: - inClass: location: newSource: + cue + - the cue for compilation, including receiver class, optional context, and original source code - category - - the category in which the method will be classified - code - - the source code to be compiled or evaluated - doitFlag - true if this is a doIt (code to evaluate), false if this is a method (code of a method to be compiled) errorMessage - contains information about the syntax error - inClass - - target class in which to compile the method - location - position in the source code where the syntax error occured newSource + - eventually hold a source code replacement typically passed by the SyntaxError window! - - eventually hold a source code replacement typically passed by the SyntaxError window - ! Item was added: + ----- Method: SyntaxErrorNotification class>>cue:doitFlag:errorMessage:location: (in category 'instance creation') ----- + cue: aCue doitFlag: doitFlag errorMessage: errorString location: location + + ^ self new + setCue: aCue + doitFlag: doitFlag + errorMessage: errorString + location: location! Item was changed: + ----- Method: SyntaxErrorNotification class>>inClass:withCode:doitFlag:errorMessage:location: (in category 'instance creation') ----- - ----- Method: SyntaxErrorNotification class>>inClass:withCode:doitFlag:errorMessage:location: (in category 'exceptionInstantiator') ----- inClass: aClass withCode: codeString doitFlag: doitFlag errorMessage: errorString location: location + + self deprecated: 'ct: Use #cue:doitFlag:errorMessage:location:'. + ^ self + cue: (CompilationCue source: codeString class: aClass requestor: nil) - ^self new - setClass: aClass - code: codeString doitFlag: doitFlag errorMessage: errorString location: location! Item was added: + ----- Method: SyntaxErrorNotification>>context (in category 'accessing') ----- + context + + ^ cue context! Item was added: + ----- Method: SyntaxErrorNotification>>environment (in category 'accessing') ----- + environment + + ^ cue environment! Item was changed: ----- Method: SyntaxErrorNotification>>errorClass (in category 'accessing') ----- errorClass + + ^ cue getClass! - ^inClass! Item was changed: ----- Method: SyntaxErrorNotification>>errorCode (in category 'accessing') ----- errorCode + + ^ cue source! - ^code! Item was changed: ----- Method: SyntaxErrorNotification>>messageText (in category 'accessing') ----- messageText ^ super messageText + ifEmpty: [messageText := self errorCode]! - ifEmpty: [messageText := code]! Item was changed: ----- Method: SyntaxErrorNotification>>reparse:notifying:ifFail: (in category 'accessing') ----- reparse: aString notifying: aController ifFail: failBlock "Try to parse if aString has correct syntax, but do not evaluate/install any code. In case of incorrect syntax, execute failBlock and let a Compiler interact with the requestor. In case of correct syntax, set newSource." + + (doitFlag ifTrue: [nil class] ifFalse: [self errorClass]) newCompiler + compileCue: (cue copy + source: aString; + requestor: aController; + yourself) + noPattern: doitFlag + ifFail: failBlock. + newSource := aString.! - doitFlag - ifTrue: [nil class newCompiler compileNoPattern: aString in: nil class notifying: aController ifFail: failBlock] - ifFalse: [inClass newCompiler compile: aString in: inClass notifying: aController ifFail: failBlock]. - newSource := aString! Item was removed: - ----- Method: SyntaxErrorNotification>>setClass:code:doitFlag:errorMessage:location: (in category 'accessing') ----- - setClass: aClass code: codeString doitFlag: aBoolean errorMessage: errorString location: anInteger - inClass := aClass. - code := codeString. - doitFlag := aBoolean. - errorMessage := errorString. - location := anInteger! Item was added: + ----- Method: SyntaxErrorNotification>>setCue:doitFlag:errorMessage:location: (in category 'initialize-release') ----- + setCue: aCue doitFlag: aBoolean errorMessage: errorString location: anInteger + + cue := aCue. + doitFlag := aBoolean. + errorMessage := errorString. + location := anInteger! From commits at source.squeak.org Thu Feb 18 13:19:14 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:19:14 0000 Subject: [squeak-dev] The Trunk: Compiler-ct.449.mcz Message-ID: Marcel Taeumel uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler-ct.449.mcz ==================== Summary ==================== Name: Compiler-ct.449 Author: ct Time: 24 October 2020, 12:12:47.879256 am UUID: f4dcd413-ed53-bf47-8762-a0e1c23f7a7f Ancestors: Compiler-tobe.448 Redesigns SyntaxErrorNotification to hold a CompilationCue instead of 'inClass' and 'code', in orderto allow for recompilation of syntax errors where other compilation parameters have been specified, e.g. context or environment. For example, the following syntax error could not be resolved before this patch: Compiler new evaluate: 'aCue yourself:' in: thisContext sender to: thisContext sender receiver. =============== Diff against Compiler-tobe.448 =============== Item was added: + ----- Method: CompilationCue>>source: (in category 'accessing') ----- + source: aString + + source := aString. + sourceStream := source readStream.! Item was changed: ----- Method: Parser>>notify:at: (in category 'error handling') ----- notify: string at: location | messageText | messageText := '"' , string , ' ->"'. cue requestor isNil ifTrue: [ | notification | (encoder == self or: [encoder isNil]) ifTrue: [^ self fail "failure setting up syntax error"]. (notification := SyntaxErrorNotification + cue: (cue copy + source: (source contents asText + copyReplaceFrom: location + to: location - 1 + with: messageText); + yourself) - inClass: encoder classEncoding - withCode: (source contents asText - copyReplaceFrom: location - to: location - 1 - with: messageText) doitFlag: doitFlag errorMessage: string location: location) signal. notification tryNewSourceIfAvailable] ifFalse: [cue requestor notify: messageText at: location in: source]. ^ self fail! Item was changed: Error subclass: #SyntaxErrorNotification + instanceVariableNames: 'cue doitFlag errorMessage location newSource' - instanceVariableNames: 'inClass code doitFlag errorMessage location newSource' classVariableNames: '' poolDictionaries: '' category: 'Compiler-Exceptions'! + !SyntaxErrorNotification commentStamp: 'ct 10/24/2020 00:01' prior: 0! - !SyntaxErrorNotification commentStamp: 'nice 9/18/2013 22:16' prior: 0! A SyntaxErrorNotification is an Exception occuring when compiling a Smalltalk source code with incorrect syntax. Note that in interactive mode, this exception is not raised because the Compiler will interact directly with source code editor. The defaultAction is to raise a SyntaxError pop up window so as to enable interactive handling even in non interactive mode. Instance Variables + cue: - category: - code: doitFlag: errorMessage: - inClass: location: newSource: + cue + - the cue for compilation, including receiver class, optional context, and original source code - category - - the category in which the method will be classified - code - - the source code to be compiled or evaluated - doitFlag - true if this is a doIt (code to evaluate), false if this is a method (code of a method to be compiled) errorMessage - contains information about the syntax error - inClass - - target class in which to compile the method - location - position in the source code where the syntax error occured newSource + - eventually hold a source code replacement typically passed by the SyntaxError window! - - eventually hold a source code replacement typically passed by the SyntaxError window - ! Item was added: + ----- Method: SyntaxErrorNotification class>>cue:doitFlag:errorMessage:location: (in category 'instance creation') ----- + cue: aCue doitFlag: doitFlag errorMessage: errorString location: location + + ^ self new + setCue: aCue + doitFlag: doitFlag + errorMessage: errorString + location: location! Item was changed: + ----- Method: SyntaxErrorNotification class>>inClass:withCode:doitFlag:errorMessage:location: (in category 'instance creation') ----- - ----- Method: SyntaxErrorNotification class>>inClass:withCode:doitFlag:errorMessage:location: (in category 'exceptionInstantiator') ----- inClass: aClass withCode: codeString doitFlag: doitFlag errorMessage: errorString location: location + + self deprecated: 'ct: Use #cue:doitFlag:errorMessage:location:'. + ^ self + cue: (CompilationCue source: codeString class: aClass requestor: nil) - ^self new - setClass: aClass - code: codeString doitFlag: doitFlag errorMessage: errorString location: location! Item was added: + ----- Method: SyntaxErrorNotification>>context (in category 'accessing') ----- + context + + ^ cue context! Item was changed: ----- Method: SyntaxErrorNotification>>errorClass (in category 'accessing') ----- errorClass + + ^ cue getClass! - ^inClass! Item was changed: ----- Method: SyntaxErrorNotification>>errorCode (in category 'accessing') ----- errorCode + + ^ cue source! - ^code! Item was changed: ----- Method: SyntaxErrorNotification>>messageText (in category 'accessing') ----- messageText ^ super messageText + ifEmpty: [messageText := self errorCode]! - ifEmpty: [messageText := code]! Item was changed: ----- Method: SyntaxErrorNotification>>reparse:notifying:ifFail: (in category 'accessing') ----- reparse: aString notifying: aController ifFail: failBlock "Try to parse if aString has correct syntax, but do not evaluate/install any code. In case of incorrect syntax, execute failBlock and let a Compiler interact with the requestor. In case of correct syntax, set newSource." + + (doitFlag ifTrue: [nil class] ifFalse: [self errorClass]) newCompiler + compileCue: (cue copy + source: aString; + requestor: aController; + yourself) + noPattern: doitFlag + ifFail: failBlock. + newSource := aString.! - doitFlag - ifTrue: [nil class newCompiler compileNoPattern: aString in: nil class notifying: aController ifFail: failBlock] - ifFalse: [inClass newCompiler compile: aString in: inClass notifying: aController ifFail: failBlock]. - newSource := aString! Item was removed: - ----- Method: SyntaxErrorNotification>>setClass:code:doitFlag:errorMessage:location: (in category 'accessing') ----- - setClass: aClass code: codeString doitFlag: aBoolean errorMessage: errorString location: anInteger - inClass := aClass. - code := codeString. - doitFlag := aBoolean. - errorMessage := errorString. - location := anInteger! Item was added: + ----- Method: SyntaxErrorNotification>>setCue:doitFlag:errorMessage:location: (in category 'initialize-release') ----- + setCue: aCue doitFlag: aBoolean errorMessage: errorString location: anInteger + + cue := aCue. + doitFlag := aBoolean. + errorMessage := errorString. + location := anInteger! From commits at source.squeak.org Thu Feb 18 13:19:23 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:19:23 0000 Subject: [squeak-dev] The Trunk: Compiler-ct.426.mcz Message-ID: Marcel Taeumel uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler-ct.426.mcz ==================== Summary ==================== Name: Compiler-ct.426 Author: ct Time: 28 March 2020, 1:22:49.51256 am UUID: 761924e9-77a0-1144-9533-8a7c22c03332 Ancestors: Compiler-ct.424 Fixes a bug regarding decompilation of special selectors. The following did not work before: (OrderedCollection >> #asArray) decompile generate valueWithReceiver: {42} asOrderedCollection arguments: #(). "MessageNotUnderstood: OrderedCollection>>#Array=>Array" See also this thread: http://forum.world.st/The-Inbox-EToys-ct-367-mcz-tp5105507p5114020.html =============== Diff against Compiler-ct.424 =============== Item was changed: ----- Method: DecompilerConstructor>>codeAnySelector: (in category 'constructor') ----- codeAnySelector: selector ^SelectorNode new key: selector + index: nil - index: 0 type: SendType! From commits at source.squeak.org Thu Feb 18 13:19:30 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:19:30 0000 Subject: [squeak-dev] The Trunk: Compiler-ct.424.mcz Message-ID: Marcel Taeumel uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler-ct.424.mcz ==================== Summary ==================== Name: Compiler-ct.424 Author: ct Time: 26 March 2020, 5:19:54.71456 pm UUID: 10f4405b-896c-3149-b76b-b9cd45ca5734 Ancestors: Compiler-nice.420 Fixes a bug regarding decompilation of FullBlockClosures Sample to reproduce: [^ true] decompile should NOT return {[]}! =============== Diff against Compiler-nice.420 =============== Item was changed: ----- Method: Decompiler>>blockTo: (in category 'control') ----- blockTo: end + "Decompile a range of code as in statementsTo:, but return a block node. NB: end is an exclusive index." - "Decompile a range of code as in statementsTo:, but return a block node." | exprs block oldBase lastStatementOfBlockIsNil | oldBase := blockStackBase. blockStackBase := stack size. exprs := self statementsTo: end. lastStatementOfBlockIsNil := pc < method endPC and: [exprs notEmpty and: [exprs last == (constTable at: 4)]]. lastStatementOfBlockIsNil ifTrue: [exprs := exprs allButLast]. block := constructor codeBlock: exprs returns: lastReturnPc = lastPc. blockStackBase := oldBase. lastReturnPc := -1. "So as not to mislead outer calls" ^block! Item was changed: ----- Method: Decompiler>>doClosureCopy:copiedValues: (in category 'control') ----- doClosureCopy: aCompiledBlock copiedValues: blockCopiedValues "implementation note: must be invoked on a copy because it modifies states" | savedPC blockArgs blockTemps blockTempsOffset block mark | numLocalTemps := aCompiledBlock numTemps - aCompiledBlock numArgs - blockCopiedValues size. blockTempsOffset := aCompiledBlock numArgs + blockCopiedValues size. (blockStartsToTempVars notNil "implies we were intialized with temp names." and: [blockStartsToTempVars includesKey: aCompiledBlock]) ifTrue: [tempVars := blockStartsToTempVars at: aCompiledBlock] ifFalse: [blockArgs := (1 to: aCompiledBlock numArgs) collect: [:i| (constructor codeTemp: i - 1 named: 't', (tempVarCount + i) printString) beBlockArg]. blockTemps := (1 to: numLocalTemps) collect: [:i| constructor codeTemp: i + blockTempsOffset - 1 named: 't', (tempVarCount + i + aCompiledBlock numArgs) printString]. tempVars := blockArgs, blockCopiedValues, blockTemps]. tempVarCount := tempVarCount + aCompiledBlock numArgs + numLocalTemps. lastJumpIfPcStack := OrderedCollection new. caseExits := OrderedCollection new. statements := OrderedCollection new: 20. savedPC := pc. self method: (method := aCompiledBlock) pc: aCompiledBlock initialPC. mark := stack size. + block := self blockTo: aCompiledBlock endPC + 1. - block := self blockTo: aCompiledBlock endPC. mark = stack size ifFalse: [self error: 'block did alter the stack']. ^((constructor codeArguments: (tempVars copyFrom: 1 to: aCompiledBlock numArgs) temps: (tempVars copyFrom: blockTempsOffset + 1 to: blockTempsOffset + numLocalTemps) block: block) pc: aCompiledBlock -> savedPC; "c.f. BytecodeEncoder>>pc" yourself).! From Christoph.Thiede at student.hpi.uni-potsdam.de Thu Feb 18 13:29:48 2021 From: Christoph.Thiede at student.hpi.uni-potsdam.de (Thiede, Christoph) Date: Thu, 18 Feb 2021 13:29:48 +0000 Subject: [squeak-dev] The Trunk: Compiler-ct.449.mcz In-Reply-To: References: Message-ID: Yahoo, merge party! 🎉 ________________________________ Von: Squeak-dev im Auftrag von commits at source.squeak.org Gesendet: Donnerstag, 18. Februar 2021 14:19 Uhr An: squeak-dev at lists.squeakfoundation.org; packages at lists.squeakfoundation.org Betreff: [squeak-dev] The Trunk: Compiler-ct.449.mcz Marcel Taeumel uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler-ct.449.mcz ==================== Summary ==================== Name: Compiler-ct.449 Author: ct Time: 24 October 2020, 12:12:47.879256 am UUID: f4dcd413-ed53-bf47-8762-a0e1c23f7a7f Ancestors: Compiler-tobe.448 Redesigns SyntaxErrorNotification to hold a CompilationCue instead of 'inClass' and 'code', in orderto allow for recompilation of syntax errors where other compilation parameters have been specified, e.g. context or environment. For example, the following syntax error could not be resolved before this patch: Compiler new evaluate: 'aCue yourself:' in: thisContext sender to: thisContext sender receiver. =============== Diff against Compiler-tobe.448 =============== Item was added: + ----- Method: CompilationCue>>source: (in category 'accessing') ----- + source: aString + + source := aString. + sourceStream := source readStream.! Item was changed: ----- Method: Parser>>notify:at: (in category 'error handling') ----- notify: string at: location | messageText | messageText := '"' , string , ' ->"'. cue requestor isNil ifTrue: [ | notification | (encoder == self or: [encoder isNil]) ifTrue: [^ self fail "failure setting up syntax error"]. (notification := SyntaxErrorNotification + cue: (cue copy + source: (source contents asText + copyReplaceFrom: location + to: location - 1 + with: messageText); + yourself) - inClass: encoder classEncoding - withCode: (source contents asText - copyReplaceFrom: location - to: location - 1 - with: messageText) doitFlag: doitFlag errorMessage: string location: location) signal. notification tryNewSourceIfAvailable] ifFalse: [cue requestor notify: messageText at: location in: source]. ^ self fail! Item was changed: Error subclass: #SyntaxErrorNotification + instanceVariableNames: 'cue doitFlag errorMessage location newSource' - instanceVariableNames: 'inClass code doitFlag errorMessage location newSource' classVariableNames: '' poolDictionaries: '' category: 'Compiler-Exceptions'! + !SyntaxErrorNotification commentStamp: 'ct 10/24/2020 00:01' prior: 0! - !SyntaxErrorNotification commentStamp: 'nice 9/18/2013 22:16' prior: 0! A SyntaxErrorNotification is an Exception occuring when compiling a Smalltalk source code with incorrect syntax. Note that in interactive mode, this exception is not raised because the Compiler will interact directly with source code editor. The defaultAction is to raise a SyntaxError pop up window so as to enable interactive handling even in non interactive mode. Instance Variables + cue: - category: - code: doitFlag: errorMessage: - inClass: location: newSource: + cue + - the cue for compilation, including receiver class, optional context, and original source code - category - - the category in which the method will be classified - code - - the source code to be compiled or evaluated - doitFlag - true if this is a doIt (code to evaluate), false if this is a method (code of a method to be compiled) errorMessage - contains information about the syntax error - inClass - - target class in which to compile the method - location - position in the source code where the syntax error occured newSource + - eventually hold a source code replacement typically passed by the SyntaxError window! - - eventually hold a source code replacement typically passed by the SyntaxError window - ! Item was added: + ----- Method: SyntaxErrorNotification class>>cue:doitFlag:errorMessage:location: (in category 'instance creation') ----- + cue: aCue doitFlag: doitFlag errorMessage: errorString location: location + + ^ self new + setCue: aCue + doitFlag: doitFlag + errorMessage: errorString + location: location! Item was changed: + ----- Method: SyntaxErrorNotification class>>inClass:withCode:doitFlag:errorMessage:location: (in category 'instance creation') ----- - ----- Method: SyntaxErrorNotification class>>inClass:withCode:doitFlag:errorMessage:location: (in category 'exceptionInstantiator') ----- inClass: aClass withCode: codeString doitFlag: doitFlag errorMessage: errorString location: location + + self deprecated: 'ct: Use #cue:doitFlag:errorMessage:location:'. + ^ self + cue: (CompilationCue source: codeString class: aClass requestor: nil) - ^self new - setClass: aClass - code: codeString doitFlag: doitFlag errorMessage: errorString location: location! Item was added: + ----- Method: SyntaxErrorNotification>>context (in category 'accessing') ----- + context + + ^ cue context! Item was changed: ----- Method: SyntaxErrorNotification>>errorClass (in category 'accessing') ----- errorClass + + ^ cue getClass! - ^inClass! Item was changed: ----- Method: SyntaxErrorNotification>>errorCode (in category 'accessing') ----- errorCode + + ^ cue source! - ^code! Item was changed: ----- Method: SyntaxErrorNotification>>messageText (in category 'accessing') ----- messageText ^ super messageText + ifEmpty: [messageText := self errorCode]! - ifEmpty: [messageText := code]! Item was changed: ----- Method: SyntaxErrorNotification>>reparse:notifying:ifFail: (in category 'accessing') ----- reparse: aString notifying: aController ifFail: failBlock "Try to parse if aString has correct syntax, but do not evaluate/install any code. In case of incorrect syntax, execute failBlock and let a Compiler interact with the requestor. In case of correct syntax, set newSource." + + (doitFlag ifTrue: [nil class] ifFalse: [self errorClass]) newCompiler + compileCue: (cue copy + source: aString; + requestor: aController; + yourself) + noPattern: doitFlag + ifFail: failBlock. + newSource := aString.! - doitFlag - ifTrue: [nil class newCompiler compileNoPattern: aString in: nil class notifying: aController ifFail: failBlock] - ifFalse: [inClass newCompiler compile: aString in: inClass notifying: aController ifFail: failBlock]. - newSource := aString! Item was removed: - ----- Method: SyntaxErrorNotification>>setClass:code:doitFlag:errorMessage:location: (in category 'accessing') ----- - setClass: aClass code: codeString doitFlag: aBoolean errorMessage: errorString location: anInteger - inClass := aClass. - code := codeString. - doitFlag := aBoolean. - errorMessage := errorString. - location := anInteger! Item was added: + ----- Method: SyntaxErrorNotification>>setCue:doitFlag:errorMessage:location: (in category 'initialize-release') ----- + setCue: aCue doitFlag: aBoolean errorMessage: errorString location: anInteger + + cue := aCue. + doitFlag := aBoolean. + errorMessage := errorString. + location := anInteger! -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Thu Feb 18 13:31:33 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:31:33 0000 Subject: [squeak-dev] The Trunk: EToys-mt.422.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-mt.422.mcz ==================== Summary ==================== Name: EToys-mt.422 Author: mt Time: 18 February 2021, 2:31:24.938649 pm UUID: 65503b97-01b4-134f-8b1f-d6967bc024a7 Ancestors: EToys-mt.421, EToys-ct.370, EToys-ct.368, EToys-ct.390, EToys-ct.404 Merges Christoph's (ct) efforts to improve code-to-tile conversion. =============== Diff against EToys-mt.421 =============== Item was added: + ----- Method: BlockNode>>asTileSetForPlayer: (in category '*Etoys-tiles') ----- + asTileSetForPlayer: aPlayer + + ^ self statements gather: [:statement | + [statement asStatementTileSetForPlayer: aPlayer] + ifError: [{statement asMorphicSyntaxIn: SyntaxMorph new}]]! Item was added: + ----- Method: BlockNode>>withoutImplicitReturns (in category '*Etoys-tiles') ----- + withoutImplicitReturns + + (self statements ifEmpty: [^ self]) last isImplicitReturn + ifFalse: [^ self]. + ^ self copy statements: self statements allButLast! Item was added: + ----- Method: CascadeNode>>asStatementTileSetForPlayer: (in category '*Etoys-tiles') ----- + asStatementTileSetForPlayer: aPlayer + + ^ self asTileSetForPlayer: aPlayer! Item was added: + ----- Method: CascadeNode>>asTileSetForPlayer: (in category '*Etoys-tiles') ----- + asTileSetForPlayer: aPlayer + + ^ self messages gather: [:message | + message copy + receiver: self receiver; + asTileSetForPlayer: aPlayer]! Item was added: + ----- Method: CommentNode>>asTileSetForPlayer: (in category '*Etoys-tiles') ----- + asTileSetForPlayer: aPlayer + + ^ #()! Item was changed: ----- Method: EtoysDebugger>>evaluateNextTile (in category 'evaluating') ----- evaluateNextTile (scriptEditor isTextuallyCoded) ifTrue:[^ self inform: 'You can''t step through textually coded scripts.\Use a script''s tile-based representation instead.' withCRs translated]. [next = (scriptEditor tiles at: 1 ifAbsent: [nil]) ifTrue: ["We are about to evaluate the first tile" self updateStartingPosition]. + (self trailMorph ifNotNil: #batchPenTrails ifNil: [false]) - self trailMorph batchPenTrails ifTrue: [self evaluateNextTileWithBatchPenTrails] ifFalse: [next evaluateOn: self]] on: Error do: [:err || newNext | newNext := scriptEditor tiles at: 1 ifAbsent: [^ self]. newNext = next ifTrue: [err pass] ifFalse: [next := newNext]. self evaluateNextTile] ! Item was added: + ----- Method: LiteralNode>>asTileForPlayer: (in category '*Etoys-tiles') ----- + asTileForPlayer: aPlayer + + ^ aPlayer presenter constantTile: self literalValue! Item was added: + ----- Method: MessageNode>>asStatementTileSetForPlayer: (in category '*Etoys-tiles') ----- + asStatementTileSetForPlayer: aPlayer + + ^ self asTileSetForPlayer: aPlayer! Item was added: + ----- Method: MessageNode>>asTileForPlayer: (in category '*Etoys-tiles') ----- + asTileForPlayer: aPlayer + + | receiverType argumentType resultType phrase receiverTiles | + "Catch edge case: Color tile" + (self receiver isVariableNode and: [self receiver key = (Smalltalk bindingOf: #Color)]) + ifTrue: [ | source result | + source := String streamContents: (MessageSend receiver: self selector: #shortPrintOn:). + result := [Compiler evaluate: source] ifError: [nil]. + result isColor ifTrue: [^ result newTileMorphRepresentative]]. + + "Catch edge case: Test tile" + self ifConditionNormalizeAndDo: [:conditionNode :trueNode :falseNode | | compound | + compound := StandardScriptingSystem new yesNoComplexOfTiles. + compound testPart insertTileRow: (conditionNode asTileSetForPlayer: aPlayer) after: 0. + compound yesPart insertTileRow: (trueNode withoutImplicitReturns asTileSetForPlayer: aPlayer) after: 0. + compound noPart insertTileRow: (falseNode withoutImplicitReturns asTileSetForPlayer: aPlayer) after: 0. + compound enforceTileColorPolicy; layoutChanged; fullBounds. + ^ compound]. + + "Otherwise, try to build a phrase tile" + self arguments size < 2 ifFalse: [^ self convertToTileError]. + + receiverType := #unknown. + argumentType := self arguments ifEmpty: [nil] ifNotEmpty: [#unknown]. + resultType := #unknown. + phrase := PhraseTileMorph new. + phrase + setOperator: self selector key + type: resultType + rcvrType: receiverType + argType: argumentType. + receiverTiles := self receiver asTileSetForPlayer: aPlayer. + receiverTiles size = 1 ifFalse: [^ self convertToTileError]. + phrase firstSubmorph + addMorph: receiverTiles first; + hResizing: #shrinkWrap; vResizing: #shrinkWrap. + self arguments ifNotEmpty: [ | argumentTiles | + argumentTiles := self arguments first asTileSetForPlayer: aPlayer. + argumentTiles size = 1 ifFalse: [^ self convertToTileError]. + phrase lastSubmorph + setType: argumentType; + changeTableLayout; + addMorph: argumentTiles first; + hResizing: #shrinkWrap; vResizing: #shrinkWrap]. + + ^ phrase + hResizing: #shrinkWrap; vResizing: #shrinkWrap; + yourself! Item was added: + ----- Method: MessageNode>>ifConditionNormalizeAndDo: (in category '*Etoys-tiles') ----- + ifConditionNormalizeAndDo: aBlock + + | blocks | + blocks := self selector key + caseOf: { + [#ifTrue:ifFalse:] -> [arguments]. + [#ifFalse:ifTrue:] -> [self arguments reversed]. + [#ifTrue:] -> [self arguments copyWith: (BlockNode statements: #() returns: #())]. + [#ifFalse:] -> [self arguments copyWithFirst: (BlockNode statements: #() returns: #())] } + otherwise: [^ self]. + ^ aBlock value: self receiver value: blocks first value: blocks last! Item was added: + ----- Method: MethodNode>>asScriptEditorFor: (in category '*Etoys-tiles') ----- + asScriptEditorFor: aPlayer + + | editor | + editor := ScriptEditorMorph new. + editor + playerScripted: aPlayer; + setMorph: aPlayer costume scriptName: self selector. + + (self asTileSetForPlayer: aPlayer) + withIndexDo: [:tile :index | + editor insertTileRow: {tile} after: index]. + editor + removeSpaces; + enforceTileColorPolicy; + scriptEdited; + allMorphsDo: #layoutChanged. + ^ editor! Item was added: + ----- Method: MethodNode>>asTileSetForPlayer: (in category '*Etoys-tiles') ----- + asTileSetForPlayer: aPlayer + + ^ self block withoutImplicitReturns asTileSetForPlayer: aPlayer! Item was added: + ----- Method: MethodTempsNode>>asTileSetForPlayer: (in category '*Etoys-tiles') ----- + asTileSetForPlayer: aPlayer + + ^ #()! Item was added: + ----- Method: MethodWithInterface>>revertTileVersionFrom:for: (in category 'updating') ----- + revertTileVersionFrom: anEditor for: playerScripted + "Only for universal tiles." + + ^ self revertToLastSavedTileVersionFor: anEditor! Item was added: + ----- Method: ParseNode>>asStatementTileSetForPlayer: (in category '*Etoys-tiles') ----- + asStatementTileSetForPlayer: aPlayer + + ^ self convertToTileError! Item was added: + ----- Method: ParseNode>>asTileForPlayer: (in category '*Etoys-tiles') ----- + asTileForPlayer: aPlayer + "Private. Better call #asTileMorphsForPlayer:." + + ^ self convertToTileError! Item was added: + ----- Method: ParseNode>>asTileSetForPlayer: (in category '*Etoys-tiles') ----- + asTileSetForPlayer: aPlayer + + ^ {self asTileForPlayer: aPlayer}! Item was added: + ----- Method: ParseNode>>convertToTileError (in category '*Etoys-tiles') ----- + convertToTileError + + ^ self error: 'Cannot convert this expression to a tile'! Item was added: + ----- Method: ParseNode>>isImplicitReturn (in category '*Etoys-tiles') ----- + isImplicitReturn + + ^false! Item was added: + ----- Method: ReturnNode>>asTileSetForPlayer: (in category '*Etoys-tiles') ----- + asTileSetForPlayer: aPlayer + + "self isReturnSelf ifTrue: [^ #()]." + ^ self expr asTileSetForPlayer: aPlayer! Item was added: + ----- Method: ReturnNode>>isImplicitReturn (in category '*Etoys-tiles') ----- + isImplicitReturn + + ^ self isReturnSelf! Item was added: + ----- Method: ScriptEditorMorph>>convertToTileVersion (in category 'save & revert') ----- + convertToTileVersion + "The receiver, currently showing textual code, is asked to revert to the last-saved tile version" + + | aUserScript | + + self + hResizing: #shrinkWrap; + vResizing: #shrinkWrap. + aUserScript := playerScripted class userScriptForPlayer: playerScripted selector: scriptName. + aUserScript revertTileVersionFrom: self for: playerScripted. + self currentWorld startSteppingSubmorphsOf: self! Item was changed: ----- Method: ScriptEditorMorph>>offerScriptorMenu (in category 'other') ----- offerScriptorMenu "Put up a menu in response to the user's clicking in the menu-request area of the scriptor's heaer" | aMenu count | - self modernize. self currentHand showTemporaryCursor: nil. + - Preferences eToyFriendly ifTrue: [^ self offerSimplerScriptorMenu]. + - aMenu := MenuMorph new defaultTarget: self. aMenu addTitle: scriptName asString. aMenu addStayUpItem. "NB: the kids version in #offerSimplerScriptorMenu does not deploy the stay-up item" + - aMenu addList: (self hasParameter ifTrue: [{ {'remove parameter' translated. #ceaseHavingAParameter}}] ifFalse: [{ {'add parameter' translated. #addParameter}}]). self hasParameter ifFalse: [aMenu addTranslatedList: { {'button to fire this script' translatedNoop. #tearOfButtonToFireScript}. {'fires per tick...' translatedNoop. #chooseFrequency}. #- }]. + + aMenu addUpdating: #showingCaretsString target: self action: #toggleShowingCarets. - - aMenu addUpdating: #showingCaretsString target: self action: #toggleShowingCarets. aMenu addLine. aMenu addList: { {'edit balloon help for this script' translated. #editMethodDescription}. {'explain status alternatives' translated. #explainStatusAlternatives}. {'button to show/hide this script' translated. #buttonToOpenOrCloseThisScript}. #- }. + + Preferences universalTiles ifFalse: [ + count := self savedTileVersionsCount. - - - Preferences universalTiles ifFalse: - [count := self savedTileVersionsCount. self showingMethodPane + ifFalse: [ "currently showing tiles" + aMenu add: 'show code textually' translated action: #showSourceInScriptor. + count > 0 ifTrue: [ + aMenu add: 'revert to tile version...' translated action: #revertScriptVersion]. + aMenu add: 'save this version' translated action: #saveScriptVersion ] + ifTrue: [ "current showing textual source" + aMenu add: 'convert to tile version' translated action: #toggleWhetherShowingTiles. + count > 0 ifTrue: + [aMenu add: 'revert to tile version...' translated action: #revertScriptVersion]] ]. + - ifFalse: "currently showing tiles" - [aMenu add: 'show code textually' translated action: #toggleWhetherShowingTiles. - count > 0 ifTrue: - [aMenu add: 'revert to tile version...' translated action: #revertScriptVersion]. - aMenu add: 'save this version' translated action: #saveScriptVersion] - - ifTrue: "current showing textual source" - [count >= 1 ifTrue: - [aMenu add: 'revert to tile version' translated action: #toggleWhetherShowingTiles]]]. - "aMenu addLine. self addGoldBoxItemsTo: aMenu." + - aMenu addLine. + aMenu add: 'grab this object' translated target: playerScripted selector: #grabPlayerIn: argument: ActiveWorld. - aMenu add: 'grab this object' translated target: playerScripted selector: #grabPlayerIn: argument: self currentWorld. aMenu balloonTextForLastItem: 'This will actually pick up the object bearing this script and hand it to you. Click the (left) button to drop it' translated. + + aMenu add: 'reveal this object' translated target: playerScripted selector: #revealPlayerIn: argument: ActiveWorld. - - aMenu add: 'reveal this object' translated target: playerScripted selector: #revealPlayerIn: argument: self currentWorld. aMenu balloonTextForLastItem: 'If you have misplaced the object bearing this script, use this item to (try to) make it visible' translated. + - aMenu add: 'tile representing this object' translated target: playerScripted action: #tearOffTileForSelf. aMenu balloonTextForLastItem: 'choose this to obtain a tile which represents the object associated with this script' translated. + - aMenu addTranslatedList: { #-. {'open viewer' translatedNoop. #openObjectsViewer. 'open the viewer of the object to which this script belongs' translatedNoop}. {'detached method pane' translatedNoop. #makeIsolatedCodePane. 'open a little window that shows the Smalltalk code underlying this script.' translatedNoop}. #-. {'destroy this script' translatedNoop. #destroyScript} }. + + aMenu popUpInWorld: self currentWorld.! - - - ^ aMenu popUpInWorld: self currentWorld! Item was changed: ----- Method: ScriptEditorMorph>>parseNodeWith: (in category '*Etoys-Squeakland-other') ----- parseNodeWith: encoder | statements ret | statements := WriteStream on: (Array new: self tileRows size). + self tileRows do: [:row | + row do: [:morph | + (morph respondsTo: #parseNodeWith:asStatement:) ifTrue: [ + statements nextPut: (morph parseNodeWith: encoder asStatement: true)]]]. - self tileRows do: [:r | - r do: [:m | - ((m isKindOf: TileMorph) - or: [(m isKindOf: CompoundTileMorph) - or: [m isKindOf: PhraseTileMorph]]) ifTrue: [ - statements nextPut: (m parseNodeWith: encoder asStatement: true)]]]. statements := statements contents. ret := ReturnNode new expr: (encoder encodeVariable: 'self'). + ^ BlockNode new + arguments: #() + statements: (statements copyWith: ret) + returns: true + from: encoder.! - ^ BlockNode new arguments: #() statements: (statements copyWith: ret) returns: true from: encoder. - ! Item was removed: - ----- Method: ScriptEditorMorph>>revertToTileVersion (in category 'save & revert') ----- - revertToTileVersion - "The receiver, currently showing textual code, is asked to revert to the last-saved tile version" - - | aUserScript | - - self - hResizing: #shrinkWrap; - vResizing: #shrinkWrap. - aUserScript := playerScripted class userScriptForPlayer: playerScripted selector: scriptName. - aUserScript revertToLastSavedTileVersionFor: self. - self currentWorld startSteppingSubmorphsOf: self! Item was changed: ----- Method: ScriptEditorMorph>>toggleWhetherShowingTiles (in category 'other') ----- toggleWhetherShowingTiles "Toggle between showing the method pane and showing the tiles pane" + - self showingMethodPane + ifFalse: [ "currently showing tiles" + self showSourceInScriptor ] + ifTrue: [ "currently showing textual source" + self convertToTileVersion ].! - ifFalse: "currently showing tiles" - [self showSourceInScriptor] - - ifTrue: "current showing textual source" - [Preferences universalTiles - ifTrue: [^ self revertToTileVersion]. - self savedTileVersionsCount >= 1 - ifTrue: - [(self userScriptObject lastSourceString = (playerScripted class sourceCodeAt: scriptName)) - ifFalse: - [(self confirm: - 'Caution -- this script was changed - textually; if you revert to tiles at this - point you will lose all the changes you - may have made textually. Do you - really want to do this?' translated) ifFalse: [^ self]]. - self revertToTileVersion] - ifFalse: - [Beeper beep]]! Item was added: + TestCase subclass: #ScriptEditorMorphTest + instanceVariableNames: 'editor minimalMethod player' + classVariableNames: '' + poolDictionaries: '' + category: 'Etoys-Tests'! Item was added: + ----- Method: ScriptEditorMorphTest>>exampleMinimalPlayerCode (in category 'accessing') ----- + exampleMinimalPlayerCode + + self forward: 6 * 7. + self turn: 6. + self forward: 7. + self getIsUnderMouse ifFalse: [self abandon]. + "self color: (Color r: 1 g: 0.6 b: 0). + [[''''''''] cull: 42] onDNU: #foo do: #ba."! Item was added: + ----- Method: ScriptEditorMorphTest>>examplePlayerCode (in category 'accessing') ----- + examplePlayerCode + + self forward: 6 * 7. + self + turn: 6; + forward: 7. + self getIsUnderMouse ifFalse: [self abandon]. + "self color: (Color fromString: '#ff9900'). + [[''''''''] cull: 42] onDNU: #foo do: #ba."! Item was added: + ----- Method: ScriptEditorMorphTest>>setUp (in category 'running') ----- + setUp + + super setUp. + + player := Morph new assuredPlayer. + minimalMethod := (self class lookupSelector: #exampleMinimalPlayerCode) decompile.! Item was added: + ----- Method: ScriptEditorMorphTest>>tearDown (in category 'running') ----- + tearDown + + [editor ifNotNil: #destroyScript] valueSuppressingMessages: #('*destroy*'). + super tearDown.! Item was added: + ----- Method: ScriptEditorMorphTest>>testCodeToTileAndBack (in category 'testing') ----- + testCodeToTileAndBack + + | templateMethod | + templateMethod := (self class lookupSelector: #examplePlayerCode) decompile. + editor := templateMethod asScriptEditorFor: player. + self + assert: minimalMethod block printString + equals: (player class lookupSelector: #examplePlayerCode) decompile block printString! Item was added: + ----- Method: ScriptEditorMorphTest>>testMinimalCodeToTileAndBack (in category 'testing') ----- + testMinimalCodeToTileAndBack + + editor := minimalMethod asScriptEditorFor: player. + self + assert: minimalMethod block printString + equals: (player class lookupSelector: #exampleMinimalPlayerCode) decompile block printString.! Item was changed: ----- Method: SyntaxMorph>>parseNodeWith:asStatement: (in category '*Etoys-Squeakland-code generation') ----- parseNodeWith: encoder asStatement: aBoolean + | methodNode | + methodNode := self parseNodeWith: encoder. + ^ aBoolean + ifFalse: [methodNode] + ifTrue: [methodNode block]! - ^ self parseNode! Item was added: + ----- Method: UniclassScript>>revertTileVersionFrom:for: (in category 'updating') ----- + revertTileVersionFrom: anEditor for: playerScripted + + anEditor removeAllButFirstSubmorph. + Preferences universalTiles + ifFalse: [ + ((self playerClass >> self selector) decompile asTileSetForPlayer: playerScripted) + withIndexDo: [:tile :index | + anEditor insertTileRow: {tile} after: index]. + anEditor allMorphsDo: #layoutChanged] + ifTrue: [ + anEditor insertUniversalTiles]. + anEditor showingMethodPane: false. + isTextuallyCoded := false.! Item was added: + ----- Method: UserScript>>revertTileVersionFrom:for: (in category 'versions') ----- + revertTileVersionFrom: anEditor for: playerScripted + + anEditor removeAllButFirstSubmorph. + ((self playerClass >> self selector) decompile asTileSetForPlayer: playerScripted) + withIndexDo: [:tile :index | + anEditor insertTileRow: {tile} after: index]. + anEditor allMorphsDo: #layoutChanged. + anEditor showingMethodPane: false. + self becomeTextuallyCoded.! Item was added: + ----- Method: VariableNode>>asTileForPlayer: (in category '*Etoys-tiles') ----- + asTileForPlayer: aPlayer + + | target | + self isSelfPseudoVariable + ifTrue: [^ aPlayer tileToRefer]. + target := self key isVariableBinding + ifTrue: [aPlayer environment at: self key key] + ifFalse: [self key]. + ^ TileMorph new + setToReferTo: target; + yourself! Item was added: + ----- Method: VariableNode>>isImplicitReturn (in category '*Etoys-tiles') ----- + isImplicitReturn + + ^ self = NodeNil! From commits at source.squeak.org Thu Feb 18 13:32:04 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:32:04 0000 Subject: [squeak-dev] The Trunk: EToys-ct.366.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-ct.366.mcz ==================== Summary ==================== Name: EToys-ct.366 Author: ct Time: 15 October 2019, 2:41:49.434129 pm UUID: f77dfa54-471c-9049-bfc8-f03473a25099 Ancestors: EToys-mt.361 Adds basic support for reconverting ParseNodes into EToys tiles Try out: p := World assuredPlayer. e := (Player >> #liftAllPens) decompile asScriptEditorFor: p. e openInHand. =============== Diff against EToys-mt.361 =============== Item was added: + ----- Method: BlockNode>>asTileSetForPlayer: (in category '*Etoys-tiles') ----- + asTileSetForPlayer: aPlayer + + ^ self statements gather: [:statement | + [statement asStatementTileSetForPlayer: aPlayer] + ifError: [{statement asMorphicSyntaxIn: SyntaxMorph new}]]! Item was added: + ----- Method: BlockNode>>withoutImplicitReturns (in category '*Etoys-tiles') ----- + withoutImplicitReturns + + (self statements ifEmpty: [^ self]) last isReturnSelf + ifFalse: [^ self]. + ^ self copy statements: self statements allButLast! Item was added: + ----- Method: CascadeNode>>asStatementTileSetForPlayer: (in category '*Etoys-tiles') ----- + asStatementTileSetForPlayer: aPlayer + + ^ self asTileSetForPlayer: aPlayer! Item was added: + ----- Method: CascadeNode>>asTileSetForPlayer: (in category '*Etoys-tiles') ----- + asTileSetForPlayer: aPlayer + + ^ self messages gather: [:message | + message copy + receiver: self receiver; + asTileSetForPlayer: aPlayer]! Item was added: + ----- Method: CommentNode>>asTileSetForPlayer: (in category '*Etoys-tiles') ----- + asTileSetForPlayer: aPlayer + + ^ #()! Item was changed: ----- Method: EtoysDebugger>>evaluateNextTile (in category 'evaluating') ----- evaluateNextTile (scriptEditor isTextuallyCoded) ifTrue:[^ self inform: 'You can''t step through textually coded scripts.\Use a script''s tile-based representation instead.' withCRs translated]. [next = (scriptEditor tiles at: 1 ifAbsent: [nil]) ifTrue: ["We are about to evaluate the first tile" self updateStartingPosition]. + (self trailMorph ifNotNil: #batchPenTrails ifNil: [false]) - self trailMorph batchPenTrails ifTrue: [self evaluateNextTileWithBatchPenTrails] ifFalse: [next evaluateOn: self]] on: Error do: [:err || newNext | newNext := scriptEditor tiles at: 1 ifAbsent: [^ self]. newNext = next ifTrue: [err pass] ifFalse: [next := newNext]. self evaluateNextTile] ! Item was added: + ----- Method: LiteralNode>>asTileForPlayer: (in category '*Etoys-tiles') ----- + asTileForPlayer: aPlayer + + ^ aPlayer presenter constantTile: self literalValue! Item was added: + ----- Method: MessageNode>>asStatementTileSetForPlayer: (in category '*Etoys-tiles') ----- + asStatementTileSetForPlayer: aPlayer + + ^ self asTileSetForPlayer: aPlayer! Item was added: + ----- Method: MessageNode>>asTileForPlayer: (in category '*Etoys-tiles') ----- + asTileForPlayer: aPlayer + + | receiverType argumentType resultType phrase receiverTiles | + "Catch edge case: Color tile" + (self receiver isVariableNode and: [self receiver key = (Smalltalk bindingOf: #Color)]) + ifTrue: [ | source result | + source := String streamContents: (MessageSend receiver: self selector: #shortPrintOn:). + result := [Compiler evaluate: source] ifError: [nil]. + result isColor ifTrue: [^ result newTileMorphRepresentative]]. + + "Catch edge case: Test tile" + self ifConditionNormalizeAndDo: [:conditionNode :trueNode :falseNode | | compound | + compound := StandardScriptingSystem new yesNoComplexOfTiles. + compound testPart insertTileRow: (conditionNode asTileSetForPlayer: aPlayer) after: 0. + compound yesPart insertTileRow: (trueNode asTileSetForPlayer: aPlayer) after: 0. + compound noPart insertTileRow: (falseNode asTileSetForPlayer: aPlayer) after: 0. + compound enforceTileColorPolicy; layoutChanged; fullBounds. + ^ compound]. + + "Otherwise, try to build a phrase tile" + self arguments size < 2 ifFalse: [^ self convertToTileError]. + + receiverType := #unknown. + argumentType := self arguments ifEmpty: [nil] ifNotEmpty: [#unknown]. + resultType := #unkown. + phrase := PhraseTileMorph new. + phrase + setOperator: self selector key + type: resultType + rcvrType: receiverType + argType: argumentType. + receiverTiles := self receiver asTileSetForPlayer: aPlayer. + receiverTiles size = 1 ifFalse: [^ self convertToTileError]. + phrase firstSubmorph + addMorph: receiverTiles first; + hResizing: #shrinkWrap; vResizing: #shrinkWrap. + self arguments ifNotEmpty: [ | argumentTiles | + argumentTiles := self arguments first asTileSetForPlayer: aPlayer. + argumentTiles size = 1 ifFalse: [^ self convertToTileError]. + phrase lastSubmorph + setType: argumentType; + addMorph: argumentTiles first; + hResizing: #shrinkWrap; vResizing: #shrinkWrap]. + ^ phrase + hResizing: #shrinkWrap; vResizing: #shrinkWrap; + yourself! Item was added: + ----- Method: MessageNode>>ifConditionNormalizeAndDo: (in category '*Etoys-tiles') ----- + ifConditionNormalizeAndDo: aBlock + + | blocks | + blocks := self selector key + caseOf: { + [#ifTrue:ifFalse:] -> [arguments]. + [#ifFalse:ifTrue:] -> [self arguments reversed]. + [#ifTrue:] -> [self arguments copyWith: BlockNode new]. + [#ifFalse:] -> [self arguments copyWithFirst: BlockNode new] } + otherwise: [^ self]. + ^ aBlock value: self receiver value: blocks first value: blocks last! Item was added: + ----- Method: MethodNode>>asScriptEditorFor: (in category '*Etoys-tiles') ----- + asScriptEditorFor: aPlayer + + | editor | + editor := ScriptEditorMorph new. + editor + playerScripted: aPlayer; + setMorph: aPlayer costume scriptName: self selector. + (self asTileSetForPlayer: aPlayer) + withIndexDo: [:tile :index | + editor insertTileRow: {tile} after: index]. + editor + removeSpaces; + enforceTileColorPolicy; + fullBounds; + scriptEdited; + allMorphsDo: #layoutChanged. + ^ editor! Item was added: + ----- Method: MethodNode>>asTileSetForPlayer: (in category '*Etoys-tiles') ----- + asTileSetForPlayer: aPlayer + + ^ self block withoutImplicitReturns asTileSetForPlayer: aPlayer! Item was added: + ----- Method: MethodTempsNode>>asTileSetForPlayer: (in category '*Etoys-tiles') ----- + asTileSetForPlayer: aPlayer + + ^ #()! Item was added: + ----- Method: ParseNode>>asStatementTileSetForPlayer: (in category '*Etoys-tiles') ----- + asStatementTileSetForPlayer: aPlayer + + ^ self convertToTileError! Item was added: + ----- Method: ParseNode>>asTileForPlayer: (in category '*Etoys-tiles') ----- + asTileForPlayer: aPlayer + "Private. Better call #asTileMorphsForPlayer:." + + ^ self convertToTileError! Item was added: + ----- Method: ParseNode>>asTileSetForPlayer: (in category '*Etoys-tiles') ----- + asTileSetForPlayer: aPlayer + + ^ {self asTileForPlayer: aPlayer}! Item was added: + ----- Method: ParseNode>>convertToTileError (in category '*Etoys-tiles') ----- + convertToTileError + + ^ self error: 'Cannot convert this expression to a tile'! Item was added: + ----- Method: ReturnNode>>asTileSetForPlayer: (in category '*Etoys-tiles') ----- + asTileSetForPlayer: aPlayer + + "self isReturnSelf ifTrue: [^ #()]." + ^ self expr asTileSetForPlayer: aPlayer! Item was added: + ----- Method: VariableNode>>asTileForPlayer: (in category '*Etoys-tiles') ----- + asTileForPlayer: aPlayer + + | target | + self isSelfPseudoVariable + ifTrue: [^ aPlayer tileToRefer]. + target := self key isVariableBinding + ifTrue: [aPlayer environment at: self key key] + ifFalse: [self key]. + ^ TileMorph new + setToReferTo: target; + yourself! From commits at source.squeak.org Thu Feb 18 13:32:12 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:32:12 0000 Subject: [squeak-dev] The Trunk: EToys-ct.368.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-ct.368.mcz ==================== Summary ==================== Name: EToys-ct.368 Author: ct Time: 15 October 2019, 2:57:44.969129 pm UUID: a02688f9-acfd-4240-a068-bdb24539e268 Ancestors: EToys-ct.366 Changes "revert to tile version" behavior in script editor: Instead of discarding the changed code, always use the new approach and convert the decompiled code back to tiles. =============== Diff against EToys-ct.366 =============== Item was added: + ----- Method: MethodWithInterface>>revertTileVersionFrom:for: (in category 'updating') ----- + revertTileVersionFrom: anEditor for: playerScripted + "Only for universal tiles." + + anEditor removeAllButFirstSubmorph. + anEditor insertUniversalTiles. + anEditor showingMethodPane: false! Item was changed: ----- Method: ScriptEditorMorph>>revertToTileVersion (in category 'save & revert') ----- revertToTileVersion "The receiver, currently showing textual code, is asked to revert to the last-saved tile version" | aUserScript | self hResizing: #shrinkWrap; vResizing: #shrinkWrap. aUserScript := playerScripted class userScriptForPlayer: playerScripted selector: scriptName. + aUserScript revertTileVersionFrom: self for: playerScripted. - aUserScript revertToLastSavedTileVersionFor: self. self currentWorld startSteppingSubmorphsOf: self! Item was changed: ----- Method: ScriptEditorMorph>>toggleWhetherShowingTiles (in category 'other') ----- toggleWhetherShowingTiles "Toggle between showing the method pane and showing the tiles pane" self showingMethodPane ifFalse: "currently showing tiles" [self showSourceInScriptor] + ifTrue: "currently showing textual source" + [self revertToTileVersion]! - - ifTrue: "current showing textual source" - [Preferences universalTiles - ifTrue: [^ self revertToTileVersion]. - self savedTileVersionsCount >= 1 - ifTrue: - [(self userScriptObject lastSourceString = (playerScripted class sourceCodeAt: scriptName)) - ifFalse: - [(self confirm: - 'Caution -- this script was changed - textually; if you revert to tiles at this - point you will lose all the changes you - may have made textually. Do you - really want to do this?' translated) ifFalse: [^ self]]. - self revertToTileVersion] - ifFalse: - [Beeper beep]]! Item was added: + ----- Method: UniclassScript>>revertTileVersionFrom:for: (in category 'updating') ----- + revertTileVersionFrom: anEditor for: playerScripted + + anEditor removeAllButFirstSubmorph. + Preferences universalTiles + ifFalse: [ + ((self playerClass >> self selector) decompile asTileSetForPlayer: playerScripted) + withIndexDo: [:tile :index | + anEditor insertTileRow: {tile} after: index]. + anEditor allMorphsDo: #layoutChanged] + ifTrue: [ + anEditor insertUniversalTiles]. + anEditor showingMethodPane: false. + isTextuallyCoded := false.! Item was added: + ----- Method: UserScript>>revertTileVersionFrom:for: (in category 'versions') ----- + revertTileVersionFrom: anEditor for: playerScripted + + anEditor removeAllButFirstSubmorph. + ((self playerClass >> self selector) decompile asTileSetForPlayer: playerScripted) + withIndexDo: [:tile :index | + anEditor insertTileRow: {tile} after: index]. + anEditor allMorphsDo: #layoutChanged. + anEditor showingMethodPane: false. + self becomeTextuallyCoded.! From commits at source.squeak.org Thu Feb 18 13:32:19 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:32:19 0000 Subject: [squeak-dev] The Trunk: EToys-ct.369.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-ct.369.mcz ==================== Summary ==================== Name: EToys-ct.369 Author: ct Time: 15 October 2019, 9:56:30.25283 pm UUID: 0328de9a-3f0f-fb44-a8d9-12b8bee91796 Ancestors: EToys-ct.366 Refines conversion of MessageNodes into test tiles: Don't fill empty cases with "nil" =============== Diff against EToys-ct.366 =============== Item was changed: ----- Method: BlockNode>>withoutImplicitReturns (in category '*Etoys-tiles') ----- withoutImplicitReturns + (self statements ifEmpty: [^ self]) last isImplicitReturn - (self statements ifEmpty: [^ self]) last isReturnSelf ifFalse: [^ self]. ^ self copy statements: self statements allButLast! Item was changed: ----- Method: MessageNode>>asTileForPlayer: (in category '*Etoys-tiles') ----- asTileForPlayer: aPlayer | receiverType argumentType resultType phrase receiverTiles | "Catch edge case: Color tile" (self receiver isVariableNode and: [self receiver key = (Smalltalk bindingOf: #Color)]) ifTrue: [ | source result | source := String streamContents: (MessageSend receiver: self selector: #shortPrintOn:). result := [Compiler evaluate: source] ifError: [nil]. result isColor ifTrue: [^ result newTileMorphRepresentative]]. "Catch edge case: Test tile" self ifConditionNormalizeAndDo: [:conditionNode :trueNode :falseNode | | compound | compound := StandardScriptingSystem new yesNoComplexOfTiles. compound testPart insertTileRow: (conditionNode asTileSetForPlayer: aPlayer) after: 0. + compound yesPart insertTileRow: (trueNode withoutImplicitReturns asTileSetForPlayer: aPlayer) after: 0. + compound noPart insertTileRow: (falseNode withoutImplicitReturns asTileSetForPlayer: aPlayer) after: 0. - compound yesPart insertTileRow: (trueNode asTileSetForPlayer: aPlayer) after: 0. - compound noPart insertTileRow: (falseNode asTileSetForPlayer: aPlayer) after: 0. compound enforceTileColorPolicy; layoutChanged; fullBounds. ^ compound]. "Otherwise, try to build a phrase tile" self arguments size < 2 ifFalse: [^ self convertToTileError]. receiverType := #unknown. argumentType := self arguments ifEmpty: [nil] ifNotEmpty: [#unknown]. resultType := #unkown. phrase := PhraseTileMorph new. phrase setOperator: self selector key type: resultType rcvrType: receiverType argType: argumentType. receiverTiles := self receiver asTileSetForPlayer: aPlayer. receiverTiles size = 1 ifFalse: [^ self convertToTileError]. phrase firstSubmorph addMorph: receiverTiles first; hResizing: #shrinkWrap; vResizing: #shrinkWrap. self arguments ifNotEmpty: [ | argumentTiles | argumentTiles := self arguments first asTileSetForPlayer: aPlayer. argumentTiles size = 1 ifFalse: [^ self convertToTileError]. phrase lastSubmorph setType: argumentType; addMorph: argumentTiles first; hResizing: #shrinkWrap; vResizing: #shrinkWrap]. ^ phrase hResizing: #shrinkWrap; vResizing: #shrinkWrap; yourself! Item was changed: ----- Method: MessageNode>>ifConditionNormalizeAndDo: (in category '*Etoys-tiles') ----- ifConditionNormalizeAndDo: aBlock | blocks | blocks := self selector key caseOf: { [#ifTrue:ifFalse:] -> [arguments]. [#ifFalse:ifTrue:] -> [self arguments reversed]. + [#ifTrue:] -> [self arguments copyWith: (BlockNode statements: #() returns: #())]. + [#ifFalse:] -> [self arguments copyWithFirst: (BlockNode statements: #() returns: #())] } - [#ifTrue:] -> [self arguments copyWith: BlockNode new]. - [#ifFalse:] -> [self arguments copyWithFirst: BlockNode new] } otherwise: [^ self]. ^ aBlock value: self receiver value: blocks first value: blocks last! Item was added: + ----- Method: ParseNode>>isImplicitReturn (in category '*Etoys-tiles') ----- + isImplicitReturn + + ^false! Item was added: + ----- Method: ReturnNode>>isImplicitReturn (in category '*Etoys-tiles') ----- + isImplicitReturn + + ^ self isReturnSelf! Item was added: + ----- Method: VariableNode>>isImplicitReturn (in category '*Etoys-tiles') ----- + isImplicitReturn + + ^ self = NodeNil! From commits at source.squeak.org Thu Feb 18 13:32:25 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:32:25 0000 Subject: [squeak-dev] The Trunk: EToys-ct.370.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-ct.370.mcz ==================== Summary ==================== Name: EToys-ct.370 Author: ct Time: 15 October 2019, 10:00:31.84083 pm UUID: 8acf5f1b-6545-1146-b173-821ef32c3322 Ancestors: EToys-ct.369 Tests conversion between ParseNodes and tiles =============== Diff against EToys-ct.369 =============== Item was added: + TestCase subclass: #ScriptEditorMorphTest + instanceVariableNames: 'editor minimalMethod player' + classVariableNames: '' + poolDictionaries: '' + category: 'Etoys-Tests'! Item was added: + ----- Method: ScriptEditorMorphTest>>exampleMinimalPlayerCode (in category 'accessing') ----- + exampleMinimalPlayerCode + + self forward: 6 * 7. + self turn: 6. + self forward: 7. + self getIsUnderMouse ifFalse: [self abandon]. + "self color: (Color r: 1 g: 0.6 b: 0). + [[''''''''] cull: 42] onDNU: #foo do: #ba."! Item was added: + ----- Method: ScriptEditorMorphTest>>examplePlayerCode (in category 'accessing') ----- + examplePlayerCode + + self forward: 6 * 7. + self + turn: 6; + forward: 7. + self getIsUnderMouse ifFalse: [self abandon]. + "self color: (Color fromString: '#ff9900'). + [[''''''''] cull: 42] onDNU: #foo do: #ba."! Item was added: + ----- Method: ScriptEditorMorphTest>>setUp (in category 'running') ----- + setUp + + super setUp. + + player := Morph new assuredPlayer. + minimalMethod := (self class lookupSelector: #exampleMinimalPlayerCode) decompile.! Item was added: + ----- Method: ScriptEditorMorphTest>>tearDown (in category 'running') ----- + tearDown + + [editor ifNotNil: #destroyScript] valueSuppressingMessages: #('*destroy*'). + super tearDown.! Item was added: + ----- Method: ScriptEditorMorphTest>>testCodeToTileAndBack (in category 'testing') ----- + testCodeToTileAndBack + + | templateMethod | + templateMethod := (self class lookupSelector: #examplePlayerCode) decompile. + editor := templateMethod asScriptEditorFor: player. + self + assert: minimalMethod block printString + equals: (player class lookupSelector: #examplePlayerCode) decompile block printString! Item was added: + ----- Method: ScriptEditorMorphTest>>testMinimalCodeToTileAndBack (in category 'testing') ----- + testMinimalCodeToTileAndBack + + editor := minimalMethod asScriptEditorFor: player. + self + assert: minimalMethod block printString + equals: (player class lookupSelector: #exampleMinimalPlayerCode) decompile block printString.! From commits at source.squeak.org Thu Feb 18 13:32:32 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:32:32 0000 Subject: [squeak-dev] The Trunk: EToys-ct.390.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-ct.390.mcz ==================== Summary ==================== Name: EToys-ct.390 Author: ct Time: 27 March 2020, 9:39:10.801235 pm UUID: d54c1d9b-6381-784b-8a2d-497804eab2a7 Ancestors: EToys-eem.388 Refines parsing of SyntaxMorphs, respecting asStatement: aBoolean If a statement is requested, don't return the whole method to avoid nested methods. Also cleans up ScriptEditorMorph >> #parseNodeWith: (strengthening polymorphy). =============== Diff against EToys-eem.388 =============== Item was changed: ----- Method: ScriptEditorMorph>>parseNodeWith: (in category '*Etoys-Squeakland-other') ----- parseNodeWith: encoder | statements ret | statements := WriteStream on: (Array new: self tileRows size). + self tileRows do: [:row | + row do: [:morph | + (morph respondsTo: #parseNodeWith:asStatement:) ifTrue: [ + statements nextPut: (morph parseNodeWith: encoder asStatement: true)]]]. - self tileRows do: [:r | - r do: [:m | - ((m isKindOf: TileMorph) - or: [(m isKindOf: CompoundTileMorph) - or: [m isKindOf: PhraseTileMorph]]) ifTrue: [ - statements nextPut: (m parseNodeWith: encoder asStatement: true)]]]. statements := statements contents. ret := ReturnNode new expr: (encoder encodeVariable: 'self'). + ^ BlockNode new + arguments: #() + statements: (statements copyWith: ret) + returns: true + from: encoder.! - ^ BlockNode new arguments: #() statements: (statements copyWith: ret) returns: true from: encoder. - ! Item was changed: ----- Method: SyntaxMorph>>parseNodeWith:asStatement: (in category '*Etoys-Squeakland-code generation') ----- parseNodeWith: encoder asStatement: aBoolean + | methodNode | + methodNode := self parseNodeWith: encoder. + ^ aBoolean + ifFalse: [methodNode] + ifTrue: [methodNode block]! - ^ self parseNode! From commits at source.squeak.org Thu Feb 18 13:32:39 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 13:32:39 0000 Subject: [squeak-dev] The Trunk: EToys-ct.404.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-ct.404.mcz ==================== Summary ==================== Name: EToys-ct.404 Author: ct Time: 17 September 2020, 12:08:06.252813 pm UUID: d9eaf56f-8f92-314a-91b7-f15e0b463c55 Ancestors: EToys-eem.400 Refactors new parse node to tile conversion and revises editor menu intergration. Minor refactorings: Method splitting, renaming, and some typo and layout fixes. Keeps depending on EToys-ct.366, EToys-ct.368, EToys-ct.369, EToys-ct.370, EToys-ct.389, EToys-ct.390. Sorry for the cluttered ancestry, for the next project, I will really use changesets! =============== Diff against EToys-eem.400 =============== Item was added: + ----- Method: MessageNode>>asTileForPlayer: (in category '*Etoys-tiles') ----- + asTileForPlayer: aPlayer + + | receiverType argumentType resultType phrase receiverTiles | + "Catch edge case: Color tile" + (self receiver isVariableNode and: [self receiver key = (Smalltalk bindingOf: #Color)]) + ifTrue: [ | source result | + source := String streamContents: (MessageSend receiver: self selector: #shortPrintOn:). + result := [Compiler evaluate: source] ifError: [nil]. + result isColor ifTrue: [^ result newTileMorphRepresentative]]. + + "Catch edge case: Test tile" + self ifConditionNormalizeAndDo: [:conditionNode :trueNode :falseNode | | compound | + compound := StandardScriptingSystem new yesNoComplexOfTiles. + compound testPart insertTileRow: (conditionNode asTileSetForPlayer: aPlayer) after: 0. + compound yesPart insertTileRow: (trueNode withoutImplicitReturns asTileSetForPlayer: aPlayer) after: 0. + compound noPart insertTileRow: (falseNode withoutImplicitReturns asTileSetForPlayer: aPlayer) after: 0. + compound enforceTileColorPolicy; layoutChanged; fullBounds. + ^ compound]. + + "Otherwise, try to build a phrase tile" + self arguments size < 2 ifFalse: [^ self convertToTileError]. + + receiverType := #unknown. + argumentType := self arguments ifEmpty: [nil] ifNotEmpty: [#unknown]. + resultType := #unknown. + phrase := PhraseTileMorph new. + phrase + setOperator: self selector key + type: resultType + rcvrType: receiverType + argType: argumentType. + receiverTiles := self receiver asTileSetForPlayer: aPlayer. + receiverTiles size = 1 ifFalse: [^ self convertToTileError]. + phrase firstSubmorph + addMorph: receiverTiles first; + hResizing: #shrinkWrap; vResizing: #shrinkWrap. + self arguments ifNotEmpty: [ | argumentTiles | + argumentTiles := self arguments first asTileSetForPlayer: aPlayer. + argumentTiles size = 1 ifFalse: [^ self convertToTileError]. + phrase lastSubmorph + setType: argumentType; + changeTableLayout; + addMorph: argumentTiles first; + hResizing: #shrinkWrap; vResizing: #shrinkWrap]. + + ^ phrase + hResizing: #shrinkWrap; vResizing: #shrinkWrap; + yourself! Item was added: + ----- Method: MethodNode>>asScriptEditorFor: (in category '*Etoys-tiles') ----- + asScriptEditorFor: aPlayer + + | editor | + editor := ScriptEditorMorph new. + editor + playerScripted: aPlayer; + setMorph: aPlayer costume scriptName: self selector. + + (self asTileSetForPlayer: aPlayer) + withIndexDo: [:tile :index | + editor insertTileRow: {tile} after: index]. + editor + removeSpaces; + enforceTileColorPolicy; + scriptEdited; + allMorphsDo: #layoutChanged. + ^ editor! Item was added: + ----- Method: MethodWithInterface>>revertTileVersionFrom:for: (in category 'updating') ----- + revertTileVersionFrom: anEditor for: playerScripted + "Only for universal tiles." + + ^ self revertToLastSavedTileVersionFor: anEditor! Item was added: + ----- Method: ScriptEditorMorph>>convertToTileVersion (in category 'save & revert') ----- + convertToTileVersion + "The receiver, currently showing textual code, is asked to revert to the last-saved tile version" + + | aUserScript | + + self + hResizing: #shrinkWrap; + vResizing: #shrinkWrap. + aUserScript := playerScripted class userScriptForPlayer: playerScripted selector: scriptName. + aUserScript revertTileVersionFrom: self for: playerScripted. + self currentWorld startSteppingSubmorphsOf: self! Item was changed: ----- Method: ScriptEditorMorph>>offerScriptorMenu (in category 'other') ----- offerScriptorMenu "Put up a menu in response to the user's clicking in the menu-request area of the scriptor's heaer" | aMenu count | - self modernize. ActiveHand showTemporaryCursor: nil. + - Preferences eToyFriendly ifTrue: [^ self offerSimplerScriptorMenu]. + - aMenu := MenuMorph new defaultTarget: self. aMenu addTitle: scriptName asString. aMenu addStayUpItem. "NB: the kids version in #offerSimplerScriptorMenu does not deploy the stay-up item" + - aMenu addList: (self hasParameter ifTrue: [{ {'remove parameter' translated. #ceaseHavingAParameter}}] ifFalse: [{ {'add parameter' translated. #addParameter}}]). self hasParameter ifFalse: [aMenu addTranslatedList: { {'button to fire this script' translatedNoop. #tearOfButtonToFireScript}. {'fires per tick...' translatedNoop. #chooseFrequency}. #- }]. + + aMenu addUpdating: #showingCaretsString target: self action: #toggleShowingCarets. - - aMenu addUpdating: #showingCaretsString target: self action: #toggleShowingCarets. aMenu addLine. aMenu addList: { {'edit balloon help for this script' translated. #editMethodDescription}. {'explain status alternatives' translated. #explainStatusAlternatives}. {'button to show/hide this script' translated. #buttonToOpenOrCloseThisScript}. #- }. + + Preferences universalTiles ifFalse: [ + count := self savedTileVersionsCount. - - - Preferences universalTiles ifFalse: - [count := self savedTileVersionsCount. self showingMethodPane + ifFalse: [ "currently showing tiles" + aMenu add: 'show code textually' translated action: #showSourceInScriptor. + count > 0 ifTrue: [ + aMenu add: 'revert to tile version...' translated action: #revertScriptVersion]. + aMenu add: 'save this version' translated action: #saveScriptVersion ] + ifTrue: [ "current showing textual source" + aMenu add: 'convert to tile version' translated action: #toggleWhetherShowingTiles. + count > 0 ifTrue: + [aMenu add: 'revert to tile version...' translated action: #revertScriptVersion]] ]. + - ifFalse: "currently showing tiles" - [aMenu add: 'show code textually' translated action: #toggleWhetherShowingTiles. - count > 0 ifTrue: - [aMenu add: 'revert to tile version...' translated action: #revertScriptVersion]. - aMenu add: 'save this version' translated action: #saveScriptVersion] - - ifTrue: "current showing textual source" - [count >= 1 ifTrue: - [aMenu add: 'revert to tile version' translated action: #toggleWhetherShowingTiles]]]. - "aMenu addLine. self addGoldBoxItemsTo: aMenu." + - aMenu addLine. aMenu add: 'grab this object' translated target: playerScripted selector: #grabPlayerIn: argument: ActiveWorld. aMenu balloonTextForLastItem: 'This will actually pick up the object bearing this script and hand it to you. Click the (left) button to drop it' translated. + - aMenu add: 'reveal this object' translated target: playerScripted selector: #revealPlayerIn: argument: ActiveWorld. aMenu balloonTextForLastItem: 'If you have misplaced the object bearing this script, use this item to (try to) make it visible' translated. + - aMenu add: 'tile representing this object' translated target: playerScripted action: #tearOffTileForSelf. aMenu balloonTextForLastItem: 'choose this to obtain a tile which represents the object associated with this script' translated. + - aMenu addTranslatedList: { #-. {'open viewer' translatedNoop. #openObjectsViewer. 'open the viewer of the object to which this script belongs' translatedNoop}. {'detached method pane' translatedNoop. #makeIsolatedCodePane. 'open a little window that shows the Smalltalk code underlying this script.' translatedNoop}. #-. {'destroy this script' translatedNoop. #destroyScript} }. + + aMenu popUpInWorld: self currentWorld.! - - - aMenu popUpInWorld: self currentWorld. - ! Item was removed: - ----- Method: ScriptEditorMorph>>revertToTileVersion (in category 'save & revert') ----- - revertToTileVersion - "The receiver, currently showing textual code, is asked to revert to the last-saved tile version" - - | aUserScript | - - self - hResizing: #shrinkWrap; - vResizing: #shrinkWrap. - aUserScript := playerScripted class userScriptForPlayer: playerScripted selector: scriptName. - aUserScript revertToLastSavedTileVersionFor: self. - self currentWorld startSteppingSubmorphsOf: self! Item was changed: ----- Method: ScriptEditorMorph>>toggleWhetherShowingTiles (in category 'other') ----- toggleWhetherShowingTiles "Toggle between showing the method pane and showing the tiles pane" + - self showingMethodPane + ifFalse: [ "currently showing tiles" + self showSourceInScriptor ] + ifTrue: [ "currently showing textual source" + self convertToTileVersion ].! - ifFalse: "currently showing tiles" - [self showSourceInScriptor] - - ifTrue: "current showing textual source" - [Preferences universalTiles - ifTrue: [^ self revertToTileVersion]. - self savedTileVersionsCount >= 1 - ifTrue: - [(self userScriptObject lastSourceString = (playerScripted class sourceCodeAt: scriptName)) - ifFalse: - [(self confirm: - 'Caution -- this script was changed - textually; if you revert to tiles at this - point you will lose all the changes you - may have made textually. Do you - really want to do this?' translated) ifFalse: [^ self]]. - self revertToTileVersion] - ifFalse: - [Beeper beep]]! Item was added: + ----- Method: UserScript>>revertTileVersionFrom:for: (in category 'versions') ----- + revertTileVersionFrom: anEditor for: playerScripted + + anEditor removeAllButFirstSubmorph. + ((self playerClass >> self selector) decompile asTileSetForPlayer: playerScripted) + withIndexDo: [:tile :index | + anEditor insertTileRow: {tile} after: index]. + anEditor allMorphsDo: #layoutChanged. + anEditor showingMethodPane: false. + self becomeTextuallyCoded.! From marcel.taeumel at hpi.de Thu Feb 18 14:04:25 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Thu, 18 Feb 2021 15:04:25 +0100 Subject: [squeak-dev] thisContext method ... can answer a compiled block Message-ID: Hi all -- Looking at the implementation of CompiledBlock >> #method and CompiledMethod >> #method, I wonder whether the implementation of Context >> #method is correct. What should be the answer of    [ thisContext method ] value An instance of CompiledMethod or an instance of CompiledBlock? If the latter is okay, then "thisContext method method" would be the necessary idiom to support lookup in the underlying behavior. Best, Marcel -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Thu Feb 18 15:07:46 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 15:07:46 0000 Subject: [squeak-dev] The Trunk: Graphics-mt.446.mcz Message-ID: Marcel Taeumel uploaded a new version of Graphics to project The Trunk: http://source.squeak.org/trunk/Graphics-mt.446.mcz ==================== Summary ==================== Name: Graphics-mt.446 Author: mt Time: 18 February 2021, 4:07:36.927082 pm UUID: 7970ec57-0257-ff4c-a2e3-13d3e06d4807 Ancestors: Graphics-dtl.445 Adds new version for LayoutFrame to be able to convert old versions with 'nil' fields. =============== Diff against Graphics-dtl.445 =============== Item was changed: ----- Method: LayoutFrame class>>classVersion (in category 'accessing') ----- classVersion + ^ 2 "fractions and offsets are never 'nil' anymore" - ^1 "changed treatment of bottomOffset and rightOffset" ! Item was added: + ----- Method: LayoutFrame class>>withClassVersion: (in category 'objects from disk') ----- + withClassVersion: aVersion + + aVersion <= self classVersion ifTrue: [^ self]. + ^ super withClassVersion: aVersion! Item was changed: ----- Method: LayoutFrame>>convertToCurrentVersion:refStream: (in category 'objects from disk') ----- convertToCurrentVersion: varDict refStream: smartRefStrm | className oldClassVersion | "JW 2/1/2001" "Since class version isn't passed in varDict, look it up through smartRefSrm." className := varDict at: #ClassName. oldClassVersion := (smartRefStrm structures at: className) first. + (oldClassVersion = 0) ifTrue: [ self negateBottomRightOffsets; fixup ]. + (oldClassVersion = 1) ifTrue: [ self fixup ]. - (oldClassVersion = 0) ifTrue: [ self negateBottomRightOffsets ]. ^super convertToCurrentVersion: varDict refStream: smartRefStrm. ! Item was changed: + ----- Method: LayoutFrame>>fixup (in category 'objects from disk') ----- - ----- Method: LayoutFrame>>fixup (in category 'initialize-release') ----- fixup "Set-up default value for un-initialized layout frames" "LayoutFrame allInstancesDo: [:e | e fixup]." leftFraction ifNil: [leftFraction := 0]. leftOffset ifNil: [leftOffset := 0]. topFraction ifNil: [topFraction := 0]. topOffset ifNil: [topOffset := 0]. rightFraction ifNil: [rightFraction := 0]. rightOffset ifNil: [rightOffset := 0]. bottomFraction ifNil: [bottomFraction := 0]. bottomOffset ifNil: [bottomOffset := 0].! From commits at source.squeak.org Thu Feb 18 15:13:56 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 15:13:56 0000 Subject: [squeak-dev] The Trunk: EToys-mt.423.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-mt.423.mcz ==================== Summary ==================== Name: EToys-mt.423 Author: mt Time: 18 February 2021, 4:13:47.008082 pm UUID: ce09c0e8-7fc5-ba41-95c8-0dd8a987d38e Ancestors: EToys-mt.422 Support CompiledBlock in error reports. Merges forgotten fix from Etoys 5 to make StandardViewer >> #addHeaderMorphWithBarHeight:includeDismissButton: work again, in case you got costumes. =============== Diff against EToys-mt.422 =============== Item was changed: ----- Method: AlignmentMorph>>addUpDownArrowsFor: (in category '*Etoys-initialization') ----- addUpDownArrowsFor: aMorph "Add a column of up and down arrows that serve to send upArrowHit and downArrowHit to aMorph when they're pressed/held down" + | downArrow upArrow | + (TileMorph addArrowsOn: self) + in: [:array | + upArrow := array first. + downArrow := array second]. - | holder downArrow upArrow | - holder := Morph new extent: 16 @ 16; beTransparent. - downArrow := ImageMorph new image: (ScriptingSystem formAtKey: 'DownArrow'). - upArrow := ImageMorph new image: (ScriptingSystem formAtKey: 'UpArrow'). - upArrow position: holder bounds topLeft + (2 @ 2). - downArrow align: downArrow bottomLeft - with: holder topLeft + (0 @ TileMorph defaultH) + (2 @ -2). - holder addMorph: upArrow. - holder addMorph: downArrow. - self addMorphBack: holder. upArrow on: #mouseDown send: #upArrowHit to: aMorph. upArrow on: #mouseStillDown send: #upArrowHit to: aMorph. downArrow on: #mouseDown send: #downArrowHit to: aMorph. downArrow on: #mouseStillDown send: #downArrowHit to: aMorph.! Item was changed: ----- Method: StandardScriptingSystem>>reportToUser: (in category '*Etoys-utilities') ----- reportToUser: aString "Make a message accessible to the user. " | trigger current baseTriggerer topTriggerer mclass sel topSelector | trigger := Player compiledMethodAt: #triggerScript:. current := thisContext. baseTriggerer := nil. topTriggerer := nil. [current notNil] whileTrue: [ topTriggerer ifNil: [ current receiver class isUniClass ifTrue: [ "Look for the top-most uniclass script in the call chain." + sel := current receiver class selectorAtMethod: current method "aCompiledBlock" method setClass: [:c | mclass := c]. - sel := current receiver class selectorAtMethod: current method setClass: [:c | mclass := c]. mclass = current receiver class ifTrue: [ topTriggerer := current. topSelector := sel. ]. ]. ]. (current method = trigger and: [current isExecutingBlock not]) ifTrue: [ "Look for the bottom-most #triggerScript: and its selector." baseTriggerer := current ]. current := current sender. ]. baseTriggerer ifNotNil: [ (baseTriggerer receiver scriptInstantiationForSelector: (baseTriggerer at: 1)) resetTo: #paused ifCurrently: #ticking. ]. (topTriggerer notNil and: [topSelector notNil]) ifTrue: [ ^ self eToysError: aString, '\', topTriggerer receiver knownName, '\', topSelector. ]. self error: aString! From commits at source.squeak.org Thu Feb 18 15:54:08 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 15:54:08 0000 Subject: [squeak-dev] The Trunk: System-mt.1218.mcz Message-ID: Marcel Taeumel uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-mt.1218.mcz ==================== Summary ==================== Name: System-mt.1218 Author: mt Time: 18 February 2021, 4:54:03.4367 pm UUID: 1cbfb74f-d6b3-6c49-986a-c17bb1760d43 Ancestors: System-mt.1217 Removes dependency of System from EToys with a pragma-based extension. =============== Diff against System-mt.1217 =============== Item was changed: ----- Method: ImageSegment>>comeFullyUpOnReload: (in category 'fileIn') ----- comeFullyUpOnReload: smartRefStream "fix up the objects in the segment that changed size. An object in the segment is the wrong size for the modern version of the class. Construct a fake class that is the old size. Replace the modern class with the old one in outPointers. Load the segment. Traverse the instances, making new instances by copying fields, and running conversion messages. Keep the new instances. Bulk forward become the old to the new. Let go of the fake objects and classes. After the install (below), arrayOfRoots is filled in. Globalize new classes. Caller may want to do some special install on certain objects in arrayOfRoots. May want to write the segment out to disk in its new form." + | mapFakeClassesToReal receiverClasses existing forgetDoItsClass endianness | - | mapFakeClassesToReal receiverClasses rootsToUnhiberhate myProject existing forgetDoItsClass endianness | forgetDoItsClass := Set new. RecentlyRenamedClasses := nil. "in case old data hanging around" mapFakeClassesToReal := smartRefStream reshapedClassesIn: outPointers. "Dictionary of just the ones that change shape. Substitute them in outPointers." self fixCapitalizationOfSymbols. endianness := self endianness. segment := self loadSegmentFrom: segment outPointers: outPointers. arrayOfRoots := segment first. mapFakeClassesToReal isEmpty ifFalse: [ self reshapeClasses: mapFakeClassesToReal refStream: smartRefStream ]. "When a Project is stored, arrayOfRoots has all objects in the project, except those in outPointers" arrayOfRoots do: [:importedObject | ((importedObject isMemberOf: WideString) or: [importedObject isMemberOf: WideSymbol]) ifTrue: [ importedObject mutateJISX0208StringToUnicode. importedObject class = WideSymbol ifTrue: [ "self halt." Symbol hasInterned: importedObject asString ifTrue: [:multiSymbol | multiSymbol == importedObject ifFalse: [ importedObject becomeForward: multiSymbol. ]. ]. ]. ]. (importedObject isMemberOf: TTCFontSet) ifTrue: [ existing := TTCFontSet familyName: importedObject familyName pointSize: importedObject pointSize. "supplies default" existing == importedObject ifFalse: [importedObject becomeForward: existing]. ]. ]. receiverClasses := self restoreEndianness: endianness ~~ Smalltalk endianness. "rehash sets" smartRefStream checkFatalReshape: receiverClasses. "Classes in this segment." arrayOfRoots do: [:importedObject | importedObject class class == Metaclass ifTrue: [forgetDoItsClass add: importedObject. self declare: importedObject]]. - rootsToUnhiberhate := OrderedCollection new. - arrayOfRoots do: [:importedObject | - ((importedObject isMemberOf: ScriptEditorMorph) - or: [(importedObject isKindOf: TileMorph) - or: [(importedObject isMemberOf: ScriptingTileHolder) - or: [importedObject isKindOf: CompoundTileMorph]]]) ifTrue: [ - rootsToUnhiberhate add: importedObject - ]. - (importedObject isMemberOf: Project) ifTrue: [ - myProject := importedObject. - importedObject ensureChangeSetNameUnique. - Project addingProject: importedObject. - importedObject restoreReferences. - self dependentsRestore: importedObject. - ScriptEditorMorph writingUniversalTiles: - ((importedObject projectPreferenceAt: #universalTiles) ifNil: [false])]]. + "Let all extensions work with the current arrayOfRoots." + self processRoots. - myProject ifNotNil: [ - myProject world setProperty: #thingsToUnhibernate toValue: rootsToUnhiberhate asArray. - ]. mapFakeClassesToReal isEmpty ifFalse: [ mapFakeClassesToReal keysAndValuesDo: [:aFake :aReal | aFake removeFromSystemUnlogged. aFake becomeForward: aReal]. SystemOrganization removeEmptyCategories]. forgetDoItsClass do: [:c | self forgetDoItsInClass: c]. "^ self" ! Item was added: + ----- Method: ImageSegment>>processRoots (in category 'fileIn') ----- + processRoots + + ImageSegment methodsDo: [:method | + (method hasPragma: #rootsEnumerator) ifTrue: [ + self executeMethod: method]].! From commits at source.squeak.org Thu Feb 18 15:54:48 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 15:54:48 0000 Subject: [squeak-dev] The Trunk: EToys-mt.424.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-mt.424.mcz ==================== Summary ==================== Name: EToys-mt.424 Author: mt Time: 18 February 2021, 4:54:40.1357 pm UUID: 1ed13291-c689-614e-948b-4b4187c84f6d Ancestors: EToys-mt.423 Complements System-mt.1218 =============== Diff against EToys-mt.423 =============== Item was added: + ----- Method: ImageSegment>>eToysCollectThingsToUnhibernate (in category '*Etoys-Object Storage') ----- + eToysCollectThingsToUnhibernate + + + | rootsToUnhiberhate myProject | + rootsToUnhiberhate := OrderedCollection new. + arrayOfRoots do: [:importedObject | + ((importedObject isMemberOf: ScriptEditorMorph) + or: [(importedObject isKindOf: TileMorph) + or: [(importedObject isMemberOf: ScriptingTileHolder) + or: [importedObject isKindOf: CompoundTileMorph]]]) ifTrue: [ + rootsToUnhiberhate add: importedObject + ]. + (importedObject isMemberOf: Project) ifTrue: [ + myProject := importedObject. + importedObject ensureChangeSetNameUnique. + Project addingProject: importedObject. + importedObject restoreReferences. + self dependentsRestore: importedObject. + ScriptEditorMorph writingUniversalTiles: + ((importedObject projectPreferenceAt: #universalTiles) ifNil: [false])]]. + + myProject ifNotNil: [ + myProject world setProperty: #thingsToUnhibernate toValue: rootsToUnhiberhate asArray. + ].! From cunningham.cb at gmail.com Thu Feb 18 16:42:55 2021 From: cunningham.cb at gmail.com (Chris Cunningham) Date: Thu, 18 Feb 2021 08:42:55 -0800 Subject: [squeak-dev] The Trunk: SystemReporter-mt.49.mcz In-Reply-To: References: Message-ID: This is nice. It would be really nice if the Monticello Browser also noted from which repository the packages were loaded from. That would have been my first place to look for information like this - and, of course, not find it. On Wed, Feb 17, 2021 at 8:15 AM Marcel Taeumel wrote: > I wanted to figure out which inbox code I already loaded into my image. > > Am 17.02.2021 17:08:58 schrieb Marcel Taeumel : > > Am 17.02.2021 17:08:34 schrieb commits at source.squeak.org < > commits at source.squeak.org>: > Marcel Taeumel uploaded a new version of SystemReporter to project The > Trunk: > http://source.squeak.org/trunk/SystemReporter-mt.49.mcz > > ==================== Summary ==================== > > Name: SystemReporter-mt.49 > Author: mt > Time: 17 February 2021, 5:08:25.667893 pm > UUID: 29b81ef5-5233-3c4f-981d-2c8205f4ce49 > Ancestors: SystemReporter-eem.48 > > Adds report about "Image Packages" to help organize all code artifacts in > your personal working image. > > =============== Diff against SystemReporter-eem.48 =============== > > Item was changed: > ----- Method: SystemReporter>>initialize (in category > 'initialize-release') ----- > initialize > self > add: #'Contributors' method: #reportContributors; > add: #Image method: #reportImage; > add: #'Image Parameters' method: #reportImageParameters; > add: #'Image Sources' method: #reportSources; > add: #'Image Preferences' method: #reportPreferences; > + add: #'Image Packages' method: #reportImagePackages; > add: #'MC Repositories' method: #reportRepositories; > add: #'MC Working Copies' method: #reportWorkingCopies; > add: #'VM General' method: #reportVM; > add: #'VM Options' method: #reportVMOptions; > add: #'VM Modules' method: #reportModules; > add: #'VM Parameters' method: #reportVMParameters; > add: #'VM Stats' method: #reportVMStats. > Smalltalk os platformName = 'Win32' ifTrue: [ > self > add: #'VM Configuration' method: #reportWin32VMConfig. > ]. > self > add: #'OS General' method: #reportOS. > Smalltalk os platformName = 'Win32' ifTrue: [ > self > add: #'OS Details' method: #reportWin32OSDetails; > add: #'Hardware Details' method: #reportWin32HardwareDetails; > add: #'GFX Hardware Details' method: #reportWin32GFXDetails. > ]. > Smalltalk os osVersion = 'linux' ifTrue: [ > self > add: #'OS Details' method: #reportLinuxOSDetails > ]. > self > add: #'Tiny Benchmarks' method: #reportTinyBenchmarks; > add: #'Space Analysis' method: #reportSpaceAnalysis; > add: #'SUnit' method: #reportTestRunner; > add: #'Debug Log' method: #reportDebugLog. > categoriesSelected := Set with: #Image with: #'VM General'. > self updateReport > ! > > Item was added: > + ----- Method: SystemReporter>>reportImagePackages: (in category > 'reporting') ----- > + reportImagePackages: aStream > + > + | organizer trunk treated inbox release releaseRepo attribute others | > + organizer := PackageOrganizer default. > + > + self header: 'System Categories with Unknown Package' on: aStream. > + SystemOrganization categories > + select: [:category | (organizer packageOfSystemCategory: category > ifNone: []) isNil] > + thenDo: [:category | aStream nextPutAll: category; cr]. > + > + aStream cr. > + self header: 'Packages with Only Cache Repository' on: aStream. > + organizer packages > + select: [:package | > + | repos | > + repos := package mcPackage workingCopy repositoryGroup repositories. > + repos size = 1 and: [repos first == MCRepository packageCache]] > + thenDo: [:package | aStream nextPutAll: package mcPackage workingCopy > description; cr]. > + > + aStream cr. > + self header: 'Official Packages' on: aStream. > + others := OrderedCollection new. > + trunk := MCRepository trunk allVersionNames. > + inbox := MCRepository inbox allVersionNames. > + treated := MCRepository treated allVersionNames. > + releaseRepo := [[ReleaseBuilder releaseRepository] valueSupplyingAnswer: > {'*'. true}] on: ReleaseBuilderFailed do: [:ex | nil]. > + release := releaseRepo ifNotNil: [:repo | repo allVersionNames] ifNil: > [#()]. > + > + (organizer packages sorted: [:a :b | a packageName <= b packageName]) > + collect: [:package | package mcPackage workingCopy] > + thenDo: [:workingCopy | | version repo | > + version := workingCopy ancestry ancestors ifNotEmpty: [:a | a first]. > + version ifNotNil: [version := version name]. > + attribute := TextEmphasis normal. > + (release includes: version) > + ifTrue: [repo := releaseRepo] > + ifFalse: [(trunk includes: version) > + ifTrue: [repo := MCRepository trunk] > + ifFalse: [(inbox includes: version) > + ifTrue: [repo := MCRepository inbox. attribute := TextEmphasis bold] > + ifFalse: [(treated includes: version) > + ifTrue: [repo := treated. attribute := TextColor gray] > + ifFalse: [others add: workingCopy]]]. > + repo ifNotNil: [ "Only official packages here." > + aStream withAttribute: attribute do: [ > + aStream > + nextPutAll: workingCopy description; > + nextPutAll: ' --- '; > + nextPutAll: repo description; cr]]]]. > + > + aStream cr. > + self header: 'Other Packages' on: aStream. > + others > + select: [:workingCopy | workingCopy repositoryGroup repositories size > > 1] > + thenDo: [:workingCopy | > + aStream > + nextPutAll: workingCopy description; > + nextPutAll: ' --- '; > + nextPutAll: workingCopy repositoryGroup repositories second description; > cr] > + ! > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image.png Type: image/png Size: 124530 bytes Desc: not available URL: From eliot.miranda at gmail.com Thu Feb 18 17:19:45 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Thu, 18 Feb 2021 09:19:45 -0800 Subject: [squeak-dev] thisContext method ... can answer a compiled block In-Reply-To: References: Message-ID: <2A73A276-846A-4751-9396-28A7A70861BD@gmail.com> > On Feb 18, 2021, at 6:04 AM, Marcel Taeumel wrote: > >  > Hi all -- > > Looking at the implementation of CompiledBlock >> #method and CompiledMethod >> #method, I wonder whether the implementation of Context >> #method is correct. > > What should be the answer of > [ thisContext method ] value > > An instance of CompiledMethod or an instance of CompiledBlock? If the latter is okay, then "thisContext method method" would be the necessary idiom to support lookup in the underlying behavior. thisContext home method thisContext method home I think thisContext method *must* answer the method object thisContext is referring to, and hence will refer to a CompiledBlock fir a lock activation when using SistaV1. thisContext home method or thisContext method home will answer the CompiledMethod. We could, indeed should, provide thisContext homeMethod. > > Best, > Marcel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Thu Feb 18 17:26:46 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 17:26:46 0000 Subject: [squeak-dev] The Trunk: Kernel-eem.1373.mcz Message-ID: Eliot Miranda uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-eem.1373.mcz ==================== Summary ==================== Name: Kernel-eem.1373 Author: eem Time: 18 February 2021, 9:26:43.175183 am UUID: e0852235-f3e5-4b35-a017-57a8bd0568f5 Ancestors: Kernel-eem.1372 Provide Context>>homeMethod as a convenience for thisContext method homeMethod or thisContext home method. homeMethod is polymorphic with BlockClosure and CompiledCode. =============== Diff against Kernel-eem.1372 =============== Item was added: + ----- Method: Context>>homeMethod (in category 'accessing') ----- + homeMethod + "Answer the home method associated with the receiver. + This is polymorphic with BlockClosure, CompiledCode, etc" + ^method homeMethod! From commits at source.squeak.org Thu Feb 18 22:43:51 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 22:43:51 0000 Subject: [squeak-dev] The Trunk: Compiler-codefrau.454.mcz Message-ID: Vanessa Freudenberg uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler-codefrau.454.mcz ==================== Summary ==================== Name: Compiler-codefrau.454 Author: codefrau Time: 18 February 2021, 2:37:39.920599 pm UUID: 1c50118a-0c26-4496-851f-e48ff051ca67 Ancestors: Compiler-eem.453 Move bytecodeSetName to BytecodeEncoder =============== Diff against Compiler-eem.453 =============== Item was added: + ----- Method: BytecodeEncoder class>>bytecodeSetName (in category 'compiled method support') ----- + bytecodeSetName + ^self name copyReplaceAll: 'EncoderFor' with: ''! From commits at source.squeak.org Thu Feb 18 22:44:44 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 22:44:44 0000 Subject: [squeak-dev] The Trunk: Kernel-codefrau.1374.mcz Message-ID: Vanessa Freudenberg uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-codefrau.1374.mcz ==================== Summary ==================== Name: Kernel-codefrau.1374 Author: codefrau Time: 18 February 2021, 2:44:41.361952 pm UUID: 69ebed8c-9b16-43ab-9610-2aaef6f932b5 Ancestors: Kernel-eem.1373 Move bytecodeSetName to BytecodeEncoder =============== Diff against Kernel-eem.1373 =============== Item was changed: ----- Method: CompiledCode>>bytecodeSetName (in category 'accessing') ----- bytecodeSetName + ^self encoderClass bytecodeSetName! - ^self encoderClass name copyReplaceAll: 'EncoderFor' with: ''! From commits at source.squeak.org Thu Feb 18 22:45:55 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Thu, 18 Feb 2021 22:45:55 0000 Subject: [squeak-dev] The Trunk: SystemReporter-codefrau.50.mcz Message-ID: Vanessa Freudenberg uploaded a new version of SystemReporter to project The Trunk: http://source.squeak.org/trunk/SystemReporter-codefrau.50.mcz ==================== Summary ==================== Name: SystemReporter-codefrau.50 Author: codefrau Time: 18 February 2021, 2:45:54.300961 pm UUID: 93f2f77e-eef8-4ffc-964a-4bd419f68570 Ancestors: SystemReporter-mt.49 Report preferred bytecode set =============== Diff against SystemReporter-mt.49 =============== Item was changed: ----- Method: SystemReporter>>reportImage: (in category 'reporting') ----- reportImage: aStream self header: 'Image' on: aStream. aStream nextPutAll: Smalltalk image imageName; cr; nextPutAll: SystemVersion current version; cr; nextPutAll: Smalltalk image lastUpdateString; cr; nextPutAll: Smalltalk image currentChangeSetString; cr. [aStream nextPutAll: 'Image format '; print: Smalltalk image imageFormatVersion; nextPutAll: ' ('; print: Smalltalk image wordSize * 8; nextPutAll: ' bit)'; cr] on: Warning + do: ["primitive not present in VM"]. + [aStream + nextPutAll: 'Preferred bytecode set: '; + nextPutAll: CompiledMethod preferredBytecodeSetEncoderClass bytecodeSetName; cr] + on: MessageNotUnderstood + do: [:ex | ex resume: '---']. - do: ["primitive not present in VM"] "self new reportImage: Transcript. Transcript flush"! From leves at caesar.elte.hu Thu Feb 18 23:16:48 2021 From: leves at caesar.elte.hu (Levente Uzonyi) Date: Fri, 19 Feb 2021 00:16:48 +0100 (CET) Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: Hi Chris, On Wed, 17 Feb 2021, Chris Muller wrote: > This is what I would do: > > merging: listOfRects >     "A number of callers of merge: should use this method." >     ^ listOfRects >         inject: >             (self >                 origin: Float infinity @ Float infinity >                 corner: Float infinity negated @ Float infinity negated) >         into: [ : rect : each | rect quickMerge: each ] > > With #quickMerge:, you're only creating a new Rectangle when it needed to grow to accomodate the current element, but many of the elements might fit completely, resulting in no additional instantiation.  Do an analysis of how > many temporary Point objects we create -- hint: it's a ton -- and my own attempts to optimize that in my Kml framework were not fruitful (e.g., ~1%), with a trade-off of duplicating implementation across multiple methods and > making the system's code harder to read and understand and maintain. With my benchmark, your version is slower than the one from 2003, especially when the collection is small. And it doesn't handle the case of empty listOfRects the same way: it silently returns a rectangle instead of raising an error. Here's the version I came up with the other day: merging: listOfRects "A number of callers of merge: should use this method." | minTopLeftX minTopLeftY maxBottomRightX maxBottomRightY | listOfRects do: [ :rectangle | | topLeft bottomRight | topLeft := rectangle topLeft. bottomRight := rectangle bottomRight. minTopLeftX ifNil: [ minTopLeftX := topLeft x. minTopLeftY := topLeft y. maxBottomRightX := bottomRight x. maxBottomRightY := bottomRight y ] ifNotNil: [ topLeft x < minTopLeftX ifTrue: [ minTopLeftX := topLeft x ]. topLeft y < minTopLeftY ifTrue: [ minTopLeftY := topLeft y ]. bottomRight x > maxBottomRightX ifTrue: [ maxBottomRightX := bottomRight x ]. bottomRight y > maxBottomRightY ifTrue: [ maxBottomRightY := bottomRight y ] ] ]. ^self origin: minTopLeftX @ minTopLeftY corner: maxBottomRightX @ maxBottomRightY Levente > >  - Chris > > > On Wed, Feb 17, 2021 at 11:27 AM Levente Uzonyi wrote: > On Wed, 17 Feb 2021, Marcel Taeumel wrote: > > > Hmm... looking at performance ... why not just add #asSequenceableCollection, which would only impact Set arguments? > > I don't think we have such method. Adding one would raise the usual > question: should it create a new collection or return self if self > already to the requested collection kind? > IIRC currently the only outlier is #asOrderedCollection which always > creates a copy when the receiver is an OrderedCollection, and that > property is being relied on, so it can't be changed... > > > As a programmer, I do not want to choose between #merge: and #quickMerge:. Or similar. :-) > > IMO, we simply need one quick solution. If you have a Set, you may need > that help from the library even more. > #quickMerge: is only good for merging two rectangles. It does not solve > the GC issue #merge: has. > > > Levente > > > > > Best, > > Marcel > > > >       Am 13.02.2021 17:05:07 schrieb commits at source.squeak.org : > > > >       Nicolas Cellier uploaded a new version of Graphics to project The Inbox: > >       http://source.squeak.org/inbox/Graphics-nice.446.mcz > > > >       ==================== Summary ==================== > > > >       Name: Graphics-nice.446 > >       Author: nice > >       Time: 13 February 2021, 5:04:52.453325 pm > >       UUID: d13c1db2-370f-4fa6-b7ae-e6766bf0c8fb > >       Ancestors: Graphics-dtl.445 > > > >       Let Rectangle merging:/encompassing: an unordered collection. > > > >       =============== Diff against Graphics-dtl.445 =============== > > > >       Item was changed: > >       ----- Method: Rectangle class>>encompassing: (in category 'instance creation') ----- > >       encompassing: listOfPoints > >       "A number of callers of encompass: should use this method." > >       | topLeft bottomRight | > >       + topLeft := bottomRight := listOfPoints anyOne. > >       + listOfPoints do: > >       - topLeft := bottomRight := listOfPoints first. > >       - listOfPoints allButFirstDo: > >       [:p |topLeft := topLeft min: p. > >       + bottomRight := bottomRight max: p]. > >       - bottomRight := bottomRight max: p]. > >       ^self origin: topLeft corner: bottomRight > >       ! > > > >       Item was changed: > >       ----- Method: Rectangle class>>merging: (in category 'instance creation') ----- > >       merging: listOfRects > >       "A number of callers of merge: should use this method." > >       + | aRectangle bottomRight topLeft | > >       + aRectangle := listOfRects anyOne. > >       + topLeft := aRectangle topLeft. > >       + bottomRight := aRectangle bottomRight. > >       - | bottomRight topLeft | > >       - topLeft := listOfRects first topLeft. > >       - bottomRight := listOfRects first bottomRight. > >       listOfRects > >       + do: [:r | topLeft := topLeft min: r topLeft. > >       - allButFirstDo: [:r | topLeft := topLeft min: r topLeft. > >       bottomRight := bottomRight max: r bottomRight]. > >       ^self origin: topLeft corner: bottomRight. > >       ! > > > > > > > > > > > From marcel.taeumel at hpi.de Fri Feb 19 07:59:05 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Fri, 19 Feb 2021 08:59:05 +0100 Subject: [squeak-dev] The Trunk: SystemReporter-mt.49.mcz In-Reply-To: References: Message-ID: Hi Chris. > It would be really nice if the Monticello Browser also noted from which repository the packages were loaded from. That would have been my first place to look for information like this - and, of course, not find it. Hmm... maybe it would be possible with "a clever caching strategy" (tm) :-D -- It doesn't take *that* long to fetch the list of file names from a file-based repository. Best, Marcel Am 18.02.2021 17:43:20 schrieb Chris Cunningham : This is nice. It would be really nice if the Monticello Browser also noted from which repository the packages were loaded from. That would have been my first place to look for information like this - and, of course, not find it. On Wed, Feb 17, 2021 at 8:15 AM Marcel Taeumel wrote: I wanted to figure out which inbox code I already loaded into my image. Am 17.02.2021 17:08:58 schrieb Marcel Taeumel : Am 17.02.2021 17:08:34 schrieb commits at source.squeak.org [mailto:commits at source.squeak.org] : Marcel Taeumel uploaded a new version of SystemReporter to project The Trunk: http://source.squeak.org/trunk/SystemReporter-mt.49.mcz [http://source.squeak.org/trunk/SystemReporter-mt.49.mcz] ==================== Summary ==================== Name: SystemReporter-mt.49 Author: mt Time: 17 February 2021, 5:08:25.667893 pm UUID: 29b81ef5-5233-3c4f-981d-2c8205f4ce49 Ancestors: SystemReporter-eem.48 Adds report about "Image Packages" to help organize all code artifacts in your personal working image. =============== Diff against SystemReporter-eem.48 =============== Item was changed: ----- Method: SystemReporter>>initialize (in category 'initialize-release') ----- initialize self add: #'Contributors' method: #reportContributors; add: #Image method: #reportImage; add: #'Image Parameters' method: #reportImageParameters; add: #'Image Sources' method: #reportSources; add: #'Image Preferences' method: #reportPreferences; + add: #'Image Packages' method: #reportImagePackages; add: #'MC Repositories' method: #reportRepositories; add: #'MC Working Copies' method: #reportWorkingCopies; add: #'VM General' method: #reportVM; add: #'VM Options' method: #reportVMOptions; add: #'VM Modules' method: #reportModules; add: #'VM Parameters' method: #reportVMParameters; add: #'VM Stats' method: #reportVMStats. Smalltalk os platformName = 'Win32' ifTrue: [ self add: #'VM Configuration' method: #reportWin32VMConfig. ]. self add: #'OS General' method: #reportOS. Smalltalk os platformName = 'Win32' ifTrue: [ self add: #'OS Details' method: #reportWin32OSDetails; add: #'Hardware Details' method: #reportWin32HardwareDetails; add: #'GFX Hardware Details' method: #reportWin32GFXDetails. ]. Smalltalk os osVersion = 'linux' ifTrue: [ self add: #'OS Details' method: #reportLinuxOSDetails ]. self add: #'Tiny Benchmarks' method: #reportTinyBenchmarks; add: #'Space Analysis' method: #reportSpaceAnalysis; add: #'SUnit' method: #reportTestRunner; add: #'Debug Log' method: #reportDebugLog. categoriesSelected := Set with: #Image with: #'VM General'. self updateReport ! Item was added: + ----- Method: SystemReporter>>reportImagePackages: (in category 'reporting') ----- + reportImagePackages: aStream + + | organizer trunk treated inbox release releaseRepo attribute others | + organizer := PackageOrganizer default. + + self header: 'System Categories with Unknown Package' on: aStream. + SystemOrganization categories + select: [:category | (organizer packageOfSystemCategory: category ifNone: []) isNil] + thenDo: [:category | aStream nextPutAll: category; cr]. + + aStream cr. + self header: 'Packages with Only Cache Repository' on: aStream. + organizer packages + select: [:package | + | repos | + repos := package mcPackage workingCopy repositoryGroup repositories. + repos size = 1 and: [repos first == MCRepository packageCache]] + thenDo: [:package | aStream nextPutAll: package mcPackage workingCopy description; cr]. + + aStream cr. + self header: 'Official Packages' on: aStream. + others := OrderedCollection new. + trunk := MCRepository trunk allVersionNames. + inbox := MCRepository inbox allVersionNames. + treated := MCRepository treated allVersionNames. + releaseRepo := [[ReleaseBuilder releaseRepository] valueSupplyingAnswer: {'*'. true}] on: ReleaseBuilderFailed do: [:ex | nil]. + release := releaseRepo ifNotNil: [:repo | repo allVersionNames] ifNil: [#()]. + + (organizer packages sorted: [:a :b | a packageName <= b packageName]) + collect: [:package | package mcPackage workingCopy] + thenDo: [:workingCopy | | version repo | + version := workingCopy ancestry ancestors ifNotEmpty: [:a | a first]. + version ifNotNil: [version := version name]. + attribute := TextEmphasis normal. + (release includes: version) + ifTrue: [repo := releaseRepo] + ifFalse: [(trunk includes: version) + ifTrue: [repo := MCRepository trunk] + ifFalse: [(inbox includes: version) + ifTrue: [repo := MCRepository inbox. attribute := TextEmphasis bold] + ifFalse: [(treated includes: version) + ifTrue: [repo := treated. attribute := TextColor gray] + ifFalse: [others add: workingCopy]]]. + repo ifNotNil: [ "Only official packages here." + aStream withAttribute: attribute do: [ + aStream + nextPutAll: workingCopy description; + nextPutAll: ' --- '; + nextPutAll: repo description; cr]]]]. + + aStream cr. + self header: 'Other Packages' on: aStream. + others + select: [:workingCopy | workingCopy repositoryGroup repositories size > 1] + thenDo: [:workingCopy | + aStream + nextPutAll: workingCopy description; + nextPutAll: ' --- '; + nextPutAll: workingCopy repositoryGroup repositories second description; cr] + ! -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image.png Type: image/png Size: 124530 bytes Desc: not available URL: From tomjonabc at gmail.com Fri Feb 19 09:01:35 2021 From: tomjonabc at gmail.com (Tom Beckmann) Date: Fri, 19 Feb 2021 09:01:35 +0000 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: Hi everyone, just another idea for your consideration: merging3: listOfRects ^ listOfRects reduce: [:a :b | self origin: (a origin min: b origin) corner: (a corner max: b corner)] If you care more about performance than idioms (not even sure if this is legal): merging4: listOfRects ^ listOfRects reduce: [:a :b | a setOrigin: (a origin min: b origin) corner: (a corner max: b corner)] And finally, the, in my opinion, most elegant version. Sadly, it's also the slowest. merging5: listOfRects ^ listOfRects reduce: [:a :b | a quickMerge: b] Some unrepresentative benchmarks: " Levente's version from above with temps " [Rectangle merging2: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '3,740,000 per second. 267 nanoseconds per run. 37.46501 % GC time.' " the 'clean' version " [Rectangle merging3: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '3,020,000 per second. 331 nanoseconds per run. 40.93181 % GC time.' " the version that mutates rectangles " [Rectangle merging4: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100} asSet] bench '3,330,000 per second. 300 nanoseconds per run. 40.53189 % GC time.' " using quickMerge " [Rectangle merging5: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '2,930,000 per second. 341 nanoseconds per run. 42.32 % GC time.' Best, Tom On Thu, Feb 18, 2021 at 11:17 PM Levente Uzonyi wrote: > Hi Chris, > > On Wed, 17 Feb 2021, Chris Muller wrote: > > > This is what I would do: > > > > merging: listOfRects > > "A number of callers of merge: should use this method." > > ^ listOfRects > > inject: > > (self > > origin: Float infinity @ Float infinity > > corner: Float infinity negated @ Float infinity negated) > > into: [ : rect : each | rect quickMerge: each ] > > > > With #quickMerge:, you're only creating a new Rectangle when it needed > to grow to accomodate the current element, but many of the elements might > fit completely, resulting in no additional instantiation. Do an analysis > of how > > many temporary Point objects we create -- hint: it's a ton -- and my own > attempts to optimize that in my Kml framework were not fruitful (e.g., > ~1%), with a trade-off of duplicating implementation across multiple > methods and > > making the system's code harder to read and understand and maintain. > > With my benchmark, your version is slower than the one from 2003, > especially when the collection is small. And it doesn't handle the case of > empty listOfRects the same way: it silently returns a rectangle instead of > raising an error. > > Here's the version I came up with the other day: > > > merging: listOfRects > "A number of callers of merge: should use this method." > > | minTopLeftX minTopLeftY maxBottomRightX maxBottomRightY | > listOfRects do: [ :rectangle | > | topLeft bottomRight | > topLeft := rectangle topLeft. > bottomRight := rectangle bottomRight. > minTopLeftX > ifNil: [ > minTopLeftX := topLeft x. > minTopLeftY := topLeft y. > maxBottomRightX := bottomRight x. > maxBottomRightY := bottomRight y ] > ifNotNil: [ > topLeft x < minTopLeftX ifTrue: [ > minTopLeftX := topLeft x ]. > topLeft y < minTopLeftY ifTrue: [ > minTopLeftY := topLeft y ]. > bottomRight x > maxBottomRightX ifTrue: [ > maxBottomRightX := bottomRight x ]. > bottomRight y > maxBottomRightY ifTrue: [ > maxBottomRightY := bottomRight y ] ] ]. > ^self origin: minTopLeftX @ minTopLeftY corner: maxBottomRightX @ > maxBottomRightY > > > Levente > > > > > - Chris > > > > > > On Wed, Feb 17, 2021 at 11:27 AM Levente Uzonyi > wrote: > > On Wed, 17 Feb 2021, Marcel Taeumel wrote: > > > > > Hmm... looking at performance ... why not just add > #asSequenceableCollection, which would only impact Set arguments? > > > > I don't think we have such method. Adding one would raise the usual > > question: should it create a new collection or return self if self > > already to the requested collection kind? > > IIRC currently the only outlier is #asOrderedCollection which > always > > creates a copy when the receiver is an OrderedCollection, and that > > property is being relied on, so it can't be changed... > > > > > As a programmer, I do not want to choose between #merge: and > #quickMerge:. Or similar. :-) > > > > IMO, we simply need one quick solution. If you have a Set, you may > need > > that help from the library even more. > > #quickMerge: is only good for merging two rectangles. It does not > solve > > the GC issue #merge: has. > > > > > > Levente > > > > > > > > Best, > > > Marcel > > > > > > Am 13.02.2021 17:05:07 schrieb commits at source.squeak.org < > commits at source.squeak.org>: > > > > > > Nicolas Cellier uploaded a new version of Graphics to > project The Inbox: > > > http://source.squeak.org/inbox/Graphics-nice.446.mcz > > > > > > ==================== Summary ==================== > > > > > > Name: Graphics-nice.446 > > > Author: nice > > > Time: 13 February 2021, 5:04:52.453325 pm > > > UUID: d13c1db2-370f-4fa6-b7ae-e6766bf0c8fb > > > Ancestors: Graphics-dtl.445 > > > > > > Let Rectangle merging:/encompassing: an unordered > collection. > > > > > > =============== Diff against Graphics-dtl.445 > =============== > > > > > > Item was changed: > > > ----- Method: Rectangle class>>encompassing: (in category > 'instance creation') ----- > > > encompassing: listOfPoints > > > "A number of callers of encompass: should use this method." > > > | topLeft bottomRight | > > > + topLeft := bottomRight := listOfPoints anyOne. > > > + listOfPoints do: > > > - topLeft := bottomRight := listOfPoints first. > > > - listOfPoints allButFirstDo: > > > [:p |topLeft := topLeft min: p. > > > + bottomRight := bottomRight max: p]. > > > - bottomRight := bottomRight max: p]. > > > ^self origin: topLeft corner: bottomRight > > > ! > > > > > > Item was changed: > > > ----- Method: Rectangle class>>merging: (in category > 'instance creation') ----- > > > merging: listOfRects > > > "A number of callers of merge: should use this method." > > > + | aRectangle bottomRight topLeft | > > > + aRectangle := listOfRects anyOne. > > > + topLeft := aRectangle topLeft. > > > + bottomRight := aRectangle bottomRight. > > > - | bottomRight topLeft | > > > - topLeft := listOfRects first topLeft. > > > - bottomRight := listOfRects first bottomRight. > > > listOfRects > > > + do: [:r | topLeft := topLeft min: r topLeft. > > > - allButFirstDo: [:r | topLeft := topLeft min: r topLeft. > > > bottomRight := bottomRight max: r bottomRight]. > > > ^self origin: topLeft corner: bottomRight. > > > ! > > > > > > > > > > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Fri Feb 19 08:07:09 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 19 Feb 2021 08:07:09 0000 Subject: [squeak-dev] The Trunk: System-mt.1219.mcz Message-ID: Marcel Taeumel uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-mt.1219.mcz ==================== Summary ==================== Name: System-mt.1219 Author: mt Time: 19 February 2021, 9:07:02.127408 am UUID: 7a1ac093-4949-fd43-87b4-d9379f327f88 Ancestors: System-mt.1218 Adds 'codefrau' initials. =============== Diff against System-mt.1218 =============== Item was changed: ----- Method: SystemNavigation class>>privateAuthorsRaw (in category 'class initialization') ----- (excessive size, no diff calculated) Item was changed: + (PackageInfo named: 'System') postscript: 'SystemNavigation initializeAuthors......'! - (PackageInfo named: 'System') postscript: 'SystemNavigation initializeAuthors.....'! From marcel.taeumel at hpi.de Fri Feb 19 08:12:22 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Fri, 19 Feb 2021 09:12:22 +0100 Subject: [squeak-dev] thisContext method ... can answer a compiled block In-Reply-To: <2A73A276-846A-4751-9396-28A7A70861BD@gmail.com> References: <2A73A276-846A-4751-9396-28A7A70861BD@gmail.com> Message-ID: Hi Eliot. > I think thisContext method *must* answer the method object thisContext is referring to [...] Agreed. Hmm... why not having #code instead of #method in Context? Or #compiledCode? I suppose that this would leak the parallel structure (or "nature") of CompiledBlock and CompiledMethod too much? > We could, indeed should, provide thisContext homeMethod. Yes, #homeMethod is what I was looking for. :-) Best, Marcel Am 18.02.2021 18:19:59 schrieb Eliot Miranda : On Feb 18, 2021, at 6:04 AM, Marcel Taeumel wrote:  Hi all -- Looking at the implementation of CompiledBlock >> #method and CompiledMethod >> #method, I wonder whether the implementation of Context >> #method is correct. What should be the answer of    [ thisContext method ] value An instance of CompiledMethod or an instance of CompiledBlock? If the latter is okay, then "thisContext method method" would be the necessary idiom to support lookup in the underlying behavior. thisContext home method thisContext method home I think thisContext method *must* answer the method object thisContext is referring to, and hence will refer to a CompiledBlock fir a lock activation when using SistaV1. thisContext home method or thisContext method home will answer the CompiledMethod. We could, indeed should, provide thisContext homeMethod. Best, Marcel -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Fri Feb 19 08:15:20 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 19 Feb 2021 08:15:20 0000 Subject: [squeak-dev] The Trunk: EToys-mt.425.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-mt.425.mcz ==================== Summary ==================== Name: EToys-mt.425 Author: mt Time: 19 February 2021, 9:15:11.952408 am UUID: 2c3addb0-2333-bd49-ad33-bb885cf5642a Ancestors: EToys-mt.424 Complements Kernel-eem.1373 =============== Diff against EToys-mt.424 =============== Item was changed: ----- Method: StandardScriptingSystem>>reportToUser: (in category '*Etoys-utilities') ----- reportToUser: aString "Make a message accessible to the user. " | trigger current baseTriggerer topTriggerer mclass sel topSelector | trigger := Player compiledMethodAt: #triggerScript:. current := thisContext. baseTriggerer := nil. topTriggerer := nil. [current notNil] whileTrue: [ topTriggerer ifNil: [ current receiver class isUniClass ifTrue: [ "Look for the top-most uniclass script in the call chain." + sel := current receiver class selectorAtMethod: current homeMethod setClass: [:c | mclass := c]. - sel := current receiver class selectorAtMethod: current method "aCompiledBlock" method setClass: [:c | mclass := c]. mclass = current receiver class ifTrue: [ topTriggerer := current. topSelector := sel. ]. ]. ]. (current method = trigger and: [current isExecutingBlock not]) ifTrue: [ "Look for the bottom-most #triggerScript: and its selector." baseTriggerer := current ]. current := current sender. ]. baseTriggerer ifNotNil: [ (baseTriggerer receiver scriptInstantiationForSelector: (baseTriggerer at: 1)) resetTo: #paused ifCurrently: #ticking. ]. (topTriggerer notNil and: [topSelector notNil]) ifTrue: [ ^ self eToysError: aString, '\', topTriggerer receiver knownName, '\', topSelector. ]. self error: aString! From commits at source.squeak.org Fri Feb 19 08:25:54 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 19 Feb 2021 08:25:54 0000 Subject: [squeak-dev] The Trunk: Morphic-mt.1723.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.1723.mcz ==================== Summary ==================== Name: Morphic-mt.1723 Author: mt Time: 19 February 2021, 9:25:48.003408 am UUID: d3f91505-ae1c-f246-92f4-c4fdd2a6c929 Ancestors: Morphic-mt.1722 Minor clean-up. WorldState already handles deferred updates and min-cycle lapse. (I think this was just forgotten when WoldState was introduced. Note that I kept the commentary in #disableDeferredUpdates:) =============== Diff against Morphic-mt.1722 =============== Item was changed: BorderedMorph subclass: #PasteUpMorph instanceVariableNames: 'presenter model cursor padding backgroundMorph turtleTrailsForm turtlePen lastTurtlePositions isPartsBin indicateCursor wantsMouseOverHalos worldState griddingOn' + classVariableNames: 'GlobalCommandKeysEnabled WindowEventHandler' - classVariableNames: 'DisableDeferredUpdates GlobalCommandKeysEnabled MinCycleLapse StillAlive WindowEventHandler' poolDictionaries: '' category: 'Morphic-Worlds'! !PasteUpMorph commentStamp: '' prior: 0! A morph whose submorphs comprise a paste-up of rectangular subparts which "show through". Anything called a 'Playfield' is a PasteUpMorph. Facilities commonly needed on pages of graphical presentations and on simulation playfields, such as the painting of new objects, turtle trails, gradient fills, background paintings, parts-bin behavior, collision-detection, etc., are (or will be) provided. A World, the entire Smalltalk screen, is a PasteUpMorph. A World responds true to isWorld. Morph subclasses that have specialized menus (BookMorph) build them in the message addBookMenuItemsTo:hand:. A PasteUpMorph that is a world, builds its menu in HandMorph buildWorldMenu. presenter A Presenter in charge of stopButton stepButton and goButton, mouseOverHalosEnabled soundsEnabled fenceEnabled coloredTilesEnabled. model cursor ?? padding ?? backgroundMorph A Form that covers the background. turtleTrailsForm Moving submorphs may leave trails on this form. turtlePen Draws the trails. lastTurtlePositions A Dictionary of (aPlayer -> aPoint) so turtle trails can be drawn only once each step cycle. The point is the start of the current stroke. isPartsBin If true, every object dragged out is copied. autoLineLayout ?? indicateCursor ?? resizeToFit ?? wantsMouseOverHalos If true, simply moving the cursor over a submorph brings up its halo. worldState If I am also a World, keeps the hands, damageRecorder, stepList etc. griddingOn If true, submorphs are on a grid ! Item was removed: - ----- Method: PasteUpMorph class>>MinCycleLapse: (in category 'project') ----- - MinCycleLapse: milliseconds - "set the minimum amount of time that may transpire between two calls to doOneCycle" - MinCycleLapse := milliseconds ifNotNil: [ milliseconds rounded ].! Item was removed: - ----- Method: PasteUpMorph class>>disableDeferredUpdates (in category 'project') ----- - disableDeferredUpdates - - ^DisableDeferredUpdates ifNil: [DisableDeferredUpdates := false] - ! Item was removed: - ----- Method: PasteUpMorph class>>disableDeferredUpdates: (in category 'project') ----- - disableDeferredUpdates: aBoolean - "If the argument is true, disable deferred screen updating." - "Details: When deferred updating is used, Morphic performs double-buffered screen updates by telling the VM to de-couple the Display from the hardware display buffer, drawing directly into the Display, and then forcing the changed regions of the Display to be copied to the screen. This saves both time (an extra BitBlt is avoided) and space (an extra display buffer is avoided). However, on platforms on which the Display points directly to the hardware screen buffer, deferred updating can't be used (you'd see ugly flashing as the layers of the drawing were assembled). In this case, the drawing is composited into an offscreen FormCanvas and then copied to the hardware display buffer." - - DisableDeferredUpdates := aBoolean. - ! Item was added: + ----- Method: WorldState class>>disableDeferredUpdates (in category 'accessing') ----- + disableDeferredUpdates + + ^DisableDeferredUpdates ifNil: [DisableDeferredUpdates := false] + ! Item was added: + ----- Method: WorldState class>>disableDeferredUpdates: (in category 'accessing') ----- + disableDeferredUpdates: aBoolean + "If the argument is true, disable deferred screen updating." + "Details: When deferred updating is used, Morphic performs double-buffered screen updates by telling the VM to de-couple the Display from the hardware display buffer, drawing directly into the Display, and then forcing the changed regions of the Display to be copied to the screen. This saves both time (an extra BitBlt is avoided) and space (an extra display buffer is avoided). However, on platforms on which the Display points directly to the hardware screen buffer, deferred updating can't be used (you'd see ugly flashing as the layers of the drawing were assembled). In this case, the drawing is composited into an offscreen FormCanvas and then copied to the hardware display buffer." + + DisableDeferredUpdates := aBoolean. + ! Item was changed: ----- Method: WorldState>>doDeferredUpdatingFor: (in category 'update cycle') ----- doDeferredUpdatingFor: aWorld "If this platform supports deferred updates, then make my canvas be the Display (or a rectangular portion of it), set the Display to deferred update mode, and answer true. Otherwise, do nothing and answer false. One can set the class variable DisableDeferredUpdates to true to completely disable the deferred updating feature." | properDisplay | + DisableDeferredUpdates ifTrue: [^ false]. - PasteUpMorph disableDeferredUpdates ifTrue: [^ false]. (Display deferUpdates: true) ifNil: [^ false]. "deferred updates not supported" remoteServer ifNotNil:[ self assuredCanvas. ^true]. properDisplay := canvas notNil and: [canvas form == Display]. aWorld == Project current world ifTrue: [ "this world fills the entire Display" properDisplay ifFalse: [ aWorld viewBox: Display boundingBox. "do first since it may clear canvas" self canvas: (Display getCanvas copyClipRect: Display boundingBox). ] ]. ^ true ! From commits at source.squeak.org Fri Feb 19 08:26:34 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 19 Feb 2021 08:26:34 0000 Subject: [squeak-dev] The Trunk: EToys-mt.426.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-mt.426.mcz ==================== Summary ==================== Name: EToys-mt.426 Author: mt Time: 19 February 2021, 9:26:25.709408 am UUID: 2d83eaa7-77bb-7846-aa2e-d0b5abc69d29 Ancestors: EToys-mt.425 Complements Morphic-mt.1723 =============== Diff against EToys-mt.425 =============== Item was removed: - ----- Method: WiWPasteUpMorph>>doDeferredUpdating (in category 'update cycle') ----- - doDeferredUpdating - "If this platform supports deferred updates, then make my canvas be the Display (or a rectangular portion of it), set the Display to deferred update mode, and answer true. Otherwise, do nothing and answer false. One can set the class variable DisableDeferredUpdates to true to completely disable the deferred updating feature." - - PasteUpMorph disableDeferredUpdates ifTrue: [^ false]. - (Display deferUpdates: true) ifNil: [^ false]. "deferred updates not supported" - - self resetViewBox. - ^ true - ! From nicolas.cellier.aka.nice at gmail.com Fri Feb 19 10:05:02 2021 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Fri, 19 Feb 2021 11:05:02 +0100 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: Hi Tom, yes this looks cleaner. But that's precisely what we try to avoid here: create lots of intermediate short-lived objects (Rectangle and Point). This is because it may be a performance critical routine. Le ven. 19 févr. 2021 à 09:01, Tom Beckmann a écrit : > > Hi everyone, > > just another idea for your consideration: > > merging3: listOfRects > ^ listOfRects reduce: [:a :b | > self origin: (a origin min: b origin) corner: (a corner max: b corner)] > > If you care more about performance than idioms (not even sure if this is legal): > merging4: listOfRects > ^ listOfRects reduce: [:a :b | > a setOrigin: (a origin min: b origin) corner: (a corner max: b corner)] > > And finally, the, in my opinion, most elegant version. Sadly, it's also the slowest. > merging5: listOfRects > ^ listOfRects reduce: [:a :b | a quickMerge: b] > > > > Some unrepresentative benchmarks: > > " Levente's version from above with temps " > [Rectangle merging2: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '3,740,000 per second. 267 nanoseconds per run. 37.46501 % GC time.' > " the 'clean' version " > [Rectangle merging3: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '3,020,000 per second. 331 nanoseconds per run. 40.93181 % GC time.' > " the version that mutates rectangles " > [Rectangle merging4: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100} asSet] bench '3,330,000 per second. 300 nanoseconds per run. 40.53189 % GC time.' > " using quickMerge " > [Rectangle merging5: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '2,930,000 per second. 341 nanoseconds per run. 42.32 % GC time.' > > Best, > Tom > > On Thu, Feb 18, 2021 at 11:17 PM Levente Uzonyi wrote: >> >> Hi Chris, >> >> On Wed, 17 Feb 2021, Chris Muller wrote: >> >> > This is what I would do: >> > >> > merging: listOfRects >> > "A number of callers of merge: should use this method." >> > ^ listOfRects >> > inject: >> > (self >> > origin: Float infinity @ Float infinity >> > corner: Float infinity negated @ Float infinity negated) >> > into: [ : rect : each | rect quickMerge: each ] >> > >> > With #quickMerge:, you're only creating a new Rectangle when it needed to grow to accomodate the current element, but many of the elements might fit completely, resulting in no additional instantiation. Do an analysis of how >> > many temporary Point objects we create -- hint: it's a ton -- and my own attempts to optimize that in my Kml framework were not fruitful (e.g., ~1%), with a trade-off of duplicating implementation across multiple methods and >> > making the system's code harder to read and understand and maintain. >> >> With my benchmark, your version is slower than the one from 2003, >> especially when the collection is small. And it doesn't handle the case of >> empty listOfRects the same way: it silently returns a rectangle instead of >> raising an error. >> >> Here's the version I came up with the other day: >> >> >> merging: listOfRects >> "A number of callers of merge: should use this method." >> >> | minTopLeftX minTopLeftY maxBottomRightX maxBottomRightY | >> listOfRects do: [ :rectangle | >> | topLeft bottomRight | >> topLeft := rectangle topLeft. >> bottomRight := rectangle bottomRight. >> minTopLeftX >> ifNil: [ >> minTopLeftX := topLeft x. >> minTopLeftY := topLeft y. >> maxBottomRightX := bottomRight x. >> maxBottomRightY := bottomRight y ] >> ifNotNil: [ >> topLeft x < minTopLeftX ifTrue: [ minTopLeftX := topLeft x ]. >> topLeft y < minTopLeftY ifTrue: [ minTopLeftY := topLeft y ]. >> bottomRight x > maxBottomRightX ifTrue: [ maxBottomRightX := bottomRight x ]. >> bottomRight y > maxBottomRightY ifTrue: [ maxBottomRightY := bottomRight y ] ] ]. >> ^self origin: minTopLeftX @ minTopLeftY corner: maxBottomRightX @ maxBottomRightY >> >> >> Levente >> >> > >> > - Chris >> > >> > >> > On Wed, Feb 17, 2021 at 11:27 AM Levente Uzonyi wrote: >> > On Wed, 17 Feb 2021, Marcel Taeumel wrote: >> > >> > > Hmm... looking at performance ... why not just add #asSequenceableCollection, which would only impact Set arguments? >> > >> > I don't think we have such method. Adding one would raise the usual >> > question: should it create a new collection or return self if self >> > already to the requested collection kind? >> > IIRC currently the only outlier is #asOrderedCollection which always >> > creates a copy when the receiver is an OrderedCollection, and that >> > property is being relied on, so it can't be changed... >> > >> > > As a programmer, I do not want to choose between #merge: and #quickMerge:. Or similar. :-) >> > >> > IMO, we simply need one quick solution. If you have a Set, you may need >> > that help from the library even more. >> > #quickMerge: is only good for merging two rectangles. It does not solve >> > the GC issue #merge: has. >> > >> > >> > Levente >> > >> > > >> > > Best, >> > > Marcel >> > > >> > > Am 13.02.2021 17:05:07 schrieb commits at source.squeak.org : >> > > >> > > Nicolas Cellier uploaded a new version of Graphics to project The Inbox: >> > > http://source.squeak.org/inbox/Graphics-nice.446.mcz >> > > >> > > ==================== Summary ==================== >> > > >> > > Name: Graphics-nice.446 >> > > Author: nice >> > > Time: 13 February 2021, 5:04:52.453325 pm >> > > UUID: d13c1db2-370f-4fa6-b7ae-e6766bf0c8fb >> > > Ancestors: Graphics-dtl.445 >> > > >> > > Let Rectangle merging:/encompassing: an unordered collection. >> > > >> > > =============== Diff against Graphics-dtl.445 =============== >> > > >> > > Item was changed: >> > > ----- Method: Rectangle class>>encompassing: (in category 'instance creation') ----- >> > > encompassing: listOfPoints >> > > "A number of callers of encompass: should use this method." >> > > | topLeft bottomRight | >> > > + topLeft := bottomRight := listOfPoints anyOne. >> > > + listOfPoints do: >> > > - topLeft := bottomRight := listOfPoints first. >> > > - listOfPoints allButFirstDo: >> > > [:p |topLeft := topLeft min: p. >> > > + bottomRight := bottomRight max: p]. >> > > - bottomRight := bottomRight max: p]. >> > > ^self origin: topLeft corner: bottomRight >> > > ! >> > > >> > > Item was changed: >> > > ----- Method: Rectangle class>>merging: (in category 'instance creation') ----- >> > > merging: listOfRects >> > > "A number of callers of merge: should use this method." >> > > + | aRectangle bottomRight topLeft | >> > > + aRectangle := listOfRects anyOne. >> > > + topLeft := aRectangle topLeft. >> > > + bottomRight := aRectangle bottomRight. >> > > - | bottomRight topLeft | >> > > - topLeft := listOfRects first topLeft. >> > > - bottomRight := listOfRects first bottomRight. >> > > listOfRects >> > > + do: [:r | topLeft := topLeft min: r topLeft. >> > > - allButFirstDo: [:r | topLeft := topLeft min: r topLeft. >> > > bottomRight := bottomRight max: r bottomRight]. >> > > ^self origin: topLeft corner: bottomRight. >> > > ! >> > > >> > > >> > > >> > > >> > >> > >> > > > From bruce.oneel at pckswarms.ch Fri Feb 19 15:19:18 2021 From: bruce.oneel at pckswarms.ch (Bruce O'Neel) Date: Fri, 19 Feb 2021 16:19:18 +0100 Subject: [squeak-dev] Do you remember those sound problems we were having? Message-ID: <1613747958-d26c2d009379e830eb36da9b780c08c2@pckswarms.ch> Well I used to hear them too on my MacBook air running Linux. Now Linux Mini is 20.1, Pulse Audio is 1:13.99.1, and Squeak is 6.0alpha with update 20211, and the VM is from sources of 202101092147. And the Bach fugue sound perfect. So something changed to make it work well. Does a recent VM plus a recent Squeak 6.0 Alpha make the PI sound good? Thanks. bruce -------------- next part -------------- An HTML attachment was scrubbed... URL: From lproven at gmail.com Fri Feb 19 17:16:07 2021 From: lproven at gmail.com (Liam Proven) Date: Fri, 19 Feb 2021 18:16:07 +0100 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS Message-ID: Hello folks. New member here. Forgive me if this is the wrong channel. I did a talk at the FOSDEM conference a little under 2 weeks ago about a proposal for a new type of OS, based entirely on FOSS code. A major component of it would be Squeak. I was wondering if this would be an appropriate place to talk about it, but I don't want to spam you with links if it's the wrong channel. If this is not the right place, then where might be? -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From jecel at merlintec.com Fri Feb 19 17:45:41 2021 From: jecel at merlintec.com (Jecel Assumpcao Jr) Date: Fri, 19 Feb 2021 14:45:41 -0300 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS In-Reply-To: References: Message-ID: <20210219174547.420721A00054@proxy.email-ssl.com.br> Liam, > Hello folks. New member here. Forgive me if this is the wrong channel. > > I did a talk at the FOSDEM conference a little under 2 weeks ago about > a proposal for a new type of OS, based entirely on FOSS code. A major > component of it would be Squeak. I was wondering if this would be an > appropriate place to talk about it, but I don't want to spam you with > links if it's the wrong channel. I post the link for you, then: https://fosdem.org/2021/schedule/event/new_type_of_computer/ > If this is not the right place, then where might be? There are much better places to have this discussion, but they are all pretty much dead. So I would not have any objection to having it here. Let's see what other people think. http://mailman.mit.edu/mailman/listinfo/fonclist http://lists.tunes.org/mailman/listinfo -- Jecel From leves at caesar.elte.hu Fri Feb 19 18:53:37 2021 From: leves at caesar.elte.hu (Levente Uzonyi) Date: Fri, 19 Feb 2021 19:53:37 +0100 (CET) Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: Hi Tom, On Fri, 19 Feb 2021, Tom Beckmann wrote: > Hi everyone, > > just another idea for your consideration: > > merging3: listOfRects >     ^ listOfRects reduce: [:a :b | >          self origin: (a origin min: b origin) corner: (a corner max: b corner)] > > If you care more about performance than idioms (not even sure if this is legal): > merging4: listOfRects >     ^ listOfRects reduce: [:a :b | >          a setOrigin: (a origin min: b origin) corner: (a corner max: b corner)] > > And finally, the, in my opinion, most elegant version. Sadly, it's also the slowest. > merging5: listOfRects >      ^ listOfRects reduce: [:a :b | a quickMerge: b] > > > > Some unrepresentative benchmarks: > > " Levente's version from above with temps " > [Rectangle merging2: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '3,740,000 per second. 267 nanoseconds per run. 37.46501 % GC time.' > " the 'clean' version " > [Rectangle merging3: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '3,020,000 per second. 331 nanoseconds per run. 40.93181 % GC time.' > " the version that mutates rectangles " > [Rectangle merging4: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100} asSet] bench '3,330,000 per second. 300 nanoseconds per run. 40.53189 % GC time.' You left an #asSet send in the above benchmark. Levente > " using quickMerge " > [Rectangle merging5: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '2,930,000 per second. 341 nanoseconds per run. 42.32 % GC time.' > > Best, > Tom > > On Thu, Feb 18, 2021 at 11:17 PM Levente Uzonyi wrote: > Hi Chris, > > On Wed, 17 Feb 2021, Chris Muller wrote: > > > This is what I would do: > > > > merging: listOfRects > >     "A number of callers of merge: should use this method." > >     ^ listOfRects > >         inject: > >             (self > >                 origin: Float infinity @ Float infinity > >                 corner: Float infinity negated @ Float infinity negated) > >         into: [ : rect : each | rect quickMerge: each ] > > > > With #quickMerge:, you're only creating a new Rectangle when it needed to grow to accomodate the current element, but many of the elements might fit completely, resulting in no additional instantiation.  Do an > analysis of how > > many temporary Point objects we create -- hint: it's a ton -- and my own attempts to optimize that in my Kml framework were not fruitful (e.g., ~1%), with a trade-off of duplicating implementation across > multiple methods and > > making the system's code harder to read and understand and maintain. > > With my benchmark, your version is slower than the one from 2003, > especially when the collection is small. And it doesn't handle the case of > empty listOfRects the same way: it silently returns a rectangle instead of > raising an error. > > Here's the version I came up with the other day: > > > merging: listOfRects >         "A number of callers of merge: should use this method." > >         | minTopLeftX minTopLeftY maxBottomRightX maxBottomRightY | >         listOfRects do: [ :rectangle | >                 | topLeft bottomRight | >                 topLeft := rectangle topLeft. >                 bottomRight := rectangle bottomRight. >                 minTopLeftX >                         ifNil: [ >                                 minTopLeftX := topLeft x. >                                 minTopLeftY := topLeft y. >                                 maxBottomRightX := bottomRight x. >                                 maxBottomRightY := bottomRight y ] >                         ifNotNil: [ >                                 topLeft x < minTopLeftX ifTrue: [ minTopLeftX := topLeft x ]. >                                 topLeft y < minTopLeftY ifTrue: [ minTopLeftY := topLeft y ]. >                                 bottomRight x > maxBottomRightX ifTrue: [ maxBottomRightX := bottomRight x ]. >                                 bottomRight y > maxBottomRightY ifTrue: [ maxBottomRightY := bottomRight y ] ] ]. >         ^self origin: minTopLeftX @ minTopLeftY corner: maxBottomRightX @ maxBottomRightY > > > Levente > > > > >  - Chris > > > > > > On Wed, Feb 17, 2021 at 11:27 AM Levente Uzonyi wrote: > >       On Wed, 17 Feb 2021, Marcel Taeumel wrote: > > > >       > Hmm... looking at performance ... why not just add #asSequenceableCollection, which would only impact Set arguments? > > > >       I don't think we have such method. Adding one would raise the usual > >       question: should it create a new collection or return self if self > >       already to the requested collection kind? > >       IIRC currently the only outlier is #asOrderedCollection which always > >       creates a copy when the receiver is an OrderedCollection, and that > >       property is being relied on, so it can't be changed... > > > >       > As a programmer, I do not want to choose between #merge: and #quickMerge:. Or similar. :-) > > > >       IMO, we simply need one quick solution. If you have a Set, you may need > >       that help from the library even more. > >       #quickMerge: is only good for merging two rectangles. It does not solve > >       the GC issue #merge: has. > > > > > >       Levente > > > >       > > >       > Best, > >       > Marcel > >       > > >       >       Am 13.02.2021 17:05:07 schrieb commits at source.squeak.org : > >       > > >       >       Nicolas Cellier uploaded a new version of Graphics to project The Inbox: > >       >       http://source.squeak.org/inbox/Graphics-nice.446.mcz > >       > > >       >       ==================== Summary ==================== > >       > > >       >       Name: Graphics-nice.446 > >       >       Author: nice > >       >       Time: 13 February 2021, 5:04:52.453325 pm > >       >       UUID: d13c1db2-370f-4fa6-b7ae-e6766bf0c8fb > >       >       Ancestors: Graphics-dtl.445 > >       > > >       >       Let Rectangle merging:/encompassing: an unordered collection. > >       > > >       >       =============== Diff against Graphics-dtl.445 =============== > >       > > >       >       Item was changed: > >       >       ----- Method: Rectangle class>>encompassing: (in category 'instance creation') ----- > >       >       encompassing: listOfPoints > >       >       "A number of callers of encompass: should use this method." > >       >       | topLeft bottomRight | > >       >       + topLeft := bottomRight := listOfPoints anyOne. > >       >       + listOfPoints do: > >       >       - topLeft := bottomRight := listOfPoints first. > >       >       - listOfPoints allButFirstDo: > >       >       [:p |topLeft := topLeft min: p. > >       >       + bottomRight := bottomRight max: p]. > >       >       - bottomRight := bottomRight max: p]. > >       >       ^self origin: topLeft corner: bottomRight > >       >       ! > >       > > >       >       Item was changed: > >       >       ----- Method: Rectangle class>>merging: (in category 'instance creation') ----- > >       >       merging: listOfRects > >       >       "A number of callers of merge: should use this method." > >       >       + | aRectangle bottomRight topLeft | > >       >       + aRectangle := listOfRects anyOne. > >       >       + topLeft := aRectangle topLeft. > >       >       + bottomRight := aRectangle bottomRight. > >       >       - | bottomRight topLeft | > >       >       - topLeft := listOfRects first topLeft. > >       >       - bottomRight := listOfRects first bottomRight. > >       >       listOfRects > >       >       + do: [:r | topLeft := topLeft min: r topLeft. > >       >       - allButFirstDo: [:r | topLeft := topLeft min: r topLeft. > >       >       bottomRight := bottomRight max: r bottomRight]. > >       >       ^self origin: topLeft corner: bottomRight. > >       >       ! > >       > > >       > > >       > > >       > > > > > > > > > > From lproven at gmail.com Fri Feb 19 19:41:05 2021 From: lproven at gmail.com (Liam Proven) Date: Fri, 19 Feb 2021 20:41:05 +0100 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS In-Reply-To: <20210219174547.420721A00054@proxy.email-ssl.com.br> References: <20210219174547.420721A00054@proxy.email-ssl.com.br> Message-ID: On Fri, 19 Feb 2021 at 18:45, Jecel Assumpcao Jr wrote: > > I post the link for you, then: > > https://fosdem.org/2021/schedule/event/new_type_of_computer/ Hi again, Jecel, and thank you. :-) Since we conversed on Hacker News, I have downloaded and installed Squeak and am working my way through the Red, Green and Blue Books. I may be some time, though. I have put the slides, the script and a downloadable video on my blog as well, here: https://liam-on-linux.livejournal.com/77065.html > There are much better places to have this discussion, but they are all > pretty much dead. So I would not have any objection to having it here. > Let's see what other people think. Sounds good to me. -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From Lou at Keystone-Software.com Fri Feb 19 19:57:52 2021 From: Lou at Keystone-Software.com (Louis LaBrunda) Date: Fri, 19 Feb 2021 14:57:52 -0500 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS References: <20210219174547.420721A00054@proxy.email-ssl.com.br> Message-ID: Hi Guys, Is there any of Intel's 3D Xpoint as byte addressable ram or is it just SSDs? Lou On Fri, 19 Feb 2021 14:45:41 -0300, "Jecel Assumpcao Jr" wrote: >Liam, > >> Hello folks. New member here. Forgive me if this is the wrong channel. >> >> I did a talk at the FOSDEM conference a little under 2 weeks ago about >> a proposal for a new type of OS, based entirely on FOSS code. A major >> component of it would be Squeak. I was wondering if this would be an >> appropriate place to talk about it, but I don't want to spam you with >> links if it's the wrong channel. > >I post the link for you, then: > >https://fosdem.org/2021/schedule/event/new_type_of_computer/ > >> If this is not the right place, then where might be? > >There are much better places to have this discussion, but they are all >pretty much dead. So I would not have any objection to having it here. >Let's see what other people think. > >http://mailman.mit.edu/mailman/listinfo/fonclist > >http://lists.tunes.org/mailman/listinfo > >-- Jecel > -- Louis LaBrunda Keystone Software Corp. SkypeMe callto://PhotonDemon From lproven at gmail.com Fri Feb 19 20:10:33 2021 From: lproven at gmail.com (Liam Proven) Date: Fri, 19 Feb 2021 21:10:33 +0100 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS In-Reply-To: References: <20210219174547.420721A00054@proxy.email-ssl.com.br> Message-ID: On Fri, 19 Feb 2021 at 20:58, Louis LaBrunda wrote: > > Hi Guys, > > Is there any of Intel's 3D Xpoint as byte addressable ram or is it just SSDs? 3D Xpoint is all byte-addressable and byte-erasable, yes. It is also available in DIMM form, called NVDIMMs, that plug directly into the machine's memory bus and make it appear in the memory map. Linux being Linux, however, the primary usage model is to partition it, format it, and use it as a very very fast disk drive. :-( I wrote the section of SUSE Linux Enterprise Server's documentation concerning NVDIMMs. :-) -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From eric.gade at gmail.com Fri Feb 19 21:02:00 2021 From: eric.gade at gmail.com (Eric Gade) Date: Fri, 19 Feb 2021 16:02:00 -0500 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS In-Reply-To: References: <20210219174547.420721A00054@proxy.email-ssl.com.br> Message-ID: Hi Liam, I saw your talk and enjoyed it very much. I think people on this chain will have a lot to add, particularly about projects like SqueakNOS. I want to point you to the most recent of these kinds of efforts that I know about called CogNOS (https://github.com/nopsys/CogNOS) . I am not affiliated with this project though and don't really know the status of it. On Fri, Feb 19, 2021 at 3:10 PM Liam Proven wrote: I did a talk at the FOSDEM conference a little under 2 weeks ago about > a proposal for a new type of OS, based entirely on FOSS code. A major > component of it would be Squeak. > > -- Eric -------------- next part -------------- An HTML attachment was scrubbed... URL: From Lou at Keystone-Software.com Fri Feb 19 21:46:03 2021 From: Lou at Keystone-Software.com (Louis LaBrunda) Date: Fri, 19 Feb 2021 16:46:03 -0500 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS References: <20210219174547.420721A00054@proxy.email-ssl.com.br> Message-ID: Hi Guys, Thanks for the reply. >> Is there any of Intel's 3D Xpoint as byte addressable ram or is it just SSDs? >3D Xpoint is all byte-addressable and byte-erasable, yes. >It is also available in DIMM form, called NVDIMMs, that plug directly >into the machine's memory bus and make it appear in the memory map. >Linux being Linux, however, the primary usage model is to partition >it, format it, and use it as a very very fast disk drive. :-( When Intel first announced this memory (years ago now) I realized right away it's potential as an object database for Smalltalk. The OS would need to be changed to assign it to a given userId or program. The Smalltalk VM would need to recognize it as a special object memory that contained persistent objects and deal with it properly. I don't think the change to the OS or the VM should be a very big deal. I hadn't heard much about the memory a while. Searching now I see that 256GB goes for about $1900 and 512GB for $9000, not cheap. If the prices come down and the size goes up, it would be a great object database with all the ease of accessing the data (objects) via Smalltalk. Lou >I wrote the section of SUSE Linux Enterprise Server's documentation >concerning NVDIMMs. :-) -- Louis LaBrunda Keystone Software Corp. SkypeMe callto://PhotonDemon From lproven at gmail.com Fri Feb 19 23:51:01 2021 From: lproven at gmail.com (Liam Proven) Date: Sat, 20 Feb 2021 00:51:01 +0100 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS In-Reply-To: References: <20210219174547.420721A00054@proxy.email-ssl.com.br> Message-ID: On Fri, 19 Feb 2021 at 22:02, Eric Gade wrote: > > Hi Liam, > > I saw your talk and enjoyed it very much. Thank you -- I'm very pleased and flattered to hear that! > I think people on this chain will have a lot to add, I rather thought they might. ;-) > particularly about projects like SqueakNOS. I am aware of it and have read about it in as much depth as I was able to follow, some time ago. I made a very brief mention of SqueakNOS in the talk when introducing Squeak itself, when I said: « The latest development in Smalltalk is an educational programming environment called Squeak. Its runtime is implemented in C, *and there’s even a bare-metal version*, but Smalltalk runtimes have been built in other languages, including Javascript. The JIT technology in Oracle’s JVM started off as a Smalltalk engine called StrongTalk. » > I want to point you to the most recent of these kinds of efforts that I know about called CogNOS (https://github.com/nopsys/CogNOS). > I am not affiliated with this project though and don't really know the status of it. That flavour is new to me and I was previously unfamiliar with it. Thanks for the info. I have had a quick read and I am glad to see that there is some life, but no commits in 2 years suggests perhaps not that much... I was taken aback to see commits by "charig" but it is not Francis Charig as for a wild moment I thought it might be. Charig was one of the founders of Tao Group, who created Taos and later Elate and Intent, perhaps the most technically impressive OSes I've ever seen. https://en.wikipedia.org/wiki/Francis_Charig But this ChariG is Guido Chari and the username seems to be a coincidence. I very much do not want to tread on anyone's toes or upset anyone, but let me try to explain why I proposed something different to the SqueakNOS approach. I explain my reasoning in more detail in the talk itself -- the script is here, BTW: https://docs.google.com/document/d/1wM1-c7euvQaRaCL4hKCaE8VRJ8OxpVdkzHxQF_8X5So/edit But I had two main goals: [1] eliminate absolutely as much of the existing legacy technology stack as possible. This very much includes eliminating the C language. [2] that my proposed design should be portable and readily and easily adapted to different CPU architectures; at a minimum, x86-64 and ARM. As I understand it -- please correct me if I am wrong -- SqueakNOS is C-based and only supports x86. A third goal, one perhaps much more difficult to achieve, was to offer choices, and as a second option, harder to implement and based on less-complete code, I also proposed, instead of a Smalltalk layer, a Lisp layer, to include both a conventional Lisp and the friendlier, higher-level Dylan language. In an ideal world, perhaps these could be to some degree interoperable. A man can dream. Such goals imply, to me, a relatively mature, high-performance, small OS underneath, delivering some degree of portability -- something written in a type-safe, memory-managed language, with multiprocessor support and networking and so on already present, so that these things do not have to be implemented in the higher-level system. My suggestion for that OS is the Oberon system, specifically the version called A2. It has its own windowing GUI, called Bluebottle, which I think would be largely irrelevant to Squeak, but it already has a native x86 version (alongside Windows, Linux and macOS hosted forms) and formerly also supported StrongARM and a number of other CPUs. It is SMP- and multicore-capable, supports Ethernet and TCP/IP, a USB stack and so on. -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From lproven at gmail.com Fri Feb 19 23:58:21 2021 From: lproven at gmail.com (Liam Proven) Date: Sat, 20 Feb 2021 00:58:21 +0100 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS In-Reply-To: References: <20210219174547.420721A00054@proxy.email-ssl.com.br> Message-ID: On Fri, 19 Feb 2021 at 22:46, Louis LaBrunda wrote: > > I hadn't heard much about the memory a while. Searching now I see that 256GB goes for about $1900 and 512GB for $9000, > not cheap. If the prices come down and the size goes up, it would be a great object database with all the ease of > accessing the data (objects) via Smalltalk. I don't know where you are looking but those figures look *wildly* off to me. A tiny 16GB disk is $20: https://www.amazon.com/Intel-Optane-Memory-Module-MEMPEK1W016GA/dp/B07CGYTXQK/ A bigger 256GB one only $99: https://www.amazon.com/Intel-760P-256GB-80mm-PCIe/dp/B078VBL3T9/ Intel also offers NVDIMM modules but those do not currently appear on Amazon. https://www.extremetech.com/computing/259155-micron-launches-new-nand-based-dimms-intel-announces-optane-dimms https://techunplugged.io/2020/07/03/intel-announces-2nd-gen-optane-persistent-memory-modules/ -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From jecel at merlintec.com Sat Feb 20 00:19:47 2021 From: jecel at merlintec.com (Jecel Assumpcao Jr) Date: Fri, 19 Feb 2021 21:19:47 -0300 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS In-Reply-To: References: <20210219174547.420721A00054@proxy.email-ssl.com.br> Message-ID: <20210220001952.9E4949C03DC@proxy.email-ssl.com.br> Liam, > As I understand it -- please correct me if I am wrong -- SqueakNOS is > C-based and only supports x86. CogNOS is a bit more dependent on C than SqueakNOS, but neither is really built on C. The bulk of the code is written in Slang, which is a restricted subset of Smalltalk-80. This gets translated to C which is then compiled to whatever processor you use but it would be a relatively small project to eliminate the C step. If you want to use some of the VM extensions that happen to be written in C instead of Slang then you would indeed need C. The drivers are written in normal Smalltalk-80 and so don't depend at all on the x86 (or C). But they do mean you can use only a particular Ethernet card or a specific interrupt chip. You need PS/2 keyboard and mouse. So I would say it only supports PCs, but the processor can be any one you like. That is for the interpreter. If you want to use the Cog compiler then the processor must be ARM32, ARM64, x86, AMD64 or MIPS since those are currently the ones for which code generators have been implemented. > My suggestion for that OS is the Oberon system, specifically the > version called A2. [...] In the early 1990s a friend saw that I was designing Smalltalk computers and suggested that I should consider Oberon. I was already familiar with the older Lilith project and was happy to try it on the 386 machine I had at the time. While I liked it a lot I felt it was too static to grow very far. I felt the same thing about the C++ based BeOS and though they had some great results and amazing applications I don't think I was wrong about that. -- Jecel From tomjonabc at gmail.com Sat Feb 20 12:28:48 2021 From: tomjonabc at gmail.com (Tom Beckmann) Date: Sat, 20 Feb 2021 12:28:48 +0000 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: Hi Levente, hi Nicolas, To Levente's comment: > You left an #asSet send in the above benchmark. Oups, indeed. But I think the actual measurement was done without the asSet, I just added it later for experimentation. The numbers appear consistent when I rerun the lines without #asSet. After sending the mail, I also realized that the setOrigin:corner:/merging4: version is of course not legal, since we mutate the original rectangle that was passed in. To Nicolas' comment: > But that's precisely what we try to avoid here: create lots of > intermediate short-lived objects (Rectangle and Point). > This is because it may be a performance critical routine. The most optimized version with the inlined temporaries is a great implementation but looks like quite a beast to me, which in my opinion would be sad for something that appears in our standard library. After looking for senders of Rectangle class>>merging: in my trunk image I only saw one critical path in recordInvalidRect:, which appears to on average trigger merging: only once per damaged frame. Is there another use case we know of? Best regards, Tom On Fri, Feb 19, 2021 at 6:53 PM Levente Uzonyi wrote: > Hi Tom, > > On Fri, 19 Feb 2021, Tom Beckmann wrote: > > > Hi everyone, > > > > just another idea for your consideration: > > > > merging3: listOfRects > > ^ listOfRects reduce: [:a :b | > > self origin: (a origin min: b origin) corner: (a corner max: b > corner)] > > > > If you care more about performance than idioms (not even sure if this is > legal): > > merging4: listOfRects > > ^ listOfRects reduce: [:a :b | > > a setOrigin: (a origin min: b origin) corner: (a corner max: b > corner)] > > > > And finally, the, in my opinion, most elegant version. Sadly, it's also > the slowest. > > merging5: listOfRects > > ^ listOfRects reduce: [:a :b | a quickMerge: b] > > > > > > > > Some unrepresentative benchmarks: > > > > " Levente's version from above with temps " > > [Rectangle merging2: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ > 80. 30 @ 30 extent: 100 @ 100}] bench '3,740,000 per second. 267 > nanoseconds per run. 37.46501 % GC time.' > > " the 'clean' version " > > [Rectangle merging3: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ > 80. 30 @ 30 extent: 100 @ 100}] bench '3,020,000 per second. 331 > nanoseconds per run. 40.93181 % GC time.' > > " the version that mutates rectangles " > > [Rectangle merging4: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ > 80. 30 @ 30 extent: 100 @ 100} asSet] bench '3,330,000 per second. 300 > nanoseconds per run. 40.53189 % GC time.' > > You left an #asSet send in the above benchmark. > > > Levente > > > " using quickMerge " > > [Rectangle merging5: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ > 80. 30 @ 30 extent: 100 @ 100}] bench '2,930,000 per second. 341 > nanoseconds per run. 42.32 % GC time.' > > > > Best, > > Tom > > > > On Thu, Feb 18, 2021 at 11:17 PM Levente Uzonyi > wrote: > > Hi Chris, > > > > On Wed, 17 Feb 2021, Chris Muller wrote: > > > > > This is what I would do: > > > > > > merging: listOfRects > > > "A number of callers of merge: should use this method." > > > ^ listOfRects > > > inject: > > > (self > > > origin: Float infinity @ Float infinity > > > corner: Float infinity negated @ Float infinity > negated) > > > into: [ : rect : each | rect quickMerge: each ] > > > > > > With #quickMerge:, you're only creating a new Rectangle when it > needed to grow to accomodate the current element, but many of the elements > might fit completely, resulting in no additional instantiation. Do an > > analysis of how > > > many temporary Point objects we create -- hint: it's a ton -- > and my own attempts to optimize that in my Kml framework were not fruitful > (e.g., ~1%), with a trade-off of duplicating implementation across > > multiple methods and > > > making the system's code harder to read and understand and > maintain. > > > > With my benchmark, your version is slower than the one from 2003, > > especially when the collection is small. And it doesn't handle the > case of > > empty listOfRects the same way: it silently returns a rectangle > instead of > > raising an error. > > > > Here's the version I came up with the other day: > > > > > > merging: listOfRects > > "A number of callers of merge: should use this method." > > > > | minTopLeftX minTopLeftY maxBottomRightX maxBottomRightY | > > listOfRects do: [ :rectangle | > > | topLeft bottomRight | > > topLeft := rectangle topLeft. > > bottomRight := rectangle bottomRight. > > minTopLeftX > > ifNil: [ > > minTopLeftX := topLeft x. > > minTopLeftY := topLeft y. > > maxBottomRightX := bottomRight x. > > maxBottomRightY := bottomRight y ] > > ifNotNil: [ > > topLeft x < minTopLeftX ifTrue: [ > minTopLeftX := topLeft x ]. > > topLeft y < minTopLeftY ifTrue: [ > minTopLeftY := topLeft y ]. > > bottomRight x > maxBottomRightX > ifTrue: [ maxBottomRightX := bottomRight x ]. > > bottomRight y > maxBottomRightY > ifTrue: [ maxBottomRightY := bottomRight y ] ] ]. > > ^self origin: minTopLeftX @ minTopLeftY corner: > maxBottomRightX @ maxBottomRightY > > > > > > Levente > > > > > > > > - Chris > > > > > > > > > On Wed, Feb 17, 2021 at 11:27 AM Levente Uzonyi < > leves at caesar.elte.hu> wrote: > > > On Wed, 17 Feb 2021, Marcel Taeumel wrote: > > > > > > > Hmm... looking at performance ... why not just add > #asSequenceableCollection, which would only impact Set arguments? > > > > > > I don't think we have such method. Adding one would raise > the usual > > > question: should it create a new collection or return self > if self > > > already to the requested collection kind? > > > IIRC currently the only outlier is #asOrderedCollection > which always > > > creates a copy when the receiver is an OrderedCollection, > and that > > > property is being relied on, so it can't be changed... > > > > > > > As a programmer, I do not want to choose between #merge: > and #quickMerge:. Or similar. :-) > > > > > > IMO, we simply need one quick solution. If you have a Set, > you may need > > > that help from the library even more. > > > #quickMerge: is only good for merging two rectangles. It > does not solve > > > the GC issue #merge: has. > > > > > > > > > Levente > > > > > > > > > > > Best, > > > > Marcel > > > > > > > > Am 13.02.2021 17:05:07 schrieb > commits at source.squeak.org : > > > > > > > > Nicolas Cellier uploaded a new version of Graphics > to project The Inbox: > > > > > http://source.squeak.org/inbox/Graphics-nice.446.mcz > > > > > > > > ==================== Summary ==================== > > > > > > > > Name: Graphics-nice.446 > > > > Author: nice > > > > Time: 13 February 2021, 5:04:52.453325 pm > > > > UUID: d13c1db2-370f-4fa6-b7ae-e6766bf0c8fb > > > > Ancestors: Graphics-dtl.445 > > > > > > > > Let Rectangle merging:/encompassing: an unordered > collection. > > > > > > > > =============== Diff against Graphics-dtl.445 > =============== > > > > > > > > Item was changed: > > > > ----- Method: Rectangle class>>encompassing: (in > category 'instance creation') ----- > > > > encompassing: listOfPoints > > > > "A number of callers of encompass: should use this > method." > > > > | topLeft bottomRight | > > > > + topLeft := bottomRight := listOfPoints anyOne. > > > > + listOfPoints do: > > > > - topLeft := bottomRight := listOfPoints first. > > > > - listOfPoints allButFirstDo: > > > > [:p |topLeft := topLeft min: p. > > > > + bottomRight := bottomRight max: p]. > > > > - bottomRight := bottomRight max: p]. > > > > ^self origin: topLeft corner: bottomRight > > > > ! > > > > > > > > Item was changed: > > > > ----- Method: Rectangle class>>merging: (in > category 'instance creation') ----- > > > > merging: listOfRects > > > > "A number of callers of merge: should use this > method." > > > > + | aRectangle bottomRight topLeft | > > > > + aRectangle := listOfRects anyOne. > > > > + topLeft := aRectangle topLeft. > > > > + bottomRight := aRectangle bottomRight. > > > > - | bottomRight topLeft | > > > > - topLeft := listOfRects first topLeft. > > > > - bottomRight := listOfRects first bottomRight. > > > > listOfRects > > > > + do: [:r | topLeft := topLeft min: r topLeft. > > > > - allButFirstDo: [:r | topLeft := topLeft min: r > topLeft. > > > > bottomRight := bottomRight max: r bottomRight]. > > > > ^self origin: topLeft corner: bottomRight. > > > > ! > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Sat Feb 20 11:46:59 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sat, 20 Feb 2021 11:46:59 0000 Subject: [squeak-dev] The Trunk: Morphic-mt.1724.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.1724.mcz ==================== Summary ==================== Name: Morphic-mt.1724 Author: mt Time: 20 February 2021, 12:46:52.542759 pm UUID: 635e4922-d576-8b43-b47e-6529b967d1a4 Ancestors: Morphic-mt.1723 Extracts gridding from PasteUpMorph as new layout policy: GridLayout -- so that it is available to any morph. - Adjust drag implementation in resizer-grips and splitters to be relative to the mouse-down position to make gridding feel better - Adds "self disableLayout: true" to avoid gridding in overlay morphs such as dialogs, flaps, balloons, menus - Adds new preference(s) for enabling the project world's grid - Inst var "griddingOn" no longer needed in PasteUpMorph - Removes all those scattered "gridPoint:" calls bc. layout policy takes care of that now - Some code clean-up in table-layout properties - Documents an interesting bug in HandMorph >> #handleEvent:, which is not caused by this change =============== Diff against Morphic-mt.1723 =============== Item was changed: ----- Method: AbstractResizerMorph>>mouseDown: (in category 'event handling') ----- mouseDown: anEvent + self referencePoint: anEvent position - self position.! - self referencePoint: anEvent position.! Item was changed: ----- Method: BalloonMorph>>initialize (in category 'initialization') ----- initialize "initialize the state of the receiver" super initialize. + self disableLayout: true. "" self beSmoothCurve. offsetFromTarget := 0 @ 0. self setDefaultParameters.! Item was changed: ----- Method: BorderedMorph>>doFastWindowReframe: (in category 'resize handling') ----- doFastWindowReframe: ptName | newBounds delta | "For fast display, only higlight the rectangle during loop" newBounds := self bounds newRectButtonPressedDo: [:f | f withSideOrCorner: ptName setToPoint: (self pointFromWorld: Sensor cursorPoint) minExtent: self minimumExtent]. delta := newBounds origin - self bounds origin. self bounds: newBounds. self flag: #workaround. "mt: Due to a layout-specific 'let us start in the top-left corner of a layout cell'-behavior, we have to go up the owner chain and propagate the delta. See Morph >> #layoutInBounds:positioning: and there section 1.2." self allOwnersDo: [:owner | + (owner layoutPolicy notNil and: [owner ~~ Project current world]) + ifTrue: [owner topLeft: owner topLeft + delta]]. - owner layoutPolicy ifNotNil: [owner topLeft: owner topLeft + delta]]. ^newBounds.! Item was changed: ----- Method: BottomLeftGripMorph>>apply: (in category 'target resize') ----- apply: delta | oldBounds | oldBounds := self target bounds. self target bounds: (oldBounds origin + (delta x @ 0) corner: oldBounds corner + (0 @ delta y)). self flag: #workaround. "mt: Due to a layout-specific 'let us start in the top-left corner of a layout cell'-behavior, we have to go up the owner chain and propagate the delta. See Morph >> #layoutInBounds:positioning: and there section 1.2." self target allOwnersDo: [:owner | + (owner layoutPolicy notNil and: [owner ~~ Project current world]) + ifTrue: [owner left: owner left + delta x]].! - owner layoutPolicy ifNotNil: [owner left: owner left + delta x]].! Item was changed: ----- Method: CornerGripMorph>>mouseMove: (in category 'event handling') ----- mouseMove: anEvent | delta | self target ifNil: [^ self]. self target fastFramingOn ifTrue: [delta := self target doFastWindowReframe: self ptName] ifFalse: [ + delta := anEvent position - (self referencePoint + self position). - delta := self referencePoint ifNil: [0 at 0] ifNotNil: [anEvent position - self referencePoint]. - self referencePoint: anEvent position. self apply: delta. self bounds: (self bounds origin + delta extent: self bounds extent)].! Item was changed: ----- Method: DialogWindow>>createFilter (in category 'initialization') ----- createFilter "This is an invisible morph that catches keystrokes to filter content in multiple widgets at once. Needs #filterEnabled to be true." filterMorph := '' asText asMorph lock. filterMorph name: 'Filter'; visible: false; + disableLayout: true. - disableTableLayout: true. ^ filterMorph! Item was changed: ----- Method: DialogWindow>>initialize (in category 'initialization') ----- initialize super initialize. self changeTableLayout; listDirection: #topToBottom; hResizing: #shrinkWrap; vResizing: #shrinkWrap; rubberBandCells: true; + disableLayout: true; setProperty: #indicateKeyboardFocus toValue: #never. self createTitle: 'Dialog'. self createBody. self setDefaultParameters. keyMap := Dictionary new. exclusive := true. autoCancel := false. preferredPosition := self currentWorld center.! Item was changed: ----- Method: DialogWindow>>updateFilter (in category 'updating') ----- updateFilter self buttons do: [:ea | ea enabled: (self filter isEmpty or: [ea label asString includesSubstring: self filter caseSensitive: false])]. filterMorph visible: self filter notEmpty; + disableLayout: self filter isEmpty; - disableTableLayout: self filter isEmpty; contents: '<', self filter, '>'; textColor: self messageMorph textColor. self ensureSelectedButton.! Item was added: + LayoutPolicy subclass: #GridLayout + instanceVariableNames: '' + classVariableNames: '' + poolDictionaries: '' + category: 'Morphic-Layouts'! Item was added: + ----- Method: GridLayout>>griddedPoint:in: (in category 'layout') ----- + griddedPoint: ungriddedPoint in: container + "For convenience only. Manually grid a point from the outside." + + | properties | + properties := container assureGridLayoutProperties. + ^ ((ungriddedPoint - container position - properties origin) + grid: properties modulus) + + container position + properties origin! Item was added: + ----- Method: GridLayout>>isGridLayout (in category 'testing') ----- + isGridLayout + + ^ true! Item was added: + ----- Method: GridLayout>>layout:in: (in category 'layout') ----- + layout: container in: box + "Moves and resizes the container's submorphs to snap to the grid cells. Ignore edge-adhereing morphs such as docking bars." + + | properties cellOrigin cellExtent | + properties := container assureGridLayoutProperties. + container submorphsDo: [:morph | + (morph disableLayout or: [morph hasProperty: #edgeToAdhereTo]) ifFalse: [ + cellOrigin := ((morph position - container position - properties origin) + grid: properties modulus) + + container position + properties origin. + cellExtent := (morph extent grid: properties modulus) max: properties modulus "= minExtent". + morph layoutInBounds: (cellOrigin extent: cellExtent) positioning: properties cellPositioning]].! Item was added: + LayoutProperties subclass: #GridLayoutProperties + instanceVariableNames: 'origin modulus layoutInset' + classVariableNames: '' + poolDictionaries: '' + category: 'Morphic-Layouts'! Item was added: + ----- Method: GridLayoutProperties>>includesGridLayoutProperties (in category 'testing') ----- + includesGridLayoutProperties + + ^ true! Item was added: + ----- Method: GridLayoutProperties>>initialize (in category 'initialize') ----- + initialize + + super initialize. + + origin := 0 at 0. + modulus := 8 at 8. + layoutInset := 0.! Item was added: + ----- Method: GridLayoutProperties>>layoutInset (in category 'accessing') ----- + layoutInset + + self flag: #todo. "mt: Move up to LayoutProperties." + ^ layoutInset! Item was added: + ----- Method: GridLayoutProperties>>layoutInset: (in category 'accessing') ----- + layoutInset: anObject + + self flag: #todo. "mt: Move up to LayoutProperties." + layoutInset := anObject.! Item was added: + ----- Method: GridLayoutProperties>>modulus (in category 'accessing') ----- + modulus + + ^ modulus! Item was added: + ----- Method: GridLayoutProperties>>modulus: (in category 'accessing') ----- + modulus: anObject + + modulus := anObject.! Item was added: + ----- Method: GridLayoutProperties>>origin (in category 'accessing') ----- + origin + + self flag: #discuss. "mt: Is this really needed? We could easily configure this through #layoutInset." + ^ origin! Item was added: + ----- Method: GridLayoutProperties>>origin: (in category 'accessing') ----- + origin: anObject + + origin := anObject.! Item was changed: ----- Method: HaloMorph>>doDrag:with: (in category 'private') ----- doDrag: evt with: dragHandle | thePoint | evt hand obtainHalo: self. thePoint := target point: evt position - positionOffset from: owner. + target setConstrainedPosition: thePoint hangOut: true. - target setConstrainedPosition:(target griddedPoint: thePoint) hangOut: true. ! Item was changed: ----- Method: HaloMorph>>doGrow:with: (in category 'private') ----- doGrow: evt with: growHandle "Called while the mouse is down in the grow handle" | newExtent extentToUse scale | evt hand obtainHalo: self. + newExtent := (target pointFromWorld: evt cursorPoint - positionOffset) - newExtent := (target pointFromWorld: (target griddedPoint: evt cursorPoint - positionOffset)) - target topLeft. evt shiftPressed ifTrue: [ scale := (newExtent x / (originalExtent x max: 1)) min: (newExtent y / (originalExtent y max: 1)). newExtent := (originalExtent x * scale) asInteger @ (originalExtent y * scale) asInteger ]. (newExtent x < 1 or: [newExtent y < 1 ]) ifTrue: [^ self]. target renderedMorph setExtentFromHalo: (extentToUse := newExtent). growHandle position: evt cursorPoint - (growHandle extent // 2). self layoutChanged. (self valueOfProperty: #commandInProgress) ifNotNil: [:cmd | "Update the final extent" cmd redoTarget: target renderedMorph selector: #setFlexExtentFromHalo: argument: extentToUse] ! Item was changed: ----- Method: HandMorph>>griddedPoint: (in category 'gridded cursor') ----- griddedPoint: aPoint "return the equivalent point snapped to the grid, if indeed any gridding is set" + self valueOfProperty: #gridStep ifPresentDo: [:step | | offset | - self valueOfProperty: #gridStep ifPresentDo: [:grid| |offset| offset := self valueOfProperty: #gridOffset ifAbsent: [0 at 0]. + ^ ((aPoint + targetOffset - offset) grid: step) - targetOffset + offset]. - ^ offset + (aPoint + (grid //2) - offset truncateTo: grid)]. ^aPoint! Item was added: + ----- Method: HandMorph>>griddingOn (in category 'gridded cursor') ----- + griddingOn + + ^ self hasSubmorphs + and: [(self hasProperty: #gridStep) + and: [self firstSubmorph disableLayout not]]! Item was changed: ----- Method: HandMorph>>handleEvent: (in category 'events-processing') ----- handleEvent: unfilteredEvent | filteredEvent | owner ifNil: [^ unfilteredEvent "not necessary but good style -- see Morph >> #handleEvent:"]. self logEvent: unfilteredEvent. "Mouse-over events occur really, really, really often. They are kind of the heart beat of the Morphic UI process." unfilteredEvent isMouseOver ifTrue: [^ self sendMouseEvent: unfilteredEvent]. self showEvent: unfilteredEvent. self sendListenEvents: unfilteredEvent. filteredEvent := self sendFilterEventCapture: unfilteredEvent for: nil. "filteredEvent := unfilteredEvent" " <-- use this to disable global capture filters" filteredEvent wasIgnored ifTrue: [ self mouseOverHandler processMouseOver: lastMouseEvent. ^ filteredEvent]. filteredEvent isWindowEvent ifTrue: [ self sendEvent: filteredEvent focus: nil. self mouseOverHandler processMouseOver: lastMouseEvent. ^ filteredEvent]. filteredEvent isKeyboard ifTrue:[ self sendKeyboardEvent: filteredEvent. self mouseOverHandler processMouseOver: lastMouseEvent. ^ filteredEvent]. filteredEvent isDropEvent ifTrue:[ self sendEvent: filteredEvent focus: nil. self mouseOverHandler processMouseOver: lastMouseEvent. ^ filteredEvent]. filteredEvent isMouse ifFalse: [ self mouseOverHandler processMouseOver: lastMouseEvent. ^ filteredEvent]. " ********** MOUSE EVENT *********** " lastMouseEvent := filteredEvent. "Check for pending drag or double click operations." mouseClickState ifNotNil:[ (mouseClickState handleEvent: filteredEvent from: self) ifFalse:[ "Possibly dispatched #click: or something and will not re-establish otherwise" self mouseOverHandler processMouseOver: lastMouseEvent. ^ filteredEvent]]. filteredEvent isMouseWheel ifTrue: [ self class sendMouseWheelToKeyboardFocus ifFalse: [self sendMouseEvent: filteredEvent] ifTrue: [self sendEvent: filteredEvent focus: self keyboardFocus clear: [self keyboardFocus: nil]]. self mouseOverHandler processMouseOver: lastMouseEvent. ^ filteredEvent]. filteredEvent isMove ifTrue:[ self position: filteredEvent position. self sendMouseEvent: filteredEvent. self mouseOverHandler processMouseOver: lastMouseEvent. ^ filteredEvent]. "Issue a synthetic move event if we're not at the position of the event" + self flag: #bug. "mt: Incompatible with how #mouseMove: is handled when #wantsEveryMouseMove: answers false. Handler might think that #mouseDown: was already received. For example, TextEditor and HaloMorph will issue drags in their #mouseMove: based on old data. That is, the first #mouseMove: appears to come before #mouseDown: while actually sent due to #moveToEvent:." filteredEvent position = self position ifFalse: [self moveToEvent: filteredEvent]. "Drop submorphs on button events" self hasSubmorphs ifTrue:[self dropMorphs: filteredEvent] ifFalse:[self sendMouseEvent: filteredEvent]. self mouseOverHandler processMouseOver: lastMouseEvent. ^ filteredEvent "not necessary but good style -- see Morph >> #handleEvent:" ! Item was changed: ----- Method: HandMorph>>position: (in category 'geometry') ----- + position: ungriddedPosition - position: aPoint "Overridden to align submorph origins to the grid if gridding is on." | adjustedPosition delta box | + adjustedPosition := ungriddedPosition. + self griddingOn + ifTrue: [adjustedPosition := self griddedPoint: ungriddedPosition]. + temporaryCursor + ifNotNil: [adjustedPosition := adjustedPosition + temporaryCursorOffset]. - adjustedPosition := aPoint. - temporaryCursor ifNotNil: [adjustedPosition := (self griddedPoint: adjustedPosition) + temporaryCursorOffset]. "Copied from Morph to avoid owner layoutChanged" "Change the position of this morph and and all of its submorphs." delta := adjustedPosition - bounds topLeft. delta isZero ifTrue: [^ self]. "Null change" box := self fullBounds. (delta dotProduct: delta) > 100 ifTrue:[ "e.g., more than 10 pixels moved" self invalidRect: box. self invalidRect: (box translateBy: delta). ] ifFalse:[ self invalidRect: (box merge: (box translateBy: delta)). ]. self privateFullMoveBy: delta. ! Item was added: + ----- Method: HandMorph>>turnOnGridding (in category 'gridded cursor') ----- + turnOnGridding + + self + gridTo: self world gridModulus + origin: self world gridOrigin.! Item was changed: ----- Method: HandleMorph>>initialize (in category 'initialization') ----- initialize "initialize the state of the receiver" super initialize. "" self extent: 16 @ 16. + self disableLayout: true.! - ! Item was added: + ----- Method: LayoutPolicy>>isGridLayout (in category 'testing') ----- + isGridLayout + + ^ false! Item was added: + ----- Method: LayoutProperties>>asGridLayoutProperties (in category 'converting') ----- + asGridLayoutProperties + + ^ GridLayoutProperties new + hResizing: self hResizing; + vResizing: self vResizing; + disableLayout: self disableLayout; + yourself! Item was changed: ----- Method: LayoutProperties>>asTableLayoutProperties (in category 'converting') ----- asTableLayoutProperties + + ^ TableLayoutProperties new - ^(TableLayoutProperties new) hResizing: self hResizing; vResizing: self vResizing; + disableLayout: self disableLayout; - disableTableLayout: self disableTableLayout; yourself! Item was changed: + ----- Method: LayoutProperties>>cellGap (in category 'defaults - table layout') ----- - ----- Method: LayoutProperties>>cellGap (in category 'table defaults') ----- cellGap "Default" ^0! Item was changed: + ----- Method: LayoutProperties>>cellInset (in category 'defaults - table layout') ----- - ----- Method: LayoutProperties>>cellInset (in category 'table defaults') ----- cellInset "Default" ^0! Item was changed: + ----- Method: LayoutProperties>>cellPositioning (in category 'defaults - table layout') ----- - ----- Method: LayoutProperties>>cellPositioning (in category 'table defaults') ----- cellPositioning ^#center! Item was changed: + ----- Method: LayoutProperties>>cellSpacing (in category 'defaults - table layout') ----- - ----- Method: LayoutProperties>>cellSpacing (in category 'table defaults') ----- cellSpacing "Default" ^#none! Item was added: + ----- Method: LayoutProperties>>includesGridLayoutProperties (in category 'testing') ----- + includesGridLayoutProperties + + ^ false! Item was added: + ----- Method: LayoutProperties>>includesTableLayoutProperties (in category 'testing') ----- + includesTableLayoutProperties + + ^ false! Item was removed: - ----- Method: LayoutProperties>>includesTableProperties (in category 'testing') ----- - includesTableProperties - ^false! Item was changed: ----- Method: LayoutProperties>>initializeFrom: (in category 'initialize') ----- initializeFrom: defaultProvider "Initialize the receiver from a default provider" + self hResizing: defaultProvider hResizing. self vResizing: defaultProvider vResizing. + self disableLayout: defaultProvider disableLayout.! - self disableTableLayout: defaultProvider disableTableLayout.! Item was changed: + ----- Method: LayoutProperties>>layoutInset (in category 'defaults - table layout') ----- - ----- Method: LayoutProperties>>layoutInset (in category 'table defaults') ----- layoutInset ^0! Item was changed: + ----- Method: LayoutProperties>>listCentering (in category 'defaults - table layout') ----- - ----- Method: LayoutProperties>>listCentering (in category 'table defaults') ----- listCentering "Default" ^#topLeft! Item was changed: + ----- Method: LayoutProperties>>listDirection (in category 'defaults - table layout') ----- - ----- Method: LayoutProperties>>listDirection (in category 'table defaults') ----- listDirection "Default" ^#topToBottom! Item was changed: + ----- Method: LayoutProperties>>listSpacing (in category 'defaults - table layout') ----- - ----- Method: LayoutProperties>>listSpacing (in category 'table defaults') ----- listSpacing "Default" ^#none! Item was changed: + ----- Method: LayoutProperties>>maxCellSize (in category 'defaults - table layout') ----- - ----- Method: LayoutProperties>>maxCellSize (in category 'table defaults') ----- maxCellSize ^SmallInteger maxVal! Item was changed: + ----- Method: LayoutProperties>>minCellSize (in category 'defaults - table layout') ----- - ----- Method: LayoutProperties>>minCellSize (in category 'table defaults') ----- minCellSize ^0! Item was added: + ----- Method: LayoutProperties>>modulus (in category 'defaults - grid layout') ----- + modulus + + ^ 8 at 8! Item was added: + ----- Method: LayoutProperties>>origin (in category 'defaults - grid layout') ----- + origin + + ^ 0 at 0! Item was added: + ----- Method: LayoutProperties>>printOn: (in category 'printing') ----- + printOn: stream + + self flag: #todo. "mt: Find a more readable format. Maybe with line breaks and tabs." + self storeOn: stream.! Item was changed: + ----- Method: LayoutProperties>>reverseTableCells (in category 'defaults - table layout') ----- - ----- Method: LayoutProperties>>reverseTableCells (in category 'table defaults') ----- reverseTableCells ^false! Item was changed: + ----- Method: LayoutProperties>>rubberBandCells (in category 'defaults - table layout') ----- - ----- Method: LayoutProperties>>rubberBandCells (in category 'table defaults') ----- rubberBandCells ^false! Item was added: + ----- Method: LayoutProperties>>storeOn: (in category 'printing') ----- + storeOn: stream + + | defaultProperties uniquePropertiesNames | + defaultProperties := self class new. + uniquePropertiesNames := self class allInstVarNames + select: [:name | (self instVarNamed: name) ~= (defaultProperties instVarNamed: name)]. + stream + nextPutAll: '(', self species name; + nextPutAll: ' new'. + uniquePropertiesNames + do: [:name | + stream + nextPutAll: ' ', name, ': '; + store: (self instVarNamed: name); + nextPut: $;]. + stream nextPutAll: ' yourself)'.! Item was removed: - ----- Method: LayoutProperties>>stringWithLayout (in category 'table defaults') ----- - stringWithLayout - | defaultValues uniqueValues | - defaultValues := TableLayoutProperties new. - uniqueValues := self class allInstVarNames - select: [:title | (self instVarNamed: title) - ~= (defaultValues instVarNamed: title)]. - ^ String - streamContents: [:aStream | - aStream nextPutAll: 'TableLayout new; '. - uniqueValues - do: [:title | aStream nextPutAll: title; - nextPut: $:; - space; - - print: (self instVarNamed: title). - (title = uniqueValues last) - ifTrue:[ aStream nextPut:$.] - ifFalse:[ aStream nextPut: $;; cr] - ]]! Item was changed: + ----- Method: LayoutProperties>>wrapCentering (in category 'defaults - table layout') ----- - ----- Method: LayoutProperties>>wrapCentering (in category 'table defaults') ----- wrapCentering ^#topLeft! Item was changed: + ----- Method: LayoutProperties>>wrapDirection (in category 'defaults - table layout') ----- - ----- Method: LayoutProperties>>wrapDirection (in category 'table defaults') ----- wrapDirection ^#none! Item was changed: ----- Method: LeftGripMorph>>apply: (in category 'target resize') ----- apply: delta | oldBounds | oldBounds := self target bounds. self target bounds: (oldBounds origin + (delta x @ 0) corner: oldBounds corner). self flag: #workaround. "mt: Due to a layout-specific 'let us start in the top-left corner of a layout cell'-behavior, we have to go up the owner chain and propagate the delta. See Morph >> #layoutInBounds:positioning: and there section 1.2." self target allOwnersDo: [:owner | + (owner layoutPolicy notNil and: [owner ~~ Project current world]) + ifTrue: [owner left: owner left + delta x]].! - owner layoutPolicy ifNotNil: [owner left: owner left + delta x]].! Item was changed: ----- Method: MenuMorph>>initialize (in category 'initialization') ----- initialize super initialize. self setDefaultParameters. self changeTableLayout. self listDirection: #topToBottom. self hResizing: #shrinkWrap. self vResizing: #shrinkWrap. + self disableLayout: true. defaultTarget := nil. selectedItem := nil. stayUp := false. popUpOwner := nil.! Item was added: + ----- Method: Morph>>assureGridLayoutProperties (in category 'layout properties') ----- + assureGridLayoutProperties + + | assuredProperties | + self layoutProperties + ifNil: [ + self layoutProperties: (assuredProperties := GridLayoutProperties new initializeFrom: self)] + ifNotNil: [:existingProperties | + existingProperties includesGridLayoutProperties + ifTrue: [assuredProperties := existingProperties] + ifFalse: [self layoutProperties: (assuredProperties := existingProperties asGridLayoutProperties)]]. + ^ assuredProperties! Item was changed: + ----- Method: Morph>>assureLayoutProperties (in category 'layout properties') ----- - ----- Method: Morph>>assureLayoutProperties (in category 'layout-properties') ----- assureLayoutProperties | props | props := self layoutProperties. props == self ifTrue:[props := nil]. props ifNil:[ props := LayoutProperties new initializeFrom: self. self layoutProperties: props]. ^props! Item was added: + ----- Method: Morph>>assureTableLayoutProperties (in category 'layout properties') ----- + assureTableLayoutProperties + + | assuredProperties | + self layoutProperties + ifNil: [ + self layoutProperties: (assuredProperties := TableLayoutProperties new initializeFrom: self)] + ifNotNil: [:existingProperties | + existingProperties includesTableLayoutProperties + ifTrue: [assuredProperties := existingProperties] + ifFalse: [self layoutProperties: (assuredProperties := existingProperties asTableLayoutProperties)]]. + ^ assuredProperties! Item was removed: - ----- Method: Morph>>assureTableProperties (in category 'layout-properties') ----- - assureTableProperties - | props | - props := self layoutProperties. - props == self ifTrue:[props := nil]. - props ifNil:[ - props := TableLayoutProperties new initializeFrom: self. - self layoutProperties: props]. - props includesTableProperties - ifFalse:[self layoutProperties: (props := props asTableLayoutProperties)]. - ^props! Item was changed: ----- Method: Morph>>beFlap: (in category 'accessing') ----- beFlap: aBool "Mark the receiver with the #flap property, or unmark it" aBool ifTrue: [self setProperty: #flap toValue: true. + self disableLayout: true. self hResizing: #rigid. self vResizing: #rigid] ifFalse: + [self removeProperty: #flap. + self disableLayout: false]! - [self removeProperty: #flap]! Item was changed: + ----- Method: Morph>>cellGap (in category 'layout properties - table') ----- - ----- Method: Morph>>cellGap (in category 'layout-properties') ----- cellGap "Layout specific. This property specifies an extra space *between* cells in the layout." | props | props := self layoutProperties. ^props ifNil:[0] ifNotNil:[props cellGap].! Item was changed: + ----- Method: Morph>>cellGap: (in category 'layout properties - table') ----- - ----- Method: Morph>>cellGap: (in category 'layout-properties') ----- cellGap: aNumber "Layout specific. This property specifies an extra space *between* cells in the layout." + self assureTableLayoutProperties cellGap: aNumber. - self assureTableProperties cellGap: aNumber. self layoutChanged.! Item was changed: + ----- Method: Morph>>cellInset (in category 'layout properties - table') ----- - ----- Method: Morph>>cellInset (in category 'layout-properties') ----- cellInset "Layout specific. This property specifies an extra inset for each cell in the layout." | props | props := self layoutProperties. ^props ifNil:[0] ifNotNil:[props cellInset].! Item was changed: + ----- Method: Morph>>cellInset: (in category 'layout properties - table') ----- - ----- Method: Morph>>cellInset: (in category 'layout-properties') ----- cellInset: aNumber "Layout specific. This property specifies an extra inset for each cell in the layout." + self assureTableLayoutProperties cellInset: aNumber. - self assureTableProperties cellInset: aNumber. self layoutChanged.! Item was changed: + ----- Method: Morph>>cellPositioning (in category 'layout properties - table') ----- - ----- Method: Morph>>cellPositioning (in category 'layout-properties') ----- cellPositioning "Layout specific. This property describes how the receiver should be layed out in its owner when the bounds of the cell assigned to the receiver do not exactly match its bounds. Possible values are: #topLeft, #topRight, #bottomLeft, #bottomRight, #topCenter, #leftCenter, #rightCenter, #bottomCenter, #center which align the receiver's bounds with the cell at the given point." | props | props := self layoutProperties. ^props ifNil:[#center] ifNotNil:[props cellPositioning].! Item was changed: + ----- Method: Morph>>cellPositioning: (in category 'layout properties - table') ----- - ----- Method: Morph>>cellPositioning: (in category 'layout-properties') ----- cellPositioning: aSymbol "Layout specific. This property describes how the receiver should be layed out in its owner when the bounds of the cell assigned to the receiver do not exactly match its bounds. Possible values are: #topLeft, #topRight, #bottomLeft, #bottomRight, #topCenter, #leftCenter, #rightCenter, #bottomCenter, #center which align the receiver's bounds with the cell at the given point." + self assureTableLayoutProperties cellPositioning: aSymbol. - self assureTableProperties cellPositioning: aSymbol. self layoutChanged.! Item was changed: + ----- Method: Morph>>cellPositioningString: (in category 'layout-menu') ----- - ----- Method: Morph>>cellPositioningString: (in category 'layout-properties') ----- cellPositioningString: aSymbol ^self layoutMenuPropertyString: aSymbol from: self cellPositioning! Item was changed: + ----- Method: Morph>>cellSpacing (in category 'layout properties - table') ----- - ----- Method: Morph>>cellSpacing (in category 'layout-properties') ----- cellSpacing "Layout specific. This property describes how the cell size for each element in a list should be computed. #globalRect - globally equal rectangular cells #globalSquare - globally equal square cells #localRect - locally (e.g., per row/column) equal rectangular cells #localSquare - locally (e.g., per row/column) equal square cells #none - cells are sized based on available row/column constraints " | props | props := self layoutProperties. ^props ifNil:[#none] ifNotNil:[props cellSpacing].! Item was changed: + ----- Method: Morph>>cellSpacing: (in category 'layout properties - table') ----- - ----- Method: Morph>>cellSpacing: (in category 'layout-properties') ----- cellSpacing: aSymbol "Layout specific. This property describes how the cell size for each element in a list should be computed. #globalRect - globally equal rectangular cells #globalSquare - globally equal square cells #localRect - locally (e.g., per row/column) equal rectangular cells #localSquare - locally (e.g., per row/column) equal square cells #none - cells are sized based on available row/column constraints " self checkCellSpacingProperty: aSymbol. + self assureTableLayoutProperties cellSpacing: aSymbol. - self assureTableProperties cellSpacing: aSymbol. self layoutChanged.! Item was changed: + ----- Method: Morph>>cellSpacingString: (in category 'layout-menu') ----- - ----- Method: Morph>>cellSpacingString: (in category 'layout-properties') ----- cellSpacingString: aSymbol ^self layoutMenuPropertyString: aSymbol from: self cellSpacing! Item was changed: + ----- Method: Morph>>copyLayoutProperties (in category 'layout properties') ----- - ----- Method: Morph>>copyLayoutProperties (in category 'layout-properties') ----- copyLayoutProperties + ^[Clipboard clipboardText: self layoutProperties storeString] ifError:[ nil ] ! - ^[Clipboard clipboardText: self layoutProperties stringWithLayout] ifError:[ nil ] ! Item was changed: + ----- Method: Morph>>disableLayout (in category 'layout properties') ----- - ----- Method: Morph>>disableLayout (in category 'layout-properties') ----- disableLayout "Layout specific. Disable laying out the receiver in a layout" | props | props := self layoutProperties. ^props ifNil:[false] ifNotNil:[props disableLayout].! Item was changed: + ----- Method: Morph>>disableLayout: (in category 'layout properties') ----- - ----- Method: Morph>>disableLayout: (in category 'layout-properties') ----- disableLayout: aBool + "Layout specific. Disable laying out the receiver in the owner's layout if any. The receiver's layout (policy) is not affected by this." - "Layout specific. Disable laying out the receiver in a layout" self fullBounds; layoutChanged. self assureLayoutProperties disableLayout: aBool. self fullBounds; layoutChanged; changed.! Item was changed: + ----- Method: Morph>>disableTableLayout (in category 'layout properties') ----- - ----- Method: Morph>>disableTableLayout (in category 'layout-properties') ----- disableTableLayout "Layout specific. Disable laying out the receiver in table layout" | props | props := self layoutProperties. ^props ifNil:[false] ifNotNil:[props disableTableLayout].! Item was changed: + ----- Method: Morph>>disableTableLayout: (in category 'layout properties') ----- - ----- Method: Morph>>disableTableLayout: (in category 'layout-properties') ----- disableTableLayout: aBool "Layout specific. Disable laying out the receiver in table layout" self fullBounds; layoutChanged. self assureLayoutProperties disableTableLayout: aBool. self fullBounds; layoutChanged; changed.! Item was added: + ----- Method: Morph>>gridModulus (in category 'layout properties - grid') ----- + gridModulus + "Layout specific. This property describes how the cell size in the grid." + + ^ self layoutProperties ifNil: [8 at 8] ifNotNil: [:properties | properties modulus]! Item was added: + ----- Method: Morph>>gridModulus: (in category 'layout properties - grid') ----- + gridModulus: aPoint + "Layout specific. This property describes how the cell size in the grid." + + self assureGridLayoutProperties modulus: aPoint. + self layoutChanged.! Item was added: + ----- Method: Morph>>gridOrigin (in category 'layout properties - grid') ----- + gridOrigin + "Layout specific. This property describes the offset in the grid." + + ^ self layoutProperties ifNil: [0 at 0] ifNotNil: [:properties | properties origin]! Item was added: + ----- Method: Morph>>gridOrigin: (in category 'layout properties - grid') ----- + gridOrigin: aPoint + "Layout specific. This property describes the offset in the grid." + + self assureGridLayoutProperties origin: aPoint. + self layoutChanged.! Item was removed: - ----- Method: Morph>>gridPoint: (in category 'geometry - misc') ----- - gridPoint: ungriddedPoint - - ^ ungriddedPoint! Item was removed: - ----- Method: Morph>>griddedPoint: (in category 'geometry - misc') ----- - griddedPoint: ungriddedPoint - - | griddingContext | - self flag: #arNote. "Used by event handling - should transform to pasteUp for gridding" - (griddingContext := self pasteUpMorph) ifNil: [^ ungriddedPoint]. - ^ griddingContext gridPoint: ungriddedPoint! Item was changed: + ----- Method: Morph>>hResizing (in category 'layout properties') ----- - ----- Method: Morph>>hResizing (in category 'layout-properties') ----- hResizing "Layout specific. This property describes how the receiver should be resized with respect to its owner and its children. Possible values are: #rigid - do not resize the receiver #spaceFill - resize to fill owner's available space #shrinkWrap - resize to fit children " | props | props := self layoutProperties. ^props ifNil:[#rigid] ifNotNil:[props hResizing].! Item was changed: + ----- Method: Morph>>hResizing: (in category 'layout properties') ----- - ----- Method: Morph>>hResizing: (in category 'layout-properties') ----- hResizing: aSymbol "Layout specific. This property describes how the receiver should be resized with respect to its owner and its children. Possible values are: #rigid - do not resize the receiver #spaceFill - resize to fill owner's available space #shrinkWrap - resize to fit children " self checkResizingProperty: aSymbol. self assureLayoutProperties hResizing: aSymbol. self layoutChanged. ! Item was changed: + ----- Method: Morph>>hResizingString: (in category 'layout-menu') ----- - ----- Method: Morph>>hResizingString: (in category 'layout-properties') ----- hResizingString: aSymbol ^self layoutMenuPropertyString: aSymbol from: self hResizing! Item was changed: + ----- Method: Morph>>layoutFrame (in category 'layout properties - proportional') ----- - ----- Method: Morph>>layoutFrame (in category 'layout-properties') ----- layoutFrame "Layout specific. Return the layout frame describing where the receiver should appear in a proportional layout" ^ extension ifNotNil: [extension layoutFrame]! Item was changed: + ----- Method: Morph>>layoutFrame: (in category 'layout properties - proportional') ----- - ----- Method: Morph>>layoutFrame: (in category 'layout-properties') ----- layoutFrame: aLayoutFrame "Layout specific. Return the layout frame describing where the receiver should appear in a proportional layout" self layoutFrame == aLayoutFrame ifTrue:[^self]. self assureExtension layoutFrame: aLayoutFrame. self layoutChanged.! Item was changed: + ----- Method: Morph>>layoutInset (in category 'layout properties') ----- - ----- Method: Morph>>layoutInset (in category 'layout-properties') ----- layoutInset "Return the extra inset for layouts" | props | props := self layoutProperties. ^props ifNil:[0] ifNotNil:[props layoutInset].! Item was changed: + ----- Method: Morph>>layoutInset: (in category 'layout properties') ----- - ----- Method: Morph>>layoutInset: (in category 'layout-properties') ----- layoutInset: aNumber "Return the extra inset for layouts" + + self flag: #todo. "mt: Change to #assureLayoutProperties." + self assureTableLayoutProperties layoutInset: aNumber. - self assureTableProperties layoutInset: aNumber. self layoutChanged.! Item was changed: + ----- Method: Morph>>layoutPolicy (in category 'layout properties') ----- - ----- Method: Morph>>layoutPolicy (in category 'layout-properties') ----- layoutPolicy "Layout specific. Return the layout policy describing how children of the receiver should appear." ^ extension ifNotNil: [ extension layoutPolicy]! Item was changed: + ----- Method: Morph>>layoutPolicy: (in category 'layout properties') ----- - ----- Method: Morph>>layoutPolicy: (in category 'layout-properties') ----- layoutPolicy: aLayoutPolicy "Layout specific. Return the layout policy describing how children of the receiver should appear." self layoutPolicy == aLayoutPolicy ifTrue:[^self]. self assureExtension layoutPolicy: aLayoutPolicy. self layoutChanged.! Item was changed: + ----- Method: Morph>>layoutProperties (in category 'layout properties') ----- - ----- Method: Morph>>layoutProperties (in category 'layout-properties') ----- layoutProperties "Return the current layout properties associated with the receiver" ^ extension ifNotNil: [ extension layoutProperties]! Item was changed: + ----- Method: Morph>>layoutProperties: (in category 'layout properties') ----- - ----- Method: Morph>>layoutProperties: (in category 'layout-properties') ----- layoutProperties: newProperties "Return the current layout properties associated with the receiver" self layoutProperties == newProperties ifTrue:[^self]. self assureExtension layoutProperties: newProperties. ! Item was changed: + ----- Method: Morph>>listCentering (in category 'layout properties - table') ----- - ----- Method: Morph>>listCentering (in category 'layout-properties') ----- listCentering "Layout specific. This property describes how the rows/columns in a list-like layout should be centered. #topLeft - center at start of primary direction #bottomRight - center at end of primary direction #center - center in the middle of primary direction #justified - insert extra space inbetween rows/columns " | props | props := self layoutProperties. ^props ifNil:[#topLeft] ifNotNil:[props listCentering].! Item was changed: + ----- Method: Morph>>listCentering: (in category 'layout properties - table') ----- - ----- Method: Morph>>listCentering: (in category 'layout-properties') ----- listCentering: aSymbol "Layout specific. This property describes how the rows/columns in a list-like layout should be centered. #topLeft - center at start of primary direction #bottomRight - center at end of primary direction #center - center in the middle of primary direction #justified - insert extra space inbetween rows/columns " + self assureTableLayoutProperties listCentering: aSymbol. - self assureTableProperties listCentering: aSymbol. self layoutChanged.! Item was changed: + ----- Method: Morph>>listCenteringString: (in category 'layout-menu') ----- - ----- Method: Morph>>listCenteringString: (in category 'layout-properties') ----- listCenteringString: aSymbol ^self layoutMenuPropertyString: aSymbol from: self listCentering! Item was changed: + ----- Method: Morph>>listDirection (in category 'layout properties - table') ----- - ----- Method: Morph>>listDirection (in category 'layout-properties') ----- listDirection "Layout specific. This property describes the direction in which a list-like layout should be applied. Possible values are: #leftToRight #rightToLeft #topToBottom #bottomToTop indicating the direction in which any layout should take place" | props | props := self layoutProperties. ^props ifNil:[#topToBottom] ifNotNil:[props listDirection].! Item was changed: + ----- Method: Morph>>listDirection: (in category 'layout properties - table') ----- - ----- Method: Morph>>listDirection: (in category 'layout-properties') ----- listDirection: aSymbol "Layout specific. This property describes the direction in which a list-like layout should be applied. Possible values are: #leftToRight #rightToLeft #topToBottom #bottomToTop indicating the direction in which any layout should take place" + self assureTableLayoutProperties listDirection: aSymbol. - self assureTableProperties listDirection: aSymbol. self layoutChanged.! Item was changed: + ----- Method: Morph>>listDirectionString: (in category 'layout-menu') ----- - ----- Method: Morph>>listDirectionString: (in category 'layout-properties') ----- listDirectionString: aSymbol ^self layoutMenuPropertyString: aSymbol from: self listDirection! Item was changed: + ----- Method: Morph>>listSpacing (in category 'layout properties - table') ----- - ----- Method: Morph>>listSpacing (in category 'layout-properties') ----- listSpacing "Layout specific. This property describes how the heights for different rows in a table layout should be handled. #equal - all rows have the same height #none - all rows may have different heights " | props | props := self layoutProperties. ^props ifNil:[#none] ifNotNil:[props listSpacing].! Item was changed: + ----- Method: Morph>>listSpacing: (in category 'layout properties - table') ----- - ----- Method: Morph>>listSpacing: (in category 'layout-properties') ----- listSpacing: aSymbol "Layout specific. This property describes how the heights for different rows in a table layout should be handled. #equal - all rows have the same height #none - all rows may have different heights " self checkListSpacingProperty: aSymbol. + self assureTableLayoutProperties listSpacing: aSymbol. - self assureTableProperties listSpacing: aSymbol. self layoutChanged.! Item was changed: + ----- Method: Morph>>listSpacingString: (in category 'layout-menu') ----- - ----- Method: Morph>>listSpacingString: (in category 'layout-properties') ----- listSpacingString: aSymbol ^self layoutMenuPropertyString: aSymbol from: self listSpacing! Item was changed: + ----- Method: Morph>>maxCellSize (in category 'layout properties - table') ----- - ----- Method: Morph>>maxCellSize (in category 'layout-properties') ----- maxCellSize "Layout specific. This property specifies the maximum size of a table cell." | props | props := self layoutProperties. ^props ifNil:[SmallInteger maxVal] ifNotNil:[props maxCellSize].! Item was changed: + ----- Method: Morph>>maxCellSize: (in category 'layout properties - table') ----- - ----- Method: Morph>>maxCellSize: (in category 'layout-properties') ----- maxCellSize: aPoint "Layout specific. This property specifies the maximum size of a table cell." + self assureTableLayoutProperties maxCellSize: aPoint. - self assureTableProperties maxCellSize: aPoint. self layoutChanged.! Item was changed: + ----- Method: Morph>>minCellSize (in category 'layout properties - table') ----- - ----- Method: Morph>>minCellSize (in category 'layout-properties') ----- minCellSize "Layout specific. This property specifies the minimal size of a table cell." | props | props := self layoutProperties. ^props ifNil:[0] ifNotNil:[props minCellSize].! Item was changed: + ----- Method: Morph>>minCellSize: (in category 'layout properties - table') ----- - ----- Method: Morph>>minCellSize: (in category 'layout-properties') ----- minCellSize: aPoint "Layout specific. This property specifies the minimal size of a table cell." + self assureTableLayoutProperties minCellSize: aPoint. - self assureTableProperties minCellSize: aPoint. self layoutChanged.! Item was changed: ----- Method: Morph>>resizeMorph: (in category 'meta-actions') ----- resizeMorph: evt | handle | handle := HandleMorph new forEachPointDo: [:newPoint | + self extent: newPoint - self bounds topLeft]. - self extent: (self griddedPoint: newPoint) - self bounds topLeft]. evt hand attachMorph: handle. handle startStepping. ! Item was changed: + ----- Method: Morph>>reverseTableCells (in category 'layout properties - table') ----- - ----- Method: Morph>>reverseTableCells (in category 'layout-properties') ----- reverseTableCells "Layout specific. This property describes if the cells should be treated in reverse order of submorphs." | props | props := self layoutProperties. ^props ifNil:[false] ifNotNil:[props reverseTableCells].! Item was changed: + ----- Method: Morph>>reverseTableCells: (in category 'layout properties - table') ----- - ----- Method: Morph>>reverseTableCells: (in category 'layout-properties') ----- reverseTableCells: aBool "Layout specific. This property describes if the cells should be treated in reverse order of submorphs." + self assureTableLayoutProperties reverseTableCells: aBool. - self assureTableProperties reverseTableCells: aBool. self layoutChanged.! Item was changed: + ----- Method: Morph>>rubberBandCells (in category 'layout properties - table') ----- - ----- Method: Morph>>rubberBandCells (in category 'layout-properties') ----- rubberBandCells "Layout specific. This property describes if a parent that is #shrinkWrapped around its children should ignore any #spaceFill children. E.g., when #rubberBandCells is true, the compound layout will always stay at the smallest available size, even though some child may be able to grow." | props | props := self layoutProperties. ^props ifNil:[false] ifNotNil:[props rubberBandCells].! Item was changed: + ----- Method: Morph>>rubberBandCells: (in category 'layout properties - table') ----- - ----- Method: Morph>>rubberBandCells: (in category 'layout-properties') ----- rubberBandCells: aBool "Layout specific. This property describes if a parent that is #shrinkWrapped around its children should ignore any #spaceFill children. E.g., when #rubberBandCells is true, the compound layout will always stay at the smallest available size, even though some child may be able to grow." + self assureTableLayoutProperties rubberBandCells: aBool. - self assureTableProperties rubberBandCells: aBool. self layoutChanged.! Item was changed: + ----- Method: Morph>>spaceFillWeight (in category 'layout properties - table') ----- - ----- Method: Morph>>spaceFillWeight (in category 'layout-properties') ----- spaceFillWeight "Layout specific. This property describes the relative weight that should be given to the receiver when extra space is distributed between different #spaceFill cells." ^ self valueOfProperty: #spaceFillWeight ifAbsent: [1]! Item was changed: + ----- Method: Morph>>spaceFillWeight: (in category 'layout properties - table') ----- - ----- Method: Morph>>spaceFillWeight: (in category 'layout-properties') ----- spaceFillWeight: aNumber "Layout specific. This property describes the relative weight that should be given to the receiver when extra space is distributed between different #spaceFill cells." aNumber = 1 ifTrue:[self removeProperty: #spaceFillWeight] ifFalse:[self setProperty: #spaceFillWeight toValue: aNumber]. self layoutChanged.! Item was changed: + ----- Method: Morph>>vResizeToFit: (in category 'layout properties') ----- - ----- Method: Morph>>vResizeToFit: (in category 'layout-properties') ----- vResizeToFit: aBoolean aBoolean ifTrue:[ self vResizing: #shrinkWrap. ] ifFalse:[ self vResizing: #rigid. ].! Item was changed: + ----- Method: Morph>>vResizing (in category 'layout properties') ----- - ----- Method: Morph>>vResizing (in category 'layout-properties') ----- vResizing "Layout specific. This property describes how the receiver should be resized with respect to its owner and its children. Possible values are: #rigid - do not resize the receiver #spaceFill - resize to fill owner's available space #shrinkWrap - resize to fit children " | props | props := self layoutProperties. ^props ifNil:[#rigid] ifNotNil:[props vResizing].! Item was changed: + ----- Method: Morph>>vResizing: (in category 'layout properties') ----- - ----- Method: Morph>>vResizing: (in category 'layout-properties') ----- vResizing: aSymbol "Layout specific. This property describes how the receiver should be resized with respect to its owner and its children. Possible values are: #rigid - do not resize the receiver #spaceFill - resize to fill owner's available space #shrinkWrap - resize to fit children " self checkResizingProperty: aSymbol. self assureLayoutProperties vResizing: aSymbol. self layoutChanged. ! Item was changed: + ----- Method: Morph>>vResizingString: (in category 'layout-menu') ----- - ----- Method: Morph>>vResizingString: (in category 'layout-properties') ----- vResizingString: aSymbol ^self layoutMenuPropertyString: aSymbol from: self vResizing! Item was changed: + ----- Method: Morph>>wrapCentering (in category 'layout properties - table') ----- - ----- Method: Morph>>wrapCentering (in category 'layout-properties') ----- wrapCentering "Layout specific. This property describes how the rows/columns in a list-like layout should be centered. #topLeft - center at start of secondary direction #bottomRight - center at end of secondary direction #center - center in the middle of secondary direction #justified - insert extra space inbetween rows/columns " | props | props := self layoutProperties. ^props ifNil:[#topLeft] ifNotNil:[props wrapCentering].! Item was changed: + ----- Method: Morph>>wrapCentering: (in category 'layout properties - table') ----- - ----- Method: Morph>>wrapCentering: (in category 'layout-properties') ----- wrapCentering: aSymbol "Layout specific. This property describes how the rows/columns in a list-like layout should be centered. #topLeft - center at start of secondary direction #bottomRight - center at end of secondary direction #center - center in the middle of secondary direction #justified - insert extra space inbetween rows/columns " + self assureTableLayoutProperties wrapCentering: aSymbol. - self assureTableProperties wrapCentering: aSymbol. self layoutChanged.! Item was changed: + ----- Method: Morph>>wrapCenteringString: (in category 'layout-menu') ----- - ----- Method: Morph>>wrapCenteringString: (in category 'layout-properties') ----- wrapCenteringString: aSymbol ^self layoutMenuPropertyString: aSymbol from: self wrapCentering! Item was changed: + ----- Method: Morph>>wrapDirection (in category 'layout properties - table') ----- - ----- Method: Morph>>wrapDirection (in category 'layout-properties') ----- wrapDirection "Layout specific. This property describes the direction along which a list-like layout should be wrapped. Possible values are: #leftToRight #rightToLeft #topToBottom #bottomToTop #none indicating in which direction wrapping should occur. This direction must be orthogonal to the list direction, that is if listDirection is #leftToRight or #rightToLeft then wrapDirection must be #topToBottom or #bottomToTop and vice versa." | props | props := self layoutProperties. ^props ifNil:[#none] ifNotNil:[props wrapDirection].! Item was changed: + ----- Method: Morph>>wrapDirection: (in category 'layout properties - table') ----- - ----- Method: Morph>>wrapDirection: (in category 'layout-properties') ----- wrapDirection: aSymbol "Layout specific. This property describes the direction along which a list-like layout should be wrapped. Possible values are: #leftToRight #rightToLeft #topToBottom #bottomToTop #none indicating in which direction wrapping should occur. This direction must be orthogonal to the list direction, that is if listDirection is #leftToRight or #rightToLeft then wrapDirection must be #topToBottom or #bottomToTop and vice versa." + self assureTableLayoutProperties wrapDirection: aSymbol. - self assureTableProperties wrapDirection: aSymbol. self layoutChanged. ! Item was changed: + ----- Method: Morph>>wrapDirectionString: (in category 'layout-menu') ----- - ----- Method: Morph>>wrapDirectionString: (in category 'layout-properties') ----- wrapDirectionString: aSymbol ^self layoutMenuPropertyString: aSymbol from: self wrapDirection ! Item was added: + ----- Method: MorphicProject class>>applyUserInterfaceTheme (in category 'preferences') ----- + applyUserInterfaceTheme + + self current addDeferredUIMessage: [ + "After all immediate changes where applied, we can reset to values that match the current world configuration:" + self worldGridOrigin: nil. + self worldGridModulus: nil. + self current world griddingOn + ifTrue: [self current world firstHand turnOnGridding]].! Item was added: + ----- Method: MorphicProject class>>worldGridEnabled (in category 'preferences') ----- + worldGridEnabled + + ^ self current isMorphic and: [self current world griddingOn]! Item was added: + ----- Method: MorphicProject class>>worldGridEnabled: (in category 'preferences') ----- + worldGridEnabled: aBooleanOrNil + + (aBooleanOrNil ifNil: [false]) = self current world griddingOn + ifFalse: [self current world griddingOnOff]. + + "Snap to grid when dragging something." + self current world griddingOn + ifTrue: [self current world firstHand turnOnGridding] + ifFalse: [self current world firstHand turnOffGridding].! Item was added: + ----- Method: MorphicProject class>>worldGridModulus (in category 'preferences') ----- + worldGridModulus + + + ^ self current isMorphic + ifFalse: [0 at 0] + ifTrue: [self current world gridModulus]! Item was added: + ----- Method: MorphicProject class>>worldGridModulus: (in category 'preferences') ----- + worldGridModulus: aPointOrCode + + | value | + self current isMorphic ifFalse: [^ self]. + value := (aPointOrCode isString ifTrue: [Compiler evaluate: aPointOrCode]) ifNil: [(self current world clearArea width // 60 "num cells") asPoint]. + value isPoint ifFalse: [^ self]. + self current world gridModulus: value.! Item was added: + ----- Method: MorphicProject class>>worldGridOrigin (in category 'preferences') ----- + worldGridOrigin + + + ^ self current isMorphic + ifFalse: [0 at 0] + ifTrue: [self current world gridOrigin]! Item was added: + ----- Method: MorphicProject class>>worldGridOrigin: (in category 'preferences') ----- + worldGridOrigin: aPointOrCode + + | value | + self current isMorphic ifFalse: [^ self]. + value := (aPointOrCode isString ifTrue: [Compiler evaluate: aPointOrCode]) ifNil: [self current world clearArea origin]. + value isPoint ifFalse: [^ self]. + self current world gridOrigin: value. ! Item was changed: ----- Method: NewBalloonMorph>>initialize (in category 'initialization') ----- initialize super initialize. + self disableLayout: true. self setDefaultParameters. textMorph := TextMorph new wrapFlag: false; lock; yourself. self addMorph: textMorph.! Item was changed: BorderedMorph subclass: #PasteUpMorph + instanceVariableNames: 'presenter model cursor padding backgroundMorph turtleTrailsForm turtlePen lastTurtlePositions isPartsBin indicateCursor wantsMouseOverHalos worldState' - instanceVariableNames: 'presenter model cursor padding backgroundMorph turtleTrailsForm turtlePen lastTurtlePositions isPartsBin indicateCursor wantsMouseOverHalos worldState griddingOn' classVariableNames: 'GlobalCommandKeysEnabled WindowEventHandler' poolDictionaries: '' category: 'Morphic-Worlds'! !PasteUpMorph commentStamp: '' prior: 0! A morph whose submorphs comprise a paste-up of rectangular subparts which "show through". Anything called a 'Playfield' is a PasteUpMorph. Facilities commonly needed on pages of graphical presentations and on simulation playfields, such as the painting of new objects, turtle trails, gradient fills, background paintings, parts-bin behavior, collision-detection, etc., are (or will be) provided. A World, the entire Smalltalk screen, is a PasteUpMorph. A World responds true to isWorld. Morph subclasses that have specialized menus (BookMorph) build them in the message addBookMenuItemsTo:hand:. A PasteUpMorph that is a world, builds its menu in HandMorph buildWorldMenu. presenter A Presenter in charge of stopButton stepButton and goButton, mouseOverHalosEnabled soundsEnabled fenceEnabled coloredTilesEnabled. model cursor ?? padding ?? backgroundMorph A Form that covers the background. turtleTrailsForm Moving submorphs may leave trails on this form. turtlePen Draws the trails. lastTurtlePositions A Dictionary of (aPlayer -> aPoint) so turtle trails can be drawn only once each step cycle. The point is the start of the current stroke. isPartsBin If true, every object dragged out is copied. autoLineLayout ?? indicateCursor ?? resizeToFit ?? wantsMouseOverHalos If true, simply moving the cursor over a submorph brings up its halo. worldState If I am also a World, keeps the hands, damageRecorder, stepList etc. griddingOn If true, submorphs are on a grid ! Item was changed: ----- Method: PasteUpMorph>>acceptDroppingMorph:event: (in category 'dropping/grabbing') ----- acceptDroppingMorph: dropped event: evt "The supplied morph, known to be acceptable to the receiver, is now to be assimilated; the precipitating event is supplied" | aMorph | (self isWorldMorph and: [dropped isTransferMorph and: [dropped dragTransferType = #filesAndDirectories]]) ifTrue: [^ self dropFiles: dropped passenger event: evt]. aMorph := self morphToDropFrom: dropped. self isWorldMorph ifFalse: [super acceptDroppingMorph: aMorph event: evt] ifTrue: ["Add the given morph to this world and start stepping it if it wants to be." aMorph isInWorld ifFalse: [aMorph position: evt position]. self addMorphFront: aMorph. (aMorph fullBounds intersects: self viewBox) ifFalse: [Beeper beep. aMorph position: self bounds center]]. aMorph submorphsDo: [:m | (m isKindOf: HaloMorph) ifTrue: [m delete]]. aMorph allMorphsDo: "Establish any penDown morphs in new world" [:m | | tfm mm | m player ifNotNil: [m player getPenDown ifTrue: [((mm := m player costume) notNil and: [(tfm := mm owner transformFrom: self) notNil]) ifTrue: [self noteNewLocation: (tfm localPointToGlobal: mm referencePosition) forPlayer: m player]]]]. self isPartsBin ifTrue: [aMorph isPartsDonor: true. aMorph stopSteppingSelfAndSubmorphs. aMorph suspendEventHandler] ifFalse: [self world startSteppingSubmorphsOf: aMorph]. " self presenter morph: aMorph droppedIntoPasteUpMorph: self." - self griddingOn ifTrue: [aMorph position: (self gridPoint: aMorph position)]. self showingListView ifTrue: [self sortSubmorphsBy: (self valueOfProperty: #sortOrder). self currentWorld abandonAllHalos]. self bringTopmostsToFront.! Item was removed: - ----- Method: PasteUpMorph>>gridModulus (in category 'gridding') ----- - gridModulus - - ^ self gridSpec extent! Item was removed: - ----- Method: PasteUpMorph>>gridModulus: (in category 'gridding') ----- - gridModulus: newModulus - - self gridSpecPut: (self gridOrigin extent: newModulus). - self changed! Item was removed: - ----- Method: PasteUpMorph>>gridOrigin (in category 'gridding') ----- - gridOrigin - - ^ self gridSpec origin! Item was removed: - ----- Method: PasteUpMorph>>gridOrigin: (in category 'gridding') ----- - gridOrigin: newOrigin - - ^ self gridSpecPut: (newOrigin extent: self gridModulus)! Item was removed: - ----- Method: PasteUpMorph>>gridPoint: (in category 'geometry') ----- - gridPoint: ungriddedPoint - - self griddingOn ifFalse: [^ ungriddedPoint]. - ^ (ungriddedPoint - self position - self gridOrigin grid: self gridModulus) - + self position + self gridOrigin! Item was removed: - ----- Method: PasteUpMorph>>gridSpec (in category 'gridding') ----- - gridSpec - "Gridding rectangle provides origin and modulus" - - ^ self valueOfProperty: #gridSpec ifAbsent: [0 at 0 extent: 8 at 8]! Item was removed: - ----- Method: PasteUpMorph>>gridSpecPut: (in category 'gridding') ----- - gridSpecPut: newSpec - "Gridding rectangle provides origin and modulus" - - ^ self setProperty: #gridSpec toValue: newSpec! Item was changed: ----- Method: PasteUpMorph>>griddingOn (in category 'gridding') ----- griddingOn + ^ self layoutPolicy notNil and: [self layoutPolicy isGridLayout]! - ^ griddingOn ifNil: [false]! Item was changed: ----- Method: PasteUpMorph>>griddingOnOff (in category 'gridding') ----- griddingOnOff + "Change grid layout. Consider the #clearArea to ignore docking bars and other adhereing morphs." + + self layoutPolicy: (self griddingOn ifFalse: [GridLayout new]).! - - griddingOn := self griddingOn not. - self changed! Item was changed: ----- Method: PolygonMorph>>addHandles (in category 'editing') ----- addHandles "Put moving handles at the vertices. Put adding handles at edge midpoints. Moving over adjacent vertex and dropping will delete a vertex. " | tri | self removeHandles. handles := OrderedCollection new. tri := Array with: 0 @ -4 with: 4 @ 3 with: -3 @ 3. + tri := (tri * RealEstateAgent scaleFactor) truncated. vertices withIndexDo: [:vertPt :vertIndex | | handle | handle := EllipseMorph + newBounds: (Rectangle center: vertPt extent: (8 at 8) * RealEstateAgent scaleFactor) - newBounds: (Rectangle center: vertPt extent: 8 @ 8) color: (self handleColorAt: vertIndex) . + handle disableLayout: true. handle on: #mouseMove send: #dragVertex:event:fromHandle: to: self withValue: vertIndex. handle on: #mouseUp send: #dropVertex:event:fromHandle: to: self withValue: vertIndex. handle on: #click send: #clickVertex:event:fromHandle: to: self withValue: vertIndex. self addMorph: handle. handles addLast: handle. (closed or: [1 = vertices size "Give a small polygon a chance to grow. -wiz" or: [vertIndex < vertices size]]) ifTrue: [| newVert | newVert := PolygonMorph vertices: (tri collect: [:p | p + (vertPt + (vertices atWrap: vertIndex + 1) // 2)]) color: Color green borderWidth: 1 borderColor: Color black. + newVert disableLayout: true. newVert on: #mouseDown send: #newVertex:event:fromHandle: to: self withValue: vertIndex. self addMorph: newVert. handles addLast: newVert]]. self isCurvy ifTrue: [self updateHandles; layoutChanged]. self changed! Item was changed: ----- Method: PolygonMorph>>dragVertex:event:fromHandle: (in category 'editing') ----- dragVertex: ix event: evt fromHandle: handle | p | + p := evt cursorPoint. + self flag: #workaround. "mt: Explicitely check for grid layout in owner to then let the vertex snap to that grid." + (self owner notNil and: [self owner layoutPolicy notNil and: [self owner layoutPolicy isGridLayout]]) + ifTrue: [p := self owner layoutPolicy griddedPoint: p in: self owner]. - p := self isCurve - ifTrue: [evt cursorPoint] - ifFalse: [self griddedPoint: evt cursorPoint]. handle position: p - (handle extent//2). self verticesAt: ix put: p. ! Item was changed: ----- Method: PolygonMorph>>extent: (in category 'geometry') ----- extent: newExtent "Not really advisable, but we can preserve most of the geometry if we don't shrink things too small." + | safeExtent | + (self extent closeTo: newExtent) ifTrue: [^ self]. + safeExtent := newExtent max: self minimumExtent. - | safeExtent center | - center := self referencePosition. - safeExtent := newExtent max: 20 at 20. self setVertices: (vertices collect: + [:p | p - self position * (safeExtent asFloatPoint / (bounds extent max: 1 at 1)) + self position])! - [:p | p - center * (safeExtent asFloatPoint / (bounds extent max: 1 at 1)) + center])! Item was changed: ----- Method: PolygonMorph>>initialize (in category 'initialization') ----- initialize "initialize the state of the receiver" super initialize. "" + self minimumExtent: 20 at 20. vertices := Array with: 5 @ 0 with: 20 @ 10 with: 0 @ 20. closed := true. smoothCurve := false. arrows := #none. self computeBounds! Item was removed: - ----- Method: PolygonMorph>>justDroppedInto:event: (in category 'dropping/grabbing') ----- - justDroppedInto: newOwner event: evt - - | delta | - (newOwner isKindOf: PasteUpMorph) ifTrue: - ["Compensate for border width so that gridded drop - is consistent with gridded drag of handles." - delta := self borderWidth+1//2. - self position: (newOwner gridPoint: self position + delta) - delta]. - ^ super justDroppedInto: newOwner event: evt! Item was changed: ----- Method: ProportionalSplitterMorph>>updateFromEvent: (in category 'events') ----- updateFromEvent: anEvent | delta | + lastMouse ifNil: [ lastMouse := anEvent position - self position ]. - lastMouse ifNil: [ lastMouse := anEvent position ]. delta := splitsTopAndBottom + ifTrue: [ 0 @ ((self normalizedY: anEvent cursorPoint y) - (lastMouse y + self top)) ] + ifFalse: [ (self normalizedX: anEvent cursorPoint x) - (lastMouse x + self left) @ 0 ]. - ifTrue: [ 0 @ ((self normalizedY: anEvent cursorPoint y) - lastMouse y) ] - ifFalse: [ (self normalizedX: anEvent cursorPoint x) - lastMouse x @ 0 ]. - lastMouse := splitsTopAndBottom - ifTrue: [ lastMouse x @ (self normalizedY: anEvent cursorPoint y) ] - ifFalse: [ (self normalizedX: anEvent cursorPoint x) @ lastMouse y ]. self repositionBy: delta! Item was removed: - ----- Method: SelectionMorph>>aboutToBeGrabbedBy: (in category 'dropping/grabbing') ----- - aboutToBeGrabbedBy: aHand - slippage := 0 at 0. - ^ super aboutToBeGrabbedBy: aHand - ! Item was changed: ----- Method: SelectionMorph>>extent: (in category 'geometry') ----- extent: newExtent "Set the receiver's extent Extend or contract the receiver's selection to encompass morphs within the new extent." super extent: newExtent. + self selectSubmorphsOf: (self world ifNil: [^ self])! - self selectSubmorphsOf: (self pasteUpMorph ifNil: [^ self])! Item was changed: ----- Method: SelectionMorph>>initialize (in category 'initialization') ----- initialize "initialize the state of the receiver" super initialize. "" selectedItems := OrderedCollection new. + itemsAlreadySelected := OrderedCollection new.! - itemsAlreadySelected := OrderedCollection new. - slippage := 0 @ 0! Item was changed: ----- Method: SelectionMorph>>privateFullMoveBy: (in category 'private') ----- privateFullMoveBy: delta + "Overridden to also move the currently encompassed morphs like they would be my submorphs." + + super privateFullMoveBy: delta. + selectedItems do: [:m | m position: m position + delta]. - - | griddedDelta griddingMorph | - selectedItems isEmpty ifTrue: [^ super privateFullMoveBy: delta]. - griddingMorph := self pasteUpMorph. - griddingMorph ifNil: [^ super privateFullMoveBy: delta]. - griddedDelta := (griddingMorph gridPoint: self position + delta + slippage) - - (griddingMorph gridPoint: self position). - slippage := slippage + (delta - griddedDelta). "keep track of how we lag the true movement." - griddedDelta = (0 at 0) ifTrue: [^ self]. - super privateFullMoveBy: griddedDelta. - selectedItems do: - [:m | m position: (m position + griddedDelta) ] ! Item was added: + ----- Method: SimpleHaloMorph>>initialize (in category 'initialization') ----- + initialize + + super initialize. + + "Each halo is a (kind of global) overlay that should not be bothered with the world's current layout policy. For example, a halo must match the target's bounds, which can be any inner part of the graphical hierarchy." + self disableLayout: true.! Item was changed: ----- Method: SystemWindow>>justDroppedInto:event: (in category 'geometry') ----- justDroppedInto: aMorph event: anEvent isCollapsed ifTrue: [self position: ((self position max: 0 at 0) grid: 8 at 8). collapsedFrame := self bounds] ifFalse: [fullFrame := self bounds]. self beKeyWindow. self hasDropShadow: Preferences menuAppearance3d. "See #startDragFromLabel:." aMorph == self world ifTrue: [self assureLabelAreaVisible]. (Project uiManager openToolsAttachedToMouseCursor and: (self hasProperty: #initialDrop)) ifTrue: [ self removeProperty: #initialDrop. (self submorphs detect: [:m | m isKindOf: BottomRightGripMorph] ifNone: []) ifNotNil: [:grip | grip + referencePoint: anEvent position - grip position; - referencePoint: anEvent position; setProperty: #targetHadDropShadow toValue: true "See MorphicToolBuilder >> #open:". self hasDropShadow: false; lookFocused. anEvent hand newMouseFocus: grip.]]. ^super justDroppedInto: aMorph event: anEvent! Item was changed: ----- Method: TableLayout>>layout:in: (in category 'layout') ----- layout: aMorph in: box "Compute the layout for the given morph based on the new bounds" | cells arrangement horizontal newBounds | aMorph hasSubmorphs ifFalse: [^self]. + properties := aMorph assureTableLayoutProperties. - properties := aMorph assureTableProperties. newBounds := box origin asIntegerPoint corner: box corner asIntegerPoint. (properties wrapDirection == #none and: [properties cellSpacing == #none]) ifTrue: ["get into the fast lane" properties listCentering == #justified ifFalse: ["can't deal with that" properties listDirection == #leftToRight ifTrue: [^self layoutLeftToRight: aMorph in: newBounds]. properties listDirection == #topToBottom ifTrue: [^self layoutTopToBottom: aMorph in: newBounds]]]. horizontal := (properties listDirection == #topToBottom or: [properties listDirection == #bottomToTop]) not. "Step 1: Compute the minimum extent for all the children of aMorph" cells := self computeCellSizes: aMorph in: (0 @ 0 corner: newBounds extent) horizontal: horizontal. "Step 2: Compute the arrangement of the cells for each row and column" arrangement := self computeCellArrangement: cells in: newBounds horizontal: horizontal target: aMorph. "Step 3: Compute the extra spacing for each cell" self computeExtraSpacing: arrangement in: newBounds horizontal: horizontal target: aMorph. "Step 4: Place the children within the cells accordingly" self placeCells: arrangement in: newBounds horizontal: horizontal target: aMorph! Item was changed: ----- Method: TableLayout>>minExtentOf:in: (in category 'layout') ----- minExtentOf: aMorph in: box "Return the minimal size aMorph's children would require given the new bounds" | cells arrangement horizontal newBounds minX minY dir | minExtentCache isNil ifFalse: [^minExtentCache]. aMorph hasSubmorphs ifFalse: [^0 @ 0]. + properties := aMorph assureTableLayoutProperties. - properties := aMorph assureTableProperties. (properties wrapDirection == #none and: [properties cellSpacing == #none]) ifTrue: ["Get into the fast lane" dir := properties listDirection. (dir == #leftToRight or: [dir == #rightToLeft]) ifTrue: [^self minExtentHorizontal: aMorph]. (dir == #topToBottom or: [dir == #bottomToTop]) ifTrue: [^self minExtentVertical: aMorph]]. newBounds := box origin asIntegerPoint corner: box corner asIntegerPoint. horizontal := (properties listDirection == #topToBottom or: [properties listDirection == #bottomToTop]) not. "Step 1: Compute the minimum extent for all the children of aMorph" cells := self computeCellSizes: aMorph in: (0 @ 0 corner: newBounds extent) horizontal: horizontal. "Step 2: Compute the arrangement of the cells for each row and column" arrangement := self computeCellArrangement: cells in: newBounds horizontal: horizontal target: aMorph. "Step 3: Extract the minimum size out of the arrangement" minX := minY := 0. arrangement do: [:cell | minX := minX max: cell cellSize x + cell extraSpace x. minY := minY + cell cellSize y + cell extraSpace y]. minExtentCache := horizontal ifTrue: [minX @ minY] ifFalse: [minY @ minX]. ^minExtentCache! Item was changed: + ----- Method: TableLayoutProperties>>cellGap (in category 'accessing') ----- - ----- Method: TableLayoutProperties>>cellGap (in category 'table defaults') ----- cellGap "ifNil is just for migration of old instances." ^ cellGap ifNil: [0]! Item was changed: + ----- Method: TableLayoutProperties>>cellInset (in category 'accessing') ----- - ----- Method: TableLayoutProperties>>cellInset (in category 'table defaults') ----- cellInset ^cellInset! Item was changed: + ----- Method: TableLayoutProperties>>cellPositioning (in category 'accessing') ----- - ----- Method: TableLayoutProperties>>cellPositioning (in category 'table defaults') ----- cellPositioning ^cellPositioning! Item was changed: + ----- Method: TableLayoutProperties>>cellSpacing (in category 'accessing') ----- - ----- Method: TableLayoutProperties>>cellSpacing (in category 'table defaults') ----- cellSpacing ^cellSpacing! Item was added: + ----- Method: TableLayoutProperties>>includesTableLayoutProperties (in category 'testing') ----- + includesTableLayoutProperties + + ^ true! Item was removed: - ----- Method: TableLayoutProperties>>includesTableProperties (in category 'testing') ----- - includesTableProperties - ^true! Item was changed: + ----- Method: TableLayoutProperties>>layoutInset (in category 'accessing') ----- - ----- Method: TableLayoutProperties>>layoutInset (in category 'table defaults') ----- layoutInset + + self flag: #todo. "mt: Move up to LayoutProperties. Maybe also #cellInset and #cellPositioning because those seem rather independent from the way cells as computed." + ^ layoutInset! - ^layoutInset! Item was changed: ----- Method: TableLayoutProperties>>layoutInset: (in category 'accessing') ----- layoutInset: aNumber + + self flag: #todo. "mt: Move up to LayoutProperties. Maybe also #cellInset and #cellPositioning because those seem rather independent from the way cells as computed." + layoutInset := aNumber.! - layoutInset := aNumber! Item was changed: + ----- Method: TableLayoutProperties>>listCentering (in category 'accessing') ----- - ----- Method: TableLayoutProperties>>listCentering (in category 'table defaults') ----- listCentering ^listCentering! Item was changed: + ----- Method: TableLayoutProperties>>listDirection (in category 'accessing') ----- - ----- Method: TableLayoutProperties>>listDirection (in category 'table defaults') ----- listDirection ^listDirection! Item was changed: + ----- Method: TableLayoutProperties>>listSpacing (in category 'accessing') ----- - ----- Method: TableLayoutProperties>>listSpacing (in category 'table defaults') ----- listSpacing ^listSpacing! Item was changed: + ----- Method: TableLayoutProperties>>maxCellSize (in category 'accessing') ----- - ----- Method: TableLayoutProperties>>maxCellSize (in category 'table defaults') ----- maxCellSize ^maxCellSize! Item was changed: + ----- Method: TableLayoutProperties>>minCellSize (in category 'accessing') ----- - ----- Method: TableLayoutProperties>>minCellSize (in category 'table defaults') ----- minCellSize ^minCellSize! Item was changed: + ----- Method: TableLayoutProperties>>reverseTableCells (in category 'accessing') ----- - ----- Method: TableLayoutProperties>>reverseTableCells (in category 'table defaults') ----- reverseTableCells ^reverseTableCells! Item was changed: + ----- Method: TableLayoutProperties>>rubberBandCells (in category 'accessing') ----- - ----- Method: TableLayoutProperties>>rubberBandCells (in category 'table defaults') ----- rubberBandCells ^rubberBandCells! Item was changed: + ----- Method: TableLayoutProperties>>wrapCentering (in category 'accessing') ----- - ----- Method: TableLayoutProperties>>wrapCentering (in category 'table defaults') ----- wrapCentering ^wrapCentering! Item was changed: + ----- Method: TableLayoutProperties>>wrapDirection (in category 'accessing') ----- - ----- Method: TableLayoutProperties>>wrapDirection (in category 'table defaults') ----- wrapDirection ^wrapDirection! Item was changed: ----- Method: TopGripMorph>>apply: (in category 'target resize') ----- apply: delta | oldBounds | oldBounds := self target bounds. self target bounds: (oldBounds origin + (0 @ delta y) corner: oldBounds corner). self flag: #workaround. "mt: Due to a layout-specific 'let us start in the top-left corner of a layout cell'-behavior, we have to go up the owner chain and propagate the delta. See Morph >> #layoutInBounds:positioning: and there section 1.2." self target allOwnersDo: [:owner | + (owner layoutPolicy notNil and: [owner ~~ Project current world]) + ifTrue: [owner top: owner top + delta y]].! - owner layoutPolicy ifNotNil: [owner top: owner top + delta y]].! Item was changed: ----- Method: TopLeftGripMorph>>apply: (in category 'target resize') ----- apply: delta | oldBounds | oldBounds := self target bounds. self target bounds: (oldBounds origin + delta corner: oldBounds corner). self flag: #workaround. "mt: Due to a layout-specific 'let us start in the top-left corner of a layout cell'-behavior, we have to go up the owner chain and propagate the delta. See Morph >> #layoutInBounds:positioning: and there section 1.2." self target allOwnersDo: [:owner | + (owner layoutPolicy notNil and: [owner ~~ Project current world]) + ifTrue: [owner topLeft: owner topLeft + delta]].! - owner layoutPolicy ifNotNil: [owner topLeft: owner topLeft + delta]].! Item was changed: ----- Method: TopRightGripMorph>>apply: (in category 'target resize') ----- apply: delta | oldBounds | oldBounds := self target bounds. self target bounds: (oldBounds origin + (0 at delta y) corner: oldBounds corner + (delta x @ 0)). self flag: #workaround. "mt: Due to a layout-specific 'let us start in the top-left corner of a layout cell'-behavior, we have to go up the owner chain and propagate the delta. See Morph >> #layoutInBounds:positioning: and there section 1.2." self target allOwnersDo: [:owner | + (owner layoutPolicy notNil and: [owner ~~ Project current world]) + ifTrue: [owner top: owner top + delta y]].! - owner layoutPolicy ifNotNil: [owner top: owner top + delta y]].! Item was changed: ----- Method: TransferMorph>>initialize (in category 'initialization') ----- initialize super initialize. self changeTableLayout; + disableLayout: true; listDirection: #leftToRight; hResizing: #shrinkWrap; vResizing: #shrinkWrap; layoutInset: 3; cellGap: 3; wrapCentering: #center; cellPositioning: #leftCenter; setProperty: #indicateKeyboardFocus toValue: #never. self doMove. self on: #keyStroke send: #keyStroke: to: self. self on: #keyUp send: #updateFromUserInputEvent: to: self. self on: #keyDown send: #updateFromUserInputEvent: to: self. self setDefaultParameters.! From commits at source.squeak.org Sat Feb 20 11:47:37 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sat, 20 Feb 2021 11:47:37 0000 Subject: [squeak-dev] The Trunk: MorphicTests-mt.69.mcz Message-ID: Marcel Taeumel uploaded a new version of MorphicTests to project The Trunk: http://source.squeak.org/trunk/MorphicTests-mt.69.mcz ==================== Summary ==================== Name: MorphicTests-mt.69 Author: mt Time: 20 February 2021, 12:47:37.056759 pm UUID: 9a34f942-2d5d-8649-9d6f-30697a22ca90 Ancestors: MorphicTests-mt.68 Complements Morphic-mt.1724 =============== Diff against MorphicTests-mt.68 =============== Item was added: + TestCase subclass: #GridLayoutTest + instanceVariableNames: 'container' + classVariableNames: '' + poolDictionaries: '' + category: 'MorphicTests-Layouts'! Item was added: + ----- Method: GridLayoutTest>>addMorph (in category 'support') ----- + addMorph + + | newMorph | + newMorph := Morph new + position: 0 at 0; extent: 10 at 10; + hResizing: #spaceFill; vResizing: #spaceFill; + color: Color random; + yourself. + container addMorph: newMorph. + ^ newMorph! Item was added: + ----- Method: GridLayoutTest>>setUp (in category 'running') ----- + setUp + + super setUp. + container := Morph new + color: Color random; + position: 0 at 0; + extent: 100 at 100; + layoutPolicy: GridLayout new; + gridOrigin: 0 at 0; + gridModulus: 20 at 20; + yourself.! Item was added: + ----- Method: GridLayoutTest>>test01Position (in category 'tests') ----- + test01Position + + | m | + m := self addMorph. + { + 0 at 0 . 0 at 0 . + 9 at 9 . 0 at 0 . + 10 at 10 . 20 at 20 . + 25 at 25 . 20 at 20 + } pairsDo: [:newPosition :expectedGrid | + m position: newPosition. + container fullBounds. + self assert: expectedGrid equals: m position].! Item was added: + ----- Method: GridLayoutTest>>test02Extent (in category 'tests') ----- + test02Extent + + | m | + m := self addMorph. + { + 20 at 20 . 20 at 20 . + 50 at 50 . 60 at 60 . + 49 at 49 . 40 at 40 . + } pairsDo: [:newExtent :expectedGrid | + m extent: newExtent. + container fullBounds. + self assert: expectedGrid equals: m extent].! Item was added: + ----- Method: GridLayoutTest>>test03ExtentRigid (in category 'tests') ----- + test03ExtentRigid + "The morph's extent will not be changed to match the grid cells when its resizing strategy is #rigid." + + | m | + m := self addMorph. + m hResizing: #rigid; vResizing: #rigid. + { + 20 at 20 . 20 at 20 . + 50 at 50 . 50 at 50 . + 49 at 49 . 49 at 49 . + 0 at 0 . 0 at 0 + } pairsDo: [:newExtent :expectedGrid | + m extent: newExtent. + container fullBounds. + self assert: expectedGrid equals: m extent].! Item was added: + ----- Method: GridLayoutTest>>test04ExtentMinimum (in category 'tests') ----- + test04ExtentMinimum + + | m | + m := self addMorph. + m extent: 0 at 0. + container fullBounds. + self assert: container gridModulus equals: m extent.! From commits at source.squeak.org Sat Feb 20 11:48:16 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sat, 20 Feb 2021 11:48:16 0000 Subject: [squeak-dev] The Trunk: 60Deprecated-mt.87.mcz Message-ID: Marcel Taeumel uploaded a new version of 60Deprecated to project The Trunk: http://source.squeak.org/trunk/60Deprecated-mt.87.mcz ==================== Summary ==================== Name: 60Deprecated-mt.87 Author: mt Time: 20 February 2021, 12:48:15.982759 pm UUID: 253c6d3c-68b2-8b49-aa96-53a22b205c23 Ancestors: 60Deprecated-pre.86 Complements Morphic-mt.1724 =============== Diff against 60Deprecated-pre.86 =============== Item was added: + ----- Method: Morph>>gridPoint: (in category '*60Deprecated-geometry') ----- + gridPoint: ungriddedPoint + + self deprecated: 'Use GridLayout as the container''s layout policy instead.'. + ^ ungriddedPoint! Item was added: + ----- Method: Morph>>griddedPoint: (in category '*60Deprecated-geometry') ----- + griddedPoint: ungriddedPoint + + self deprecated: 'Use GridLayout as the container''s layout policy instead.'. + ^ ungriddedPoint! From commits at source.squeak.org Sat Feb 20 11:48:55 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sat, 20 Feb 2021 11:48:55 0000 Subject: [squeak-dev] The Trunk: ToolBuilder-Morphic-mt.272.mcz Message-ID: Marcel Taeumel uploaded a new version of ToolBuilder-Morphic to project The Trunk: http://source.squeak.org/trunk/ToolBuilder-Morphic-mt.272.mcz ==================== Summary ==================== Name: ToolBuilder-Morphic-mt.272 Author: mt Time: 20 February 2021, 12:48:54.758759 pm UUID: d0cb109f-4d8a-0a44-ac07-cd78abdc71e1 Ancestors: ToolBuilder-Morphic-mt.271 Complements Morphic-mt.1724 =============== Diff against ToolBuilder-Morphic-mt.271 =============== Item was changed: ----- Method: MorphicToolBuilder>>buildPluggableWindow: (in category 'widgets required') ----- buildPluggableWindow: aSpec | widget | aSpec layout == #proportional ifFalse:[ "This needs to be implemented - probably by adding a single pane and then the rest" ^self error: 'Not implemented'. ]. widget := (self windowClassFor: aSpec) new. self register: widget id: aSpec name. widget model: aSpec model. "Set child dependent layout properties." widget wantsPaneSplitters: (aSpec wantsResizeHandles ifNil: [true]). + MorphicProject worldGridEnabled ifTrue: [ + "Snap both #position and #extent to grid." + aSpec horizontalResizing ifNil: [aSpec horizontalResizing: #spaceFill]. + aSpec verticalResizing ifNil: [aSpec verticalResizing: #spaceFill]]. self setLayoutHintsFor: widget spec: aSpec. widget layoutInset: (aSpec padding ifNil: [ProportionalSplitterMorph gripThickness]). widget cellGap: (aSpec spacing ifNil: [ProportionalSplitterMorph gripThickness]). "Now create the children." panes := OrderedCollection new. aSpec children isSymbol ifTrue: [ widget getChildrenSelector: aSpec children. widget update: aSpec children] ifFalse: [ self buildAll: aSpec children in: widget]. widget setUpdatablePanesFrom: panes. aSpec label ifNotNil: [:label| label isSymbol ifTrue:[widget getLabelSelector: label] ifFalse:[widget setLabel: label]]. aSpec multiWindowStyle notNil ifTrue: [widget savedMultiWindowState: (SavedMultiWindowState on: aSpec model)]. widget closeWindowSelector: aSpec closeAction. self buildHelpFor: widget spec: aSpec. widget bounds: (RealEstateAgent initialFrameFor: widget initialExtent: (aSpec extent ifNil:[widget initialExtent]) world: self currentWorld). widget refreshWindowColor. ^ widget! From commits at source.squeak.org Sat Feb 20 11:49:22 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sat, 20 Feb 2021 11:49:22 0000 Subject: [squeak-dev] The Trunk: MorphicExtras-mt.284.mcz Message-ID: Marcel Taeumel uploaded a new version of MorphicExtras to project The Trunk: http://source.squeak.org/trunk/MorphicExtras-mt.284.mcz ==================== Summary ==================== Name: MorphicExtras-mt.284 Author: mt Time: 20 February 2021, 12:49:19.325759 pm UUID: ea84a59f-20e8-1b49-8248-08f26c49e028 Ancestors: MorphicExtras-dtl.283 Complements Morphic-mt.1724 =============== Diff against MorphicExtras-dtl.283 =============== Item was changed: ----- Method: FlapTab>>initialize (in category 'initialization') ----- initialize "initialize the state of the receiver" super initialize. + self disableLayout: true. "" edgeToAdhereTo := #left. flapShowing := false. slidesOtherObjects := false. popOutOnDragOver := false. popOutOnMouseOver := false. inboard := false. dragged := false! From commits at source.squeak.org Sat Feb 20 11:50:10 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sat, 20 Feb 2021 11:50:10 0000 Subject: [squeak-dev] The Trunk: EToys-mt.427.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-mt.427.mcz ==================== Summary ==================== Name: EToys-mt.427 Author: mt Time: 20 February 2021, 12:50:02.706759 pm UUID: 357175d9-1c27-224f-bfe8-f9ea651cb4a5 Ancestors: EToys-mt.426 Complements Morphic-mt.1724 =============== Diff against EToys-mt.426 =============== Item was changed: ----- Method: Chess960Morph>>addButtonRow (in category 'initialize') ----- addButtonRow | r m | r := AlignmentMorph newRow hResizing: #shrinkWrap; vResizing: #shrinkWrap; color: Color transparent. r cellInset: 2. r addMorphBack: (self buttonName: ' New ' translated action: #newGame). r addMorphBack: (self buttonName: ' 960 ' translated action: #new960Game). r addMorphBack: (self buttonName: ' Help ' translated action: #findBestMove). r addMorphBack: (self buttonName: ' Play ' translated action: #thinkAndMove). r addMorphBack: (self buttonName: ' Auto ' translated action: #autoPlay). r addMorphBack: (self buttonName: ' Undo ' translated action: #undoMove). r addMorphBack: (self buttonName: ' Redo ' translated action: #redoMove). r addMorphBack: (self buttonName: ' Quit ' translated action: #delete). + r disableLayout: true. - r disableTableLayout: true. r align: r bounds topLeft with: self layoutBounds topLeft. self addMorphFront: r. m := UpdatingStringMorph on: self selector: #statusString. m useStringFormat. m disableTableLayout: true. m stepTime: 50. m align: m bounds topLeft with: r fullBounds bottomLeft. self addMorphFront: m. m font: self textFont; color: self statusColor; maximumWidth: self width - self squareSize; position: self position + (self squareSize @ self squareSize * 0.6)! Item was changed: ----- Method: ChessMorph>>addButtonRow (in category 'initialize') ----- addButtonRow | r m | r := AlignmentMorph newRow hResizing: #shrinkWrap; vResizing: #shrinkWrap; color: Color transparent. r cellInset: 2. r addMorphBack: (self buttonName: ' New ' translated action: #newGame). r addMorphBack: (self buttonName: ' Help ' translated action: #findBestMove). r addMorphBack: (self buttonName: ' Play ' translated action: #thinkAndMove). r addMorphBack: (self buttonName: ' Auto ' translated action: #autoPlay). r addMorphBack: (self buttonName: ' Undo ' translated action: #undoMove). r addMorphBack: (self buttonName: ' Redo ' translated action: #redoMove). r addMorphBack: (self buttonName: ' Quit ' translated action: #delete). + r disableLayout: true. - r disableTableLayout: true. r align: r bounds topLeft with: self layoutBounds topLeft. self addMorphFront: r. m := UpdatingStringMorph on: self selector: #statusString. m useStringFormat. m disableTableLayout: true. m align: m bounds topLeft with: r fullBounds bottomLeft. self addMorphFront: m.! From commits at source.squeak.org Sat Feb 20 11:51:39 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sat, 20 Feb 2021 11:51:39 0000 Subject: [squeak-dev] The Trunk: PreferenceBrowser-mt.111.mcz Message-ID: Marcel Taeumel uploaded a new version of PreferenceBrowser to project The Trunk: http://source.squeak.org/trunk/PreferenceBrowser-mt.111.mcz ==================== Summary ==================== Name: PreferenceBrowser-mt.111 Author: mt Time: 20 February 2021, 12:51:39.041759 pm UUID: d1a8f578-f8f1-8747-b08a-43b49361fef2 Ancestors: PreferenceBrowser-mt.110 Complements Morphic-mt.1724 =============== Diff against PreferenceBrowser-mt.110 =============== Item was changed: ----- Method: PreferenceBrowserMorph>>initializeWithModel: (in category 'initialization') ----- initializeWithModel: aPreferenceBrowser lastKeystrokeTime := 0. lastKeystrokes := ''. + self + hResizing: #spaceFill; "Snap #extent to grid if enabled. See #worldGridEnabled." + vResizing: #spaceFill; "Snap #extent to grid if enabled. See #worldGridEnabled." - self model: aPreferenceBrowser; setLabel: self model windowTitle; name: 'PreferenceBrowser'; addMorph: self rootPanel fullFrame: self rootPanelLayoutFrame; addMorph: self newButtonRow fullFrame: self buttonRowLayoutFrame.! Item was changed: ----- Method: PreferenceWizardMorph>>initialize (in category 'initialization') ----- initialize super initialize. isFullScreen := false. self hasLowPerformance ifTrue: [self color: self defaultColor] ifFalse: [self color: (self defaultColor alpha: 0.75)]. self setProperty: #indicateKeyboardFocus toValue: #never. self changeProportionalLayout; layoutInset: 20; cellGap: 10; + cellPositioning: #center; + disableLayout: true. - cellPositioning: #center. self addKeyboardCaptureFilter: self.! From commits at source.squeak.org Sat Feb 20 11:59:37 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sat, 20 Feb 2021 11:59:37 0000 Subject: [squeak-dev] The Trunk: Morphic-mt.1725.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.1725.mcz ==================== Summary ==================== Name: Morphic-mt.1725 Author: mt Time: 20 February 2021, 12:59:31.409242 pm UUID: 6dbc93ae-acaf-5745-9d5f-8c46317b4f76 Ancestors: Morphic-mt.1724 Fixes minor glitch when enabling world grid. =============== Diff against Morphic-mt.1724 =============== Item was changed: ----- Method: MorphicProject class>>worldGridEnabled: (in category 'preferences') ----- worldGridEnabled: aBooleanOrNil (aBooleanOrNil ifNil: [false]) = self current world griddingOn ifFalse: [self current world griddingOnOff]. + "Auto-configure origin and modulus to match world properties." + self worldGridOrigin: nil. + self worldGridModulus: nil. + "Snap to grid when dragging something." self current world griddingOn ifTrue: [self current world firstHand turnOnGridding] ifFalse: [self current world firstHand turnOffGridding].! From eliot.miranda at gmail.com Sat Feb 20 14:38:15 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sat, 20 Feb 2021 06:38:15 -0800 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS In-Reply-To: References: Message-ID: <0098A9B3-26C0-425D-9261-A526E31EE89C@gmail.com> Hi Liam, > On Feb 19, 2021, at 11:41 AM, Liam Proven wrote: > > On Fri, 19 Feb 2021 at 18:45, Jecel Assumpcao Jr wrote: >> >> I post the link for you, then: >> >> https://fosdem.org/2021/schedule/event/new_type_of_computer/ > > Hi again, Jecel, and thank you. :-) > > Since we conversed on Hacker News, I have downloaded and installed > Squeak and am working my way through the Red, Green and Blue Books. I > may be some time, though. A good shortcut is to read Squeak by Example, which has been updated to refer to current Squeak here: https://github.com/hpi-swa-lab/SqueakByExample-english/releases/download/5.3/SqueakByExample_5_3.pdf I’m the architect of Cog. I’d be interested in discussing where I hope Cog is going technologically to try abd find a direction that suits both your goals and the various goals of people working on Cog. > I have put the slides, the script and a downloadable video on my blog > as well, here: > https://liam-on-linux.livejournal.com/77065.html > >> There are much better places to have this discussion, but they are all >> pretty much dead. So I would not have any objection to having it here. >> Let's see what other people think. > > Sounds good to me. > > -- > Liam Proven – Profile: https://about.me/liamproven > Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com > Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven > UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From Lou at Keystone-Software.com Sat Feb 20 17:17:38 2021 From: Lou at Keystone-Software.com (Louis LaBrunda) Date: Sat, 20 Feb 2021 12:17:38 -0500 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS References: <20210219174547.420721A00054@proxy.email-ssl.com.br> Message-ID: Hi Liam, On Sat, 20 Feb 2021 00:58:21 +0100, Liam Proven wrote: >On Fri, 19 Feb 2021 at 22:46, Louis LaBrunda wrote: >> >> I hadn't heard much about the memory a while. Searching now I see that 256GB goes for about $1900 and 512GB for $9000, >> not cheap. If the prices come down and the size goes up, it would be a great object database with all the ease of >> accessing the data (objects) via Smalltalk. > >I don't know where you are looking but those figures look *wildly* off to me. I was talking about RAM cards (NVDIMM modules) not SSDs: https://www.newegg.com/p/0RN-0020-000M5?item=0RN-0020-000M5&source=region&nm_mc=knc-googleadwords-pc&cm_mmc=knc-googleadwords-pc-_-pla-_-memory+%28desktop+memory%29-_-0RN-0020-000M5&gclid=CjwKCAiAg8OBBhA8EiwAlKw3kt54KfX2xMGJSIgTUKV4qnQ3LQp8ABciwn7MNm_aMh3FPmV6LN_Q_xoCvG4QAvD_BwE&gclsrc=aw.ds https://www.newegg.com/intel-512gb-ddr-t/p/0RN-0020-00082 http://www.nextwarehouse.com/item/?4037146_g10e&gclid=CjwKCAiAg8OBBhA8EiwAlKw3khpC5DI7GaeCiwG8JA85tMWgSoOBiY66kGQ3N9UXErZulLmrrPkHvRoCA94QAvD_BwE The idea is that the objects placed in this area of ram are permanent (safe stored) and therefor constitute a database. The Smalltalk programmer need only indicate that an object be part of the database, the VM then puts it (and other objects it points to) in this special area of memory. This requires some changed to the OS and VM to police ownership of the database but I wouldn't think that would be too complicated. As for the price differences between the RAM and SSD cards, my guess (I don't know for sure) is that even though the memory can be byte addressable, the SSD cards are configured as 512 byte blocks that must be read or written as blocks. That probably brings the price way down. Lou >A tiny 16GB disk is $20: > >https://www.amazon.com/Intel-Optane-Memory-Module-MEMPEK1W016GA/dp/B07CGYTXQK/ > >A bigger 256GB one only $99: > >https://www.amazon.com/Intel-760P-256GB-80mm-PCIe/dp/B078VBL3T9/ > >Intel also offers NVDIMM modules but those do not currently appear on Amazon. > >https://www.extremetech.com/computing/259155-micron-launches-new-nand-based-dimms-intel-announces-optane-dimms > >https://techunplugged.io/2020/07/03/intel-announces-2nd-gen-optane-persistent-memory-modules/ -- Louis LaBrunda Keystone Software Corp. SkypeMe callto://PhotonDemon From tim at rowledge.org Sat Feb 20 18:16:51 2021 From: tim at rowledge.org (tim Rowledge) Date: Sat, 20 Feb 2021 10:16:51 -0800 Subject: [squeak-dev] NuScratch for Squeak 5.3 - and now in exciting 64 bit flavour! Message-ID: I've now been able to build a release of NuScratch for Squeak5.3 - many thanks for the help in working out the keyboard tracking and other issues - that will soon appear in the official Raspberry Pi OS release stream. RPF's main interest was in making sure it could work as they move to having pulse audio as the default sound system, but it was a chance to fix a couple of other things too. Not least is a version for the still-beta Pi 64 bit OS release; the final obstacle to that was surmounted this week with the successful build of a 64 bit version of the pigpio library that worked to waggle the i2c & SPI pins correctly. Obviously, this is going to be the first fairly widespread use of the AArch64 Cog VM, which I find quite exciting. Probably not as exciting as Eliot does though :-) I haven't yet updated SqueakMap but the SqueakSource packages are up to date. Caveats - You do need the UnicodePlugin available for things to run cleanly. This isn't routinely built, I think. You also need the Verdana font files and the Scratch resources directory in order to do a build from sources. You can download a somewhat Pi-specific temporary package from (32 bit) https://mega.nz/file/eElm2SAQ#2Vk5_Z5oUf8G6kidi87Cv6d7HyG7QNXniWE60l2iSFU or (64 bit) https://mega.nz/file/mR0SGSwQ#gIX31V9YSCD9tcrgAGaVVaz5GyH2nU2_ixbW_9Ileb0 Have fun - and if you find any bugs keep them to yourself, dammit, I need to spend some time on other things... tim -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim Strange OpCodes: BPB: Branch on Program Bug From lecteur at zogotounga.net Sat Feb 20 18:49:55 2021 From: lecteur at zogotounga.net (=?UTF-8?Q?St=c3=a9phane_Rollandin?=) Date: Sat, 20 Feb 2021 19:49:55 +0100 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: > To Nicolas' comment: > > But that's precisely what we try to avoid here: create lots of > > intermediate short-lived objects (Rectangle and Point). > > This is because it may be a performance critical routine. > > The most optimized version with the inlined temporaries is a great > implementation but looks like quite a beast to me, which in my opinion > would be sad for something that appears in our standard library. After > looking for senders of Rectangle class>>merging: in my trunk image I > only saw one critical path in recordInvalidRect:, which appears to on > average trigger merging: only once per damaged frame. Is there another > use case we know of? Well yes, I am using #merging: and #encompassing: as primitive methods in computational geometry stuff, and as such I want them as optimized as possible. Also, I do not get the rationale behind the idea that methods in the standard library should be subpar. Regards, Stef From lecteur at zogotounga.net Sat Feb 20 18:50:24 2021 From: lecteur at zogotounga.net (=?UTF-8?Q?St=c3=a9phane_Rollandin?=) Date: Sat, 20 Feb 2021 19:50:24 +0100 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: <429279a3-baf6-489c-0fbc-c9749c0f9dca@zogotounga.net> > But that's precisely what we try to avoid here: create lots of > intermediate short-lived objects (Rectangle and Point). > This is because it may be a performance critical routine. +1 Stef From marcel.taeumel at hpi.de Sat Feb 20 19:10:43 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Sat, 20 Feb 2021 20:10:43 +0100 Subject: [squeak-dev] NuScratch for Squeak 5.3 - and now in exciting 64 bit flavour! In-Reply-To: References: Message-ID: :-D This is good news! Thanks Tim. :-) Best, Marcel Am 20.02.2021 19:17:04 schrieb tim Rowledge : I've now been able to build a release of NuScratch for Squeak5.3 - many thanks for the help in working out the keyboard tracking and other issues - that will soon appear in the official Raspberry Pi OS release stream. RPF's main interest was in making sure it could work as they move to having pulse audio as the default sound system, but it was a chance to fix a couple of other things too. Not least is a version for the still-beta Pi 64 bit OS release; the final obstacle to that was surmounted this week with the successful build of a 64 bit version of the pigpio library that worked to waggle the i2c & SPI pins correctly. Obviously, this is going to be the first fairly widespread use of the AArch64 Cog VM, which I find quite exciting. Probably not as exciting as Eliot does though :-) I haven't yet updated SqueakMap but the SqueakSource packages are up to date. Caveats - You do need the UnicodePlugin available for things to run cleanly. This isn't routinely built, I think. You also need the Verdana font files and the Scratch resources directory in order to do a build from sources. You can download a somewhat Pi-specific temporary package from (32 bit) https://mega.nz/file/eElm2SAQ#2Vk5_Z5oUf8G6kidi87Cv6d7HyG7QNXniWE60l2iSFU or (64 bit) https://mega.nz/file/mR0SGSwQ#gIX31V9YSCD9tcrgAGaVVaz5GyH2nU2_ixbW_9Ileb0 Have fun - and if you find any bugs keep them to yourself, dammit, I need to spend some time on other things... tim -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim Strange OpCodes: BPB: Branch on Program Bug -------------- next part -------------- An HTML attachment was scrubbed... URL: From tim at rowledge.org Sat Feb 20 20:26:00 2021 From: tim at rowledge.org (tim Rowledge) Date: Sat, 20 Feb 2021 12:26:00 -0800 Subject: [squeak-dev] NuScratch for Squeak 5.3 - and now in exciting 64 bit flavour! In-Reply-To: References: Message-ID: > On 2021-02-20, at 11:10 AM, Marcel Taeumel wrote: > > :-D This is good news! Thanks Tim. :-) I hope it helps & interests people. In the actual Scratch-world it would be nice to add some of the more sophisticated blocks that Jens Mönig has made for !Snap, to add the ability to load SVG images (and better yet, edit them!), allow much bigger stages, saving of projects as text - and reading them back in, and maybe even making a block->Smalltalk transpiler/JIT. I did a trivial test a while back and some modest cases like would convert to ((a \\ 4) rounded > 2 and: [10 random = 5]) ifTrue: [ "do something" Which very roughly is 1.5 million times faster. So I think it might be interesting. One of the things I'd really love to see done is separating out the block-stacking-UI stuff from the Scratch stage/sprite thing. I'm pretty convinced that using a block stacking UI to assemble simple scripts for "Smart Home Control" would be a win. The generic Scratch "many scripts running kinda-parallel" concept would be excellent for that. Imagine being able to make little scripts for each light switch and bulb and outlet and sensor in your house. The even simpler block-stacking way of making small workflows without worrying about parallelism would be useful - I even have a business case for that. Imagine being able to create plain old methods that way, in a browser. Remember the BASIC syntax stuff DanI did years ago? tim -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim Useful Latin Phrases:- Radix lecti = Couch potato -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: file.php Type: image/png Size: 5878 bytes Desc: not available URL: From leves at caesar.elte.hu Sat Feb 20 20:51:12 2021 From: leves at caesar.elte.hu (Levente Uzonyi) Date: Sat, 20 Feb 2021 21:51:12 +0100 (CET) Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: On Sat, 20 Feb 2021, Tom Beckmann wrote: > Hi Levente, hi Nicolas, > > To Levente's comment: > > You left an #asSet send in the above benchmark. > > Oups, indeed. But I think the actual measurement was done without the asSet, I just added it later for experimentation. The numbers appear consistent when I rerun the lines without #asSet. > After sending the mail, I also realized that the setOrigin:corner:/merging4: version is of course not legal, since we mutate the original rectangle that was passed in. > > To Nicolas' comment: > > But that's precisely what we try to avoid here: create lots of > > intermediate short-lived objects (Rectangle and Point). > > This is because it may be a performance critical routine. > > The most optimized version with the inlined temporaries is a great implementation but looks like quite a beast to me, which in my opinion would be sad for something that appears in our standard library. After looking for > senders of Rectangle class>>merging: in my trunk image I only saw one critical path in recordInvalidRect:, which appears to on average trigger merging: only once per damaged frame. Is there another use case we know of? My stance on library methods is that they need to be optimized because you don't know how people will use them. If they are fast, people will be happy. If they are not, you'll leave a bad impression. This discussion exists, because Karl changed the method last year and noticed that the performance got worse[1]. And, while he was convinced about arguments always being sequenceable, it turned out that they may be sets as well. Levente [1] http://forum.world.st/The-Inbox-Graphics-kfr-434-mcz-tp5119541p5119584.html > > Best regards, > Tom > > On Fri, Feb 19, 2021 at 6:53 PM Levente Uzonyi wrote: > Hi Tom, > > On Fri, 19 Feb 2021, Tom Beckmann wrote: > > > Hi everyone, > > > > just another idea for your consideration: > > > > merging3: listOfRects > >     ^ listOfRects reduce: [:a :b | > >          self origin: (a origin min: b origin) corner: (a corner max: b corner)] > > > > If you care more about performance than idioms (not even sure if this is legal): > > merging4: listOfRects > >     ^ listOfRects reduce: [:a :b | > >          a setOrigin: (a origin min: b origin) corner: (a corner max: b corner)] > > > > And finally, the, in my opinion, most elegant version. Sadly, it's also the slowest. > > merging5: listOfRects > >      ^ listOfRects reduce: [:a :b | a quickMerge: b] > > > > > > > > Some unrepresentative benchmarks: > > > > " Levente's version from above with temps " > > [Rectangle merging2: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '3,740,000 per second. 267 nanoseconds per run. 37.46501 % GC time.' > > " the 'clean' version " > > [Rectangle merging3: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '3,020,000 per second. 331 nanoseconds per run. 40.93181 % GC time.' > > " the version that mutates rectangles " > > [Rectangle merging4: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100} asSet] bench '3,330,000 per second. 300 nanoseconds per run. 40.53189 % GC time.' > > You left an #asSet send in the above benchmark. > > > Levente > > > " using quickMerge " > > [Rectangle merging5: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '2,930,000 per second. 341 nanoseconds per run. 42.32 % GC time.' > > > > Best, > > Tom > > > > On Thu, Feb 18, 2021 at 11:17 PM Levente Uzonyi wrote: > >       Hi Chris, > > > >       On Wed, 17 Feb 2021, Chris Muller wrote: > > > >       > This is what I would do: > >       > > >       > merging: listOfRects > >       >     "A number of callers of merge: should use this method." > >       >     ^ listOfRects > >       >         inject: > >       >             (self > >       >                 origin: Float infinity @ Float infinity > >       >                 corner: Float infinity negated @ Float infinity negated) > >       >         into: [ : rect : each | rect quickMerge: each ] > >       > > >       > With #quickMerge:, you're only creating a new Rectangle when it needed to grow to accomodate the current element, but many of the elements might fit completely, resulting in no additional instantiation.  > Do an > >       analysis of how > >       > many temporary Point objects we create -- hint: it's a ton -- and my own attempts to optimize that in my Kml framework were not fruitful (e.g., ~1%), with a trade-off of duplicating implementation across > >       multiple methods and > >       > making the system's code harder to read and understand and maintain. > > > >       With my benchmark, your version is slower than the one from 2003, > >       especially when the collection is small. And it doesn't handle the case of > >       empty listOfRects the same way: it silently returns a rectangle instead of > >       raising an error. > > > >       Here's the version I came up with the other day: > > > > > >       merging: listOfRects > >               "A number of callers of merge: should use this method." > > > >               | minTopLeftX minTopLeftY maxBottomRightX maxBottomRightY | > >               listOfRects do: [ :rectangle | > >                       | topLeft bottomRight | > >                       topLeft := rectangle topLeft. > >                       bottomRight := rectangle bottomRight. > >                       minTopLeftX > >                               ifNil: [ > >                                       minTopLeftX := topLeft x. > >                                       minTopLeftY := topLeft y. > >                                       maxBottomRightX := bottomRight x. > >                                       maxBottomRightY := bottomRight y ] > >                               ifNotNil: [ > >                                       topLeft x < minTopLeftX ifTrue: [ minTopLeftX := topLeft x ]. > >                                       topLeft y < minTopLeftY ifTrue: [ minTopLeftY := topLeft y ]. > >                                       bottomRight x > maxBottomRightX ifTrue: [ maxBottomRightX := bottomRight x ]. > >                                       bottomRight y > maxBottomRightY ifTrue: [ maxBottomRightY := bottomRight y ] ] ]. > >               ^self origin: minTopLeftX @ minTopLeftY corner: maxBottomRightX @ maxBottomRightY > > > > > >       Levente > > > >       > > >       >  - Chris > >       > > >       > > >       > On Wed, Feb 17, 2021 at 11:27 AM Levente Uzonyi wrote: > >       >       On Wed, 17 Feb 2021, Marcel Taeumel wrote: > >       > > >       >       > Hmm... looking at performance ... why not just add #asSequenceableCollection, which would only impact Set arguments? > >       > > >       >       I don't think we have such method. Adding one would raise the usual > >       >       question: should it create a new collection or return self if self > >       >       already to the requested collection kind? > >       >       IIRC currently the only outlier is #asOrderedCollection which always > >       >       creates a copy when the receiver is an OrderedCollection, and that > >       >       property is being relied on, so it can't be changed... > >       > > >       >       > As a programmer, I do not want to choose between #merge: and #quickMerge:. Or similar. :-) > >       > > >       >       IMO, we simply need one quick solution. If you have a Set, you may need > >       >       that help from the library even more. > >       >       #quickMerge: is only good for merging two rectangles. It does not solve > >       >       the GC issue #merge: has. > >       > > >       > > >       >       Levente > >       > > >       >       > > >       >       > Best, > >       >       > Marcel > >       >       > > >       >       >       Am 13.02.2021 17:05:07 schrieb commits at source.squeak.org : > >       >       > > >       >       >       Nicolas Cellier uploaded a new version of Graphics to project The Inbox: > >       >       >       http://source.squeak.org/inbox/Graphics-nice.446.mcz > >       >       > > >       >       >       ==================== Summary ==================== > >       >       > > >       >       >       Name: Graphics-nice.446 > >       >       >       Author: nice > >       >       >       Time: 13 February 2021, 5:04:52.453325 pm > >       >       >       UUID: d13c1db2-370f-4fa6-b7ae-e6766bf0c8fb > >       >       >       Ancestors: Graphics-dtl.445 > >       >       > > >       >       >       Let Rectangle merging:/encompassing: an unordered collection. > >       >       > > >       >       >       =============== Diff against Graphics-dtl.445 =============== > >       >       > > >       >       >       Item was changed: > >       >       >       ----- Method: Rectangle class>>encompassing: (in category 'instance creation') ----- > >       >       >       encompassing: listOfPoints > >       >       >       "A number of callers of encompass: should use this method." > >       >       >       | topLeft bottomRight | > >       >       >       + topLeft := bottomRight := listOfPoints anyOne. > >       >       >       + listOfPoints do: > >       >       >       - topLeft := bottomRight := listOfPoints first. > >       >       >       - listOfPoints allButFirstDo: > >       >       >       [:p |topLeft := topLeft min: p. > >       >       >       + bottomRight := bottomRight max: p]. > >       >       >       - bottomRight := bottomRight max: p]. > >       >       >       ^self origin: topLeft corner: bottomRight > >       >       >       ! > >       >       > > >       >       >       Item was changed: > >       >       >       ----- Method: Rectangle class>>merging: (in category 'instance creation') ----- > >       >       >       merging: listOfRects > >       >       >       "A number of callers of merge: should use this method." > >       >       >       + | aRectangle bottomRight topLeft | > >       >       >       + aRectangle := listOfRects anyOne. > >       >       >       + topLeft := aRectangle topLeft. > >       >       >       + bottomRight := aRectangle bottomRight. > >       >       >       - | bottomRight topLeft | > >       >       >       - topLeft := listOfRects first topLeft. > >       >       >       - bottomRight := listOfRects first bottomRight. > >       >       >       listOfRects > >       >       >       + do: [:r | topLeft := topLeft min: r topLeft. > >       >       >       - allButFirstDo: [:r | topLeft := topLeft min: r topLeft. > >       >       >       bottomRight := bottomRight max: r bottomRight]. > >       >       >       ^self origin: topLeft corner: bottomRight. > >       >       >       ! > >       >       > > >       >       > > >       >       > > >       >       > > >       > > >       > > >       > > > > > > > > > > From m at jaromir.net Sat Feb 20 21:29:54 2021 From: m at jaromir.net (Jaromir Matas) Date: Sat, 20 Feb 2021 15:29:54 -0600 (CST) Subject: [squeak-dev] Inspector / Explorer display (printOn:) closures slightly differently Message-ID: <1613856594072-0.post@n4.nabble.com> Explorer/inspector present closures as [closure] in Class>>method or: [] in Class>>method depending on whether they are printed from Context or BlockClosure #printOn - by design or by accident? (or have I missed something?) Thanks, ----- ^[^ Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From lewis at mail.msen.com Sat Feb 20 23:29:12 2021 From: lewis at mail.msen.com (David T. Lewis) Date: Sat, 20 Feb 2021 18:29:12 -0500 Subject: [squeak-dev] NuScratch for Squeak 5.3 - and now in exciting 64 bit flavour! In-Reply-To: References: Message-ID: <20210220232912.GA60864@shell.msen.com> On Sat, Feb 20, 2021 at 10:16:51AM -0800, tim Rowledge wrote: > I've now been able to build a release of NuScratch for Squeak5.3 - many thanks for the help in working out the keyboard tracking and other issues - that will soon appear in the official Raspberry Pi OS release stream. RPF's main interest was in making sure it could work as they move to having pulse audio as the default sound system, but it was a chance to fix a couple of other things too. > That is great news! > Not least is a version for the still-beta Pi 64 bit OS release; the final obstacle to that was surmounted this week with the successful build of a 64 bit version of the pigpio library that worked to waggle the i2c & SPI pins correctly. Obviously, this is going to be the first fairly widespread use of the AArch64 Cog VM, which I find quite exciting. Probably not as exciting as Eliot does though :-) > > I haven't yet updated SqueakMap but the SqueakSource packages are up to date. > > Caveats - You do need the UnicodePlugin available for things to run cleanly. This isn't routinely built, I think. I'd like to try NuScratch on my AMD Linux box, can you remind me what pango and/or cairo development libraries you installed for the UnicodePlugin? Some magic apt-get commands I presume. Kudos and congratulations. Dave > You also need the Verdana font files and the Scratch resources directory in order to do a build from sources. > > You can download a somewhat Pi-specific temporary package from > > (32 bit) https://mega.nz/file/eElm2SAQ#2Vk5_Z5oUf8G6kidi87Cv6d7HyG7QNXniWE60l2iSFU > or > (64 bit) https://mega.nz/file/mR0SGSwQ#gIX31V9YSCD9tcrgAGaVVaz5GyH2nU2_ixbW_9Ileb0 > > Have fun - and if you find any bugs keep them to yourself, dammit, I need to spend some time on other things... > > tim > -- > tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim > Strange OpCodes: BPB: Branch on Program Bug > > > From tim at rowledge.org Sun Feb 21 00:24:18 2021 From: tim at rowledge.org (tim Rowledge) Date: Sat, 20 Feb 2021 16:24:18 -0800 Subject: [squeak-dev] NuScratch for Squeak 5.3 - and now in exciting 64 bit flavour! In-Reply-To: <20210220232912.GA60864@shell.msen.com> References: <20210220232912.GA60864@shell.msen.com> Message-ID: <39739408-A13F-4FCE-AE46-C9B3B4702908@rowledge.org> > On 2021-02-20, at 3:29 PM, David T. Lewis wrote: > > I'd like to try NuScratch on my AMD Linux box, can you remind me what pango > and/or cairo development libraries you installed for the UnicodePlugin? Some > magic apt-get commands I presume. On the Pi it looks like sudo apt-get install libcairo2-dev libpango1.0-dev mesa-common-dev should do it, though Subbu also suggested libgl1-mesa-dev libgl1-mesa-glx instead of mesa-common-dev. I'm not completely sure which choice is better; I had 'fun' with the directory naming clash for the glib includes, something that still needs a proper resolution tim -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim Strange OpCodes: CRN: Compare to Random Number From lewis at mail.msen.com Sun Feb 21 02:12:46 2021 From: lewis at mail.msen.com (David T. Lewis) Date: Sat, 20 Feb 2021 21:12:46 -0500 Subject: [squeak-dev] NuScratch for Squeak 5.3 - and now in exciting 64 bit flavour! In-Reply-To: <39739408-A13F-4FCE-AE46-C9B3B4702908@rowledge.org> References: <20210220232912.GA60864@shell.msen.com> <39739408-A13F-4FCE-AE46-C9B3B4702908@rowledge.org> Message-ID: <20210221021246.GA78074@shell.msen.com> On Sat, Feb 20, 2021 at 04:24:18PM -0800, tim Rowledge wrote: > > > > On 2021-02-20, at 3:29 PM, David T. Lewis wrote: > > > > I'd like to try NuScratch on my AMD Linux box, can you remind me what pango > > and/or cairo development libraries you installed for the UnicodePlugin? Some > > magic apt-get commands I presume. > > On the Pi it looks like > sudo apt-get install libcairo2-dev libpango1.0-dev mesa-common-dev > should do it, though Subbu also suggested libgl1-mesa-dev libgl1-mesa-glx instead of mesa-common-dev. > > I'm not completely sure which choice is better; I had 'fun' with the directory naming clash for the glib includes, something that still needs a proper resolution > Thanks. I installed libcairo2-dev libpango1.0-dev mesa-common-dev which now gives me a UnicodePlugin for the interpreter VM build, so I think these are the necessary libraries. The Spur VM build is still excluding the plugin due to something in the configure step. If I figure it out I'll report back, probably not tonight though :-/ Dave From lewis at mail.msen.com Sun Feb 21 02:32:03 2021 From: lewis at mail.msen.com (David T. Lewis) Date: Sat, 20 Feb 2021 21:32:03 -0500 Subject: [squeak-dev] NuScratch for Squeak 5.3 - and now in exciting 64 bit flavour! In-Reply-To: <20210221021246.GA78074@shell.msen.com> References: <20210220232912.GA60864@shell.msen.com> <39739408-A13F-4FCE-AE46-C9B3B4702908@rowledge.org> <20210221021246.GA78074@shell.msen.com> Message-ID: <20210221023203.GA90703@shell.msen.com> On Sat, Feb 20, 2021 at 09:12:46PM -0500, David T. Lewis wrote: > On Sat, Feb 20, 2021 at 04:24:18PM -0800, tim Rowledge wrote: > > > > > > > On 2021-02-20, at 3:29 PM, David T. Lewis wrote: > > > > > > I'd like to try NuScratch on my AMD Linux box, can you remind me what pango > > > and/or cairo development libraries you installed for the UnicodePlugin? Some > > > magic apt-get commands I presume. > > > > On the Pi it looks like > > sudo apt-get install libcairo2-dev libpango1.0-dev mesa-common-dev > > should do it, though Subbu also suggested libgl1-mesa-dev libgl1-mesa-glx instead of mesa-common-dev. > > > > I'm not completely sure which choice is better; I had 'fun' with the directory naming clash for the glib includes, something that still needs a proper resolution > > > > Thanks. I installed libcairo2-dev libpango1.0-dev mesa-common-dev which > now gives me a UnicodePlugin for the interpreter VM build, so I think > these are the necessary libraries. The Spur VM build is still excluding > the plugin due to something in the configure step. If I figure it out > I'll report back, probably not tonight though :-/ > > Dave > I think there must be something about hitting on an email that causes problems to magically solve themselves. I just copied the UnicodePlugin from my interpreter VM build into the Spur VM folder, and now NuScratch is running on my amd64 Linux PC. I'll worry about the configure issues some other day, right now I'm happy to confirm that NuScratch is running on my PC :-) Dave From ken.dickey at whidbey.com Sun Feb 21 02:51:16 2021 From: ken.dickey at whidbey.com (ken.dickey at whidbey.com) Date: Sat, 20 Feb 2021 18:51:16 -0800 Subject: [squeak-dev] Fwd: Shim OS [response to: partially Squeak based OS] In-Reply-To: References: Message-ID: <4f99b490eefcf416f91dc5c9f555a491@whidbey.com> I responded directly to Liam, but noted a lof of interest on this list.. FYI, -KenD -------- Original Message -------- .. Liam, I noted your post on the Squeak mailing list and enjoyed the FOSDEM slides. I happen to have been at Apple during the 90's and have experience writing in SK8Script, NewtonScript, Dylan, MacLisp, ScriptX, and Smalltalk (among others). Glad to see someone notice these things. A couple of thoughts.. Device drivers are, for me, complex and painful. Not considering device drivers as my value added area, my thought was to use a "shim" OS, so I got the vm-display-fbdev (frame-buffer display) up for use with Alpine Linux (MUSL + Busybox). I am primarily a Cuis Smalltalk user (I like small; Note class counts in https://github.com/Cuis-Smalltalk/Learning-Cuis) but Squeak works here as well. Ultibo.org is an interesting Free Pascal based unikernel for Raspberry Pi's. Makes use of multicores. Detecting and recovering from driver SW and HW failures is critical to robustness. Minix3.org is a microkernel whose Reincarnation Server can reload failed drivers. Erlang's HydrOS is meant to deal with HW failures (http://www.erlang-factory.com/static/upload/media/1498583896660864samwilliamshowtobuildanoswitherlang_awhistlestoptourofhydros.pdf ) Good on ya, -KenD From tim at rowledge.org Sun Feb 21 06:12:29 2021 From: tim at rowledge.org (tim Rowledge) Date: Sat, 20 Feb 2021 22:12:29 -0800 Subject: [squeak-dev] Fwd: Shim OS [response to: partially Squeak based OS] In-Reply-To: <4f99b490eefcf416f91dc5c9f555a491@whidbey.com> References: <4f99b490eefcf416f91dc5c9f555a491@whidbey.com> Message-ID: > On 2021-02-20, at 6:51 PM, ken.dickey at whidbey.com wrote: > > Device drivers are, for me, complex and painful. I don't think I've ever met anyone for whom that is not the case. Writing an entire OS seems to me to be a Quixotic dream; why bother? Yes, I know Dan Ingall's famous quotation - "An operating system is a collection of things that don't fit into a language. There shouldn't be one." However, I think that one can look at this rather differently than "have no operating system". I think the practical approach is "have nothing that doesn't fit in your language system". If we make a system that can talk to everything that an underlying OS kernel and facilities provides - device drivers, scheduling, interrupt handling, storage abstraction, network blah-blah-blah - then there is no OS as a separate thing that anyone need care about. There are no "things that don't fit into a language". The simple answer to approach this quite closely and fairly painlessly is to use an install of some linux system without the X-nightmare and use the frame buffer as the Smalltalk display. Yes, sure, there are other minimal OS' that Ken pointed out too. One would still need to work out how to handle all the facilities we take for granted for our daily use of a computer; a *good* email system, web browsing, assorted social media interfaces and on and on. I suggest that we also need to make it practical in this new world to have many Smalltalk images running at the same time so as to insulate said email/browser/twitter/etc from each other in case of serious problems, so we'd want some sort of (Smalltalk implemented, obviously) windowing system. It's doable. I think it might take a bit more than the usual tim PS Random number sigline chooser FTW, again! -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim Porting is such sweet sorrow -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: attachment.jpeg Type: image/jpeg Size: 8060 bytes Desc: not available URL: From m at jaromir.net Sun Feb 21 13:20:12 2021 From: m at jaromir.net (Jaromir Matas) Date: Sun, 21 Feb 2021 07:20:12 -0600 (CST) Subject: [squeak-dev] Inspector / Explorer display (printOn:) closures slightly differently In-Reply-To: <1613856594072-0.post@n4.nabble.com> References: <1613856594072-0.post@n4.nabble.com> Message-ID: <1613913612417-0.post@n4.nabble.com> I suspect "[closure] in Class>>method" really means: closure: [] in Class>>method while "[] in Class>>method" actually points to a context: context: [] in Class>>method I understand a "closure" is, in fact, a block in a context. For a beginner "[closure]" is really cryptic and confusing... In addition, seeing "sender = FullBlockClosure(BlockClosure)>>valueWithExit:" really twisted my brain :) The sender is, indeed, a context. May I suggest something more consistent to provide a clear clue e.g.: sender... context [] in Class>>method receiver... closure [] in Class>>method analogous, though redundant: outerContext... context [] in Class>>method closureOrNil ... closure [] in Class>>method Thanks a lot. Regards, ----- ^[^ Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From lproven at gmail.com Sun Feb 21 15:09:25 2021 From: lproven at gmail.com (Liam Proven) Date: Sun, 21 Feb 2021 16:09:25 +0100 Subject: [squeak-dev] Fwd: Shim OS [response to: partially Squeak based OS] In-Reply-To: <4f99b490eefcf416f91dc5c9f555a491@whidbey.com> References: <4f99b490eefcf416f91dc5c9f555a491@whidbey.com> Message-ID: On Sun, 21 Feb 2021 at 03:51, wrote: > > I responded directly to Liam, but noted a lof of interest on this list.. Did you? May I ask -- to which address? > -------- Original Message -------- > .. > Liam, > > I noted your post on the Squeak mailing list and enjoyed the FOSDEM > slides. > > I happen to have been at Apple during the 90's and have experience > writing in SK8Script, NewtonScript, Dylan, MacLisp, ScriptX, and > Smalltalk (among others). Glad to see someone notice these things. Oh my word, that's quite a back-catalogue! I am impressed. I generally find -- and this time is no exception -- that Lisp folk are _strongly_ resistant to any suggestion that perhaps a more conventional syntax, layered on top of a conventional prefix-notation Lisp, would make it a lot more accessible to a lot more people. One objection to this is that it significantly impedes the use of Lisp macros. On the other hand, many former Lispers are now enthusiastic about various modern xNix scripting languages that in recent versions include closures, lambda calculus and so on, and yet none of these can use Lisp-type macros. I suspect that while Lisp's macros are immensely powerful, at least potentially, they might also make it very hard to read and debug someone else's code, and therefore not be ideal for cooperative team development... And that is a sad commercial necessity. But this is not germane to the Smalltalk side of my proposal. ;-) > A couple of thoughts.. > > Device drivers are, for me, complex and painful. I am sure you're not alone. > Not considering device drivers as my value added area, my thought was to > use a "shim" OS, so I got the vm-display-fbdev (frame-buffer display) up > for use with Alpine Linux (MUSL + Busybox). I am primarily a Cuis > Smalltalk user (I like small; Note class counts in > https://github.com/Cuis-Smalltalk/Learning-Cuis) but Squeak works here > as well. I have played around with Alpine a little, but even a lightweight Linux is still a formidable amount of code, and therefore will still need frequent updates and so on. That's part of what I wanted to break away from. Secondly, I was trying to look to the future, to an OS that could run well on a machine with only RAM and persistent memory, without disk drives or anything pretending to be disk drives. I seriously think that in time PMEM could turn the notion of disk drives into legacy technology, as obsolete as tape drives -- i.e. still relevant for big enterprise servers, but completely gone from typical end-user devices. Thirdly, I suspect that keeping any element of existing technology stacks -- for instance, such as a bare-metal shim OS implemented in C -- will preserve some of the many problems with the existing stack, and represent a temptation to import other bits of the stack as well. > Ultibo.org is an interesting Free Pascal based unikernel for Raspberry > Pi's. Makes use of multicores. I am aware of it. I have a copy, and have installed Free Pascal and Lazarus, and am trying to revive dusty corroded memories of Pascal coding in the 1980s... I was hoping to resurrect my corroded skills -- meagre at the time -- by trying to do some bare-metal vintage-computer emulation. Both the Sinclair QL and Atari ST operating systems have completely FOSS derivatives these days, and getting them running on the RasPi would be fun. But probably far beyond my skills... :-( There is not much existing code to draw upon: Delphi was not a popular tool for writing emulators. > Detecting and recovering from driver SW and HW failures is critical to > robustness. This is true. > Minix3.org is a microkernel whose Reincarnation Server can reload failed > drivers. It is, but it's still an *nix. _Heavily_ filesystem-centric, implemented in C, not yet multicore capable, and anyway, it is its own thing and doing just fine. Most widely-deployed x86 xNix as it is in every recent Intel CPU. > Erlang's HydrOS is meant to deal with HW failures > (http://www.erlang-factory.com/static/upload/media/1498583896660864samwilliamshowtobuildanoswitherlang_awhistlestoptourofhydros.pdf > ) OK, this one is new to me! Erlang is a bit niche, though, and as I understand it, the price of its resilient multiprocess model is that it is quite slow... -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From lproven at gmail.com Sun Feb 21 15:18:34 2021 From: lproven at gmail.com (Liam Proven) Date: Sun, 21 Feb 2021 16:18:34 +0100 Subject: [squeak-dev] Fwd: Shim OS [response to: partially Squeak based OS] In-Reply-To: References: <4f99b490eefcf416f91dc5c9f555a491@whidbey.com> Message-ID: On Sun, 21 Feb 2021 at 07:12, tim Rowledge wrote: > > I don't think I've ever met anyone for whom that is not the case. Heh. :-) > Writing an entire OS seems to me to be a Quixotic dream; why bother? Yes, I know Dan Ingall's famous quotation - > "An operating system is a collection of things that don't fit into a language. There shouldn't be one." > > However, I think that one can look at this rather differently than "have no operating system". I think the practical approach is "have nothing that doesn't fit in your language system". If we make a system that can talk to everything that an underlying OS kernel and facilities provides - device drivers, scheduling, interrupt handling, storage abstraction, network blah-blah-blah - then there is no OS as a separate thing that anyone need care about. There are no "things that don't fit into a language". ISTM that the flipside of this is the point from my talk: that if you choose a single, sufficiently-powerful programming language, that you can build the entire stack in that one language and avoid the polyglot complexity of a modern FOSS xNix. What I would like to see would be a modern take on the single-language dynamic environments that were starting to appear on workstations in the late 1970s to early 1980s: specifically, the non-filesystem-centric ones, because as I've said elsewhere -- and in last year's FOSDEM talk ( https://liam-on-linux.livejournal.com/69099.html ) -- I think that, _pace_ suitable OSes to support it -- PMEM tech could render the entire concept of disk drives (HDDs, SDDs, whatever) obsolete. > The simple answer to approach this quite closely and fairly painlessly is to use an install of some linux system without the X-nightmare and use the frame buffer as the Smalltalk display. Yes, sure, there are other minimal OS' that Ken pointed out too. Simple to implement, perhaps, but still a big mess o' C, still completely filesystem-centric, impossible to further simplify, and essentially impossible for any single human to completely understand. > One would still need to work out how to handle all the facilities we take for granted for our daily use of a computer; a *good* email system, web browsing, assorted social media interfaces and on and on. A2 can do a surprising amount of this already, today. For a niche experimental OS it is amazingly complete. http://ignorethecode.net/blog/2009/04/22/oberon/ > I suggest that we also need to make it practical in this new world to have many Smalltalk images running at the same time so as to insulate said email/browser/twitter/etc from each other in case of serious problems, so we'd want some sort of (Smalltalk implemented, obviously) windowing system. This is a big issue. I have only a sketchy high-level theoretical understanding of Smalltalk. AFAIK the IBM RoarVM supports a multithreaded multicore Smalltalk engine, but how IBM would feel about anyone attempting to port that to Oberon or something, I don't know. > It's doable. I think it might take a bit more than the usual It is no small project, certainly. But parts of it are already there. A2 exists and works. Squeak exists and works. Putting one on the other is not impossible. That would yield a proof-of-concept to get people interested... -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From lproven at gmail.com Sun Feb 21 15:24:06 2021 From: lproven at gmail.com (Liam Proven) Date: Sun, 21 Feb 2021 16:24:06 +0100 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS In-Reply-To: <0098A9B3-26C0-425D-9261-A526E31EE89C@gmail.com> References: <0098A9B3-26C0-425D-9261-A526E31EE89C@gmail.com> Message-ID: On Sat, 20 Feb 2021 at 15:38, Eliot Miranda wrote: > > Hi Liam, > > A good shortcut is to read Squeak by Example, which has been updated to refer to current Squeak here: https://github.com/hpi-swa-lab/SqueakByExample-english/releases/download/5.3/SqueakByExample_5_3.pdf Thanks! Yes, I downloaded that too, but a former-Smalltalker friend has been trying to get me to read the R/G/B books for a decade now... > I’m the architect of Cog. I’d be interested in discussing where I hope Cog is going technologically to try abd find a direction that suits both your goals and the various goals of people working on Cog. By all means! If enough people seem to be interested, I could start a new mailing list just for it... This one does have its own agenda, I think, no? -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From lproven at gmail.com Sun Feb 21 15:29:54 2021 From: lproven at gmail.com (Liam Proven) Date: Sun, 21 Feb 2021 16:29:54 +0100 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS In-Reply-To: References: <20210219174547.420721A00054@proxy.email-ssl.com.br> Message-ID: On Sat, 20 Feb 2021 at 18:17, Louis LaBrunda wrote: > > I was talking about RAM cards (NVDIMM modules) not SSDs: Aha! > https://www.newegg.com/p/0RN-0020-000M5?item=0RN-0020-000M5&source=region&nm_mc=knc-googleadwords-pc&cm_mmc=knc-googleadwords-pc-_-pla-_-memory+%28desktop+memory%29-_-0RN-0020-000M5&gclid=CjwKCAiAg8OBBhA8EiwAlKw3kt54KfX2xMGJSIgTUKV4qnQ3LQp8ABciwn7MNm_aMh3FPmV6LN_Q_xoCvG4QAvD_BwE&gclsrc=aw.ds > > https://www.newegg.com/intel-512gb-ddr-t/p/0RN-0020-00082 > > http://www.nextwarehouse.com/item/?4037146_g10e&gclid=CjwKCAiAg8OBBhA8EiwAlKw3khpC5DI7GaeCiwG8JA85tMWgSoOBiY66kGQ3N9UXErZulLmrrPkHvRoCA94QAvD_BwE *Ouch*. Still, it's early days. I also think it might be more relevant to compare to RAM prices than flash SSD prices. E.g. $3.5K for a 256GB DDR4 DIMM: https://www.memorycow.co.uk/256gb-ddr4-pc4-23400-2933mhz-288-pin-dimm-ecc-lrdimm-memory-ram > The idea is that the objects placed in this area of ram are permanent (safe stored) and therefor constitute a database. > The Smalltalk programmer need only indicate that an object be part of the database, the VM then puts it (and other > objects it points to) in this special area of memory. This requires some changed to the OS and VM to police ownership > of the database but I wouldn't think that would be too complicated. Seems reasonable. > As for the price differences between the RAM and SSD cards, my guess (I don't know for sure) is that even though the > memory can be byte addressable, the SSD cards are configured as 512 byte blocks that must be read or written as blocks. > That probably brings the price way down. There is a talk about another PMEM-centric OS on Youtube, Twizzler, that mentions this in passing. https://youtu.be/bSNda9EzNOI It's quite long (~1h20m) but so bursting with ideas that it's a packed hour+ even at 1.25x speed, which necessitated pausing and rewinding a few times for me. -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From eliot.miranda at gmail.com Sun Feb 21 16:53:43 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sun, 21 Feb 2021 08:53:43 -0800 Subject: [squeak-dev] NuScratch for Squeak 5.3 - and now in exciting 64 bit flavour! In-Reply-To: <20210221023203.GA90703@shell.msen.com> References: <20210221023203.GA90703@shell.msen.com> Message-ID: <23D2FA37-A0E5-4683-87BF-0D8636E15698@gmail.com> Hi Holger, if you have time and inclination I (we) would very much appreciate you taking a look at the autoconf issue that is preventing the Unicode plug-in from being built in the ARM64 build on Linux Raspberry Pi (build.linux64ARMv8 IIRC). Cheers! _,,,^..^,,,_ (phone) > On Feb 20, 2021, at 6:32 PM, David T. Lewis wrote: > > On Sat, Feb 20, 2021 at 09:12:46PM -0500, David T. Lewis wrote: >>> On Sat, Feb 20, 2021 at 04:24:18PM -0800, tim Rowledge wrote: >>> >>> >>>> On 2021-02-20, at 3:29 PM, David T. Lewis wrote: >>>> >>>> I'd like to try NuScratch on my AMD Linux box, can you remind me what pango >>>> and/or cairo development libraries you installed for the UnicodePlugin? Some >>>> magic apt-get commands I presume. >>> >>> On the Pi it looks like >>> sudo apt-get install libcairo2-dev libpango1.0-dev mesa-common-dev >>> should do it, though Subbu also suggested libgl1-mesa-dev libgl1-mesa-glx instead of mesa-common-dev. >>> >>> I'm not completely sure which choice is better; I had 'fun' with the directory naming clash for the glib includes, something that still needs a proper resolution >>> >> >> Thanks. I installed libcairo2-dev libpango1.0-dev mesa-common-dev which >> now gives me a UnicodePlugin for the interpreter VM build, so I think >> these are the necessary libraries. The Spur VM build is still excluding >> the plugin due to something in the configure step. If I figure it out >> I'll report back, probably not tonight though :-/ >> >> Dave >> > > I think there must be something about hitting on an email that > causes problems to magically solve themselves. > > I just copied the UnicodePlugin from my interpreter VM build into the > Spur VM folder, and now NuScratch is running on my amd64 Linux PC. > > I'll worry about the configure issues some other day, right now I'm > happy to confirm that NuScratch is running on my PC :-) > > Dave > From Lou at Keystone-Software.com Sun Feb 21 17:03:07 2021 From: Lou at Keystone-Software.com (Louis LaBrunda) Date: Sun, 21 Feb 2021 12:03:07 -0500 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS References: <20210219174547.420721A00054@proxy.email-ssl.com.br> Message-ID: <62453gd7uhqu4evdmqijd4fovf28iac2ql@4ax.com> Hi Liam, snip... >*Ouch*. > >Still, it's early days. I also think it might be more relevant to compare to RAM prices than flash SSD prices. I agree. If the object database can fit in the 512GB (and the OS and Smalltalk VM are changed to do what is needed) $9,000 isn't that bad. Being able to use Smalltalk collections in an object that would ordinarily be an SQL table row and require complex SQL tables and code, makes the cost of the memory look cheep. Lou -- Louis LaBrunda Keystone Software Corp. SkypeMe callto://PhotonDemon From tim at rowledge.org Sun Feb 21 18:44:04 2021 From: tim at rowledge.org (tim Rowledge) Date: Sun, 21 Feb 2021 10:44:04 -0800 Subject: [squeak-dev] Fwd: Shim OS [response to: partially Squeak based OS] In-Reply-To: References: <4f99b490eefcf416f91dc5c9f555a491@whidbey.com> Message-ID: > On 2021-02-21, at 7:18 AM, Liam Proven wrote: > > [snip] > ISTM that the flipside of this is the point from my talk: that if you > choose a single, sufficiently-powerful programming language, that you > can build the entire stack in that one language and avoid the polyglot > complexity of a modern FOSS xNix. I'm pretty sure that with sufficient time, determination, staff, and luck, one could write a full stack of software in any language at all. I mean, I've been involved in a few (partial) attempts over the decades. RISC OS was almost entirely written in ARM assembler, even a lot of the applications. The Interval MediaPad was Smalltalk all the way down to process scheduling and interrupt handling. And so on. I guess that my engineering/designer ethos is simply happier to suggest that saving time by avoiding the tedious bits someone has already done is a good way of getting to do the fun bits. Of course, it does depend on what one considers 'the fun bits'. For me, that is doing stuff in Smalltalk, frequently the doing stuff *to* Smalltalk part. I'm content to consider those lowest level bits as very large primitives and then just use them. There's absolutely no reason I can think of why we shouldn't have a world where lower level bits get gradually replaced by Smalltalk whilst other users keep on 'talking. Indeed I remember a nice example from ... a long time ago... when Eliot realised that the RISC OS filesystem code provided sufficiently low level commands that he could make a DOS format read/write filestream class for an OS that used a decidedly 'interesting' file format natively. Consider this as a suggestion to remember the protocol for eating an Elephant (not that one should actually do that; they get quite annoyed) - don't try to swallow it all at once. We have a rather good language system in Smalltalk. Linux is a not appalling stratum to build over; start by perhaps replacing some of the insane numbers of unix applications filling /usr/bin etc. Gradually infiltrate and push down and out and up. Eventually there's nothing left but the POST and initial loader, the rest just gets garbage collected. > > What I would like to see would be a modern take on the single-language > dynamic environments that were starting to appear on workstations in > the late 1970s to early 1980s: specifically, the > non-filesystem-centric ones, because as I've said elsewhere -- and in > last year's FOSDEM talk ( > https://liam-on-linux.livejournal.com/69099.html ) -- I think that, > _pace_ suitable OSes to support it -- PMEM tech could render the > entire concept of disk drives (HDDs, SDDs, whatever) obsolete. Yes, the idiotic tyranny of the unix 'everything is a file' approach has a long tail and needs winding up and hanging in the back of the 'weird ideas from the primitive past' cupboard. The one thing good about it is that the *consistency* provided a lot of leverage. Rather like the consistency of 'everything is an object; yes, even that' for Smalltalk. > >> The simple answer to approach this quite closely and fairly painlessly is to use an install of some linux system without the X-nightmare and use the frame buffer as the Smalltalk display. Yes, sure, there are other minimal OS' that Ken pointed out too. > > Simple to implement, perhaps, but still a big mess o' C, still > completely filesystem-centric, impossible to further simplify, and > essentially impossible for any single human to completely understand. I am minded of a Wise Saying from the Very Wise Alan Knight - `One of the great leaps in OO is to be able to answer the question “How does this work?” with “I don’t care”.`[1] Sometimes it is more practical to accept there isn't enough time to know it all. I had to give up trying to understand the details of CPU design some years ago and just let it be something I use. Now, I will certainly cheer loudly if someone comes up with a way to simplify things enough to solve all this; I'm just not going to hold my breath since blue is such a bad choice of colour for my face. >> I suggest that we also need to make it practical in this new world to have many Smalltalk images running at the same time so as to insulate said email/browser/twitter/etc from each other in case of serious problems, so we'd want some sort of (Smalltalk implemented, obviously) windowing system. > > This is a big issue. I have only a sketchy high-level theoretical > understanding of Smalltalk. AFAIK the IBM RoarVM supports a > multithreaded multicore Smalltalk engine, but how IBM would feel about > anyone attempting to port that to Oberon or something, I don't know. My thought these days is to skip the attempts to have a single memory space shared between threads/cores/whatever and have many separate systems running and communicating. Yes, it may be 'less performant' to pass bits down whatever variety of damp string required, but so what. Computers are better than 10 million times faster today than they were when we did BrouHaHa on RISC OS and the Active Book. Let's have a 512 core AARCH64 machine running 1500 images. In your pocket (admittedly right now a fairly large and well cooled pocket). I'd also point back to some of Alan's early writings about Smalltalk being a like collection of biological cells with the 'cell walls' isolating each from the other and communication being by (chemical) messages. Separate worlds seem much better implemented in separate memory spaces to me. tim [1] My most famous Wise Saying is probably "An x86 cpu is a waste of perfectly good sand", dating from circa 1985 when I first got ARMed. People laughed back then. Not so much now. -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim No one is listening until you make a mistake From eliot.miranda at gmail.com Sun Feb 21 19:33:28 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sun, 21 Feb 2021 11:33:28 -0800 Subject: [squeak-dev] Fwd: Shim OS [response to: partially Squeak based OS] In-Reply-To: References: Message-ID: <34AE42A2-6987-443B-BFAD-40CA28A4CA1F@gmail.com> > On Feb 21, 2021, at 10:44 AM, tim Rowledge wrote: > >  > >> On 2021-02-21, at 7:18 AM, Liam Proven wrote: >> >> > [snip] >> ISTM that the flipside of this is the point from my talk: that if you >> choose a single, sufficiently-powerful programming language, that you >> can build the entire stack in that one language and avoid the polyglot >> complexity of a modern FOSS xNix. > > I'm pretty sure that with sufficient time, determination, staff, and luck, one could write a full stack of software in any language at all. I mean, I've been involved in a few (partial) attempts over the decades. RISC OS was almost entirely written in ARM assembler, even a lot of the applications. The Interval MediaPad was Smalltalk all the way down to process scheduling and interrupt handling. And so on. > > I guess that my engineering/designer ethos is simply happier to suggest that saving time by avoiding the tedious bits someone has already done is a good way of getting to do the fun bits. Of course, it does depend on what one considers 'the fun bits'. For me, that is doing stuff in Smalltalk, frequently the doing stuff *to* Smalltalk part. > > I'm content to consider those lowest level bits as very large primitives and then just use them. There's absolutely no reason I can think of why we shouldn't have a world where lower level bits get gradually replaced by Smalltalk whilst other users keep on 'talking. Indeed I remember a nice example from ... a long time ago... when Eliot realised that the RISC OS filesystem code provided sufficiently low level commands that he could make a DOS format read/write filestream class for an OS that used a decidedly 'interesting' file format natively. > > Consider this as a suggestion to remember the protocol for eating an Elephant (not that one should actually do that; they get quite annoyed) - don't try to swallow it all at once. We have a rather good language system in Smalltalk. Linux is a not appalling stratum to build over; start by perhaps replacing some of the insane numbers of unix applications filling /usr/bin etc. Gradually infiltrate and push down and out and up. Eventually there's nothing left but the POST and initial loader, the rest just gets garbage collected. +10. Don’t let the perfect be the enemy of the good. Incremental progress benefits from amplifying feedback. An absence of progress can’t. >> What I would like to see would be a modern take on the single-language >> dynamic environments that were starting to appear on workstations in >> the late 1970s to early 1980s: specifically, the >> non-filesystem-centric ones, because as I've said elsewhere -- and in >> last year's FOSDEM talk ( >> https://liam-on-linux.livejournal.com/69099.html ) -- I think that, >> _pace_ suitable OSes to support it -- PMEM tech could render the >> entire concept of disk drives (HDDs, SDDs, whatever) obsolete. > > > Yes, the idiotic tyranny of the unix 'everything is a file' approach has a long tail and needs winding up and hanging in the back of the 'weird ideas from the primitive past' cupboard. The one thing good about it is that the *consistency* provided a lot of leverage. Rather like the consistency of 'everything is an object; yes, even that' for Smalltalk. > > >> >>> The simple answer to approach this quite closely and fairly painlessly is to use an install of some linux system without the X-nightmare and use the frame buffer as the Smalltalk display. Yes, sure, there are other minimal OS' that Ken pointed out too. >> >> Simple to implement, perhaps, but still a big mess o' C, still >> completely filesystem-centric, impossible to further simplify, and >> essentially impossible for any single human to completely understand. > > I am minded of a Wise Saying from the Very Wise Alan Knight - > > `One of the great leaps in OO is to be able to answer the question “How does this work?” with “I don’t care”.`[1] > > Sometimes it is more practical to accept there isn't enough time to know it all. I had to give up trying to understand the details of CPU design some years ago and just let it be something I use. Now, I will certainly cheer loudly if someone comes up with a way to simplify things enough to solve all this; I'm just not going to hold my breath since blue is such a bad choice of colour for my face. > > > >>> I suggest that we also need to make it practical in this new world to have many Smalltalk images running at the same time so as to insulate said email/browser/twitter/etc from each other in case of serious problems, so we'd want some sort of (Smalltalk implemented, obviously) windowing system. >> >> This is a big issue. I have only a sketchy high-level theoretical >> understanding of Smalltalk. AFAIK the IBM RoarVM supports a >> multithreaded multicore Smalltalk engine, but how IBM would feel about >> anyone attempting to port that to Oberon or something, I don't know. > > My thought these days is to skip the attempts to have a single memory space shared between threads/cores/whatever and have many separate systems running and communicating. Yes, it may be 'less performant' to pass bits down whatever variety of damp string required, but so what. Computers are better than 10 million times faster today than they were when we did BrouHaHa on RISC OS and the Active Book. Let's have a 512 core AARCH64 machine running 1500 images. In your pocket (admittedly right now a fairly large and well cooled pocket). > > I'd also point back to some of Alan's early writings about Smalltalk being a like collection of biological cells with the 'cell walls' isolating each from the other and communication being by (chemical) messages. Separate worlds seem much better implemented in separate memory spaces to me. > > > tim > [1] My most famous Wise Saying is probably "An x86 cpu is a waste of perfectly good sand", dating from circa 1985 when I first got ARMed. People laughed back then. Not so much now. > > -- > tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim > No one is listening until you make a mistake > > > From squeaklist at gmail.com Sun Feb 21 20:00:33 2021 From: squeaklist at gmail.com (Kjell Godo) Date: Sun, 21 Feb 2021 12:00:33 -0800 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS In-Reply-To: <62453gd7uhqu4evdmqijd4fovf28iac2ql@4ax.com> References: <20210219174547.420721A00054@proxy.email-ssl.com.br> <62453gd7uhqu4evdmqijd4fovf28iac2ql@4ax.com> Message-ID: [_]— is there a Squeak option to have Squeak do an Oberon like infinite size desktop plus Oberon like zooming ? i don’t think so but if not wouldn’t that be easy to configure ? To make Squeak Roassal like ? with the Connectors etc plus scroll up = zoom out plus scroll down = zoom in and also mouse gestures some quick gesture plus a drag up zooms out drag down=in i will add Oberon Button words to my thing as anything that is underlined is a Button so no Smalltalk selecting first anymore and if the cursor is Arrow keyed into the underline the underline gets selected and if you then hit it tries to run it . If you hit twice within a time limit then the selection gets replaced by a CrLf . if you do this in helpMode: it tells what is happening with links . And then i hook up to Roassal to get the infinite zoomable desktop thing going but the keyboard control of the zooming has to be quicker maybe it is now i d k . An Oberon like Squeak desktop option would be good in my opinion and the Oberon Button word is easy too it’s just removing the selecting part as desired by underlining in my case . A popup to lay an icon over the word could be good . In a more generalized thing you select some Smalltalk popup [ Make A Link ] and replace it with a hyperlink or a graphic Button but i like the simple Oberon way too. i believe this has already been done before for web links in Squeak or VisualWorks Thank you for reminding me of these Oberon ideas Liam i will implement them at once into a #todo who knows when it will get done just in time I saw a JavaScript thing that had Lisp under Smalltalk but i forget everything . Amber ? It was looking pretty good a long time ago but i only saw it work once i can’t remember the name if it’s not Amber i wish i could it was looking pretty good What i want is a Lisp dialect that is highly isomorphic to Smalltalk . I have one . ( at:ifAbsentPut: aDictionary key [...] )<——[ a SmACC pre processing could do this trick ] or ( at:ifAbsentPut: aDictionary at:key ifAbsentPut:[...] )<—-[ the extra keywords are comments ] ( at:ifAbsentPut: aDictionary atKey: key getValue-ifAbsentPutNewValue:[...] )<—-[ is the same message send but with more verbose comments ] [ x ]— i made a demo in 2011 in Vegas including a very simple idea for a Debugger feature that steps into a Macro call like one steps into a Message send i suppose it could optionally step the String expansion process too and then step the result it is very easy to do this you just have to say ok i do it maybe it’s already done Package name? [_]— You can do Macros in Smalltalk easily just mark a Method that returns a String as a Macro which can be done in Dolphin by defining a dynamic Category of which there are two pre existing examples Public and Private so just add Macro to those two now why didn’t i think of that I want this A2 you speak of i think i tried to download Oberon a while ago but the page was a ghost town run around i felt like maybe i did get it but i never saw it run so if there is something more slick and shining i want it There is a LispOS called mezzanine or something on GitHub OS lite maybe So what you are saying really is that you want a port of Squeak to A2 is this not right ? of course it is a modified A2 that is not disk centric On Sun, Feb 21, 2021 at 09:03 Louis LaBrunda wrote: > Hi Liam, > > snip... > >*Ouch*. > > > >Still, it's early days. I also think it might be more relevant to compare > to RAM prices than flash SSD prices. > > I agree. If the object database can fit in the 512GB (and the OS and > Smalltalk VM are changed to do what is needed) > $9,000 isn't that bad. Being able to use Smalltalk collections in an > object that would ordinarily be an SQL table row > and require complex SQL tables and code, makes the cost of the memory look > cheep. > > Lou > -- > Louis LaBrunda > Keystone Software Corp. > SkypeMe callto://PhotonDemon > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From squeaklist at gmail.com Sun Feb 21 20:21:35 2021 From: squeaklist at gmail.com (Kjell Godo) Date: Sun, 21 Feb 2021 12:21:35 -0800 Subject: [squeak-dev] Discussing a new design of partially Squeak-based OS In-Reply-To: References: <20210219174547.420721A00054@proxy.email-ssl.com.br> <62453gd7uhqu4evdmqijd4fovf28iac2ql@4ax.com> Message-ID: [_]— and then if you use custom colors on the code you can hide the initial at:ifAbsentPut: by coloring it cyan 255 and setting the Font to Arial 8 if you want it to be more Smalltalk looking Smalltalk is the most self documenting language i think On Sun, Feb 21, 2021 at 12:00 Kjell Godo wrote: > [_]— is there a Squeak option to have Squeak do an Oberon like infinite > size > desktop plus Oberon like zooming ? i don’t think so but if not wouldn’t > that be > easy to configure ? To make Squeak Roassal like ? with the Connectors etc > plus scroll up = zoom out plus scroll down = zoom in and > also > mouse gestures some quick gesture plus a drag up zooms out drag down=in > > i will add Oberon Button words to my thing as anything that is underlined > is a > Button so no Smalltalk selecting first anymore and if the cursor is Arrow > keyed > into the underline the underline gets selected and if you then hit > it tries > to run it . If you hit twice within a time limit then the > selection gets > replaced by a CrLf . if you do this in helpMode: it tells what is > happening with links > . And then i hook up to Roassal to get the infinite zoomable desktop > thing going > but the keyboard control of the zooming has to be quicker maybe it is now > i d k . > An Oberon like Squeak desktop option would be good in my opinion and the > Oberon Button word is easy too it’s just removing the selecting part as > desired by > underlining in my case . A popup to lay an icon over the word could be > good . In a > more generalized thing you select some Smalltalk popup [ Make A Link ] and > replace it with a hyperlink or a graphic Button but i like the simple > Oberon way too. > i believe this has already been done before for web links in Squeak or > VisualWorks > > Thank you for reminding me of these Oberon ideas Liam > i will implement them at once into a #todo > who knows when it will get done > just in time > > I saw a JavaScript thing that had Lisp under Smalltalk but i forget > everything . Amber ? It was looking pretty good a long time ago but i only > saw it work once > i can’t remember the name if it’s not Amber i wish i could > it was looking pretty good > > What i want is a Lisp dialect that is highly isomorphic to Smalltalk . I > have one . > > ( at:ifAbsentPut: aDictionary key [...] > )<——[ a SmACC pre processing could do this trick ] > or > ( at:ifAbsentPut: aDictionary at:key ifAbsentPut:[...] > )<—-[ the extra keywords are comments ] > > ( at:ifAbsentPut: aDictionary atKey: key getValue-ifAbsentPutNewValue:[...] > )<—-[ is the same message send but with more verbose comments ] > > [ x ]— i made a demo in 2011 in Vegas including a very simple idea for a > Debugger > feature that steps into a Macro call like one steps into a Message > send > i suppose it could optionally step the String expansion process too and > then step > the result > it is very easy to do this you just have to say > ok i do it > maybe it’s already done > Package name? > > [_]— You can do Macros in Smalltalk easily just mark a Method that returns > a String as a Macro which can be done in Dolphin by defining a dynamic > Category of which there are two pre existing examples Public and Private > so just add Macro to those two > now why didn’t i think of that > > I want this A2 you speak of > i think i tried to download Oberon a while ago but the page was a ghost > town > run around i felt like maybe i did get it but i never > saw it run > so if there is something more slick and shining > i want it > > There is a LispOS called mezzanine or something on GitHub > OS lite maybe > > So what you are saying really is that you want a port of Squeak to A2 > is this not right ? > of course it is > > a modified A2 that is not disk centric > > > On Sun, Feb 21, 2021 at 09:03 Louis LaBrunda > wrote: > >> Hi Liam, >> >> snip... >> >*Ouch*. >> > >> >Still, it's early days. I also think it might be more relevant to >> compare to RAM prices than flash SSD prices. >> >> I agree. If the object database can fit in the 512GB (and the OS and >> Smalltalk VM are changed to do what is needed) >> $9,000 isn't that bad. Being able to use Smalltalk collections in an >> object that would ordinarily be an SQL table row >> and require complex SQL tables and code, makes the cost of the memory >> look cheep. >> >> Lou >> -- >> Louis LaBrunda >> Keystone Software Corp. >> SkypeMe callto://PhotonDemon >> >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From ken.dickey at whidbey.com Sun Feb 21 20:52:27 2021 From: ken.dickey at whidbey.com (ken.dickey at whidbey.com) Date: Sun, 21 Feb 2021 12:52:27 -0800 Subject: [squeak-dev] Fwd: MultiCore [response to: partially Squeak based OS] In-Reply-To: References: Message-ID: <0163ce35b892ab426274c39780946538@whidbey.com> On Sun, 21 Feb 2021 at 03:51, wrote: >> I responded directly to Liam, but noted a lof of interest on this >> list.. > Did you? May I ask -- to which address? lproven at cix.co.uk Following is copy of missive to VM-Dev. vv-------- Original Message --------vv Other useful idea mines: L4 microkernel and Genode UI: https://microkerneldude.wordpress.com/2019/03/07/how-to-and-how-not-to-use-sel4-ipc/ https://genode.org/about/index -- multiple concurrent window systems https://sel4.systems/ -- very fast message based IPC (think multiple VM spaces) Just thinking of making multicore more useful & robust.. I think Aarch64 and particularly RISC-V are more useful starting points, BTW. (BeagleV is coming soon.. https://beagleboard.org/beaglev :) $0.02, -KenD ^^----------------------------------^^ Still research, but Bee Smalltalk looks like an interesting approach for small binaries done in direct style with no C (e.g. for multicore server/interrupt code communicating via fast microkernel messages). https://github.com/KenDickey/BeeYourself README.md has references to salient papers & code. [Just started this; no need to look at the BeeYourself repo itself]. FYI, -KenD From tim at rowledge.org Mon Feb 22 01:12:48 2021 From: tim at rowledge.org (tim Rowledge) Date: Sun, 21 Feb 2021 17:12:48 -0800 Subject: [squeak-dev] Shim OS [response to: partially Squeak based OS] In-Reply-To: <34AE42A2-6987-443B-BFAD-40CA28A4CA1F@gmail.com> References: <34AE42A2-6987-443B-BFAD-40CA28A4CA1F@gmail.com> Message-ID: <265ACB37-EAD0-4781-8D7E-2B54D47D764A@rowledge.org> PS to Liam - please don't take any of these comments as implying you shouldn't try; consider them reminiscences from some old farts that have tried in the past and have some suggestions about thing *not* to waste time on. Learn from our mistakes because none of us have time to repeat everyone else's. tim -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim Strange OpCodes: BIK: Buggered if I Know From kksubbu.ml at gmail.com Mon Feb 22 05:56:45 2021 From: kksubbu.ml at gmail.com (K K Subbu) Date: Mon, 22 Feb 2021 11:26:45 +0530 Subject: [squeak-dev] NuScratch for Squeak 5.3 - and now in exciting 64 bit flavour! In-Reply-To: <39739408-A13F-4FCE-AE46-C9B3B4702908@rowledge.org> References: <20210220232912.GA60864@shell.msen.com> <39739408-A13F-4FCE-AE46-C9B3B4702908@rowledge.org> Message-ID: On 21/02/21 5:54 am, tim Rowledge wrote: > On the Pi it looks like > sudo apt-get install libcairo2-dev libpango1.0-dev mesa-common-dev > should do it, though Subbu also suggested libgl1-mesa-dev libgl1-mesa-glx instead of mesa-common-dev. mesa-common-dev and libgl1-mesa-glx (runtime) are internal dependencies of libgl1-mesa-dev: ~$ apt-cache depends libgl1-mesa-dev | grep mesa- libgl1-mesa-dev Depends: mesa-common-dev Depends: libgl1-mesa-glx It may be better to stick to top level libraries: $ sudo apt-get install libcairo2-dev libpango1.0-dev libgl1-mesa-dev HTH .. Subbu From marcel.taeumel at hpi.de Mon Feb 22 07:48:36 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Mon, 22 Feb 2021 08:48:36 +0100 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: Hi Levente. > My stance on library methods is that they need to be optimized because you don't know how people will use them. If they are fast, people will be happy. If they are not, you'll leave a bad impression. +1 =) Best, Marcel Am 20.02.2021 21:51:24 schrieb Levente Uzonyi : On Sat, 20 Feb 2021, Tom Beckmann wrote: > Hi Levente, hi Nicolas, > > To Levente's comment: > > You left an #asSet send in the above benchmark. > > Oups, indeed. But I think the actual measurement was done without the asSet, I just added it later for experimentation. The numbers appear consistent when I rerun the lines without #asSet. > After sending the mail, I also realized that the setOrigin:corner:/merging4: version is of course not legal, since we mutate the original rectangle that was passed in. > > To Nicolas' comment: > > But that's precisely what we try to avoid here: create lots of > > intermediate short-lived objects (Rectangle and Point). > > This is because it may be a performance critical routine. > > The most optimized version with the inlined temporaries is a great implementation but looks like quite a beast to me, which in my opinion would be sad for something that appears in our standard library. After looking for > senders of Rectangle class>>merging: in my trunk image I only saw one critical path in recordInvalidRect:, which appears to on average trigger merging: only once per damaged frame. Is there another use case we know of? My stance on library methods is that they need to be optimized because you don't know how people will use them. If they are fast, people will be happy. If they are not, you'll leave a bad impression. This discussion exists, because Karl changed the method last year and noticed that the performance got worse[1]. And, while he was convinced about arguments always being sequenceable, it turned out that they may be sets as well. Levente [1] http://forum.world.st/The-Inbox-Graphics-kfr-434-mcz-tp5119541p5119584.html > > Best regards, > Tom > > On Fri, Feb 19, 2021 at 6:53 PM Levente Uzonyi wrote: > Hi Tom, > > On Fri, 19 Feb 2021, Tom Beckmann wrote: > > > Hi everyone, > > > > just another idea for your consideration: > > > > merging3: listOfRects > >     ^ listOfRects reduce: [:a :b | > >          self origin: (a origin min: b origin) corner: (a corner max: b corner)] > > > > If you care more about performance than idioms (not even sure if this is legal): > > merging4: listOfRects > >     ^ listOfRects reduce: [:a :b | > >          a setOrigin: (a origin min: b origin) corner: (a corner max: b corner)] > > > > And finally, the, in my opinion, most elegant version. Sadly, it's also the slowest. > > merging5: listOfRects > >      ^ listOfRects reduce: [:a :b | a quickMerge: b] > > > > > > > > Some unrepresentative benchmarks: > > > > " Levente's version from above with temps " > > [Rectangle merging2: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '3,740,000 per second. 267 nanoseconds per run. 37.46501 % GC time.' > > " the 'clean' version " > > [Rectangle merging3: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '3,020,000 per second. 331 nanoseconds per run. 40.93181 % GC time.' > > " the version that mutates rectangles " > > [Rectangle merging4: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100} asSet] bench '3,330,000 per second. 300 nanoseconds per run. 40.53189 % GC time.' > > You left an #asSet send in the above benchmark. > > > Levente > > > " using quickMerge " > > [Rectangle merging5: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '2,930,000 per second. 341 nanoseconds per run. 42.32 % GC time.' > > > > Best, > > Tom > > > > On Thu, Feb 18, 2021 at 11:17 PM Levente Uzonyi wrote: > >       Hi Chris, > > > >       On Wed, 17 Feb 2021, Chris Muller wrote: > > > >       > This is what I would do: > >       > > >       > merging: listOfRects > >       >     "A number of callers of merge: should use this method." > >       >     ^ listOfRects > >       >         inject: > >       >             (self > >       >                 origin: Float infinity @ Float infinity > >       >                 corner: Float infinity negated @ Float infinity negated) > >       >         into: [ : rect : each | rect quickMerge: each ] > >       > > >       > With #quickMerge:, you're only creating a new Rectangle when it needed to grow to accomodate the current element, but many of the elements might fit completely, resulting in no additional instantiation.  > Do an > >       analysis of how > >       > many temporary Point objects we create -- hint: it's a ton -- and my own attempts to optimize that in my Kml framework were not fruitful (e.g., ~1%), with a trade-off of duplicating implementation across > >       multiple methods and > >       > making the system's code harder to read and understand and maintain. > > > >       With my benchmark, your version is slower than the one from 2003, > >       especially when the collection is small. And it doesn't handle the case of > >       empty listOfRects the same way: it silently returns a rectangle instead of > >       raising an error. > > > >       Here's the version I came up with the other day: > > > > > >       merging: listOfRects > >               "A number of callers of merge: should use this method." > > > >               | minTopLeftX minTopLeftY maxBottomRightX maxBottomRightY | > >               listOfRects do: [ :rectangle | > >                       | topLeft bottomRight | > >                       topLeft := rectangle topLeft. > >                       bottomRight := rectangle bottomRight. > >                       minTopLeftX > >                               ifNil: [ > >                                       minTopLeftX := topLeft x. > >                                       minTopLeftY := topLeft y. > >                                       maxBottomRightX := bottomRight x. > >                                       maxBottomRightY := bottomRight y ] > >                               ifNotNil: [ > >                                       topLeft x < minTopLeftX ifTrue: [ minTopLeftX := topLeft x ]. > >                                       topLeft y < minTopLeftY ifTrue: [ minTopLeftY := topLeft y ]. > >                                       bottomRight x > maxBottomRightX ifTrue: [ maxBottomRightX := bottomRight x ]. > >                                       bottomRight y > maxBottomRightY ifTrue: [ maxBottomRightY := bottomRight y ] ] ]. > >               ^self origin: minTopLeftX @ minTopLeftY corner: maxBottomRightX @ maxBottomRightY > > > > > >       Levente > > > >       > > >       >  - Chris > >       > > >       > > >       > On Wed, Feb 17, 2021 at 11:27 AM Levente Uzonyi wrote: > >       >       On Wed, 17 Feb 2021, Marcel Taeumel wrote: > >       > > >       >       > Hmm... looking at performance ... why not just add #asSequenceableCollection, which would only impact Set arguments? > >       > > >       >       I don't think we have such method. Adding one would raise the usual > >       >       question: should it create a new collection or return self if self > >       >       already to the requested collection kind? > >       >       IIRC currently the only outlier is #asOrderedCollection which always > >       >       creates a copy when the receiver is an OrderedCollection, and that > >       >       property is being relied on, so it can't be changed... > >       > > >       >       > As a programmer, I do not want to choose between #merge: and #quickMerge:. Or similar. :-) > >       > > >       >       IMO, we simply need one quick solution. If you have a Set, you may need > >       >       that help from the library even more. > >       >       #quickMerge: is only good for merging two rectangles. It does not solve > >       >       the GC issue #merge: has. > >       > > >       > > >       >       Levente > >       > > >       >       > > >       >       > Best, > >       >       > Marcel > >       >       > > >       >       >       Am 13.02.2021 17:05:07 schrieb commits at source.squeak.org : > >       >       > > >       >       >       Nicolas Cellier uploaded a new version of Graphics to project The Inbox: > >       >       >       http://source.squeak.org/inbox/Graphics-nice.446.mcz > >       >       > > >       >       >       ==================== Summary ==================== > >       >       > > >       >       >       Name: Graphics-nice.446 > >       >       >       Author: nice > >       >       >       Time: 13 February 2021, 5:04:52.453325 pm > >       >       >       UUID: d13c1db2-370f-4fa6-b7ae-e6766bf0c8fb > >       >       >       Ancestors: Graphics-dtl.445 > >       >       > > >       >       >       Let Rectangle merging:/encompassing: an unordered collection. > >       >       > > >       >       >       =============== Diff against Graphics-dtl.445 =============== > >       >       > > >       >       >       Item was changed: > >       >       >       ----- Method: Rectangle class>>encompassing: (in category 'instance creation') ----- > >       >       >       encompassing: listOfPoints > >       >       >       "A number of callers of encompass: should use this method." > >       >       >       | topLeft bottomRight | > >       >       >       + topLeft := bottomRight := listOfPoints anyOne. > >       >       >       + listOfPoints do: > >       >       >       - topLeft := bottomRight := listOfPoints first. > >       >       >       - listOfPoints allButFirstDo: > >       >       >       [:p |topLeft := topLeft min: p. > >       >       >       + bottomRight := bottomRight max: p]. > >       >       >       - bottomRight := bottomRight max: p]. > >       >       >       ^self origin: topLeft corner: bottomRight > >       >       >       ! > >       >       > > >       >       >       Item was changed: > >       >       >       ----- Method: Rectangle class>>merging: (in category 'instance creation') ----- > >       >       >       merging: listOfRects > >       >       >       "A number of callers of merge: should use this method." > >       >       >       + | aRectangle bottomRight topLeft | > >       >       >       + aRectangle := listOfRects anyOne. > >       >       >       + topLeft := aRectangle topLeft. > >       >       >       + bottomRight := aRectangle bottomRight. > >       >       >       - | bottomRight topLeft | > >       >       >       - topLeft := listOfRects first topLeft. > >       >       >       - bottomRight := listOfRects first bottomRight. > >       >       >       listOfRects > >       >       >       + do: [:r | topLeft := topLeft min: r topLeft. > >       >       >       - allButFirstDo: [:r | topLeft := topLeft min: r topLeft. > >       >       >       bottomRight := bottomRight max: r bottomRight]. > >       >       >       ^self origin: topLeft corner: bottomRight. > >       >       >       ! > >       >       > > >       >       > > >       >       > > >       >       > > >       > > >       > > >       > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From marcel.taeumel at hpi.de Mon Feb 22 08:05:05 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Mon, 22 Feb 2021 09:05:05 +0100 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: And alternative implementations (e.g. being more readable but costly) could be documented in the method's comment, possible as pseudo code. Something like the fallback code for primitives, just as comment. Well, that alternative could be an actual method with a "self shouldNotBeUsed" warning in the beginning ... except for maybe in tests that check whether the two implementations yield the same effects. Best, Marcel Am 22.02.2021 08:48:36 schrieb Marcel Taeumel : Hi Levente. > My stance on library methods is that they need to be optimized because you don't know how people will use them. If they are fast, people will be happy. If they are not, you'll leave a bad impression. +1 =) Best, Marcel Am 20.02.2021 21:51:24 schrieb Levente Uzonyi : On Sat, 20 Feb 2021, Tom Beckmann wrote: > Hi Levente, hi Nicolas, > > To Levente's comment: > > You left an #asSet send in the above benchmark. > > Oups, indeed. But I think the actual measurement was done without the asSet, I just added it later for experimentation. The numbers appear consistent when I rerun the lines without #asSet. > After sending the mail, I also realized that the setOrigin:corner:/merging4: version is of course not legal, since we mutate the original rectangle that was passed in. > > To Nicolas' comment: > > But that's precisely what we try to avoid here: create lots of > > intermediate short-lived objects (Rectangle and Point). > > This is because it may be a performance critical routine. > > The most optimized version with the inlined temporaries is a great implementation but looks like quite a beast to me, which in my opinion would be sad for something that appears in our standard library. After looking for > senders of Rectangle class>>merging: in my trunk image I only saw one critical path in recordInvalidRect:, which appears to on average trigger merging: only once per damaged frame. Is there another use case we know of? My stance on library methods is that they need to be optimized because you don't know how people will use them. If they are fast, people will be happy. If they are not, you'll leave a bad impression. This discussion exists, because Karl changed the method last year and noticed that the performance got worse[1]. And, while he was convinced about arguments always being sequenceable, it turned out that they may be sets as well. Levente [1] http://forum.world.st/The-Inbox-Graphics-kfr-434-mcz-tp5119541p5119584.html > > Best regards, > Tom > > On Fri, Feb 19, 2021 at 6:53 PM Levente Uzonyi wrote: > Hi Tom, > > On Fri, 19 Feb 2021, Tom Beckmann wrote: > > > Hi everyone, > > > > just another idea for your consideration: > > > > merging3: listOfRects > >     ^ listOfRects reduce: [:a :b | > >          self origin: (a origin min: b origin) corner: (a corner max: b corner)] > > > > If you care more about performance than idioms (not even sure if this is legal): > > merging4: listOfRects > >     ^ listOfRects reduce: [:a :b | > >          a setOrigin: (a origin min: b origin) corner: (a corner max: b corner)] > > > > And finally, the, in my opinion, most elegant version. Sadly, it's also the slowest. > > merging5: listOfRects > >      ^ listOfRects reduce: [:a :b | a quickMerge: b] > > > > > > > > Some unrepresentative benchmarks: > > > > " Levente's version from above with temps " > > [Rectangle merging2: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '3,740,000 per second. 267 nanoseconds per run. 37.46501 % GC time.' > > " the 'clean' version " > > [Rectangle merging3: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '3,020,000 per second. 331 nanoseconds per run. 40.93181 % GC time.' > > " the version that mutates rectangles " > > [Rectangle merging4: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100} asSet] bench '3,330,000 per second. 300 nanoseconds per run. 40.53189 % GC time.' > > You left an #asSet send in the above benchmark. > > > Levente > > > " using quickMerge " > > [Rectangle merging5: {0 @ 0 extent: 100 @ 100. -20 @ -20 extent: 80 @ 80. 30 @ 30 extent: 100 @ 100}] bench '2,930,000 per second. 341 nanoseconds per run. 42.32 % GC time.' > > > > Best, > > Tom > > > > On Thu, Feb 18, 2021 at 11:17 PM Levente Uzonyi wrote: > >       Hi Chris, > > > >       On Wed, 17 Feb 2021, Chris Muller wrote: > > > >       > This is what I would do: > >       > > >       > merging: listOfRects > >       >     "A number of callers of merge: should use this method." > >       >     ^ listOfRects > >       >         inject: > >       >             (self > >       >                 origin: Float infinity @ Float infinity > >       >                 corner: Float infinity negated @ Float infinity negated) > >       >         into: [ : rect : each | rect quickMerge: each ] > >       > > >       > With #quickMerge:, you're only creating a new Rectangle when it needed to grow to accomodate the current element, but many of the elements might fit completely, resulting in no additional instantiation.  > Do an > >       analysis of how > >       > many temporary Point objects we create -- hint: it's a ton -- and my own attempts to optimize that in my Kml framework were not fruitful (e.g., ~1%), with a trade-off of duplicating implementation across > >       multiple methods and > >       > making the system's code harder to read and understand and maintain. > > > >       With my benchmark, your version is slower than the one from 2003, > >       especially when the collection is small. And it doesn't handle the case of > >       empty listOfRects the same way: it silently returns a rectangle instead of > >       raising an error. > > > >       Here's the version I came up with the other day: > > > > > >       merging: listOfRects > >               "A number of callers of merge: should use this method." > > > >               | minTopLeftX minTopLeftY maxBottomRightX maxBottomRightY | > >               listOfRects do: [ :rectangle | > >                       | topLeft bottomRight | > >                       topLeft := rectangle topLeft. > >                       bottomRight := rectangle bottomRight. > >                       minTopLeftX > >                               ifNil: [ > >                                       minTopLeftX := topLeft x. > >                                       minTopLeftY := topLeft y. > >                                       maxBottomRightX := bottomRight x. > >                                       maxBottomRightY := bottomRight y ] > >                               ifNotNil: [ > >                                       topLeft x < minTopLeftX ifTrue: [ minTopLeftX := topLeft x ]. > >                                       topLeft y < minTopLeftY ifTrue: [ minTopLeftY := topLeft y ]. > >                                       bottomRight x > maxBottomRightX ifTrue: [ maxBottomRightX := bottomRight x ]. > >                                       bottomRight y > maxBottomRightY ifTrue: [ maxBottomRightY := bottomRight y ] ] ]. > >               ^self origin: minTopLeftX @ minTopLeftY corner: maxBottomRightX @ maxBottomRightY > > > > > >       Levente > > > >       > > >       >  - Chris > >       > > >       > > >       > On Wed, Feb 17, 2021 at 11:27 AM Levente Uzonyi wrote: > >       >       On Wed, 17 Feb 2021, Marcel Taeumel wrote: > >       > > >       >       > Hmm... looking at performance ... why not just add #asSequenceableCollection, which would only impact Set arguments? > >       > > >       >       I don't think we have such method. Adding one would raise the usual > >       >       question: should it create a new collection or return self if self > >       >       already to the requested collection kind? > >       >       IIRC currently the only outlier is #asOrderedCollection which always > >       >       creates a copy when the receiver is an OrderedCollection, and that > >       >       property is being relied on, so it can't be changed... > >       > > >       >       > As a programmer, I do not want to choose between #merge: and #quickMerge:. Or similar. :-) > >       > > >       >       IMO, we simply need one quick solution. If you have a Set, you may need > >       >       that help from the library even more. > >       >       #quickMerge: is only good for merging two rectangles. It does not solve > >       >       the GC issue #merge: has. > >       > > >       > > >       >       Levente > >       > > >       >       > > >       >       > Best, > >       >       > Marcel > >       >       > > >       >       >       Am 13.02.2021 17:05:07 schrieb commits at source.squeak.org : > >       >       > > >       >       >       Nicolas Cellier uploaded a new version of Graphics to project The Inbox: > >       >       >       http://source.squeak.org/inbox/Graphics-nice.446.mcz > >       >       > > >       >       >       ==================== Summary ==================== > >       >       > > >       >       >       Name: Graphics-nice.446 > >       >       >       Author: nice > >       >       >       Time: 13 February 2021, 5:04:52.453325 pm > >       >       >       UUID: d13c1db2-370f-4fa6-b7ae-e6766bf0c8fb > >       >       >       Ancestors: Graphics-dtl.445 > >       >       > > >       >       >       Let Rectangle merging:/encompassing: an unordered collection. > >       >       > > >       >       >       =============== Diff against Graphics-dtl.445 =============== > >       >       > > >       >       >       Item was changed: > >       >       >       ----- Method: Rectangle class>>encompassing: (in category 'instance creation') ----- > >       >       >       encompassing: listOfPoints > >       >       >       "A number of callers of encompass: should use this method." > >       >       >       | topLeft bottomRight | > >       >       >       + topLeft := bottomRight := listOfPoints anyOne. > >       >       >       + listOfPoints do: > >       >       >       - topLeft := bottomRight := listOfPoints first. > >       >       >       - listOfPoints allButFirstDo: > >       >       >       [:p |topLeft := topLeft min: p. > >       >       >       + bottomRight := bottomRight max: p]. > >       >       >       - bottomRight := bottomRight max: p]. > >       >       >       ^self origin: topLeft corner: bottomRight > >       >       >       ! > >       >       > > >       >       >       Item was changed: > >       >       >       ----- Method: Rectangle class>>merging: (in category 'instance creation') ----- > >       >       >       merging: listOfRects > >       >       >       "A number of callers of merge: should use this method." > >       >       >       + | aRectangle bottomRight topLeft | > >       >       >       + aRectangle := listOfRects anyOne. > >       >       >       + topLeft := aRectangle topLeft. > >       >       >       + bottomRight := aRectangle bottomRight. > >       >       >       - | bottomRight topLeft | > >       >       >       - topLeft := listOfRects first topLeft. > >       >       >       - bottomRight := listOfRects first bottomRight. > >       >       >       listOfRects > >       >       >       + do: [:r | topLeft := topLeft min: r topLeft. > >       >       >       - allButFirstDo: [:r | topLeft := topLeft min: r topLeft. > >       >       >       bottomRight := bottomRight max: r bottomRight]. > >       >       >       ^self origin: topLeft corner: bottomRight. > >       >       >       ! > >       >       > > >       >       > > >       >       > > >       >       > > >       > > >       > > >       > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From marcel.taeumel at hpi.de Mon Feb 22 08:40:31 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Mon, 22 Feb 2021 09:40:31 +0100 Subject: [squeak-dev] Inspector / Explorer display (printOn:) closures slightly differently In-Reply-To: <1613913612417-0.post@n4.nabble.com> References: <1613856594072-0.post@n4.nabble.com> <1613913612417-0.post@n4.nabble.com> Message-ID: Hi Jaromir, hi all. Hmmm.... I think the way context's are printed is fine. Their primary use is the debugger stack. Adding the prefix "context" would be too noisy: Yet, I suggest that we somehow improve the representation of BlockClosure in the Inspector and ObjectExplorer. Note that there is no need to change #printOn:. In a custom ClosureInspector, a custom "source code" field could be added, similar to CompiledCodeInspector. Maybe also list all the closured bindings, similar to ContextInspector. To improve Object Explorer, there could be a new entry to show the source code as well via a custom #explorerContents. (Which reminds me that we should really improve the composability of inspectors, which is currently not possible due to the way how "self" is provided to inspector fields. I tried that once in MorphInspector to use DictionaryInspector for the custom properties in MorphExtension ... but failed to do so, looking at #streamPropertiesOn:) I do tend to mix up Closure and Context from time to time, given that their printOn: is very similar. :-D Changing the printOn: from "[closure] in ..." to "closure [] in ..." wouldn't help me. Best, Marcel   Am 21.02.2021 14:20:22 schrieb Jaromir Matas : I suspect "[closure] in Class>>method" really means: closure: [] in Class>>method while "[] in Class>>method" actually points to a context: context: [] in Class>>method I understand a "closure" is, in fact, a block in a context. For a beginner "[closure]" is really cryptic and confusing... In addition, seeing "sender = FullBlockClosure(BlockClosure)>>valueWithExit:" really twisted my brain :) The sender is, indeed, a context. May I suggest something more consistent to provide a clear clue e.g.: sender... context [] in Class>>method receiver... closure [] in Class>>method analogous, though redundant: outerContext... context [] in Class>>method closureOrNil ... closure [] in Class>>method Thanks a lot. Regards, ----- ^[^ Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: image.png Type: image/png Size: 102876 bytes Desc: not available URL: From m at jaromir.net Mon Feb 22 10:00:09 2021 From: m at jaromir.net (Jaromir Matas) Date: Mon, 22 Feb 2021 04:00:09 -0600 (CST) Subject: [squeak-dev] Inspector / Explorer display (printOn:) closures slightly differently In-Reply-To: References: <1613856594072-0.post@n4.nabble.com> <1613913612417-0.post@n4.nabble.com> Message-ID: <1613988009050-0.post@n4.nabble.com> Marcel, thanks, I haven't realized the debugger noise consequence - and I agree. I'll try your suggestions. I'm enclosing a comparison of what I'd find more helpful and how the current explorer presents stuff: Thanks again, ----- ^[^ Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From kirtai+st at gmail.com Mon Feb 22 10:07:46 2021 From: kirtai+st at gmail.com (Douglas Brebner) Date: Mon, 22 Feb 2021 10:07:46 +0000 Subject: [squeak-dev] Fwd: Shim OS [response to: partially Squeak based OS] In-Reply-To: References: <4f99b490eefcf416f91dc5c9f555a491@whidbey.com> Message-ID: <950502ef-aca3-ad16-56f8-c4aa8f779f58@gmail.com> On 21/02/2021 18:44, tim Rowledge wrote: > My thought these days is to skip the attempts to have a single memory > space shared between threads/cores/whatever and have many separate > systems running and communicating. Yes, it may be 'less performant' to > pass bits down whatever variety of damp string required, but so what. > Computers are better than 10 million times faster today than they were > when we did BrouHaHa on RISC OS and the Active Book. Let's have a 512 > core AARCH64 machine running 1500 images. In your pocket (admittedly > right now a fairly large and well cooled pocket). I would so love to have a machine like that. Maybe some kind of LittleSmalltalk or SmallWorld derivative could be used for tiny non-GUI specialised images. From kirtai+st at gmail.com Mon Feb 22 10:11:02 2021 From: kirtai+st at gmail.com (Douglas Brebner) Date: Mon, 22 Feb 2021 10:11:02 +0000 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: On 20/02/2021 20:51, Levente Uzonyi wrote: > My stance on library methods is that they need to be optimized because > you don't know how people will use them. If they are fast, people will > be happy. If they are not, you'll leave a bad impression. Cuis has a PerformanceImprovements package that holds the fast but difficult to understand versions of methods that use simpler but slower versions in the base image. Maybe that idea could be adopted? From marcel.taeumel at hpi.de Mon Feb 22 10:32:39 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Mon, 22 Feb 2021 11:32:39 +0100 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: > Cuis has a PerformanceImprovements package that holds the fast but difficult to understand versions of methods that use simpler but slower versions in the base image. Maybe that idea could be adopted? A central package for performance improvements would violate the idea of information hiding and hence impede modularity unless there would be such a package for each specific domain (e.g., CollectionImprovements, KernelImprovements etc.) ... but even then ... if any, extra versions of particular methods should be as close to the original artifact as possible. When programmers would stumble upon a hard-to-understand method in the code browser or debugger, the respective tool should point to the more readable version. And the other way around. I think. :-) Best, Marcel Am 22.02.2021 11:11:12 schrieb Douglas Brebner : On 20/02/2021 20:51, Levente Uzonyi wrote: > My stance on library methods is that they need to be optimized because > you don't know how people will use them. If they are fast, people will > be happy. If they are not, you'll leave a bad impression. Cuis has a PerformanceImprovements package that holds the fast but difficult to understand versions of methods that use simpler but slower versions in the base image. Maybe that idea could be adopted? -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits at source.squeak.org Mon Feb 22 10:38:59 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Mon, 22 Feb 2021 10:38:59 0000 Subject: [squeak-dev] The Trunk: Tests-mt.444.mcz Message-ID: Marcel Taeumel uploaded a new version of Tests to project The Trunk: http://source.squeak.org/trunk/Tests-mt.444.mcz ==================== Summary ==================== Name: Tests-mt.444 Author: mt Time: 22 February 2021, 11:38:58.080114 am UUID: c8e1e792-d848-8e40-9ced-6b04d6536dfd Ancestors: Tests-dtl.443 The only test #testIsFontAvailable already takes care of restoring the font. Also, this version of #tearDown would not always work with UI themes anymore. =============== Diff against Tests-dtl.443 =============== Item was removed: - ----- Method: LangEnvBugs>>tearDown (in category 'running') ----- - tearDown - - [Preferences restoreDefaultFonts] valueSupplyingAnswers: #(('Sorry, could not revert font choices' #default))! From Das.Linux at gmx.de Mon Feb 22 11:08:32 2021 From: Das.Linux at gmx.de (Tobias Pape) Date: Mon, 22 Feb 2021 12:08:32 +0100 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: <66167704-D7DD-4730-9905-2CC9CA2AEC9A@gmx.de> > On 22. Feb 2021, at 11:32, Marcel Taeumel wrote: > > > Cuis has a PerformanceImprovements package that holds the fast but > difficult to understand versions of methods that use simpler but slower > versions in the base image. Maybe that idea could be adopted? > > A central package for performance improvements would violate the idea of information hiding and hence impede modularity unless there would be such a package for each specific domain (e.g., CollectionImprovements, KernelImprovements etc.) ... but even then ... if any, extra versions of particular methods should be as close to the original artifact as possible. When programmers would stumble upon a hard-to-understand method in the code browser or debugger, the respective tool should point to the more readable version. And the other way around. I think. :-) > Mabye we can achive this with baseclasses that use the "simple" version? -t > Best, > Marcel >> Am 22.02.2021 11:11:12 schrieb Douglas Brebner : >> >> On 20/02/2021 20:51, Levente Uzonyi wrote: >> > My stance on library methods is that they need to be optimized because >> > you don't know how people will use them. If they are fast, people will >> > be happy. If they are not, you'll leave a bad impression. >> >> Cuis has a PerformanceImprovements package that holds the fast but >> difficult to understand versions of methods that use simpler but slower >> versions in the base image. Maybe that idea could be adopted? >> >> >> > From nicolas.cellier.aka.nice at gmail.com Mon Feb 22 11:11:35 2021 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Mon, 22 Feb 2021 12:11:35 +0100 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: There are two things that bothers me: 1) a performance package can be a nightmare for maintenance, unless the Kernel development freezes, or unless it's very restricted overrides opens a nest of problems, and it's a recipe for creeping incompatibilities. maybe this can be mitigated with duplicated testing (with and without performance), but still... I have maintained my own overrides for years in VW, and it's a never ending fight. 2) more generally, the code base is an example Eliminating all the intermediate objects gives much less expressive code as Tom underlined But providing only naive implementations hides the performance problems that users will have to learn sooner or later... We do not want to optimize prematurely. But we do not want to completely trade performance either. I had this very questioning when developing the accelerated large arithmetic. Maybe not everyone needs it, and it complexifies the base image. An answer could have been to place hooks in the base image in order to avoid overrides, so as to make the large arithmetic performance package unloadable. Such hooks might appear as over-engineered to the purist, but it's trade offs all the way down ;) It would have the additional advantage of easing port to other dialects (Cuis; Pharo, ...). Ideally, we would write simple code, and the system would make it efficient for us... Maybe aggressive inlining could eliminate intermediate object creation by itself ? Le lun. 22 févr. 2021 à 11:32, Marcel Taeumel a écrit : > > > Cuis has a PerformanceImprovements package that holds the fast but > difficult to understand versions of methods that use simpler but slower > versions in the base image. Maybe that idea could be adopted? > > A central package for performance improvements would violate the idea of information hiding and hence impede modularity unless there would be such a package for each specific domain (e.g., CollectionImprovements, KernelImprovements etc.) ... but even then ... if any, extra versions of particular methods should be as close to the original artifact as possible. When programmers would stumble upon a hard-to-understand method in the code browser or debugger, the respective tool should point to the more readable version. And the other way around. I think. :-) > > Best, > Marcel > > Am 22.02.2021 11:11:12 schrieb Douglas Brebner : > > On 20/02/2021 20:51, Levente Uzonyi wrote: > > My stance on library methods is that they need to be optimized because > > you don't know how people will use them. If they are fast, people will > > be happy. If they are not, you'll leave a bad impression. > > Cuis has a PerformanceImprovements package that holds the fast but > difficult to understand versions of methods that use simpler but slower > versions in the base image. Maybe that idea could be adopted? > > > > From marcel.taeumel at hpi.de Mon Feb 22 11:12:58 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Mon, 22 Feb 2021 12:12:58 +0100 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: <66167704-D7DD-4730-9905-2CC9CA2AEC9A@gmx.de> References: <66167704-D7DD-4730-9905-2CC9CA2AEC9A@gmx.de> Message-ID: > Mabye we can achive this with baseclasses that use the "simple" version? Hmm... maybe it should be in a form that does not promote re-use. Yet, it multiple methods would be involved and message/method categories wouldn't suffice --- sure --- an extra base class could work. It kind of reminds me of our RawBitsArray. Best, Marcel Am 22.02.2021 12:08:45 schrieb Tobias Pape : > On 22. Feb 2021, at 11:32, Marcel Taeumel wrote: > > > Cuis has a PerformanceImprovements package that holds the fast but > difficult to understand versions of methods that use simpler but slower > versions in the base image. Maybe that idea could be adopted? > > A central package for performance improvements would violate the idea of information hiding and hence impede modularity unless there would be such a package for each specific domain (e.g., CollectionImprovements, KernelImprovements etc.) ... but even then ... if any, extra versions of particular methods should be as close to the original artifact as possible. When programmers would stumble upon a hard-to-understand method in the code browser or debugger, the respective tool should point to the more readable version. And the other way around. I think. :-) > Mabye we can achive this with baseclasses that use the "simple" version? -t > Best, > Marcel >> Am 22.02.2021 11:11:12 schrieb Douglas Brebner : >> >> On 20/02/2021 20:51, Levente Uzonyi wrote: >> > My stance on library methods is that they need to be optimized because >> > you don't know how people will use them. If they are fast, people will >> > be happy. If they are not, you'll leave a bad impression. >> >> Cuis has a PerformanceImprovements package that holds the fast but >> difficult to understand versions of methods that use simpler but slower >> versions in the base image. Maybe that idea could be adopted? >> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lproven at gmail.com Mon Feb 22 12:41:08 2021 From: lproven at gmail.com (Liam Proven) Date: Mon, 22 Feb 2021 13:41:08 +0100 Subject: [squeak-dev] Fwd: Shim OS [response to: partially Squeak based OS] In-Reply-To: References: <4f99b490eefcf416f91dc5c9f555a491@whidbey.com> Message-ID: On Sun, 21 Feb 2021 at 19:44, tim Rowledge wrote: > > I'm pretty sure that with sufficient time, determination, staff, and luck, one could write a full stack of software in any language at all. I mean, I've been involved in a few (partial) attempts over the decades. Point conceded. I would submit that the core thing is perhaps a _single_ language, and one that is simple and accessible enough for children, adult learners, amateurs, part-timers and so on. One that won't blow your foot of if you fail to dereference a pointer or access the 42nd element of a 40-element array. > RISC OS was almost entirely written in ARM assembler, even a lot of the applications. Sure, but that's not really a good thing, IMHO. It remains possible; e.g. http://www.kolibrios.org/en/ http://menuetos.net/ That it's possible doesn't mean it's a good idea. Remember, Acorn originally tried using Modula-2: https://en.wikipedia.org/wiki/ARX_(operating_system) > The Interval MediaPad was Smalltalk all the way down to process scheduling and interrupt handling. And so on. Do tell? Google draws a blank. > I guess that my engineering/designer ethos is simply happier to suggest that saving time by avoiding the tedious bits someone has already done is a good way of getting to do the fun bits. Of course, it does depend on what one considers 'the fun bits'. For me, that is doing stuff in Smalltalk, frequently the doing stuff *to* Smalltalk part. > > I'm content to consider those lowest level bits as very large primitives and then just use them. There's absolutely no reason I can think of why we shouldn't have a world where lower level bits get gradually replaced by Smalltalk whilst other users keep on 'talking. Indeed I remember a nice example from ... a long time ago... when Eliot realised that the RISC OS filesystem code provided sufficiently low level commands that he could make a DOS format read/write filestream class for an OS that used a decidedly 'interesting' file format natively. Interesting! > Consider this as a suggestion to remember the protocol for eating an Elephant (not that one should actually do that; they get quite annoyed) - don't try to swallow it all at once. We have a rather good language system in Smalltalk. Linux is a not appalling stratum to build over; start by perhaps replacing some of the insane numbers of unix applications filling /usr/bin etc. Gradually infiltrate and push down and out and up. Eventually there's nothing left but the POST and initial loader, the rest just gets garbage collected. I disagree. For instance, firstly, this does seem to be what the systemd project is largely doing. It is causing a lot of alienation and anger. Secondly, this way you can never escape from the core assumptions, which is precisely what I am trying to do. As a parallel example: ISTM that the GNOME team are trying to design a simple, almost smartphone-like desktop for Linux by slowly & gradually rewriting a Windows-95 like desktop, implemented in plain ol' C, removing features that they do not use and therefore deem unnecessary. Personally I find the result an unusable mess and it's caused a lot of people to desert to other desktops, massively splintering the Linux desktop space and seriously damaging Linux. Worse still, due to absence of ideas and knowledge, most of the new alternatives are just other rip-offs of Win95. Poor ones, but with a lot of chrome. > Yes, the idiotic tyranny of the unix 'everything is a file' approach has a long tail and needs winding up and hanging in the back of the 'weird ideas from the primitive past' cupboard. Well, ISTM that you won't ever get there by piecemeal replacing bits of Linux, file-by-file. > The one thing good about it is that the *consistency* provided a lot of leverage. Rather like the consistency of 'everything is an object; yes, even that' for Smalltalk. Plan 9 took this a lot further. It got nowhere, to a first approximation. > I am minded of a Wise Saying from the Very Wise Alan Knight - > > `One of the great leaps in OO is to be able to answer the question “How does this work?” with “I don’t care”.`[1] > > Sometimes it is more practical to accept there isn't enough time to know it all. I had to give up trying to understand the details of CPU design some years ago and just let it be something I use. Now, I will certainly cheer loudly if someone comes up with a way to simplify things enough to solve all this; I'm just not going to hold my breath since blue is such a bad choice of colour for my face. Which again flies in the face of C, which wants you to know and understand how CPUs work. Worse still, the CPU in question being a mid-1970s PDP-11. > My thought these days is to skip the attempts to have a single memory space shared between threads/cores/whatever and have many separate systems running and communicating. Yes, it may be 'less performant' to pass bits down whatever variety of damp string required, but so what. Computers are better than 10 million times faster today than they were when we did BrouHaHa on RISC OS and the Active Book. Let's have a 512 core AARCH64 machine running 1500 images. In your pocket (admittedly right now a fairly large and well cooled pocket). Sounds good but I lack enough knowledge of Smalltalk (yet, if I'm lucky) to judge how feasible it is. My objectives were to try to propose a new way to build a new OS based solidly on existing FOSS tools and technology, and not to reinvent yet more wheels. > I'd also point back to some of Alan's early writings about Smalltalk being a like collection of biological cells with the 'cell walls' isolating each from the other and communication being by (chemical) messages. Separate worlds seem much better implemented in separate memory spaces to me. Perhaps so. > [1] My most famous Wise Saying is probably "An x86 cpu is a waste of perfectly good sand", dating from circa 1985 when I first got ARMed. People laughed back then. Not so much now. :-) -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From lproven at gmail.com Mon Feb 22 12:42:51 2021 From: lproven at gmail.com (Liam Proven) Date: Mon, 22 Feb 2021 13:42:51 +0100 Subject: [squeak-dev] Fwd: Shim OS [response to: partially Squeak based OS] In-Reply-To: <34AE42A2-6987-443B-BFAD-40CA28A4CA1F@gmail.com> References: <34AE42A2-6987-443B-BFAD-40CA28A4CA1F@gmail.com> Message-ID: On Sun, 21 Feb 2021 at 20:33, Eliot Miranda wrote: > +10. Don’t let the perfect be the enemy of the good. Incremental progress benefits from amplifying feedback. An absence of progress can’t. The problem with this is that it leads to a rather toxic final conclusion... https://dreamsongs.com/RiseOfWorseIsBetter.html https://dreamsongs.com/WorseIsBetter.html -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From lecteur at zogotounga.net Mon Feb 22 15:36:23 2021 From: lecteur at zogotounga.net (=?UTF-8?Q?St=c3=a9phane_Rollandin?=) Date: Mon, 22 Feb 2021 16:36:23 +0100 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: <299dab9d-34ed-731d-ed45-29a7f106bfdb@zogotounga.net> > Eliminating all the intermediate objects gives much less expressive > code as Tom underlined > But providing only naive implementations hides the performance > problems that users will have to learn sooner or later... Exactly. And code expressivity is a dubious criterion IMO: especially in Smalltalk, the readability of a specific algorithm can be improved by refactoring/renaming its primitive methods, or more simply by commenting the non-obvious parts. Real pedagogical value comes from explaining complex topics clearly, not from simplifying them. Stef From marcel.taeumel at hpi.de Mon Feb 22 15:40:04 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Mon, 22 Feb 2021 16:40:04 +0100 Subject: [squeak-dev] Fwd: Shim OS [response to: partially Squeak based OS] In-Reply-To: References: <34AE42A2-6987-443B-BFAD-40CA28A4CA1F@gmail.com> Message-ID: Hi Liam, hmm... I wouldn't jump from "perfectionism" directly to "worse is better". There are many problem domains that allow for iteration and experimentation. Like, you know, software that does not control airplanes, for example. Still, if you overdo that iteration part -- never being satisfied with our solution -- that can impede your overall learning progress. There can be many valid attemps along the way, ready to be put out into the field. :-) Especially, if you tackle domains that can be challenging to evaluate but depend a lot on your personal gut feeling... but then again, if you want to have something so that children can control real-life elevators or planes... I have no further comment on that. ;-) Best, Marcel Am 22.02.2021 13:43:14 schrieb Liam Proven : On Sun, 21 Feb 2021 at 20:33, Eliot Miranda wrote: > +10. Don’t let the perfect be the enemy of the good. Incremental progress benefits from amplifying feedback. An absence of progress can’t. The problem with this is that it leads to a rather toxic final conclusion... https://dreamsongs.com/RiseOfWorseIsBetter.html https://dreamsongs.com/WorseIsBetter.html -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 -------------- next part -------------- An HTML attachment was scrubbed... URL: From eliot.miranda at gmail.com Mon Feb 22 15:48:34 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon, 22 Feb 2021 07:48:34 -0800 Subject: [squeak-dev] Fwd: Shim OS [response to: partially Squeak based OS] In-Reply-To: References: Message-ID: <37204426-F499-40BD-87E8-343953539212@gmail.com> > On Feb 22, 2021, at 4:43 AM, Liam Proven wrote: > > On Sun, 21 Feb 2021 at 20:33, Eliot Miranda wrote: > >> +10. Don’t let the perfect be the enemy of the good. Incremental progress benefits from amplifying feedback. An absence of progress can’t. > > The problem with this is that it leads to a rather toxic final conclusion... /A/ problem with this is that it /can/ lead to a rather toxic final conclusion... You can’t prove a negative. It isn’t always the case. And even the classic example of the Learning Research Group/Systems Concept Group at PARC going blue plane and producing Smalltalk is a bit of a myth. There was still incremental progress here. Smalltalk-72 was written in BASIC. ‘74 evolved into ‘76 evolved into ‘80. The hardware evolved from the Alto to the Dorado. So this whole idea that the only way one gets to the future is by making giant leaps is, frankly, baloney. The part of it which *isn’t* baloney is the part if it about how marketing can cause a bad idea to drown out a good idea (VHS vs Betamax etc). But that’s not about incrementalism; that’s about capitalism. > > https://dreamsongs.com/RiseOfWorseIsBetter.html > > https://dreamsongs.com/WorseIsBetter.html > > -- > Liam Proven – Profile: https://about.me/liamproven > Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com > Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven > UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 > From marcel.taeumel at hpi.de Mon Feb 22 15:55:05 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Mon, 22 Feb 2021 16:55:05 +0100 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: <299dab9d-34ed-731d-ed45-29a7f106bfdb@zogotounga.net> References: <299dab9d-34ed-731d-ed45-29a7f106bfdb@zogotounga.net> Message-ID: Hi Stef. > Real pedagogical value comes from explaining complex topics clearly, not from simplifying them. Slightly disagree in this context. If you sacrifice readable abstraction (or modularity or information hiding in that sense) for performance, code comments can only try to alleviate the actual issue. First and foremost, source code should be written for humans, not machines, to understand. Otherwise systems with a lot of inherent complexity would be very challenging -- if not impossible -- to build and maintain. We should be very careful with every low-level detail we burden the high-level programmer with. I find the phrase "[...] problems that users will have to learn sooner or later [...]" very problematic in the sense that it seems to "just give up" on readable, high-level abstractions altogether. Of course, one should not be too naive about this.  Still, we can do better that comments. And we still need more bytecodes/sec and sends/sec. :-D Best, Marcel Am 22.02.2021 16:36:31 schrieb Stéphane Rollandin : > Eliminating all the intermediate objects gives much less expressive > code as Tom underlined > But providing only naive implementations hides the performance > problems that users will have to learn sooner or later... Exactly. And code expressivity is a dubious criterion IMO: especially in Smalltalk, the readability of a specific algorithm can be improved by refactoring/renaming its primitive methods, or more simply by commenting the non-obvious parts. Real pedagogical value comes from explaining complex topics clearly, not from simplifying them. Stef -------------- next part -------------- An HTML attachment was scrubbed... URL: From lproven at gmail.com Mon Feb 22 16:37:09 2021 From: lproven at gmail.com (Liam Proven) Date: Mon, 22 Feb 2021 17:37:09 +0100 Subject: [squeak-dev] Fwd: Shim OS [response to: partially Squeak based OS] In-Reply-To: <37204426-F499-40BD-87E8-343953539212@gmail.com> References: <37204426-F499-40BD-87E8-343953539212@gmail.com> Message-ID: On Mon, 22 Feb 2021 at 16:48, Eliot Miranda wrote: > > /A/ problem with this is that it /can/ lead to a rather toxic final conclusion... OK, conceded. :-) > And even the classic example of the Learning Research Group/Systems Concept Group at PARC going blue plane and producing Smalltalk is a bit of a myth. I do not understand "going blue plane". What does that mean? > Smalltalk-72 was written in BASIC. Good heavens, really? :-) How wonderful! Do you have any more info? ‘74 evolved into ‘76 evolved into ‘80. The hardware evolved from the Alto to the Dorado. > So this whole idea that the only way one gets to the future is by making giant leaps is, frankly, baloney. Hmmm. That is not what I was getting at. I developed this theme at some length in my _previous_ FOSDEM talk: https://liam-on-linux.livejournal.com/69099.html You might find it interesting. I would be interested in any comments. -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From lecteur at zogotounga.net Mon Feb 22 16:42:02 2021 From: lecteur at zogotounga.net (=?UTF-8?Q?St=c3=a9phane_Rollandin?=) Date: Mon, 22 Feb 2021 17:42:02 +0100 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: <299dab9d-34ed-731d-ed45-29a7f106bfdb@zogotounga.net> Message-ID: > We should be very careful with every low-level detail we burden the > high-level programmer with. I find the phrase "[...] problems that users > will have to learn sooner or later [...]" very problematic in the sense > that it seems to "just give up" on readable, high-level abstractions > altogether. Of course, one should not be too naive about this. Maybe we do not have the same idea about what "readable" means, because I do agree with you that the code must be readable in all cases. But, to me, readability cannot come from hiding complexities away - it means finding a proper vocabulary to explain them clearly, as they are and, as Nicolas said, as they will bite anyway. Stef From kksubbu.ml at gmail.com Mon Feb 22 17:03:36 2021 From: kksubbu.ml at gmail.com (K K Subbu) Date: Mon, 22 Feb 2021 22:33:36 +0530 Subject: [squeak-dev] Fwd: Shim OS [response to: partially Squeak based OS] In-Reply-To: References: <4f99b490eefcf416f91dc5c9f555a491@whidbey.com> Message-ID: SOn 22/02/21 12:14 am, tim Rowledge wrote: > My thought these days is to skip the attempts to have a single memory > space shared between threads/cores/whatever and have many separate > systems running and communicating. Yes, it may be 'less performant' > to pass bits down whatever variety of damp string required, but so > what. Computers are better than 10 million times faster today than > they were when we did BrouHaHa on RISC OS and the Active Book. Let's > have a 512 core AARCH64 machine running 1500 images. In your pocket > (admittedly right now a fairly large and well cooled pocket). Pretty close! Many peripherals today are smart and come with their own cores and images. My linux desktop already has over 1400 'firmwares' waiting to be downloaded on demand. Smartphones, too, have tens of smart peripherals with multiple cores and custom firmwares. The main problem with RAM (memory) is not that it is single space. RAM is 'dumb'. Having a core pull a word from RAM just to increment it is such a huge waste of cycles and energy. If primitive ops like incr/decr/complement/add etc. can be delegated to RAM (smart RAM) then the overall computation will become faster and energy efficient. Linux kernel itself is small enough that RAM capacity or cost is no longer a constraint. Most of the bulk in a distro is in the GNU app stacks and device drivers. That leaves power (battery). If power can also be smartly distributed, say at 8-node cluster level, then we can expect to see a cool ;-) pocket computer running 1500 images concurrently. After all, Masashi Umezawa's NetMorph demonstrated seamless migration of live objects across closely coupled Smalltalk images way back in OOPSLA 2002! Regards .. Subbu From tim at rowledge.org Mon Feb 22 18:01:19 2021 From: tim at rowledge.org (tim Rowledge) Date: Mon, 22 Feb 2021 10:01:19 -0800 Subject: [squeak-dev] NuScratch for Squeak 5.3 - and now in exciting 64 bit flavour! In-Reply-To: References: <20210220232912.GA60864@shell.msen.com> <39739408-A13F-4FCE-AE46-C9B3B4702908@rowledge.org> Message-ID: <9B9FC133-EB26-4364-BCBC-6A76B4DA3DB8@rowledge.org> > On 2021-02-21, at 9:56 PM, K K Subbu wrote: > > It may be better to stick to top level libraries: > > $ sudo apt-get install libcairo2-dev libpango1.0-dev libgl1-mesa-dev Thanks; duly noted for next time I set up a Pi. tim -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim Hackers have kernel knowledge. From tomjonabc at gmail.com Mon Feb 22 19:31:00 2021 From: tomjonabc at gmail.com (Tom Beckmann) Date: Mon, 22 Feb 2021 19:31:00 +0000 Subject: [squeak-dev] Squeak-related Talks this Friday Message-ID: Hey all, there will be two Squeak-related talks this Friday in a symposium between the HPI Research School and SAP. Fabio Niephaus will talk about Polyglot Live Programming with TruffleSqueak and I will talk about a Squeak-hosted block-based programming environment. Further, Jens Mönig will talk about recent developments in the Snap! programming environment. If you're interested, you can sign up to receive a join link for Zoom here: TruffleSqueak (11am CET): https://webinars.sap.com/ves-id-17800-52961/en/registration.aspx Snap! (11.30am CET): https://webinars.sap.com/ves-id-17800-52962/en/registration.aspx Block-based Programming (noon CET): https://webinars.sap.com/ves-id-17800-52963/en/registration.aspx Best, Tom -------------- next part -------------- An HTML attachment was scrubbed... URL: From eric.gade at gmail.com Mon Feb 22 19:47:18 2021 From: eric.gade at gmail.com (Eric Gade) Date: Mon, 22 Feb 2021 14:47:18 -0500 Subject: [squeak-dev] Fwd: Shim OS [response to: partially Squeak based OS] In-Reply-To: References: <37204426-F499-40BD-87E8-343953539212@gmail.com> Message-ID: Hey Liam, On Mon, Feb 22, 2021 at 11:37 AM Liam Proven wrote: > > Smalltalk-72 was written in BASIC. > > Good heavens, really? :-) How wonderful! Do you have any more info? > > If you've got the time, Dan Ingalls' very recent history of Smalltalk is a really informative read: https://dl.acm.org/doi/pdf/10.1145/3386335 -- Eric -------------- next part -------------- An HTML attachment was scrubbed... URL: From ken.dickey at whidbey.com Mon Feb 22 20:03:53 2021 From: ken.dickey at whidbey.com (ken.dickey at whidbey.com) Date: Mon, 22 Feb 2021 12:03:53 -0800 Subject: [squeak-dev] Worse is complicated Message-ID: <160051e97059b98c749520cb560e48d5@whidbey.com> On Sun, 21 Feb 2021 at 20:33, Eliot Miranda wrote: >> +10. Don’t let the perfect be the enemy of the good. Incremental >> progress benefits from amplifying feedback. An absence of progress >> can’t. > The problem with this is that it leads to a rather toxic final > conclusion... > .. WorseIsBetter The problem is "final". _Evolution_ is relentless and continuous. Thinking back to arguments in _The Blind Clockmaker_, one needs to continually observe and refine / replace / clarify. One does not hear much about dynamic language usage in commercial settings because [1] feature evolving faster than your competition is a strategic advantage and [2] investors get distracted by "why are you using language X" rather than focusing on strategic advantages of particular development practices within a business context. While OS features have tended to feature evolve slowly, placing ourselves in a position to evolve our systems should lead to better outcomes. One aspect we have not touched on yet is the modelling of the HW systems themselves. I like to keep in mind Dan Ingalls dictum: "Reactive Principle. Every component accessible to the user should be able to present itself in a meaningful way for observation and manipulation." Being able to present and observe what CPU/GPU/GPIO/USART/USB/.. seems a useful exercise for a meta/self-knowledgeable system, especially one concerned with hot-plug devices and live updates. Placed in this context, device drivers and memory systems can be much more interesting. IMHO, C has been a fine language for device drivers but got into trouble with trying to scale up to large systems. Perhaps the time has come when it is again useful to look at ways to scale, e.g. Smalltalk, to smaller/finer use cases. -KenD [Note also: https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.84.7354&rep=rep1&type=pdf ] From ma.chris.m at gmail.com Mon Feb 22 20:37:21 2021 From: ma.chris.m at gmail.com (Chris Muller) Date: Mon, 22 Feb 2021 14:37:21 -0600 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: Message-ID: > > The most optimized version with the inlined temporaries is a great implementation but looks like quite a beast to me, which in my opinion would be sad for something that appears in our standard library. After looking for > > senders of Rectangle class>>merging: in my trunk image I only saw one critical path in recordInvalidRect:, which appears to on average trigger merging: only once per damaged frame. Is there another use case we know of? > > My stance on library methods is that they need to be optimized because you > don't know how people will use them. If they are fast, people will be > happy. If they are not, you'll leave a bad impression. > > This discussion exists, because Karl changed the method last year and > noticed that the performance got worse[1]. And, while he was convinced > about arguments always being sequenceable, it turned out that they may be > sets as well. It's a creation method. Creation, initialization, and error-handling are all areas that don't typically need to be optimized for execution performance. Afterall, how many Rectangles will you need / be able to create before you start to run into other performance and memory issues? In seemingly trying to optimize for a gaming use-case, this plays against your statement that we don't know how people will use them. Optimizing for speed by only a small percentage (vs. Tom's #reduce: solution), but at the cost of restricting the input type, DID leave a bad impression on someone. Now they have to send "asArray", probably negating that tiny #allButFirstDo: performance gain. - Chris From craig at blackpagedigital.com Mon Feb 22 22:04:17 2021 From: craig at blackpagedigital.com (Craig Latta) Date: Mon, 22 Feb 2021 14:04:17 -0800 Subject: [squeak-dev] zooming (was "Shim OS") In-Reply-To: References: <4f99b490eefcf416f91dc5c9f555a491@whidbey.com> Message-ID: <8a08459f-261e-1390-817a-a1626d487a7c@blackpagedigital.com> Hi-- tim writes: > One would still need to work out how to handle all the facilities we > take for granted for our daily use of a computer; a *good* email > system, web browsing, assorted social media interfaces and on and on. Liam responds: > A2 can do a surprising amount of this already, today. For a niche > experimental OS it is amazingly complete. > > http://ignorethecode.net/blog/2009/04/22/oberon/ Fun! I like the zooming. I've been using the zooming capabilities of SqueakJS on mobile devices for a few years now. It's an essential feature; I like how it's an easily-leveraged part of CSS. -C -- Craig Latta :: research computer scientist Black Page Digital :: Berkeley, California 663137D7940BF5C0AFC :: 1349FB2ADA32C4D5314CE From lproven at gmail.com Mon Feb 22 22:51:10 2021 From: lproven at gmail.com (Liam Proven) Date: Mon, 22 Feb 2021 23:51:10 +0100 Subject: [squeak-dev] Fwd: Shim OS [response to: partially Squeak based OS] In-Reply-To: References: <37204426-F499-40BD-87E8-343953539212@gmail.com> Message-ID: On Mon, 22 Feb 2021 at 20:47, Eric Gade wrote: > > If you've got the time, Dan Ingalls' very recent history of Smalltalk is a really informative read: https://dl.acm.org/doi/pdf/10.1145/3386335 Great! Thank you. Added to the (considerable) list... -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From lproven at gmail.com Mon Feb 22 22:59:29 2021 From: lproven at gmail.com (Liam Proven) Date: Mon, 22 Feb 2021 23:59:29 +0100 Subject: [squeak-dev] Worse is complicated In-Reply-To: <160051e97059b98c749520cb560e48d5@whidbey.com> References: <160051e97059b98c749520cb560e48d5@whidbey.com> Message-ID: On Mon, 22 Feb 2021 at 21:03, wrote: > I like to keep in mind Dan Ingalls dictum: > > "Reactive Principle. Every component accessible to the user should be > able to present itself in a meaningful way for observation and > manipulation." > > Being able to present and observe what CPU/GPU/GPIO/USART/USB/.. seems a > useful exercise for a meta/self-knowledgeable system, especially one > concerned with hot-plug devices and live updates. > > Placed in this context, device drivers and memory systems can be much > more interesting. Well, broadly keeping this principle in mind was why I ended up proposing the Oberon system, and specifically A2, in the talk. Oberon is famed for being a readable, comprehensible system, even by a single person, even if that person is still a student. It is still being used for teaching at ETH and I believe in Linz, it still has a community of users and fans... and judging from the traffic levels and Github activity, there is quite a lot of R&D going on in Russia. I have even been invited to an online symposium on the language and OS, but my Russian is all but nonexistent. > IMHO, C has been a fine language for device drivers but got into trouble > with trying to scale up to large systems. I agree. This is a profoundly heretical view to state these days. For saying it, I have been told to kill myself on Twitter. I wish I were joking. > Perhaps the time has come when it is again useful to look at ways to > scale, e.g. Smalltalk, to smaller/finer use cases. Well, yes, that's what I was getting at! :-) -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From marcel.taeumel at hpi.de Tue Feb 23 06:45:57 2021 From: marcel.taeumel at hpi.de (Marcel Taeumel) Date: Tue, 23 Feb 2021 07:45:57 +0100 Subject: [squeak-dev] The Inbox: Graphics-nice.446.mcz In-Reply-To: References: <299dab9d-34ed-731d-ed45-29a7f106bfdb@zogotounga.net> Message-ID: Hi Stef. > But, to me, readability cannot come from hiding complexities away - it means > finding a proper vocabulary to explain them clearly, as they are and, as > Nicolas said, as they will bite anyway. Sure. "Leaky abstractions" (https://en.wikipedia.org/wiki/Leaky_abstraction) can be challenging. I just disagreed with the way you "sugarcoated" the effect of comments. Yes, you would have to explain the essential complexity for a hardly readable piece of code with a natural-language comment. Yet, it should be still considered a code smell, given that one did not yet managed to express the solution in idiomatic Smalltalk. :-) And maybe the programming language will never be able to express that essential complexity nicely because it may just not be a good fit for the problem at hand. Best, Marcel Am 22.02.2021 17:42:03 schrieb Stéphane Rollandin : > We should be very careful with every low-level detail we burden the > high-level programmer with. I find the phrase "[...] problems that users > will have to learn sooner or later [...]" very problematic in the sense > that it seems to "just give up" on readable, high-level abstractions > altogether. Of course, one should not be too naive about this. Maybe we do not have the same idea about what "readable" means, because I do agree with you that the code must be readable in all cases. But, to me, readability cannot come from hiding complexities away - it means finding a proper vocabulary to explain them clearly, as they are and, as Nicolas said, as they will bite anyway. Stef -------------- next part -------------- An HTML attachment was scrubbed... URL: From stes at telenet.be Tue Feb 23 12:47:40 2021 From: stes at telenet.be (stes@PANDORA.BE) Date: Tue, 23 Feb 2021 13:47:40 +0100 (CET) Subject: [squeak-dev] NuScratch for Squeak 5.3 - and now in exciting 64 bit flavour! Message-ID: <684562830.31233753.1614084460305.JavaMail.zimbra@telenet.be> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 > You do need the UnicodePlugin available for things to run cleanly. > This isn't routinely built, I think. > You also need the Verdana font files > and the Scratch resources directory in order to do a build from sources. At GNOME they have a beautiful script gallery : https://pango.gnome.org/ScriptGallery I wonder whether the plugin could be called PangoUnicodePlugin or GnomeUnicodePlugin instead of just UnicodePlugin. David Stes -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQEcBAEBCAAGBQJgNPkiAAoJEAwpOKXMq1Ma35sH/2TSXgYX3J1LFctnyOaaE3iu xd6SVoFHGLviVOsWMfdQAB5D6+INjEbps6vZkxQGGs44k+h1Z8Vh09rpRbZnJNAt Q28f8rya62vwgvFjOmhsPGDVN6cCsR8XGpqY1ln2cEas1d7x0THGV2SNtNGBYPTv /F0qkv85DWfHHdjHJX+Br+0iiAH40wcAqZXC8xgf07BoVauaaHmFxaSwxjplwbs9 +L+7TxDsr5aJe1MPUPKnv/4Eczp01yYE556J1aSW4DzFntyJRWakn3imFSIH9nZj HI3DQaRQfNhi+YfkwDFblhESlGPRpBxF12efonV19/n82W9jDsJAfCSV07Akl0o= =yKh6 -----END PGP SIGNATURE----- From ken.dickey at whidbey.com Wed Feb 24 16:40:57 2021 From: ken.dickey at whidbey.com (ken.dickey at whidbey.com) Date: Wed, 24 Feb 2021 08:40:57 -0800 Subject: [squeak-dev] seL4 Microkernel: How small can the shim be? Message-ID: <475801fe6c6dffe34b7c71135d7930be@whidbey.com> Liam, The reason I keep coming back to this is the complexity of modern OS threats and requirements and the desire to spend less of my time here. The core drivers of the seL4 API are (from https://microkerneldude.wordpress.com/ ; good reads here BTW): Verification ------------ -Minimality [* Small _IS_ beautiful ! *] -Policy freedom -Performance -Security -Don’t pay for what you don’t use Then there are a few non-goals: ------------------------------ -Stopping you from shooting yourself in the foot [*systems programmers have to aim through their heads;^] -Ease of use [*we can help here*] -Hardware abstraction [*we should be able to help here*] So starting with a minimalist open source microkernel running drivers, servers, apps as hot swapable Smqlltalk runtime components in separate user-land address spaces with _fast_ IPC makes sense to me as a strategy. If the systems architecture is right and there is enough interest, we can drill down to the bottom level, but in the mean time we can devise and experiment without getting bogged down learning the details of tying our shoelaces before the big race. My thought is to have a copy-on-write core (I am thinking again or something like the Bee DMR binary core here) with a system naming service that is used to intern all selectors, so IPC uses common selector keys. Capabilities map to Smalltalk objects in their home address spaces (note http://mumble.net/~jar/pubs/secureos/secureos.html). So code+component(s) = driver or service with core just copy-on-write (with resilient live update). I would think that all of this maps into (perhaps grad level) student projects as well, so [a] we can get a bit of "free labor" boost plus [b] more beginning and advanced students get exposed to Smalltalk and the ideas of the community. $0.02, -KenD From asqueaker at gmail.com Thu Feb 25 01:23:55 2021 From: asqueaker at gmail.com (Chris Muller) Date: Wed, 24 Feb 2021 19:23:55 -0600 Subject: [squeak-dev] The Trunk: SystemReporter-mt.49.mcz In-Reply-To: References: Message-ID: Hi Marcel, > > It would be really nice if the Monticello Browser also noted from which > repository the packages were loaded from. That would have been my first > place to look for information like this - and, of course, not find it. > > Hmm... maybe it would be possible with "a clever caching strategy" (tm) > :-D -- It doesn't take *that* long to fetch the list of file names from a > file-based repository. > It's an unscalable part of the model, and growing at a good clip. :) Selecting a package in the Monticello browser shows the repositories it was loaded from in the right pane. Part of the WorkingCopy model. - Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: From tim at rowledge.org Thu Feb 25 22:09:26 2021 From: tim at rowledge.org (tim Rowledge) Date: Thu, 25 Feb 2021 14:09:26 -0800 Subject: [squeak-dev] Loading code without adding to the changes file (was Re: The Trunk: System-cmm.1214.mcz) In-Reply-To: <1900AC74-9909-4316-9693-84B27FFF8CC6@rowledge.org> References: <1900AC74-9909-4316-9693-84B27FFF8CC6@rowledge.org> Message-ID: <680738DA-7C84-42A1-970E-9447D9A7B87F@rowledge.org> > On 2021-02-05, at 9:15 PM, tim Rowledge wrote: > > Ah, that reminds me of a related issue I've been meaning to bring up for , oy, 6 years. > > Last time I tried, it was not possible to load code into a system with no changes file because of an issue to do with the method tail - the bit where we keep the source details. Has that been solved? I made some time to look at this yesterday and I think we probably have a fairly simple path to solution. It looks like the key is the ClassDescription>>#acceptsLoggingOfCompilation method and other implementors. If I make it return false it becomes possible to add code and avoid writing anything out. Actually, I had fun testing this because I had turned off the no sources/no changes preference and the deleted the changes file; upon trying to recompile the method it of course failed because of no changes file and I used the debugger to change the value of the boolean on the stack to false, thus letting me complete the compilation of the method that lets me compile with no logging. Smalltalk is so very cool. There are several implementors to also consider here. MorphicModel, for example does a modestly gnarly check for the class of the compilation. So thinking of making a Preference (yes, I know I've railed against too many preferences frequently) for this, I think that a) making a preference in ClassDescription>>#acceptsLoggingOfCompilation b) changing all the other implementors except the Metaclass version to add a `super acceptsLoggingOfCompilation and: [` clause ... should do the job. An interesting benefit of having this working would be cases where we want a base image running that perhaps gets a web request to spawn a new instance to run some website or application. Currently anything that causes logging can make for an 'interesting' mess in the parent's changes file. tim -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim "Bother" said Pooh, as he realised Piglet was undercooked. From lproven at gmail.com Thu Feb 25 23:17:29 2021 From: lproven at gmail.com (Liam Proven) Date: Fri, 26 Feb 2021 00:17:29 +0100 Subject: [squeak-dev] seL4 Microkernel: How small can the shim be? In-Reply-To: <475801fe6c6dffe34b7c71135d7930be@whidbey.com> References: <475801fe6c6dffe34b7c71135d7930be@whidbey.com> Message-ID: On Wed, 24 Feb 2021 at 17:40, wrote: > > Liam, > > The reason I keep coming back to this is the complexity of modern OS > threats and requirements and the desire to spend less of my time here. > > The core drivers of the seL4 API are (from > https://microkerneldude.wordpress.com/ ; good reads here BTW): [...] > I would think that all of this maps into (perhaps grad level) student > projects as well, so [a] we can get a bit of "free labor" boost plus [b] > more beginning and advanced students get exposed to Smalltalk and the > ideas of the community. :-D Some excellent points there. I was and am slightly aware of the seL4 µkernel, but I did not seriously consider it. I want to stress that I am not really an expert in this stuff, merely an interested dilettante! But few people seem to be considering new OS designs these days, so I thought that maybe this amateur could make some interesting points. So, my reasoning for suggesting Oberon and specifically A2: • I really wanted a total and clean break from C and C-based designs; something really different. • I was hoping for a type-safe, memory-managed compiler suitable for low-level and kernel work – and I found one in Oberon. • A2 is a complete OS, with multicore support, TCP/IP stack, working USB drivers, things like that, not just a kernel. It also provides a compiler and rudimentary sort of IDE suitable for writing new drivers in. L4 is just a microkernel and needs an OS building around it, as I understand it. • I do not know much about the whole L4 family but what little I know some of the existing OSes based upon them were very vaguely Unix-ish. That's precisely what I'm trying to move away from. • I do not know if SEL4 has working multiprocessor support. I know that QNX does, which demonstrates that a Unix-like true microkernel can do this; but I also believe that Minix 3 so far lacks one, and lacks some APIs needed for POSIX and xNix compatibility. This is not an easy thing to do. • This is wild supposition on my part, but I wonder if the traditional C language's design and features, and the design philosophy of xNix, its design of separate isolated execution environments which mainly exchange data through the filesystem or IPC mechanisms, make things like microkernels seem like a desirable design: to extend this compartmentalisation right down into the kernel itself. Plan 9's developers originally intended to replace C with Aleph, but in the end abandoned that approach but applied much stricter standards to Plan 9 C than ordinary xNix/Linux C. I have read 1 isolated comment lacking more context that the design of Plan 9 makes considerations of microkernels largely irrelevant, but I do not know how or why that might be. I would very much like to know. -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From tim at rowledge.org Thu Feb 25 23:27:51 2021 From: tim at rowledge.org (tim Rowledge) Date: Thu, 25 Feb 2021 15:27:51 -0800 Subject: [squeak-dev] Loading code without adding to the changes file (was Re: The Trunk: System-cmm.1214.mcz) In-Reply-To: <680738DA-7C84-42A1-970E-9447D9A7B87F@rowledge.org> References: <1900AC74-9909-4316-9693-84B27FFF8CC6@rowledge.org> <680738DA-7C84-42A1-970E-9447D9A7B87F@rowledge.org> Message-ID: <3A99C92A-FE46-4B0D-ACB0-3A2FFC177BA5@rowledge.org> Plausible looking changeset for this; since it touches several packages it makes more sense to share a test version this way. -------------- next part -------------- A non-text attachment was scrubbed... Name: NoWriteChangeToFile.5.cs Type: application/octet-stream Size: 3333 bytes Desc: not available URL: -------------- next part -------------- One minor oddity that might need altering is that the ClassDescription preference is on the instance side rather than the class side; this is checked for in the pragma/preference adding code and so I've ended up with class side methods for the actual preference setting & pragma but an instance side usage of the added class variable. It feels messy somehow but it does work. If you disable 'Warn if no changes file', 'Warn if no sources file', 'Read document at startup', 'Log compilations to changes file' and load the DoItFirst package you can save an image, delete its changes and run a command like - `squeak my.image -doit DoSomething &` and have a server running that won't try to log any code being compiled. tim -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim Science adjusts its views based on what is observed. Faith denies observation so belief can be preserved From commits at source.squeak.org Fri Feb 26 14:43:48 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 26 Feb 2021 14:43:48 0000 Subject: [squeak-dev] The Trunk: Morphic-mt.1726.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.1726.mcz ==================== Summary ==================== Name: Morphic-mt.1726 Author: mt Time: 26 February 2021, 3:43:41.835955 pm UUID: cea183c6-2e39-c846-8c17-7b49f0fa0958 Ancestors: Morphic-mt.1725 Extracts, cleans up, and fixes Morphic layers from Worlds-in-Worlds to be available in any morph structure. - Protocol "submorphs" in Morph re-organized to highlight the basic add/remove protocol and "layers" - Existing layers can be found under "layer names" in Morph class. See MorphTest >> #test11NamedLayers to understand the current layer design. We should refine this if we stumble upon better concerns. - See the "tests - submorphs - layers" protocol in MorphTest for more examples. - A new effect is that you can change #morphicLayerNumber(:) while the morph is already in a structure (i.e. has an owner), which will then update submorph order in the owner automatically. - Another new effect is that the docking bar's sub menus are *behind* the docking bar, which makes them look more integrated into the bar. =============== Diff against Morphic-mt.1725 =============== Item was changed: ----- Method: BalloonMorph>>initialize (in category 'initialization') ----- initialize "initialize the state of the receiver" super initialize. self disableLayout: true. + self morphicLayerNumber: self class balloonLayer. "" self beSmoothCurve. offsetFromTarget := 0 @ 0. self setDefaultParameters.! Item was removed: - ----- Method: BalloonMorph>>morphicLayerNumber (in category 'WiW support') ----- - morphicLayerNumber - - "helpful for insuring some morphs always appear in front of or behind others. - smaller numbers are in front" - - ^5 "Balloons are very front-like things"! Item was changed: ----- Method: BalloonMorph>>prepareToOpen (in category 'private') ----- prepareToOpen "Override the color if not already set." self userInterfaceTheme color ifNotNil: [ : col | self color: col]. self lock ; + fullBounds! - fullBounds ; - setProperty: #morphicLayerNumber - toValue: self morphicLayerNumber! Item was changed: + ----- Method: ColorPickerMorph>>delete (in category 'submorphs - add/remove') ----- - ----- Method: ColorPickerMorph>>delete (in category 'submorphs-add/remove') ----- delete "The moment of departure has come. If the receiver has an affiliated command, finalize it and have the system remember it. In any case, delete the receiver" (selector isNil or: [ target isNil ]) ifFalse: [ self rememberCommand: (Command new cmdWording: 'color change' translated; undoTarget: target selector: selector arguments: (self argumentsWith: originalColor); redoTarget: target selector: selector arguments: (self argumentsWith: selectedColor)). ]. super delete! Item was changed: ----- Method: ColorPickerMorph>>putUpFor:near: (in category 'other') ----- putUpFor: aMorph near: aRectangle "Put the receiver up on the screen. Note highly variant behavior depending on the setting of the #modalColorPickers preference" | layerNumber | aMorph isMorph ifTrue: [ layerNumber := aMorph morphicLayerNumber. aMorph allOwnersDo:[:m| layerNumber := layerNumber min: m morphicLayerNumber]. + self morphicLayerNumber: layerNumber - 0.1 - self setProperty: #morphicLayerNumber toValue: layerNumber - 0.1 ]. isModal == true "backward compatibility" ifTrue: [self pickUpColorFor: aMorph] ifFalse: [self addToWorld: ((aMorph notNil and: [aMorph world notNil]) ifTrue: [aMorph world] ifFalse: [self currentWorld]) near: (aRectangle ifNil: [aMorph ifNil: [100 at 100 extent: 1 at 1] ifNotNil: [aMorph fullBoundsInWorld]])]! Item was changed: ----- Method: ComplexProgressIndicator>>withProgressDo: (in category 'as yet unclassified') ----- withProgressDo: aBlock | safetyFactor totals trialRect delta | Smalltalk isMorphic ifFalse: [^aBlock value]. formerProject := Project current. formerWorld := formerProject world. formerProcess := Processor activeProcess. targetMorph ifNil: [targetMorph := ProgressTargetRequestNotification signal]. targetMorph ifNil: [ trialRect := Rectangle center: Sensor cursorPoint extent: 80 at 80. delta := trialRect amountToTranslateWithin: formerWorld bounds. trialRect := trialRect translateBy: delta. translucentMorph := TranslucentProgessMorph new opaqueBackgroundColor: Color white; bounds: trialRect; openInWorld: formerWorld. ] ifNotNil: [ translucentMorph := TranslucentProgessMorph new + morphicLayerNumber: targetMorph morphicLayerNumber - 0.1; - setProperty: #morphicLayerNumber toValue: targetMorph morphicLayerNumber - 0.1; bounds: targetMorph boundsInWorld; openInWorld: targetMorph world. ]. stageCompleted := 0. safetyFactor := 1.1. "better to guess high than low" translucentMorph setProperty: #progressStageNumber toValue: 1. translucentMorph hide. totals := self loadingHistoryDataForKey: 'total'. newRatio := 1.0. estimate := totals size < 2 ifTrue: [ 15000 "be a pessimist" ] ifFalse: [ (totals sum - totals max) / (totals size - 1 max: 1) * safetyFactor. ]. start := Time millisecondClockValue. self forkProgressWatcher. [ aBlock on: ProgressInitiationException do: [ :ex | ex sendNotificationsTo: [ :min :max :curr | "ignore this as it is inaccurate" ]. ]. ] on: ProgressNotification do: [ :note | | stageCompletedString | translucentMorph show. note extraParam ifNotNil:[self addProgressDecoration: note extraParam]. stageCompletedString := (note messageText findTokens: ' ') first. stageCompleted := (stageCompletedString copyUpTo: $:) asNumber. cumulativeStageTime := Time millisecondClockValue - start max: 1. prevData := self loadingHistoryDataForKey: stageCompletedString. prevData isEmpty ifFalse: [ newRatio := (cumulativeStageTime / (prevData average max: 1)) asFloat. ]. self loadingHistoryAt: stageCompletedString add: cumulativeStageTime. translucentMorph setProperty: #progressStageNumber toValue: stageCompleted + 1. note resume. ]. stageCompleted := 999. "we may or may not get here" ! Item was changed: ----- Method: DialogWindow>>getUserResponse (in category 'running') ----- getUserResponse | hand world | self message ifEmpty: [messageMorph delete]. "Do not waste space." self paneMorph submorphs ifEmpty: ["Do not waste space and avoid strange button-row wraps." self paneMorph delete. self buttonRowMorph wrapDirection: #none]. hand := self currentHand. world := self currentWorld. self fullBounds. + self morphicLayerNumber: self class dialogLayer. self moveToPreferredPosition. self openInWorld: world. hand showTemporaryCursor: nil. "Since we are out of context, reset the cursor." hand keyboardFocus in: [:priorKeyboardFocus | hand mouseFocus in: [:priorMouseFocus | self exclusive ifTrue: [hand newMouseFocus: self]. hand newKeyboardFocus: self. [[self isInWorld] whileTrue: [world doOneSubCycle]] ifCurtailed: [self cancelDialog]. hand newKeyboardFocus: priorKeyboardFocus. self flag: #discuss. "Since 2016 we are having this *ping pong* between (a) restoring the prior mouse focus and (b) just clearing it globally. The former solution makes more sense while the latter fixes issues with some modal dialogs. We have to investigate this further." hand releaseMouseFocus. "hand newMouseFocus: priorMouseFocus."]]. ^ result! Item was changed: ----- Method: DockingBarMorph>>add:icon:help:subMenu: (in category 'construction') ----- add: wordingString icon: aForm help: helpString subMenu: aMenuMorph "Append the given submenu with the given label." | item | item := DockingBarItemMorph new. item contents: wordingString. item subMenu: aMenuMorph. item icon: aForm. helpString isNil ifFalse: [item setBalloonText: helpString]. + aMenuMorph ifNotNil: [ + aMenuMorph morphicLayerNumber: self morphicLayerNumber + 1]. self addMorphBack: item! Item was changed: ----- Method: DockingBarMorph>>add:icon:selectedIcon:help:subMenu: (in category 'construction') ----- add: wordingString icon: aForm selectedIcon: anotherForm help: helpString subMenu: aMenuMorph "Append the given submenu with the given label." | item | item := DockingBarItemMorph new contents: wordingString; subMenu: aMenuMorph; icon: aForm; selectedIcon: anotherForm. + helpString ifNotNil: [ - helpString isNil ifFalse: [ item setBalloonText: helpString ]. + aMenuMorph ifNotNil: [ + aMenuMorph morphicLayerNumber: self morphicLayerNumber + 1 ]. self addMorphBack: item! Item was changed: ----- Method: DockingBarMorph>>addItem: (in category 'construction') ----- addItem: aBlock | item | item := DockingBarItemMorph new. aBlock value: item. + item subMenu ifNotNil: [:menu | + "Docking bar and protruding menu should appear visually merged." + menu morphicLayerNumber: self morphicLayerNumber + 1]. self addMorphBack: item! Item was changed: + ----- Method: DockingBarMorph>>delete (in category 'submorphs - add/remove') ----- - ----- Method: DockingBarMorph>>delete (in category 'submorphs-add/remove') ----- delete self currentHand removeKeyboardListener: self. activeSubMenu ifNotNil: [ activeSubMenu delete]. ^ super delete! Item was changed: + ----- Method: DockingBarMorph>>morphicLayerNumber (in category 'submorphs - layers') ----- - ----- Method: DockingBarMorph>>morphicLayerNumber (in category 'WiW support') ----- morphicLayerNumber + + ^ self valueOfProperty: #morphicLayerNumber ifAbsent: [self class navigatorLayer]! - "helpful for insuring some morphs always appear in front of or - behind others. smaller numbers are in front" - ^ 11! Item was changed: ----- Method: HaloMorph>>addGraphicalHandleFrom:at: (in category 'private') ----- addGraphicalHandleFrom: formKey at: aPoint "Add the supplied form as a graphical handle centered at the given point. Return the handle." | handle aForm | aForm := (ScriptingSystem formAtKey: formKey) ifNil: [ScriptingSystem formAtKey: #SolidMenu]. handle := ImageMorph new image: aForm; bounds: (Rectangle center: aPoint extent: aForm extent). + handle borderColor: Color black; borderWidth: 2. handle wantsYellowButtonMenu: false. self addMorph: handle. handle on: #mouseUp send: #endInteraction: to: self. ^ handle ! Item was changed: + ----- Method: HaloMorph>>delete (in category 'submorphs - add/remove') ----- - ----- Method: HaloMorph>>delete (in category 'submorphs-add/remove') ----- delete "Delete the halo. Tell the target that it no longer has the halo; accept any pending edits to the name; and then either actually delete myself or start to fade out" self acceptNameEdit. self isMagicHalo: false. Preferences haloTransitions ifFalse: [super delete] ifTrue: [ self stopStepping; startStepping; startSteppingSelector: #fadeOutFinally]. ! Item was removed: - ----- Method: HaloMorph>>morphicLayerNumber (in category 'WiW support') ----- - morphicLayerNumber - - "helpful for insuring some morphs always appear in front of or behind others. - smaller numbers are in front" - - ^7 "Halos are very front-like things"! Item was changed: ----- Method: HandleMorph>>initialize (in category 'initialization') ----- initialize "initialize the state of the receiver" super initialize. "" self extent: 16 @ 16. + self disableLayout: true. + self morphicLayerNumber: self class frontmostLayer.! - self disableLayout: true.! Item was removed: - ----- Method: MVCMenuMorph>>initialize (in category 'initializing') ----- - initialize - super initialize. - self setProperty: #morphicLayerNumber toValue: self morphicLayerNumber - ! Item was removed: - ----- Method: MVCMenuMorph>>morphicLayerNumber (in category 'WiW support') ----- - morphicLayerNumber - ^self valueOfProperty: #morphicLayerNumber ifAbsent: [10]. - ! Item was changed: ----- Method: MenuMorph>>initialize (in category 'initialization') ----- initialize super initialize. self setDefaultParameters. self changeTableLayout. self listDirection: #topToBottom. self hResizing: #shrinkWrap. self vResizing: #shrinkWrap. self disableLayout: true. + self morphicLayerNumber: self class menuLayer. defaultTarget := nil. selectedItem := nil. stayUp := false. popUpOwner := nil.! Item was removed: - ----- Method: MenuMorph>>morphicLayerNumber (in category 'private') ----- - morphicLayerNumber - - "helpful for insuring some morphs always appear in front of or behind others. - smaller numbers are in front" - ^self valueOfProperty: #morphicLayerNumber ifAbsent: [ - stayUp ifTrue:[100] ifFalse:[10] - ]! Item was changed: ----- Method: MenuMorph>>stayUp: (in category 'accessing') ----- stayUp: aBoolean stayUp := aBoolean. aBoolean ifTrue: [ self removeStayUpBox ]. + self morphicLayerNumber: (aBoolean ifTrue: [ self class windowLayer ] ifFalse: [ self class menuLayer ]). originalFocusHolder := nil. "Not needed anymore."! Item was added: + ----- Method: Morph class>>backmostLayer (in category 'layer names') ----- + backmostLayer + + ^ 999! Item was added: + ----- Method: Morph class>>balloonLayer (in category 'layer names') ----- + balloonLayer + "Balloons and other tooltip-like morphs." + + ^ 5! Item was added: + ----- Method: Morph class>>defaultLayer (in category 'layer names') ----- + defaultLayer + + ^ 100! Item was added: + ----- Method: Morph class>>dialogLayer (in category 'layer names') ----- + dialogLayer + "For morphs that request user input." + + ^ self windowLayer + self menuLayer // 2! Item was added: + ----- Method: Morph class>>frontmostLayer (in category 'layer names') ----- + frontmostLayer + + ^ -999! Item was added: + ----- Method: Morph class>>haloLayer (in category 'layer names') ----- + haloLayer + "A morph's halo is like a meta menu with a tooltip-like information overlay." + + ^ self menuLayer + self balloonLayer // 2! Item was added: + ----- Method: Morph class>>menuLayer (in category 'layer names') ----- + menuLayer + "Pop-up menu-like morphs." + + ^ 10! Item was added: + ----- Method: Morph class>>navigatorLayer (in category 'layer names') ----- + navigatorLayer + "For morphs that float above all (tool) windows and provide quick access to other tools. Examples include docking bars and flaps." + + ^ self dialogLayer + self windowLayer // 2! Item was added: + ----- Method: Morph class>>progressLayer (in category 'layer names') ----- + progressLayer + "For morphs that help the user understand why a certain operation has not finished yet." + + ^ self dialogLayer + (2 * self menuLayer) // 3! Item was added: + ----- Method: Morph class>>windowLayer (in category 'layer names') ----- + windowLayer + "For morphs that represent windows and other tool-like containers." + + ^ 100! Item was changed: + ----- Method: Morph>>abandon (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>abandon (in category 'submorphs-add/remove') ----- abandon "Like delete, but we really intend not to use this morph again. Clean up a few things." self delete! Item was changed: + ----- Method: Morph>>actWhen (in category 'submorphs - misc') ----- - ----- Method: Morph>>actWhen (in category 'submorphs-add/remove') ----- actWhen "Answer when the receiver, probably being used as a button, should have its action triggered" ^ self valueOfProperty: #actWhen ifAbsentPut: [#buttonDown]! Item was changed: + ----- Method: Morph>>actWhen: (in category 'submorphs - misc') ----- - ----- Method: Morph>>actWhen: (in category 'submorphs-add/remove') ----- actWhen: aButtonPhase "Set the receiver's actWhen trait" self setProperty: #actWhen toValue: aButtonPhase! Item was changed: + ----- Method: Morph>>addAllMorphs: (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>addAllMorphs: (in category 'submorphs-add/remove') ----- addAllMorphs: aCollection ^self addAllMorphsBack: aCollection! Item was changed: + ----- Method: Morph>>addAllMorphs:after: (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>addAllMorphs:after: (in category 'submorphs-add/remove') ----- addAllMorphs: aCollection after: anotherMorph ^self addAllMorphs: aCollection behind: anotherMorph! Item was changed: + ----- Method: Morph>>addAllMorphs:behind: (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>addAllMorphs:behind: (in category 'submorphs-add/remove') ----- addAllMorphs: aCollection behind: anotherMorph ^self privateAddAllMorphs: aCollection atIndex: (submorphs indexOf: anotherMorph) + 1! Item was changed: + ----- Method: Morph>>addAllMorphs:inFrontOf: (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>addAllMorphs:inFrontOf: (in category 'submorphs-add/remove') ----- addAllMorphs: aCollection inFrontOf: anotherMorph ^self privateAddAllMorphs: aCollection atIndex: ((submorphs indexOf: anotherMorph) max: 1)! Item was changed: + ----- Method: Morph>>addAllMorphsBack: (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>addAllMorphsBack: (in category 'submorphs-add/remove') ----- addAllMorphsBack: aCollection ^self privateAddAllMorphs: aCollection atIndex: submorphs size + 1! Item was added: + ----- Method: Morph>>addAllMorphsBackInLayers: (in category 'submorphs - layers') ----- + addAllMorphsBackInLayers: morphs + + morphs do: [:morph | self addMorphBackInLayer: morph].! Item was changed: + ----- Method: Morph>>addAllMorphsFront: (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>addAllMorphsFront: (in category 'submorphs-add/remove') ----- addAllMorphsFront: aCollection ^self privateAddAllMorphs: aCollection atIndex: 1! Item was added: + ----- Method: Morph>>addAllMorphsFrontInLayers: (in category 'submorphs - layers') ----- + addAllMorphsFrontInLayers: morphs + + morphs do: [:morph | self addMorphFrontInLayer: morph].! Item was added: + ----- Method: Morph>>addAllMorphsInLayers: (in category 'submorphs - layers') ----- + addAllMorphsInLayers: morphs + + ^self addAllMorphsBackInLayers: morphs! Item was changed: + ----- Method: Morph>>addMorph: (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>addMorph: (in category 'submorphs-add/remove') ----- addMorph: aMorph self addMorphFront: aMorph.! Item was changed: + ----- Method: Morph>>addMorph:after: (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>addMorph:after: (in category 'submorphs-add/remove') ----- addMorph: newMorph after: aMorph ^self addMorph: newMorph behind: aMorph! Item was changed: + ----- Method: Morph>>addMorph:asElementNumber: (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>addMorph:asElementNumber: (in category 'submorphs-add/remove') ----- addMorph: aMorph asElementNumber: aNumber - "Add the given morph so that it becomes the aNumber'th element of my submorph list. If aMorph is already one of my submorphs, reposition it" + self flag: #deprecated. + ^ self addMorph: aMorph atIndex: aNumber! - (submorphs includes: aMorph) ifTrue: - [aMorph privateDelete]. - (aNumber <= submorphs size) - ifTrue: - [self addMorph: aMorph inFrontOf: (submorphs at: aNumber)] - ifFalse: - [self addMorphBack: aMorph] - ! Item was added: + ----- Method: Morph>>addMorph:atIndex: (in category 'submorphs - add/remove') ----- + addMorph: aMorph atIndex: aNumber + "Add the given morph so that it becomes the aNumber'th element of my submorph list. If aMorph is already one of my submorphs, reposition it." + + (submorphs includes: aMorph) ifTrue: + [aMorph privateDelete]. + (aNumber <= submorphs size) + ifTrue: + [self addMorph: aMorph inFrontOf: (submorphs at: aNumber)] + ifFalse: + [self addMorphBack: aMorph].! Item was changed: + ----- Method: Morph>>addMorph:behind: (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>addMorph:behind: (in category 'submorphs-add/remove') ----- addMorph: newMorph behind: aMorph "Add a morph to the list of submorphs behind the specified morph" ^self privateAddMorph: newMorph atIndex: (submorphs indexOf: aMorph) + 1. ! Item was changed: + ----- Method: Morph>>addMorph:fullFrame: (in category 'submorphs - misc') ----- - ----- Method: Morph>>addMorph:fullFrame: (in category 'submorphs-add/remove') ----- addMorph: aMorph fullFrame: aLayoutFrame aMorph layoutFrame: aLayoutFrame. aMorph hResizing: #spaceFill; vResizing: #spaceFill. self addMorph: aMorph. ! Item was changed: + ----- Method: Morph>>addMorph:inFrontOf: (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>addMorph:inFrontOf: (in category 'submorphs-add/remove') ----- addMorph: newMorph inFrontOf: aMorph "Add a morph to the list of submorphs in front of the specified morph" ^self privateAddMorph: newMorph atIndex: ((submorphs indexOf: aMorph) max: 1).! Item was changed: + ----- Method: Morph>>addMorphBack: (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>addMorphBack: (in category 'submorphs-add/remove') ----- addMorphBack: aMorph ^self privateAddMorph: aMorph atIndex: submorphs size+1! Item was added: + ----- Method: Morph>>addMorphBackInLayer: (in category 'submorphs - layers') ----- + addMorphBackInLayer: aMorph + "Note that we do not use #addMorph:, #addMorphBack:, #addMorphFront:, or any non-layer derivatives so that subclasses can safely overwrite those protocols and delegate to here." + + | targetLayer layerHere | + targetLayer := aMorph morphicLayerNumber. + + submorphs "frontmost to backmost" withIndexDo: [ :each :index | + layerHere := each morphicLayerNumber. + "An indirect match (<) indicates the back of the target layer." + targetLayer < layerHere ifTrue: [ + ^ self privateAddMorph: aMorph atIndex: index]]. + + ^ self privateAddMorph: aMorph atIndex: submorphs size + 1 + ! Item was changed: + ----- Method: Morph>>addMorphCentered: (in category 'submorphs - misc') ----- - ----- Method: Morph>>addMorphCentered: (in category 'submorphs-add/remove') ----- addMorphCentered: aMorph aMorph position: bounds center - (aMorph extent // 2). self addMorphFront: aMorph. ! Item was changed: + ----- Method: Morph>>addMorphFront: (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>addMorphFront: (in category 'submorphs-add/remove') ----- addMorphFront: aMorph ^self privateAddMorph: aMorph atIndex: 1! Item was changed: + ----- Method: Morph>>addMorphFront:fromWorldPosition: (in category 'submorphs - misc') ----- - ----- Method: Morph>>addMorphFront:fromWorldPosition: (in category 'submorphs-add/remove') ----- addMorphFront: aMorph fromWorldPosition: wp self addMorphFront: aMorph. aMorph position: (self transformFromWorld globalPointToLocal: wp)! Item was changed: + ----- Method: Morph>>addMorphFrontFromWorldPosition: (in category 'submorphs - misc') ----- - ----- Method: Morph>>addMorphFrontFromWorldPosition: (in category 'submorphs-add/remove') ----- addMorphFrontFromWorldPosition: aMorph ^self addMorphFront: aMorph fromWorldPosition: aMorph positionInWorld.! Item was added: + ----- Method: Morph>>addMorphFrontInLayer: (in category 'submorphs - layers') ----- + addMorphFrontInLayer: aMorph + "Note that we do not use #addMorph:, #addMorphBack:, #addMorphFront:, or any non-layer derivatives so that subclasses can safely overwrite those protocols and delegate to here." + + | targetLayer layerHere | + targetLayer := aMorph morphicLayerNumber. + + submorphs "frontmost to backmost" withIndexDo: [:each :index | + layerHere := each morphicLayerNumber. + "A direct match (=) indicates the front of the target layer." + targetLayer <= layerHere ifTrue: [ + ^ self privateAddMorph: aMorph atIndex: index]]. + + ^ self privateAddMorph: aMorph atIndex: submorphs size + 1! Item was removed: - ----- Method: Morph>>addMorphInFrontOfLayer: (in category 'WiW support') ----- - addMorphInFrontOfLayer: aMorph - - | targetLayer | - - targetLayer := aMorph morphicLayerNumberWithin: self. - submorphs do: [ :each | | layerHere | - each == aMorph ifTrue: [^self]. - layerHere := each morphicLayerNumberWithin: self. - "the <= is the difference - it insures we go to the front of our layer" - targetLayer <= layerHere ifTrue: [ - ^self addMorph: aMorph inFrontOf: each - ]. - ]. - self addMorphBack: aMorph. - ! Item was changed: + ----- Method: Morph>>addMorphInLayer: (in category 'submorphs - layers') ----- - ----- Method: Morph>>addMorphInLayer: (in category 'WiW support') ----- addMorphInLayer: aMorph + ^ self addMorphBackInLayer: aMorph! - submorphs do: [ :each | - each == aMorph ifTrue: [^self]. - aMorph morphicLayerNumber < each morphicLayerNumber ifTrue: [ - ^self addMorph: aMorph inFrontOf: each - ]. - ]. - self addMorphBack: aMorph - ! Item was changed: + ----- Method: Morph>>addMorphNearBack: (in category 'submorphs - misc') ----- - ----- Method: Morph>>addMorphNearBack: (in category 'submorphs-add/remove') ----- addMorphNearBack: aMorph | bg | (submorphs notEmpty and: [submorphs last mustBeBackmost]) ifTrue: [bg := submorphs last. bg privateDelete]. self addMorphBack: aMorph. bg ifNotNil: [self addMorphBack: bg]! Item was changed: + ----- Method: Morph>>allKnownNames (in category 'submorphs - accessing') ----- - ----- Method: Morph>>allKnownNames (in category 'submorphs-accessing') ----- allKnownNames "Return a list of all known names based on the scope of the receiver. Does not include the name of the receiver itself. Items in parts bins are excluded. Reimplementors (q.v.) can extend the list" ^ Array streamContents: [:s | self allSubmorphNamesDo: [:n | s nextPut: n]] ! Item was changed: + ----- Method: Morph>>allMorphs (in category 'submorphs - accessing') ----- - ----- Method: Morph>>allMorphs (in category 'submorphs-accessing') ----- allMorphs "Return a collection containing all morphs in this composite morph (including the receiver)." | all | all := OrderedCollection new: 100. self allMorphsDo: [: m | all add: m]. ^ all! Item was changed: + ----- Method: Morph>>allMorphsDo: (in category 'submorphs - enumerating') ----- - ----- Method: Morph>>allMorphsDo: (in category 'submorphs-accessing') ----- allMorphsDo: aBlock "Evaluate the given block for all morphs in this composite morph (including the receiver)." submorphs do: [:m | m allMorphsDo: aBlock]. aBlock value: self! Item was changed: + ----- Method: Morph>>allMorphsWithPlayersDo: (in category 'submorphs - misc') ----- - ----- Method: Morph>>allMorphsWithPlayersDo: (in category 'submorphs-add/remove') ----- allMorphsWithPlayersDo: aTwoArgumentBlock "Evaluate the given block for all morphs in this composite morph that have non-nil players. Also evaluate the block for the receiver if it has a player." submorphs do: [:m | m allMorphsWithPlayersDo: aTwoArgumentBlock ]. self playerRepresented ifNotNil: [ :p | aTwoArgumentBlock value: self value: p ]. ! Item was changed: + ----- Method: Morph>>allNonSubmorphMorphs (in category 'submorphs - misc') ----- - ----- Method: Morph>>allNonSubmorphMorphs (in category 'submorphs-accessing') ----- allNonSubmorphMorphs "Return a collection containing all morphs in this morph which are not currently in the submorph containment hierarchy (put in primarily for bookmorphs)" ^ OrderedCollection new! Item was changed: + ----- Method: Morph>>allSubmorphNamesDo: (in category 'submorphs - enumerating') ----- - ----- Method: Morph>>allSubmorphNamesDo: (in category 'submorphs-accessing') ----- allSubmorphNamesDo: nameBlock "Return a list of all known names of submorphs and nested submorphs of the receiver, based on the scope of the receiver. Items in parts bins are excluded" self isPartsBin ifTrue: [^ self]. "Don't report names from parts bins" self submorphsDo: [:m | m knownName ifNotNil: [:n | nameBlock value: n]. m allSubmorphNamesDo: nameBlock]. ! Item was changed: ----- Method: Morph>>beFlap: (in category 'accessing') ----- beFlap: aBool "Mark the receiver with the #flap property, or unmark it" aBool ifTrue: [self setProperty: #flap toValue: true. self disableLayout: true. self hResizing: #rigid. + self vResizing: #rigid. + self morphicLayerNumber: self class navigatorLayer] - self vResizing: #rigid] ifFalse: [self removeProperty: #flap. + self disableLayout: false. + self morphicLayerNumber: nil]! - self disableLayout: false]! Item was changed: + ----- Method: Morph>>comeToFront (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>comeToFront (in category 'submorphs-add/remove') ----- comeToFront | outerMorph | outerMorph := self topRendererOrSelf. (outerMorph owner isNil or: [outerMorph owner hasSubmorphs not]) ifTrue: [^self]. outerMorph owner firstSubmorph == outerMorph ifFalse: [outerMorph owner addMorphFront: outerMorph]! Item was changed: + ----- Method: Morph>>copyWithoutSubmorph: (in category 'submorphs - misc') ----- - ----- Method: Morph>>copyWithoutSubmorph: (in category 'submorphs-add/remove') ----- copyWithoutSubmorph: sub "Needed to get a morph to draw without one of its submorphs. NOTE: This must be thrown away immediately after use." ^ self shallowCopy privateSubmorphs: (submorphs copyWithout: sub)! Item was changed: + ----- Method: Morph>>delete (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>delete (in category 'submorphs-add/remove') ----- delete "Remove the receiver as a submorph of its owner and make its new owner be nil." | oldWorld | self removeHalo. (oldWorld := self world) ifNotNil: [ self disableSubmorphFocusForHand: self activeHand. self activeHand releaseKeyboardFocus: self; releaseMouseFocus: self]. owner ifNotNil: [ self privateDelete. "remove from world" self player ifNotNil: [:player | oldWorld ifNotNil: [ player noteDeletionOf: self fromWorld: oldWorld]]].! Item was changed: + ----- Method: Morph>>deleteDockingBars (in category 'submorphs - misc') ----- - ----- Method: Morph>>deleteDockingBars (in category 'submorphs-add/remove') ----- deleteDockingBars "Delete the receiver's docking bars" self dockingBars do: [:each | each delete]! Item was changed: + ----- Method: Morph>>deleteSubmorphsWithProperty: (in category 'submorphs - misc') ----- - ----- Method: Morph>>deleteSubmorphsWithProperty: (in category 'submorphs-add/remove') ----- deleteSubmorphsWithProperty: aSymbol submorphs copy do: [:m | (m hasProperty: aSymbol) ifTrue: [m delete]]! Item was changed: + ----- Method: Morph>>deleteUnlessHasFocus (in category 'submorphs - misc') ----- - ----- Method: Morph>>deleteUnlessHasFocus (in category 'submorphs-add/remove') ----- deleteUnlessHasFocus "Runs on a step timer because we cannot be guaranteed to get focus change events." (self currentHand keyboardFocus ~= self and: [ self isInWorld ]) ifTrue: [ self stopSteppingSelector: #deleteUnlessHasFocus ; delete ]! Item was changed: + ----- Method: Morph>>dismissViaHalo (in category 'submorphs - misc') ----- - ----- Method: Morph>>dismissViaHalo (in category 'submorphs-add/remove') ----- dismissViaHalo "The user has clicked in the delete halo-handle. This provides a hook in case some concomitant action should be taken, or if the particular morph is not one which should be put in the trash can, for example." | cmd | self setProperty: #lastPosition toValue: self positionInWorld. self dismissMorph. TrashCanMorph preserveTrash ifTrue: [ TrashCanMorph slideDismissalsToTrash ifTrue:[self slideToTrash: nil] ifFalse:[TrashCanMorph moveToTrash: self]. ]. cmd := Command new cmdWording: 'dismiss ' translated, self externalName. cmd undoTarget: Project current world selector: #reintroduceIntoWorld: argument: self. cmd redoTarget: Project current world selector: #onceAgainDismiss: argument: self. Project current world rememberCommand: cmd.! Item was changed: + ----- Method: Morph>>dockingBars (in category 'submorphs - misc') ----- - ----- Method: Morph>>dockingBars (in category 'submorphs-accessing') ----- dockingBars "Answer the receiver's dockingBars" ^ self submorphs select: [:each | each isDockingBar] ! Item was changed: + ----- Method: Morph>>findA: (in category 'submorphs - misc') ----- - ----- Method: Morph>>findA: (in category 'submorphs-accessing') ----- findA: aClass "Return the first submorph of the receiver that is descended from the given class. Return nil if there is no such submorph. Clients of this code should always check for a nil return value so that the code will be robust if the user takes the morph apart." ^self submorphs detect: [:p | p isKindOf: aClass] ifNone: [nil]! Item was changed: + ----- Method: Morph>>findDeepSubmorphThat:ifAbsent: (in category 'submorphs - misc') ----- - ----- Method: Morph>>findDeepSubmorphThat:ifAbsent: (in category 'submorphs-accessing') ----- findDeepSubmorphThat: block1 ifAbsent: block2 self allMorphsDo: [:m | (block1 value: m) == true ifTrue: [^ m]]. ^ block2 value! Item was changed: + ----- Method: Morph>>findDeeplyA: (in category 'submorphs - misc') ----- - ----- Method: Morph>>findDeeplyA: (in category 'submorphs-accessing') ----- findDeeplyA: aClass "Return a morph in the submorph tree of the receiver that is descended from the given class. Return nil if there is no such morph. Clients of this code should always check for a nil return value so that the code will be robust if the user takes the morph apart." ^ (self allMorphs copyWithout: self) detect: [:p | p isKindOf: aClass] ifNone: [nil]! Item was changed: + ----- Method: Morph>>findSubmorphBinary: (in category 'submorphs - misc') ----- - ----- Method: Morph>>findSubmorphBinary: (in category 'submorphs-accessing') ----- findSubmorphBinary: aBlock "Use binary search for finding a specific submorph of the receiver. Caller must be certain that the ordering holds for the submorphs." ^submorphs findBinary: aBlock ifNone:[nil].! Item was changed: + ----- Method: Morph>>firstSubmorph (in category 'submorphs - accessing') ----- - ----- Method: Morph>>firstSubmorph (in category 'submorphs-accessing') ----- firstSubmorph ^submorphs first! Item was changed: + ----- Method: Morph>>goBehind (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>goBehind (in category 'submorphs-add/remove') ----- goBehind "Move the receiver to bottom z-order." | topRend | topRend := self topRendererOrSelf. topRend owner ifNotNil: [:own | own addMorphNearBack: topRend] ! Item was changed: + ----- Method: Morph>>hasSubmorphWithProperty: (in category 'submorphs - misc') ----- - ----- Method: Morph>>hasSubmorphWithProperty: (in category 'submorphs-accessing') ----- hasSubmorphWithProperty: aSymbol ^submorphs anySatisfy: [:m | m hasProperty: aSymbol]! Item was changed: + ----- Method: Morph>>hasSubmorphs (in category 'submorphs - testing') ----- - ----- Method: Morph>>hasSubmorphs (in category 'submorphs-accessing') ----- hasSubmorphs ^submorphs notEmpty! Item was changed: + ----- Method: Morph>>indexOfMorphAbove: (in category 'submorphs - misc') ----- - ----- Method: Morph>>indexOfMorphAbove: (in category 'submorphs-accessing') ----- indexOfMorphAbove: aPoint "Return index of lowest morph whose bottom is above aPoint. Will return 0 if the first morph is not above aPoint." submorphs withIndexDo: [:mm :ii | mm fullBounds bottom >= aPoint y ifTrue: [^ ii - 1]]. ^ submorphs size! Item was changed: + ----- Method: Morph>>intoWorld: (in category 'submorphs - callbacks') ----- - ----- Method: Morph>>intoWorld: (in category 'initialization') ----- intoWorld: aWorld "The receiver has just appeared in a new world. Note: * aWorld can be nil (due to optimizations in other places) * owner is already set * owner's submorphs may not include receiver yet. Important: Keep this method fast - it is run whenever morphs are added." aWorld ifNil:[^self]. self wantsSteps ifTrue:[aWorld startStepping: self]. self submorphsDo:[:m| m intoWorld: aWorld]. ! Item was changed: + ----- Method: Morph>>lastSubmorph (in category 'submorphs - accessing') ----- - ----- Method: Morph>>lastSubmorph (in category 'submorphs-accessing') ----- lastSubmorph ^submorphs last! Item was changed: + ----- Method: Morph>>mainDockingBars (in category 'submorphs - misc') ----- - ----- Method: Morph>>mainDockingBars (in category 'submorphs-accessing') ----- mainDockingBars "Answer the receiver's main dockingBars" ^ self dockingBars select: [:each | each hasProperty: #mainDockingBarTimeStamp]! Item was changed: + ----- Method: Morph>>morphicLayerNumber (in category 'submorphs - layers') ----- - ----- Method: Morph>>morphicLayerNumber (in category 'WiW support') ----- morphicLayerNumber + "Hint the preferred position in the owner's list of submorphs. Smaller layer numbers are in front of larger ones. If not specified, go up the owner chain if possible." + + ^ self + valueOfProperty: #morphicLayerNumber + ifAbsent: [self topRendererOrSelf owner + ifNil: [self class defaultLayer] + ifNotNil: [:m | m morphicLayerNumber]]! - - "helpful for insuring some morphs always appear in front of or behind others. - smaller numbers are in front" - - ^(owner isNil or: [owner isWorldMorph]) ifTrue: [ - self valueOfProperty: #morphicLayerNumber ifAbsent: [100] - ] ifFalse: [ - owner morphicLayerNumber - ]. - - "leave lots of room for special things"! Item was added: + ----- Method: Morph>>morphicLayerNumber: (in category 'submorphs - layers') ----- + morphicLayerNumber: aNumber + "Changes the receiver's layer. If it is already part of a hierarchy, make sure that the owner's submorphs are in layer order. This can happen if you mix the use of, for example, #addMorph: and #addMorphInLayer:." + + self setProperty: #morphicLayerNumber toValue: aNumber. + self owner ifNotNil: [:o | o reorderSubmorphsInLayers].! Item was removed: - ----- Method: Morph>>morphicLayerNumberWithin: (in category 'WiW support') ----- - morphicLayerNumberWithin: anOwner - - "helpful for insuring some morphs always appear in front of or behind others. - smaller numbers are in front" - - ^(owner isNil or: [owner isWorldMorph or: [anOwner == owner]]) ifTrue: [ - self valueOfProperty: #morphicLayerNumber ifAbsent: [100] - ] ifFalse: [ - owner morphicLayerNumber - ]. - - "leave lots of room for special things"! Item was changed: + ----- Method: Morph>>morphsAt: (in category 'submorphs - accessing') ----- - ----- Method: Morph>>morphsAt: (in category 'submorphs-accessing') ----- morphsAt: aPoint "Return a collection of all morphs in this morph structure that contain the given point, possibly including the receiver itself. The order is deepest embedding first." ^self morphsAt: aPoint unlocked: false! Item was changed: + ----- Method: Morph>>morphsAt:behind:unlocked: (in category 'submorphs - misc') ----- - ----- Method: Morph>>morphsAt:behind:unlocked: (in category 'submorphs-accessing') ----- morphsAt: aPoint behind: aMorph unlocked: aBool "Return all morphs at aPoint that are behind frontMorph; if aBool is true return only unlocked, visible morphs." | isBack all tfm | all := (aMorph isNil or: [owner isNil]) ifTrue: ["Traverse down" (self fullBounds containsPoint: aPoint) ifFalse: [^#()]. (aBool and: [self isLocked or: [self visible not]]) ifTrue: [^#()]. nil] ifFalse: ["Traverse up" tfm := self transformedFrom: owner. all := owner morphsAt: (tfm localPointToGlobal: aPoint) behind: self unlocked: aBool. WriteStream with: all]. isBack := aMorph isNil. self submorphsDo: [:m | | found | isBack ifTrue: [tfm := m transformedFrom: self. found := m morphsAt: (tfm globalPointToLocal: aPoint) behind: nil unlocked: aBool. found notEmpty ifTrue: [all ifNil: [all := WriteStream on: #()]. all nextPutAll: found]]. m == aMorph ifTrue: [isBack := true]]. (isBack and: [self containsPoint: aPoint]) ifTrue: [all ifNil: [^Array with: self]. all nextPut: self]. ^all ifNil: [#()] ifNotNil: [all contents]! Item was changed: + ----- Method: Morph>>morphsAt:unlocked: (in category 'submorphs - accessing') ----- - ----- Method: Morph>>morphsAt:unlocked: (in category 'submorphs-accessing') ----- morphsAt: aPoint unlocked: aBool "Return a collection of all morphs in this morph structure that contain the given point, possibly including the receiver itself. The order is deepest embedding first." | mList | mList := WriteStream on: #(). self morphsAt: aPoint unlocked: aBool do:[:m| mList nextPut: m]. ^mList contents! Item was changed: + ----- Method: Morph>>morphsAt:unlocked:do: (in category 'submorphs - enumerating') ----- - ----- Method: Morph>>morphsAt:unlocked:do: (in category 'submorphs-accessing') ----- morphsAt: aPoint unlocked: aBool do: aBlock "Evaluate aBlock with all the morphs starting at the receiver which appear at aPoint. If aBool is true take only visible, unlocked morphs into account." (self fullBounds containsPoint: aPoint) ifFalse:[^self]. (aBool and:[self isLocked or:[self visible not]]) ifTrue:[^self]. self submorphsDo:[:m| | tfm | tfm := m transformedFrom: self. m morphsAt: (tfm globalPointToLocal: aPoint) unlocked: aBool do: aBlock]. (self containsPoint: aPoint) ifTrue:[aBlock value: self].! Item was changed: + ----- Method: Morph>>morphsInFrontOf:overlapping:do: (in category 'submorphs - misc') ----- - ----- Method: Morph>>morphsInFrontOf:overlapping:do: (in category 'submorphs-accessing') ----- morphsInFrontOf: someMorph overlapping: aRectangle do: aBlock "Evaluate aBlock with all top-level morphs in front of someMorph that overlap with the given rectangle. someMorph is either an immediate child of the receiver or nil (in which case all submorphs of the receiver are enumerated)." self submorphsDo:[:m| m == someMorph ifTrue:["Try getting out quickly" owner ifNil:[^self]. ^owner morphsInFrontOf: self overlapping: aRectangle do: aBlock]. (m fullBoundsInWorld intersects: aRectangle) ifTrue:[aBlock value: m]]. owner ifNil:[^self]. ^owner morphsInFrontOf: self overlapping: aRectangle do: aBlock.! Item was changed: + ----- Method: Morph>>morphsInFrontOverlapping: (in category 'submorphs - misc') ----- - ----- Method: Morph>>morphsInFrontOverlapping: (in category 'submorphs-accessing') ----- morphsInFrontOverlapping: aRectangle "Return all top-level morphs in front of someMorph that overlap with the given rectangle." | morphList | morphList := WriteStream on: Array new. self morphsInFrontOf: nil overlapping: aRectangle do:[:m | morphList nextPut: m]. ^morphList contents! Item was changed: + ----- Method: Morph>>morphsInFrontOverlapping:do: (in category 'submorphs - misc') ----- - ----- Method: Morph>>morphsInFrontOverlapping:do: (in category 'submorphs-accessing') ----- morphsInFrontOverlapping: aRectangle do: aBlock "Evaluate aBlock with all top-level morphs in front of someMorph that overlap with the given rectangle." ^self morphsInFrontOf: nil overlapping: aRectangle do: aBlock! Item was changed: + ----- Method: Morph>>noteNewOwner: (in category 'submorphs - callbacks') ----- - ----- Method: Morph>>noteNewOwner: (in category 'submorphs-accessing') ----- noteNewOwner: aMorph "I have just been added as a submorph of aMorph"! Item was changed: + ----- Method: Morph>>outOfWorld: (in category 'submorphs - callbacks') ----- - ----- Method: Morph>>outOfWorld: (in category 'initialization') ----- outOfWorld: aWorld "The receiver has just appeared in a new world. Notes: * aWorld can be nil (due to optimizations in other places) * owner is still valid Important: Keep this method fast - it is run whenever morphs are removed." aWorld ifNil:[^self]. "ar 1/31/2001: We could explicitly stop stepping the receiver here but for the sake of speed I'm for now relying on the lazy machinery in the world itself." "aWorld stopStepping: self." self submorphsDo:[:m| m outOfWorld: aWorld]. ! Item was changed: + ----- Method: Morph>>privateDelete (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>privateDelete (in category 'submorphs-add/remove') ----- privateDelete "Remove the receiver as a submorph of its owner" owner ifNotNil:[owner removeMorph: self].! Item was changed: + ----- Method: Morph>>removeAllMorphs (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>removeAllMorphs (in category 'submorphs-add/remove') ----- removeAllMorphs | oldMorphs myWorld | myWorld := self world. (fullBounds notNil or: [ myWorld notNil ]) ifTrue: [ self invalidRect: self fullBounds ]. submorphs do: [ : m | myWorld ifNotNil: [ m outOfWorld: myWorld ]. m privateOwner: nil ]. oldMorphs := submorphs. submorphs := Array empty. oldMorphs do: [ : m | self removedMorph: m ]. self layoutChanged! Item was changed: + ----- Method: Morph>>removeAllMorphsIn: (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>removeAllMorphsIn: (in category 'submorphs-add/remove') ----- removeAllMorphsIn: aCollection "greatly speeds up the removal of *lots* of submorphs" | set myWorld | set := IdentitySet new: aCollection size * 4 // 3. aCollection do: [:each | each owner == self ifTrue: [ set add: each]]. myWorld := self world. (fullBounds notNil or:[myWorld notNil]) ifTrue:[self invalidRect: self fullBounds]. set do: [:m | myWorld ifNotNil: [ m outOfWorld: myWorld ]. m privateOwner: nil]. submorphs := submorphs reject: [ :each | set includes: each]. set do: [ :m | self removedMorph: m ]. self layoutChanged. ! Item was changed: ----- Method: Morph>>removeHalo (in category 'halos and balloon help') ----- removeHalo "remove the surrounding halo (if any)" + self halo ifNotNil: [ self currentHand removeHalo ]! - self halo ifNotNil: [ self primaryHand removeHalo ]! Item was changed: + ----- Method: Morph>>removeMorph: (in category 'submorphs - add/remove') ----- - ----- Method: Morph>>removeMorph: (in category 'submorphs-add/remove') ----- removeMorph: aMorph "Remove the given morph from my submorphs" | aWorld | aMorph owner == self ifFalse:[^self]. aWorld := self world. aWorld ifNotNil:[ aMorph outOfWorld: aWorld. self privateInvalidateMorph: aMorph. ]. self privateRemove: aMorph. aMorph privateOwner: nil. self removedMorph: aMorph. ! Item was changed: + ----- Method: Morph>>removedMorph: (in category 'submorphs - callbacks') ----- - ----- Method: Morph>>removedMorph: (in category 'submorphs-add/remove') ----- removedMorph: aMorph "Notify the receiver that aMorph was just removed from its children" ! Item was added: + ----- Method: Morph>>reorderSubmorphsInLayers (in category 'submorphs - layers') ----- + reorderSubmorphsInLayers + "Update submorph order to match their respective layer numbers." + + ((1 to: submorphs size - 1) allSatisfy: [:index | + (submorphs at: index) morphicLayerNumber + <= (submorphs at: index + 1) morphicLayerNumber]) + ifTrue: [^ self "No reordering needed"]. + + self changed. + submorphs := submorphs sorted: [:m1 :m2 | + m1 morphicLayerNumber <= m2 morphicLayerNumber]. + self layoutChanged; changed.! Item was changed: + ----- Method: Morph>>replaceSubmorph:by: (in category 'submorphs - misc') ----- - ----- Method: Morph>>replaceSubmorph:by: (in category 'submorphs-add/remove') ----- replaceSubmorph: oldMorph by: newMorph | index itsPosition w | oldMorph stopStepping. itsPosition := oldMorph referencePositionInWorld. index := submorphs indexOf: oldMorph. oldMorph privateDelete. self privateAddMorph: newMorph atIndex: index. newMorph referencePositionInWorld: itsPosition. (w := newMorph world) ifNotNil: [w startSteppingSubmorphsOf: newMorph]! Item was changed: + ----- Method: Morph>>rootMorphsAt: (in category 'submorphs - misc') ----- - ----- Method: Morph>>rootMorphsAt: (in category 'submorphs-accessing') ----- rootMorphsAt: aPoint "Return the list of root morphs containing the given point, excluding the receiver. ar 11/8/1999: Moved into morph for an incredibly ugly hack in 3D worlds" self flag: #arNote. "check this at some point" ^ self submorphs select: [:m | (m fullContainsPoint: aPoint) and: [m isLocked not]]! Item was changed: + ----- Method: Morph>>rootMorphsAtGlobal: (in category 'submorphs - misc') ----- - ----- Method: Morph>>rootMorphsAtGlobal: (in category 'submorphs-accessing') ----- rootMorphsAtGlobal: aPoint "Return the list of root morphs containing the given point, excluding the receiver. ar 11/8/1999: Moved into morph for an incredibly ugly hack in 3D worlds" ^ self rootMorphsAt: (self pointFromWorld: aPoint)! Item was changed: + ----- Method: Morph>>shuffleSubmorphs (in category 'submorphs - misc') ----- - ----- Method: Morph>>shuffleSubmorphs (in category 'submorphs-accessing') ----- shuffleSubmorphs "Randomly shuffle the order of my submorphs. Don't call this method lightly!!" | bg | self invalidRect: self fullBounds. (submorphs notEmpty and: [submorphs last mustBeBackmost]) ifTrue: [bg := submorphs last. bg privateDelete]. submorphs := submorphs shuffled. bg ifNotNil: [self addMorphBack: bg]. self layoutChanged! Item was changed: + ----- Method: Morph>>submorphAfter (in category 'submorphs - misc') ----- - ----- Method: Morph>>submorphAfter (in category 'submorphs-accessing') ----- submorphAfter "Return the submorph after (behind) me, or nil" | ii | owner ifNil: [^ nil]. ^ (ii := owner submorphIndexOf: self) = owner submorphs size ifTrue: [nil] ifFalse: [owner submorphs at: ii+1]. ! Item was changed: + ----- Method: Morph>>submorphBefore (in category 'submorphs - misc') ----- - ----- Method: Morph>>submorphBefore (in category 'submorphs-accessing') ----- submorphBefore "Return the submorph after (behind) me, or nil" | ii | owner ifNil: [^ nil]. ^ (ii := owner submorphIndexOf: self) = 1 ifTrue: [nil] ifFalse: [owner submorphs at: ii-1]. ! Item was changed: + ----- Method: Morph>>submorphCount (in category 'submorphs - accessing') ----- - ----- Method: Morph>>submorphCount (in category 'submorphs-accessing') ----- submorphCount ^ submorphs size! Item was changed: + ----- Method: Morph>>submorphIndexOf: (in category 'submorphs - accessing') ----- - ----- Method: Morph>>submorphIndexOf: (in category 'submorphs-add/remove') ----- submorphIndexOf: aMorph "Assuming aMorph to be one of my submorphs, answer where it occurs in my submorph list" ^ submorphs indexOf: aMorph ifAbsent: [nil]! Item was changed: + ----- Method: Morph>>submorphNamed: (in category 'submorphs - accessing') ----- - ----- Method: Morph>>submorphNamed: (in category 'submorphs-accessing') ----- submorphNamed: aName ^ self submorphNamed: aName ifNone: [nil]! Item was changed: + ----- Method: Morph>>submorphNamed:ifNone: (in category 'submorphs - accessing') ----- - ----- Method: Morph>>submorphNamed:ifNone: (in category 'submorphs-accessing') ----- submorphNamed: aName ifNone: aBlock "Find the first submorph with this name, or a button with an action selector of that name" self submorphs do: [:p | p knownName = aName ifTrue: [^p]]. self submorphs do: [:button | | sub args | (button respondsTo: #actionSelector) ifTrue: [button actionSelector == aName ifTrue: [^button]]. ((button respondsTo: #arguments) and: [(args := button arguments) notNil]) ifTrue: [(args at: 2 ifAbsent: [nil]) == aName ifTrue: [^button]]. (button isAlignmentMorph) ifTrue: [(sub := button submorphNamed: aName ifNone: [nil]) ifNotNil: [^sub]]]. ^aBlock value! Item was changed: + ----- Method: Morph>>submorphOfClass: (in category 'submorphs - misc') ----- - ----- Method: Morph>>submorphOfClass: (in category 'submorphs-accessing') ----- submorphOfClass: aClass ^self findA: aClass! Item was changed: + ----- Method: Morph>>submorphThat:ifNone: (in category 'submorphs - accessing') ----- - ----- Method: Morph>>submorphThat:ifNone: (in category 'submorphs-accessing') ----- submorphThat: block1 ifNone: block2 ^submorphs detect: block1 ifNone: block2 ! Item was changed: + ----- Method: Morph>>submorphWithProperty: (in category 'submorphs - misc') ----- - ----- Method: Morph>>submorphWithProperty: (in category 'submorphs-accessing') ----- submorphWithProperty: aSymbol ^ submorphs detect: [:aMorph | aMorph hasProperty: aSymbol] ifNone: [nil]! Item was changed: + ----- Method: Morph>>submorphs (in category 'submorphs - accessing') ----- - ----- Method: Morph>>submorphs (in category 'submorphs-accessing') ----- submorphs "This method returns my actual submorphs collection. Modifying the collection directly could be dangerous; make a copy if you need to alter it." ^ submorphs ! Item was changed: + ----- Method: Morph>>submorphsBehind:do: (in category 'submorphs - enumerating') ----- - ----- Method: Morph>>submorphsBehind:do: (in category 'submorphs-accessing') ----- submorphsBehind: aMorph do: aBlock | behind | behind := false. submorphs do: [:m | m == aMorph ifTrue: [behind := true] ifFalse: [behind ifTrue: [aBlock value: m]]]. ! Item was changed: + ----- Method: Morph>>submorphsDo: (in category 'submorphs - enumerating') ----- - ----- Method: Morph>>submorphsDo: (in category 'submorphs-accessing') ----- submorphsDo: aBlock submorphs do: aBlock! Item was changed: + ----- Method: Morph>>submorphsInFrontOf:do: (in category 'submorphs - enumerating') ----- - ----- Method: Morph>>submorphsInFrontOf:do: (in category 'submorphs-accessing') ----- submorphsInFrontOf: aMorph do: aBlock | behind | behind := false. submorphs do: [:m | m == aMorph ifTrue: [behind := true] ifFalse: [behind ifFalse: [aBlock value: m]]]. ! Item was changed: + ----- Method: Morph>>submorphsReverseDo: (in category 'submorphs - enumerating') ----- - ----- Method: Morph>>submorphsReverseDo: (in category 'submorphs-accessing') ----- submorphsReverseDo: aBlock submorphs reverseDo: aBlock.! Item was changed: + ----- Method: Morph>>submorphsSatisfying: (in category 'submorphs - accessing') ----- - ----- Method: Morph>>submorphsSatisfying: (in category 'submorphs-accessing') ----- submorphsSatisfying: aBlock ^ submorphs select: [:m | (aBlock value: m) == true]! Item was changed: + ----- Method: Morph>>wantsToBeTopmost (in category 'e-toy support') ----- - ----- Method: Morph>>wantsToBeTopmost (in category 'accessing') ----- wantsToBeTopmost "Answer if the receiver want to be one of the topmost objects in its owner" ^ self isFlapOrTab! Item was changed: + ----- Method: MorphicModel>>allKnownNames (in category 'submorphs - accessing') ----- - ----- Method: MorphicModel>>allKnownNames (in category 'submorphs-accessing') ----- allKnownNames "Return a list of all known names based on the scope of the receiver. If the receiver is a member of a uniclass, incorporate the original 1997 logic that queries the known names of the values of all the instance variables." | superNames | superNames := super allKnownNames. "gather them from submorph tree" ^self belongsToUniClass ifTrue: [superNames , (self instanceVariableValues select: [:e | e notNil and: [e knownName notNil]] thenCollect: [:e | e knownName])] ifFalse: [superNames]! Item was changed: + ----- Method: MorphicModel>>delete (in category 'submorphs - add/remove') ----- - ----- Method: MorphicModel>>delete (in category 'submorphs-add/remove') ----- delete (model isMorphicModel) ifFalse: [^super delete]. slotName ifNotNil: [(UIManager default confirm: 'Shall I remove the slot ' , slotName , ' along with all associated methods?') ifTrue: [(model class selectors select: [:s | s beginsWith: slotName]) do: [:s | model class removeSelector: s]. (model class instVarNames includes: slotName) ifTrue: [model class removeInstVarName: slotName]] ifFalse: [(UIManager default confirm: '...but should I at least dismiss this morph? [choose no to leave everything unchanged]') ifFalse: [^self]]]. super delete! Item was changed: ----- Method: NewBalloonMorph>>initialize (in category 'initialization') ----- initialize super initialize. self disableLayout: true. + self morphicLayerNumber: self class balloonLayer. self setDefaultParameters. textMorph := TextMorph new wrapFlag: false; lock; yourself. self addMorph: textMorph.! Item was removed: - ----- Method: NewBalloonMorph>>morphicLayerNumber (in category 'WiW support') ----- - morphicLayerNumber - - "helpful for insuring some morphs always appear in front of or behind others. - smaller numbers are in front" - - ^5 "Balloons are very front-like things"! Item was changed: + ----- Method: NewHandleMorph>>delete (in category 'submorphs - add/remove') ----- - ----- Method: NewHandleMorph>>delete (in category 'submorphs-add/remove') ----- delete hand ifNotNil:[ hand showTemporaryCursor: nil. ]. super delete.! Item was removed: - ----- Method: NewHandleMorph>>morphicLayerNumber (in category 'WiW support') ----- - morphicLayerNumber - - ^1 "handles are very front-like - e.g. the spawn reframe logic actually asks if the first submorph of the world is one of us before deciding to create one"! Item was changed: + ----- Method: PasteUpMorph>>addAllMorphs: (in category 'submorphs - add/remove') ----- - ----- Method: PasteUpMorph>>addAllMorphs: (in category 'submorphs-add/remove') ----- addAllMorphs: array super addAllMorphs: array. self isWorldMorph ifTrue: [array do: [:m | self startSteppingSubmorphsOf: m]]. ! Item was changed: + ----- Method: PasteUpMorph>>addMorphFront: (in category 'submorphs - add/remove') ----- - ----- Method: PasteUpMorph>>addMorphFront: (in category 'submorphs-add/remove') ----- addMorphFront: aMorph + "Overwritten to arrange submorphs in layers by default." + ^ self addMorphFrontInLayer: aMorph! - ^self addMorphInFrontOfLayer: aMorph - ! Item was changed: + ----- Method: PasteUpMorph>>allMorphsDo: (in category 'submorphs - accessing') ----- - ----- Method: PasteUpMorph>>allMorphsDo: (in category 'submorphs-accessing') ----- allMorphsDo: aBlock "Enumerate all morphs in the world, including those held in hands." super allMorphsDo: aBlock. self isWorldMorph ifTrue: [worldState handsReverseDo: [:h | h allMorphsDo: aBlock]]. ! Item was removed: - ----- Method: PasteUpMorph>>morphicLayerNumber (in category 'WiW support') ----- - morphicLayerNumber - - self isFlap ifTrue:[^26]. "As navigators" - ^super morphicLayerNumber.! Item was changed: + ----- Method: PasteUpMorph>>morphsInFrontOf:overlapping:do: (in category 'submorphs - accessing') ----- - ----- Method: PasteUpMorph>>morphsInFrontOf:overlapping:do: (in category 'submorphs-accessing') ----- morphsInFrontOf: someMorph overlapping: aRectangle do: aBlock "Include hands if the receiver is the World" self handsDo:[:m| m == someMorph ifTrue:["Try getting out quickly" owner ifNil:[^self]. ^owner morphsInFrontOf: self overlapping: aRectangle do: aBlock]. "The hand only overlaps if it's not the hardware cursor" m needsToBeDrawn ifTrue:[ (m fullBoundsInWorld intersects: aRectangle) ifTrue:[aBlock value: m]]]. ^super morphsInFrontOf: someMorph overlapping: aRectangle do: aBlock! Item was changed: + ----- Method: PluggableListMorph>>allSubmorphNamesDo: (in category 'submorphs - accessing') ----- - ----- Method: PluggableListMorph>>allSubmorphNamesDo: (in category 'submorphs-accessing') ----- allSubmorphNamesDo: nameBlock "Assume list morphs do not have named parts -- saves MUCH time" ^ self! Item was changed: + ----- Method: PluggableTextMorphWithModel>>delete (in category 'submorphs - add/remove') ----- - ----- Method: PluggableTextMorphWithModel>>delete (in category 'submorphs-add/remove') ----- delete "Delete the receiver. Since I have myself as a dependent, I need to remove it. which is odd in itself. Also, the release of dependents will seemingly not be done if the *container* of the receiver is deleted rather than the receiver itself, a further problem" self removeDependent: self. super delete! Item was changed: + ----- Method: ProjectViewMorph>>abandon (in category 'submorphs - add/remove') ----- - ----- Method: ProjectViewMorph>>abandon (in category 'submorphs-add/remove') ----- abandon "Home ViewMorph of project is going away." project := nil. super abandon. ! Item was changed: + ----- Method: SelectionMorph>>delete (in category 'submorphs - add/remove') ----- - ----- Method: SelectionMorph>>delete (in category 'submorphs-add/remove') ----- delete self setProperty: #deleting toValue: true. super delete. ! Item was changed: + ----- Method: SelectionMorph>>dismissViaHalo (in category 'submorphs - add/remove') ----- - ----- Method: SelectionMorph>>dismissViaHalo (in category 'submorphs-add/remove') ----- dismissViaHalo selectedItems do: [:m | m dismissViaHalo]. super dismissViaHalo. ! Item was changed: ----- Method: SelectionMorph>>initialize (in category 'initialization') ----- initialize "initialize the state of the receiver" super initialize. "" + self disableLayout: true. + self morphicLayerNumber: self class haloLayer + 1. - selectedItems := OrderedCollection new. itemsAlreadySelected := OrderedCollection new.! Item was removed: - ----- Method: SelectionMorph>>morphicLayerNumber (in category 'WiW support') ----- - morphicLayerNumber - "helpful for insuring some morphs always appear in front of or - behind others. smaller numbers are in front" - ^ 8! Item was changed: + ----- Method: SimpleButtonMorph>>actWhen (in category 'submorphs - add/remove') ----- - ----- Method: SimpleButtonMorph>>actWhen (in category 'submorphs-add/remove') ----- actWhen "acceptable symbols: #buttonDown, #buttonUp, and #whilePressed" ^ actWhen! Item was changed: + ----- Method: SimpleButtonMorph>>actWhen: (in category 'submorphs - add/remove') ----- - ----- Method: SimpleButtonMorph>>actWhen: (in category 'submorphs-add/remove') ----- actWhen: condition "Accepts symbols: #buttonDown, #buttonUp, and #whilePressed, #startDrag" actWhen := condition. actWhen == #startDrag ifFalse: [self on: #startDrag send: nil to: nil ] ifTrue:[self on: #startDrag send: #doButtonAction to: self].! Item was changed: + ----- Method: SimpleHaloMorph>>delete (in category 'submorphs - add/remove') ----- - ----- Method: SimpleHaloMorph>>delete (in category 'submorphs-add/remove') ----- delete self target hasHalo: false. super delete.! Item was changed: ----- Method: SimpleHaloMorph>>initialize (in category 'initialization') ----- initialize super initialize. + self morphicLayerNumber: self class haloLayer. "Each halo is a (kind of global) overlay that should not be bothered with the world's current layout policy. For example, a halo must match the target's bounds, which can be any inner part of the graphical hierarchy." self disableLayout: true.! Item was changed: + ----- Method: SystemProgressMorph>>dismissViaHalo (in category 'submorphs - add/remove') ----- - ----- Method: SystemProgressMorph>>dismissViaHalo (in category 'submorphs-add/remove') ----- dismissViaHalo self class reset! Item was changed: ----- Method: SystemProgressMorph>>initialize (in category 'initialization') ----- initialize super initialize. activeSlots := 0. bars := Array new: 10. labels := Array new: 10. lock := Semaphore forMutualExclusion. self setDefaultParameters; + morphicLayerNumber: self class progressLayer; - setProperty: #morphicLayerNumber toValue: self morphicLayerNumber; layoutPolicy: TableLayout new; listDirection: #topToBottom; cellPositioning: #topCenter; cellGap: 5; listCentering: #center; hResizing: #shrinkWrap; vResizing: #shrinkWrap; layoutInset: Inset; minWidth: 150! Item was removed: - ----- Method: SystemProgressMorph>>morphicLayerNumber (in category 'initialization') ----- - morphicLayerNumber - "progress morphs are behind menus and balloons, but in front of most other stuff" - ^self valueOfProperty: #morphicLayerNumber ifAbsent: [12]. - ! Item was changed: + ----- Method: TextMorph>>addMorphFront:fromWorldPosition: (in category 'submorphs - add/remove') ----- - ----- Method: TextMorph>>addMorphFront:fromWorldPosition: (in category 'submorphs-add/remove') ----- addMorphFront: aMorph fromWorldPosition: wp "Overridden for more specific re-layout and positioning" aMorph textAnchorProperties anchorLayout == #document ifFalse:[^ self anchorMorph: aMorph at: wp type: aMorph textAnchorProperties anchorLayout]. self addMorphFront: aMorph. ! Item was changed: + ----- Method: TextMorph>>delete (in category 'submorphs - add/remove') ----- - ----- Method: TextMorph>>delete (in category 'submorphs-add/remove') ----- delete predecessor ifNotNil: [predecessor setSuccessor: successor]. successor ifNotNil: [successor setPredecessor: predecessor. successor recomposeChain]. super delete! Item was changed: + ----- Method: TextMorph>>goBehind (in category 'submorphs - add/remove') ----- - ----- Method: TextMorph>>goBehind (in category 'submorphs-add/remove') ----- goBehind "We need to save the container, as it knows about fill and run-around" | cont | container ifNil: [^ super goBehind]. self releaseParagraph. "Cause recomposition" cont := container. "Save the container" super goBehind. "This will change owner, nilling the container" container := cont. "Restore the container" self changed! Item was changed: + ----- Method: ThreePhaseButtonMorph>>actWhen: (in category 'submorphs - add/remove') ----- - ----- Method: ThreePhaseButtonMorph>>actWhen: (in category 'submorphs-add/remove') ----- actWhen: condition "Accepts symbols: #buttonDown, #buttonUp, and #whilePressed" actWhen := condition! Item was added: + ----- Method: TransformMorph>>morphicLayerNumber (in category 'submorphs - layers') ----- + morphicLayerNumber + + ^ self hasSubmorphs + ifFalse: [super morphicLayerNumber] + ifTrue: [self firstSubmorph morphicLayerNumber]! Item was added: + ----- Method: TransformMorph>>morphicLayerNumber: (in category 'submorphs - layers') ----- + morphicLayerNumber: aNumber + + ^ self hasSubmorphs + ifFalse: [super morphicLayerNumber: aNumber] + ifTrue: [self firstSubmorph morphicLayerNumber: aNumber]! Item was changed: + ----- Method: TransformationMorph>>replaceSubmorph:by: (in category 'submorphs - add/remove') ----- - ----- Method: TransformationMorph>>replaceSubmorph:by: (in category 'submorphs-add/remove') ----- replaceSubmorph: oldMorph by: newMorph | t b | t := transform. b := bounds. super replaceSubmorph: oldMorph by: newMorph. transform := t. bounds := b. self layoutChanged! Item was added: + ----- Method: TranslucentProgessMorph>>initialize (in category 'initialization') ----- + initialize + + super initialize. + self morphicLayerNumber: self class progressLayer. ! Item was removed: - ----- Method: TranslucentProgessMorph>>morphicLayerNumber (in category 'WiW support') ----- - morphicLayerNumber - - "helpful for insuring some morphs always appear in front of or behind others. - smaller numbers are in front" - - ^self valueOfProperty: #morphicLayerNumber ifAbsent: [12]. - - "progress morphs are behind menus and balloons, but in front of most other stuff"! Item was changed: + (PackageInfo named: 'Morphic') postscript: 'PasteUpMorph allInstances do: [:m | m isFlap ifTrue: [m morphicLayerNumber: Morph navigatorLayer]]. + TheWorldMainDockingBar updateInstances. + SystemProgressMorph reset. + self currentWorld reorderSubmorphsInLayers.'! - (PackageInfo named: 'Morphic') postscript: '"Turn on Morphic drawing again." - Project current world removeProperty: #shouldDisplayWorld.'! From commits at source.squeak.org Fri Feb 26 14:44:27 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 26 Feb 2021 14:44:27 0000 Subject: [squeak-dev] The Trunk: MorphicTests-mt.70.mcz Message-ID: Marcel Taeumel uploaded a new version of MorphicTests to project The Trunk: http://source.squeak.org/trunk/MorphicTests-mt.70.mcz ==================== Summary ==================== Name: MorphicTests-mt.70 Author: mt Time: 26 February 2021, 3:44:25.553955 pm UUID: 6872ad63-f538-cf4a-b162-e1a236b6604b Ancestors: MorphicTests-mt.69 Complements Morphic-mt.1726 with tests. =============== Diff against MorphicTests-mt.69 =============== Item was added: + ----- Method: MorphTest>>test01LayerNumberDefault (in category 'tests - submorphs - layers') ----- + test01LayerNumberDefault + + self assert: Morph new morphicLayerNumber isNumber.! Item was added: + ----- Method: MorphTest>>test02LayerNumberCustom (in category 'tests - submorphs - layers') ----- + test02LayerNumberCustom + + | m | + m := Morph new. + self deny: 50 equals: m morphicLayerNumber. + m morphicLayerNumber: 50. + self assert: 50 equals: m morphicLayerNumber.! Item was added: + ----- Method: MorphTest>>test03LayerNumberFromOwner (in category 'tests - submorphs - layers') ----- + test03LayerNumberFromOwner + "If not specified, inherit the owner's layer number." + + | m1 m2 | + m1 := Morph new. + m2 := Morph new. + m1 addMorph: m2. + + m1 morphicLayerNumber: 50. + self assert: 50 equals: m2 morphicLayerNumber. + + m2 morphicLayerNumber: 25. + self assert: 25 equals: m2 morphicLayerNumber. + ! Item was added: + ----- Method: MorphTest>>test04AddMorphInLayer (in category 'tests - submorphs - layers') ----- + test04AddMorphInLayer + + | container builder unordered ordered | + container := Morph new. + builder := [Morph new]. + + unordered := #(6.5 100 20 15 5.0 6 7 100 20 -10). + unordered := unordered collect: [:layerNumber | + {layerNumber . builder value morphicLayerNumber: layerNumber}]. + unordered do: [:spec | + container addMorphBackInLayer: spec second]. + + ordered := unordered. "No need to reverse the list because add-to-back directly maps to the resulting submorph order." + ordered := ordered sorted: [:a :b | a first <= b first]. "Must be stable." + ordered := ordered collect: [:spec | spec second]. "Just the morphs." + + self assert: (ordered hasEqualElements: container submorphs).! Item was added: + ----- Method: MorphTest>>test05AddMorphFrontInLayer (in category 'tests - submorphs - layers') ----- + test05AddMorphFrontInLayer + + | container builder unordered ordered | + container := Morph new. + builder := [Morph new]. + + unordered := #(6.5 100 20 15 5.0 6 7 100 20 -10). + unordered := unordered collect: [:layerNumber | + {layerNumber . builder value morphicLayerNumber: layerNumber}]. + unordered do: [:spec | + container addMorphFrontInLayer: spec second]. + + ordered := unordered reversed. "Submorph order will be reversed due to add-to-front." + ordered := ordered sorted: [:a :b | a first <= b first]. "Must be stable." + ordered := ordered collect: [:spec | spec second]. "Just the morphs." + + self assert: (ordered hasEqualElements: container submorphs).! Item was added: + ----- Method: MorphTest>>test06AddMorphBackInLayer (in category 'tests - submorphs - layers') ----- + test06AddMorphBackInLayer + + | container builder unordered ordered | + container := Morph new. + builder := [Morph new]. + + unordered := #(6.5 100 20 15 5.0 6 7 100 20 -10). + unordered := unordered collect: [:layerNumber | + {layerNumber . builder value morphicLayerNumber: layerNumber}]. + unordered do: [:spec | + container addMorphBackInLayer: spec second]. + + ordered := unordered. "No need to reverse the list because add-to-back directly maps to the resulting submorph order." + ordered := ordered sorted: [:a :b | a first <= b first]. "Must be stable." + ordered := ordered collect: [:spec | spec second]. "Just the morphs." + + self assert: (ordered hasEqualElements: container submorphs).! Item was added: + ----- Method: MorphTest>>test07ChangeLayerNumber (in category 'tests - submorphs - layers') ----- + test07ChangeLayerNumber + + | container m1 m2 | + container := Morph new. + m1 := Morph new. + m2 := Morph new. + + m1 morphicLayerNumber: 20. "behind m2" + m2 morphicLayerNumber: 10. "in front of m1" + + container addMorphInLayer: m1. + container addMorphInLayer: m2. + self assert: ({m2 . m1} hasEqualElements: container submorphs). + + m1 morphicLayerNumber: 5. "go in front of m2" + container addMorphInLayer: m1. + self assert: ({m1 . m2} hasEqualElements: container submorphs). + + m1 morphicLayerNumber: 50. "go behind m2 again" + container addMorphInLayer: m1. + self assert: ({m2 . m1} hasEqualElements: container submorphs). + ! Item was added: + ----- Method: MorphTest>>test08ChangeLayerNumberAuto (in category 'tests - submorphs - layers') ----- + test08ChangeLayerNumberAuto + + | container m1 m2 | + container := Morph new. + m1 := Morph new. + m2 := Morph new. + + m1 morphicLayerNumber: 20. "behind m2" + m2 morphicLayerNumber: 10. "in front of m1" + + container addMorphInLayer: m1. + container addMorphInLayer: m2. + self assert: ({m2 . m1} hasEqualElements: container submorphs). + + m1 morphicLayerNumber: 5. "go in front of m2" + self assert: ({m1 . m2} hasEqualElements: container submorphs). + + m1 morphicLayerNumber: 50. "go behind m2 again" + self assert: ({m2 . m1} hasEqualElements: container submorphs).! Item was added: + ----- Method: MorphTest>>test09IgnoreLayer (in category 'tests - submorphs - layers') ----- + test09IgnoreLayer + + | container m1 m2 | + container := Morph new. + m1 := Morph new. + m2 := Morph new. + + m1 morphicLayerNumber: 1. + m2 morphicLayerNumber: 999. + + container addMorphFrontInLayer: m1. + container addMorphFront: m2. "Ignore the layer of m1." + self assert: ({m2 . m1} hasEqualElements: container submorphs). + + container addMorphFrontInLayer: m1. + self assert: ({m1 . m2} hasEqualElements: container submorphs).! Item was added: + ----- Method: MorphTest>>test10TransformKeepsLayer (in category 'tests - submorphs - layers') ----- + test10TransformKeepsLayer + + | morph transform | + morph := Morph new. + transform := morph addFlexShell. + + morph morphicLayerNumber: 50. + self assert: 50 equals: transform morphicLayerNumber. + + transform morphicLayerNumber: 20. + self assert: 20 equals: transform morphicLayerNumber. + + transform removeMorph: morph. + transform morphicLayerNumber: 50. + self + assert: 20 equals: morph morphicLayerNumber; + assert: 50 equals: transform morphicLayerNumber.! Item was added: + ----- Method: MorphTest>>test11NamedLayers (in category 'tests - submorphs - layers') ----- + test11NamedLayers + + #( + frontmostLayer + + balloonLayer + haloLayer + menuLayer + + progressLayer + + dialogLayer + navigatorLayer + windowLayer + + defaultLayer + + backmostLayer + + ) overlappingPairsDo: [:a :b | + self assert: (Morph perform: a) <= (Morph perform: b)]! Item was added: + ----- Method: MorphTest>>test12ResetLayerToDefault (in category 'tests - submorphs - layers') ----- + test12ResetLayerToDefault + + | morph default | + morph := Morph new. + default := morph morphicLayerNumber. + + morph morphicLayerNumber: default * 2. + self deny: default equals: morph morphicLayerNumber. + + morph morphicLayerNumber: nil. + self assert: default equals: morph morphicLayerNumber.! Item was changed: + ----- Method: MorphTest>>testAddAllMorphs (in category 'tests - submorphs - add/remove') ----- - ----- Method: MorphTest>>testAddAllMorphs (in category 'testing - add/remove submorphs') ----- testAddAllMorphs self createAndAddMorphs: #(a b). self assert: #(a b) equals: self getSubmorphNames. morph addAllMorphs: (self createMorphs: #(x y)). self assert: #(a b x y) equals: self getSubmorphNames. morph removeAllMorphs. morph addAllMorphs: (self createMorphs: #(x y)). self assert: #(x y) equals: self getSubmorphNames.! Item was changed: + ----- Method: MorphTest>>testAddAllMorphsAfter (in category 'tests - submorphs - add/remove') ----- - ----- Method: MorphTest>>testAddAllMorphsAfter (in category 'testing - add/remove submorphs') ----- testAddAllMorphsAfter self createAndAddMorphs: #(a b). self assert: #(a b) equals: self getSubmorphNames. morph addAllMorphs: (self createMorphs: #(x y)) after: (self getSubmorph: #a). self assert: #(a x y b) equals: self getSubmorphNames. morph addAllMorphs: (self getSubmorphs: #(x y)) after: (self getSubmorph: #b). self assert: #(a b x y) equals: self getSubmorphNames. morph addAllMorphs: (self getSubmorphs: #(a x)) after: (self getSubmorph: #y). self assert: #(b y a x) equals: self getSubmorphNames. morph addAllMorphs: (self getSubmorphs: #(x y)) after: (self getSubmorph: #a). self assert: #(b a x y) equals: self getSubmorphNames.! Item was changed: + ----- Method: MorphTest>>testAddAllMorphsInFrontOf (in category 'tests - submorphs - add/remove') ----- - ----- Method: MorphTest>>testAddAllMorphsInFrontOf (in category 'testing - add/remove submorphs') ----- testAddAllMorphsInFrontOf self createAndAddMorphs: #(a b). self assert: #(a b) equals: self getSubmorphNames. morph addAllMorphs: (self createMorphs: #(x y)) inFrontOf: (self getSubmorph: #b). self assert: #(a x y b) equals: self getSubmorphNames. morph addAllMorphs: (self getSubmorphs: #(x y)) inFrontOf: (self getSubmorph: #a). self assert: #(x y a b) equals: self getSubmorphNames. morph addAllMorphs: (self getSubmorphs: #(y b)) inFrontOf: (self getSubmorph: #x). self assert: #(y b x a) equals: self getSubmorphNames. morph addAllMorphs: (self getSubmorphs: #(x y)) inFrontOf: (self getSubmorph: #b). self assert: #(x y b a) equals: self getSubmorphNames.! Item was changed: + ----- Method: MorphTest>>testIntoWorldCollapseOutOfWorld (in category 'tests - into/outOf World') ----- - ----- Method: MorphTest>>testIntoWorldCollapseOutOfWorld (in category 'testing - into/outOf World') ----- testIntoWorldCollapseOutOfWorld | m1 m2 collapsed | "Create the guys" m1 := TestInWorldMorph new. m2 := TestInWorldMorph new. self assert: (m1 intoWorldCount = 0). self assert: (m1 outOfWorldCount = 0). self assert: (m2 intoWorldCount = 0). self assert: (m2 outOfWorldCount = 0). "add them to basic morph" morph addMorphFront: m1. m1 addMorphFront: m2. self assert: (m1 intoWorldCount = 0). self assert: (m1 outOfWorldCount = 0). self assert: (m2 intoWorldCount = 0). self assert: (m2 outOfWorldCount = 0). "open the guy" morph openInWorld. self assert: (m1 intoWorldCount = 1). self assert: (m1 outOfWorldCount = 0). self assert: (m2 intoWorldCount = 1). self assert: (m2 outOfWorldCount = 0). "collapse it" collapsed := CollapsedMorph new beReplacementFor: morph. self assert: (m1 intoWorldCount = 1). self assert: (m1 outOfWorldCount = 1). self assert: (m2 intoWorldCount = 1). self assert: (m2 outOfWorldCount = 1). "expand it" collapsed collapseOrExpand. self assert: (m1 intoWorldCount = 2). self assert: (m1 outOfWorldCount = 1). self assert: (m2 intoWorldCount = 2). self assert: (m2 outOfWorldCount = 1). "delete it" morph delete. self assert: (m1 intoWorldCount = 2). self assert: (m1 outOfWorldCount = 2). self assert: (m2 intoWorldCount = 2). self assert: (m2 outOfWorldCount = 2). ! Item was changed: + ----- Method: MorphTest>>testIntoWorldDeleteOutOfWorld (in category 'tests - into/outOf World') ----- - ----- Method: MorphTest>>testIntoWorldDeleteOutOfWorld (in category 'testing - into/outOf World') ----- testIntoWorldDeleteOutOfWorld | m1 m2 | "Create the guys" m1 := TestInWorldMorph new. m2 := TestInWorldMorph new. self assert: (m1 intoWorldCount = 0). self assert: (m1 outOfWorldCount = 0). self assert: (m2 intoWorldCount = 0). self assert: (m2 outOfWorldCount = 0). morph addMorphFront: m1. m1 addMorphFront: m2. self assert: (m1 intoWorldCount = 0). self assert: (m1 outOfWorldCount = 0). self assert: (m2 intoWorldCount = 0). self assert: (m2 outOfWorldCount = 0). morph openInWorld. self assert: (m1 intoWorldCount = 1). self assert: (m1 outOfWorldCount = 0). self assert: (m2 intoWorldCount = 1). self assert: (m2 outOfWorldCount = 0). morph delete. self assert: (m1 intoWorldCount = 1). self assert: (m1 outOfWorldCount = 1). self assert: (m2 intoWorldCount = 1). self assert: (m2 outOfWorldCount = 1). ! Item was changed: + ----- Method: MorphTest>>testIntoWorldTransferToNewGuy (in category 'tests - into/outOf World') ----- - ----- Method: MorphTest>>testIntoWorldTransferToNewGuy (in category 'testing - into/outOf World') ----- testIntoWorldTransferToNewGuy | m1 m2 | "Create the guys" m1 := TestInWorldMorph new. m2 := TestInWorldMorph new. self assert: (m1 intoWorldCount = 0). self assert: (m1 outOfWorldCount = 0). self assert: (m2 intoWorldCount = 0). self assert: (m2 outOfWorldCount = 0). morph addMorphFront: m1. m1 addMorphFront: m2. self assert: (m1 intoWorldCount = 0). self assert: (m1 outOfWorldCount = 0). self assert: (m2 intoWorldCount = 0). self assert: (m2 outOfWorldCount = 0). morph openInWorld. self assert: (m1 intoWorldCount = 1). self assert: (m1 outOfWorldCount = 0). self assert: (m2 intoWorldCount = 1). self assert: (m2 outOfWorldCount = 0). morph addMorphFront: m2. self assert: (m1 intoWorldCount = 1). self assert: (m1 outOfWorldCount = 0). self assert: (m2 intoWorldCount = 1). self assert: (m2 outOfWorldCount = 0). morph addMorphFront: m1. self assert: (m1 intoWorldCount = 1). self assert: (m1 outOfWorldCount = 0). self assert: (m2 intoWorldCount = 1). self assert: (m2 outOfWorldCount = 0). m2 addMorphFront: m1. self assert: (m1 intoWorldCount = 1). self assert: (m1 outOfWorldCount = 0). self assert: (m2 intoWorldCount = 1). self assert: (m2 outOfWorldCount = 0). morph delete. self assert: (m1 intoWorldCount = 1). self assert: (m1 outOfWorldCount = 1). self assert: (m2 intoWorldCount = 1). self assert: (m2 outOfWorldCount = 1). ! Item was changed: + ----- Method: MorphTest>>testIsMorph (in category 'tests - classification') ----- - ----- Method: MorphTest>>testIsMorph (in category 'testing - classification') ----- testIsMorph self assert: (morph isMorph).! Item was changed: + ----- Method: MorphTest>>testOpenInWorld (in category 'tests - initialization') ----- - ----- Method: MorphTest>>testOpenInWorld (in category 'testing - initialization') ----- testOpenInWorld "This should not throw an exception." morph openInWorld.! From commits at source.squeak.org Fri Feb 26 14:44:58 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 26 Feb 2021 14:44:58 0000 Subject: [squeak-dev] The Trunk: 60Deprecated-mt.88.mcz Message-ID: Marcel Taeumel uploaded a new version of 60Deprecated to project The Trunk: http://source.squeak.org/trunk/60Deprecated-mt.88.mcz ==================== Summary ==================== Name: 60Deprecated-mt.88 Author: mt Time: 26 February 2021, 3:44:56.483955 pm UUID: 990c34c3-5689-fc4d-bb49-578f125bd1ec Ancestors: 60Deprecated-mt.87 Complements Morphic-mt.1726 =============== Diff against 60Deprecated-mt.87 =============== Item was added: + ----- Method: Morph>>addMorphInFrontOfLayer: (in category '*60Deprecated-WiW support') ----- + addMorphInFrontOfLayer: aMorph + + self deprecated: 'Use #addMorphFrontInLayer: instead.'. + ^ self addMorphFrontInLayer: aMorph! Item was added: + ----- Method: Morph>>morphicLayerNumberWithin: (in category '*60Deprecated-WiW support') ----- + morphicLayerNumberWithin: anOwner + + self deprecated: 'Use #morphicLayerNumber instead.'. + ^ self morphicLayerNumber! From commits at source.squeak.org Fri Feb 26 14:46:24 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 26 Feb 2021 14:46:24 0000 Subject: [squeak-dev] The Trunk: EToys-mt.428.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-mt.428.mcz ==================== Summary ==================== Name: EToys-mt.428 Author: mt Time: 26 February 2021, 3:46:14.660955 pm UUID: 717b17d4-5453-8645-b809-fba5e44796ca Ancestors: EToys-mt.427 Complements Morphic-mt.1726 =============== Diff against EToys-mt.427 =============== Item was changed: + ----- Method: ComponentLayout>>allKnownNames (in category 'submorphs - accessing') ----- - ----- Method: ComponentLayout>>allKnownNames (in category 'submorphs-accessing') ----- allKnownNames ^super allKnownNames , (self submorphs collect: [:m | m knownName] thenSelect: [:m | m notNil])! Item was changed: + ----- Method: ComponentLikeModel>>delete (in category 'submorphs - add/remove') ----- - ----- Method: ComponentLikeModel>>delete (in category 'submorphs-add/remove') ----- delete "Delete the receiver. Possibly put up confirming dialog. Abort if user changes mind" (model isKindOf: Component) ifTrue: [^self deleteComponent]. (model isMorphicModel) ifFalse: [^super delete]. slotName ifNotNil: [(PopUpMenu confirm: 'Shall I remove the slot ' , slotName , ' along with all associated methods?') ifTrue: [(model class selectors select: [:s | s beginsWith: slotName]) do: [:s | model class removeSelector: s]. (model class instVarNames includes: slotName) ifTrue: [model class removeInstVarName: slotName]] ifFalse: [(PopUpMenu confirm: '...but should I at least dismiss this morph? [choose no to leave everything unchanged]') ifFalse: [^self]]]. super delete! Item was changed: ----- Method: EtoyDAVLoginMorph>>buildPanel (in category 'private') ----- buildPanel | title | self deletePanel. panel := AlignmentMorphBob1 new. panel vResizing: #shrinkWrap; hResizing: #shrinkWrap; layoutInset: 4; color: self defaultColor; beSticky; borderWidth: self defaultBorderWidth; borderColor: self defaultBorderColor. title := TextMorph new contents: 'Etoys is trying to open your web browser.\If it does not work, you can sign up at:\\' translated withCRs, self url; beAllFont: self myFont. title beSticky. title centered. panel addARow: {title}. panel addARow: { (StringMorph contents:'') lock }. panel addARow: { self newSpacer: Color transparent. self okButton2 hResizing: #rigid. self newSpacer: Color transparent. }. + panel morphicLayerNumber: self class dialogLayer - 1. - panel setProperty: #morphicLayerNumber toValue: 9. ^ panel. ! Item was changed: ----- Method: EtoyDAVLoginMorph>>initialize (in category 'initialization') ----- initialize "initialize the state of the receiver" super initialize. "" self vResizing: #shrinkWrap; hResizing: #shrinkWrap; layoutInset: 4; beSticky; rebuild. + self morphicLayerNumber: self class dialogLayer.! - self setProperty: #morphicLayerNumber toValue: 10.! Item was changed: + ----- Method: KedamaMorph>>allSubmorphNamesDo: (in category 'submorphs - accessing') ----- - ----- Method: KedamaMorph>>allSubmorphNamesDo: (in category 'submorphs-accessing') ----- allSubmorphNamesDo: aBlock super allSubmorphNamesDo: aBlock. aBlock value: self defaultPatch externalName. ! Item was changed: ----- Method: NewVariableDialogMorph>>initialize (in category 'initialize') ----- initialize + super initialize. + + self morphicLayerNumber: self class dialogLayer. + self rebuild.! - self rebuild! Item was removed: - ----- Method: NewVariableDialogMorph>>morphicLayerNumber (in category 'accessing') ----- - morphicLayerNumber - - ^10.6! Item was changed: + ----- Method: PinMorph>>delete (in category 'submorphs - add/remove') ----- - ----- Method: PinMorph>>delete (in category 'submorphs-add/remove') ----- delete self unwire. ^ super delete! Item was changed: + ----- Method: ScriptEditorMorph>>dismissViaHalo (in category 'submorphs - add/remove') ----- - ----- Method: ScriptEditorMorph>>dismissViaHalo (in category 'submorphs-add/remove') ----- dismissViaHalo "The user has clicked in the delete halo-handle. This provides a hook in case some concomitant action should be taken, or if the particular morph is not one which should be put in the trash can, for example." self resistsRemoval ifTrue: [^ self]. self destroyScript! Item was changed: + ----- Method: SpectrumAnalyzerMorph>>delete (in category 'submorphs - add/remove') ----- - ----- Method: SpectrumAnalyzerMorph>>delete (in category 'submorphs-add/remove') ----- delete "Turn off recording when this morph is deleted." super delete. soundInput stopRecording. ! Item was changed: + ----- Method: StackMorph>>allNonSubmorphMorphs (in category 'submorphs - accessing') ----- - ----- Method: StackMorph>>allNonSubmorphMorphs (in category 'submorphs-accessing') ----- allNonSubmorphMorphs "Return a collection containing all morphs in this morph which are not currently in the submorph containment hierarchy. Especially the non-showing pages in BookMorphs." | coll | coll := OrderedCollection new. self privateCards do: [:cd | cd privateMorphs ifNotNil: [coll addAll: cd privateMorphs]]. ^ coll! Item was changed: + ----- Method: StackMorph>>insertionIndexForPaneOfType: (in category 'submorphs - accessing') ----- - ----- Method: StackMorph>>insertionIndexForPaneOfType: (in category 'submorphs-accessing') ----- insertionIndexForPaneOfType: aType | naturalIndex insertionIndex | naturalIndex := self naturalPaneOrder indexOf: aType. insertionIndex := 1. (self naturalPaneOrder copyFrom: 1 to: (naturalIndex - 1)) do: "guys that would precede" [:sym | (self hasSubmorphWithProperty: sym) ifTrue: [insertionIndex := insertionIndex + 1]]. ^ insertionIndex! Item was changed: + ----- Method: StackMorph>>naturalPaneOrder (in category 'submorphs - accessing') ----- - ----- Method: StackMorph>>naturalPaneOrder (in category 'submorphs-accessing') ----- naturalPaneOrder ^ #(header pageControl retrieve search index content)! Item was changed: ----- Method: StandardScriptingSystem>>openInfoFlapWithLabel:helpContents:edge: (in category '*Etoys-Squeakland-help in a flap') ----- openInfoFlapWithLabel: aTitle helpContents: aString edge: anEdge "Open an info flap with the given label, contents, and edge" | aPlug outer leftStrip rightStrip titleRow aDismissButton aFlapTab | Preferences enable: #scrollBarsOnRight. Preferences enable: #inboardScrollbars. aFlapTab := FlapTab new. aFlapTab assureExtension visible: false. aFlapTab referentMargin: 0 @ Project current world sugarAllowance. outer := HelpFlap newRow. outer assureExtension visible: false. outer clipSubmorphs: true. outer beTransparent. outer vResizing: #spaceFill; hResizing: #spaceFill. outer layoutInset: 0; cellInset: 0; borderWidth: 0. + outer morphicLayerNumber: outer class navigatorLayer. - outer setProperty: #morphicLayerNumber toValue: 26. leftStrip := Morph new beTransparent. leftStrip layoutInset: 0; cellInset: 0; borderWidth: 0. leftStrip width: 20. leftStrip hResizing: #rigid; vResizing: #spaceFill. outer addMorphBack: leftStrip. rightStrip := AlignmentMorph newColumn. rightStrip beTransparent. rightStrip layoutInset: 0; cellInset: 0; borderWidth: 0. outer addMorphBack: rightStrip. outer clipSubmorphs: true. titleRow := AlignmentMorph newRow. titleRow borderColor: Color veryVeryLightGray; borderWidth: 1. titleRow hResizing: #spaceFill; vResizing: #shrinkWrap. titleRow beTransparent. aDismissButton := aFlapTab tanOButton. aDismissButton actionSelector: #dismissViaHalo. titleRow addMorphFront: aDismissButton. titleRow addTransparentSpacerOfSize: 8 @ 0. titleRow addMorphBack: (StringMorph contents: aTitle font: Preferences standardEToysTitleFont). rightStrip addMorph: titleRow. aPlug := PluggableTextMorph new. aPlug width: 540. aPlug setText: aString. aPlug textMorph beAllFont: Preferences standardEToysFont. aPlug retractable: false; scrollBarOnLeft: false. aPlug hScrollBarPolicy: #never. aPlug borderColor: ScriptingSystem borderColor. aPlug setNameTo: aTitle. aPlug hResizing: #spaceFill. aPlug vResizing: #spaceFill. rightStrip addMorphBack: aPlug. aFlapTab referent ifNotNil: [aFlapTab referent delete]. aFlapTab referent: outer. aFlapTab setName: aTitle edge: anEdge color: (Color r: 0.677 g: 0.935 b: 0.484). aFlapTab submorphs first beAllFont: Preferences standardEToysFont. Project current world addMorphFront: aFlapTab. aFlapTab adaptToWorld: Project current world. aFlapTab computeEdgeFraction. anEdge == #left ifTrue: [aFlapTab position: (outer left @ outer top). outer extent: (540 @ Project current world height)]. anEdge == #right ifTrue: [aFlapTab position: ((Project current world right - aFlapTab width) @ Project current world top). outer extent: (540 @ Project current world height)]. outer beFlap: true. outer color: Color green veryMuchLighter. aPlug textMorph lock. aFlapTab referent hide. aFlapTab openFully. outer beSticky. leftStrip beSticky. rightStrip beSticky. Project current world doOneCycle. aPlug width: 540. aPlug setText: aString. "hmm, again" aPlug color: outer color. aPlug borderWidth: 0. aPlug textMorph contents: aString wrappedTo: 520. aFlapTab applyThickness: 560. aFlapTab fitOnScreen. aFlapTab referent show. ^ aFlapTab! Item was changed: ----- Method: SugarNavigatorBar>>initialize (in category 'initialization') ----- initialize super initialize. self layoutInset: 0 at 0; hResizing: #rigid; vResizing: #rigid; cellPositioning: #topLeft. self cornerStyle: #square. self resistsRemoval: true. self beSticky. self makeGray. + self morphicLayerNumber: self class navigatorLayer. ! Item was removed: - ----- Method: SugarNavigatorBar>>morphicLayerNumber (in category 'event handling') ----- - morphicLayerNumber - - ^ 100. - ! Item was changed: + ----- Method: SyntaxMorph>>findA: (in category 'submorphs - accessing') ----- - ----- Method: SyntaxMorph>>findA: (in category 'submorphs-accessing') ----- findA: aClass | ans | "Allow finding on the class of the parseNode" (ans := super findA: aClass) ifNotNil: [^ ans]. submorphs do: [:ss | ss isSyntaxMorph ifTrue: [ ss parseNode class == aClass ifTrue: [^ ss]]]. ^ nil! Item was changed: + ----- Method: VeryPickyMorph>>delete (in category 'submorphs - add/remove') ----- - ----- Method: VeryPickyMorph>>delete (in category 'submorphs-add/remove') ----- delete passengerMorph ifNotNil: [passengerMorph delete]. super delete! Item was changed: + ----- Method: WebCamMorph>>delete (in category 'submorphs - add/remove') ----- - ----- Method: WebCamMorph>>delete (in category 'submorphs-add/remove') ----- delete self off. super delete! Item was changed: + ----- Method: WireMorph>>delete (in category 'submorphs - add/remove') ----- - ----- Method: WireMorph>>delete (in category 'submorphs-add/remove') ----- delete pins do: [:p | p removeWire: self]. pins first isIsolated ifTrue: [pins first removeVariableAccess. pins second isIsolated ifTrue: [pins second removeModelVariable]] ifFalse: [pins second isIsolated ifTrue: [pins second removeVariableAccess] ifFalse: [pins second addModelVariable]]. super delete! From commits at source.squeak.org Fri Feb 26 14:47:17 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 26 Feb 2021 14:47:17 0000 Subject: [squeak-dev] The Trunk: MorphicExtras-mt.285.mcz Message-ID: Marcel Taeumel uploaded a new version of MorphicExtras to project The Trunk: http://source.squeak.org/trunk/MorphicExtras-mt.285.mcz ==================== Summary ==================== Name: MorphicExtras-mt.285 Author: mt Time: 26 February 2021, 3:47:14.471955 pm UUID: a3e97393-d97b-684b-b584-abde4e302510 Ancestors: MorphicExtras-mt.284 Complements Morphic-mt.1726 =============== Diff against MorphicExtras-mt.284 =============== Item was changed: + ----- Method: BookMorph>>abandon (in category 'submorphs - add/remove') ----- - ----- Method: BookMorph>>abandon (in category 'submorphs-add/remove') ----- abandon "Like delete, but we really intend not to use this morph again. Make the page cache release the page object." self delete. pages do: [:aPage | | pg | (pg := aPage sqkPage) ifNotNil: [ pg contentsMorph == aPage ifTrue: [ pg contentsMorph: nil]]].! Item was changed: + ----- Method: BookMorph>>allNonSubmorphMorphs (in category 'submorphs - accessing') ----- - ----- Method: BookMorph>>allNonSubmorphMorphs (in category 'submorphs-accessing') ----- allNonSubmorphMorphs "Return a collection containing all morphs in this morph which are not currently in the submorph containment hierarchy. Especially the non-showing pages in BookMorphs. (As needed, make a variant of this that brings in all pages that are not in memory.)" | coll | coll := OrderedCollection new. pages do: [:pg | pg isInMemory ifTrue: [ pg == currentPage ifFalse: [coll add: pg]]]. ^ coll! Item was changed: + ----- Method: BouncingAtomsMorph>>addMorphFront: (in category 'submorphs - add/remove') ----- - ----- Method: BouncingAtomsMorph>>addMorphFront: (in category 'submorphs-add/remove') ----- addMorphFront: aMorph "Called by the 'embed' meta action. We want non-atoms to go to the back." "Note: A user would not be expected to write this method. However, a sufficiently advanced user (e.g, an e-toy author) might do something equivalent by overridding the drag-n-drop messages when they are implemented." (aMorph isMemberOf: AtomMorph) ifTrue: [super addMorphFront: aMorph] ifFalse: [super addMorphBack: aMorph].! Item was changed: + ----- Method: EmbeddedWorldBorderMorph>>morphicLayerNumber (in category 'submorphs - layers') ----- - ----- Method: EmbeddedWorldBorderMorph>>morphicLayerNumber (in category 'WiW support') ----- morphicLayerNumber + "Embedded worlds come in front of other worlds' Project navigation morphs" + ^ self valueOfProperty: #morphicLayerNumber ifAbsent: [self class navigatorLayer - 1] + ! - "helpful for insuring some morphs always appear in front of or behind others. - smaller numbers are in front" - - ^20 "Embedded worlds come in front of other worlds' Project navigation morphs"! Item was changed: + ----- Method: FlapTab>>dismissViaHalo (in category 'submorphs - add/remove') ----- - ----- Method: FlapTab>>dismissViaHalo (in category 'submorphs-add/remove') ----- dismissViaHalo "Dismiss the receiver (and its referent), unless it resists" self resistsRemoval ifTrue: [(UIManager default chooseFrom: #( 'Yes' 'Um, no, let me reconsider') title: 'Really throw this flap away?') = 2 ifFalse: [^ self]]. referent delete. self delete! Item was changed: + ----- Method: FlapTab>>morphicLayerNumber (in category 'submorphs - layers') ----- - ----- Method: FlapTab>>morphicLayerNumber (in category 'WiW support') ----- morphicLayerNumber + + ^ self valueOfProperty: #morphicLayerNumber ifAbsent: [self class navigatorLayer]! - ^self flapShowing ifTrue: [26] ifFalse: [25] "As navigators"! Item was changed: ----- Method: Flaps class>>newPaintingFlap (in category 'predefined flaps') ----- newPaintingFlap "Add a flap with the paint palette in it" | aFlap aFlapTab | "Flaps reinstateDefaultFlaps. Flaps addPaintingFlap" aFlap := PasteUpMorph new borderWidth: 0. aFlap color: Color transparent. aFlap layoutPolicy: TableLayout new. aFlap hResizing: #shrinkWrap. aFlap vResizing: #shrinkWrap. aFlap cellPositioning: #topLeft. aFlap clipSubmorphs: false. aFlap beSticky. "really?!!" aFlap addMorphFront: PaintBoxMorph new. + aFlap beFlap: true. - aFlap setProperty: #flap toValue: true. aFlap fullBounds. "force layout" aFlapTab := FlapTab new referent: aFlap. aFlapTab setNameTo: 'Painting' translated. aFlapTab setProperty: #priorWording toValue: 'Paint' translated. aFlapTab useGraphicalTab. aFlapTab removeAllMorphs. aFlapTab setProperty: #paintingFlap toValue: true. aFlapTab addMorphFront: "(SketchMorph withForm: (ScriptingSystem formAtKey: #PaintingFlapPic))" self paintFlapButton. aFlapTab cornerStyle: #rounded. aFlapTab edgeToAdhereTo: #right. aFlapTab setToPopOutOnDragOver: false. aFlapTab setToPopOutOnMouseOver: false. aFlapTab on: #mouseUp send: #startOrFinishDrawing: to: aFlapTab. aFlapTab setBalloonText:'Click here to start or finish painting.' translated. aFlapTab fullBounds. "force layout" aFlapTab position: (0 at 6). self currentWorld addMorphFront: aFlapTab. ^ aFlapTab! Item was changed: + ----- Method: FloatingBookControlsMorph>>morphicLayerNumber (in category 'submorphs - layers') ----- - ----- Method: FloatingBookControlsMorph>>morphicLayerNumber (in category 'WiW support') ----- morphicLayerNumber + "page controls are behind menus and balloons, but in front of most other stuff" + + ^ self valueOfProperty: #morphicLayerNumber ifAbsent: [self class navigatorLayer]! - - "helpful for insuring some morphs always appear in front of or behind others. - smaller numbers are in front" - - ^23 "page controls are behind menus and balloons, but in front of most other stuff"! Item was changed: + ----- Method: ProjectNavigationMorph>>morphicLayerNumber (in category 'submorphs - layers') ----- - ----- Method: ProjectNavigationMorph>>morphicLayerNumber (in category 'WiW support') ----- morphicLayerNumber + ^ self valueOfProperty: #morphicLayerNumber ifAbsent: [self class navigatorLayer]! - "helpful for insuring some morphs always appear in front of or behind others. - smaller numbers are in front" - - ^mouseInside == true ifTrue: [26] ifFalse: [25] - - "Navigators are behind menus and balloons, but in front of most other stuff"! Item was changed: ----- Method: ProjectNavigationMorph>>soundDownEvt:morph: (in category '*MorphicExtras-Sound') ----- soundDownEvt: a morph: b soundSlider ifNotNil: [soundSlider delete]. (soundSlider := RectangleMorph new) + morphicLayerNumber: self class frontmostLayer; - setProperty: #morphicLayerNumber toValue: 1; extent: b width @ (b width * 3); color: self colorForButtons; borderStyle: BorderStyle raised; bottomLeft: b boundsInWorld origin. soundSlider addMorph: ( RectangleMorph new color: self colorForButtons; borderColor: #raised; extent: b width @ 8; center: soundSlider center x @ (soundSlider bottom - (soundSlider height * self getSoundVolume) asInteger) ). soundSlider openInWorld.! Item was changed: + ----- Method: ReferenceMorph>>allNonSubmorphMorphs (in category 'submorphs - accessing') ----- - ----- Method: ReferenceMorph>>allNonSubmorphMorphs (in category 'submorphs-accessing') ----- allNonSubmorphMorphs "we hold extra morphs" ^ Array with: referent! Item was changed: + ----- Method: ScreeningMorph>>addMorph: (in category 'submorphs - add/remove') ----- - ----- Method: ScreeningMorph>>addMorph: (in category 'submorphs-add/remove') ----- addMorph: aMorph | f | super addMorph: aMorph. submorphs size <= 2 ifTrue: [self bounds: submorphs last bounds]. submorphs size = 2 ifTrue: ["The screenMorph has just been added. Choose as the passingColor the center color of that morph" f := self screenMorph imageForm. passingColor := f colorAt: f boundingBox center. passElseBlock := true]! Item was added: + ----- Method: SketchEditorMorph>>initialize (in category 'initialization') ----- + initialize + + super initialize. + forEachHand := Dictionary new.! Item was changed: ----- Method: SketchEditorMorph>>initializeFor:inBounds:pasteUpMorph:paintBoxPosition: (in category 'initialization') ----- initializeFor: aSketchMorph inBounds: boundsToUse pasteUpMorph: aPasteUpMorph paintBoxPosition: aPosition "NB: if aPosition is nil, then it's assumed that the paintbox is obtained from a flap or some such, so do nothing special regarding a palette in this case. The palette needs already to be in the world for this to work." | w | (w := aPasteUpMorph world) addMorphInLayer: self. "in back of palette" enclosingPasteUpMorph := aPasteUpMorph. hostView := aSketchMorph. "may be ownerless" self bounds: boundsToUse. palette := w paintBox focusMorph: self. palette beStatic. "give Nebraska whatever help we can" palette addWeakDependent: self. + self morphicLayerNumber: self class dialogLayer + 1. + palette morphicLayerNumber: self class dialogLayer. aPosition ifNotNil: [w addMorphFront: palette. "bring to front" palette position: aPosition. palette beSupersized. self flag: #hacky. "mt: That super-sizing with a flex shell is awkward. Need to fix." palette owner bounds: (palette owner bounds translatedToBeWithin: self world bounds)]. paintingForm := Form extent: bounds extent depth: w assuredCanvas depth. self dimTheWindow. self addRotationScaleHandles. aSketchMorph ifNotNil: [ aSketchMorph form displayOn: paintingForm at: (hostView boundsInWorld origin - bounds origin - hostView form offset) clippingBox: (0 at 0 extent: paintingForm extent) rule: Form over fillColor: nil. "assume they are the same depth". undoBuffer := paintingForm deepCopy. rotationCenter := aSketchMorph rotationCenter]! Item was removed: - ----- Method: SketchEditorMorph>>morphicLayerNumber (in category 'WiW support') ----- - morphicLayerNumber - "Place the painting behind the paint palette" - - ^ 28! Item was changed: + ----- Method: StringButtonMorph>>actWhen: (in category 'submorphs - add/remove') ----- - ----- Method: StringButtonMorph>>actWhen: (in category 'submorphs-add/remove') ----- actWhen: aSymbol "Set the condition under which to invoke my action to one of: #buttonDown, #buttonUp, and #whilePressed." actWhen := aSymbol. ! Item was changed: + ----- Method: TabbedPalette>>replaceSubmorph:by: (in category 'submorphs - add/remove') ----- - ----- Method: TabbedPalette>>replaceSubmorph:by: (in category 'submorphs-add/remove') ----- replaceSubmorph: oldMorph by: newMorph super replaceSubmorph: oldMorph by: newMorph. oldMorph == currentPage ifTrue: [currentPage := newMorph]! Item was changed: + ----- Method: ThreadNavigationMorph>>morphicLayerNumber (in category 'submorphs - layers') ----- - ----- Method: ThreadNavigationMorph>>morphicLayerNumber (in category 'private') ----- morphicLayerNumber + ^ self valueOfProperty: #morphicLayerNumber ifAbsent: [self class navigatorLayer]! - "helpful for insuring some morphs always appear in front of or behind others. - smaller numbers are in front" - - ^15 "Navigators are behind menus and balloons, but in front of most other stuff"! Item was changed: + ----- Method: ViewerFlapTab>>allNonSubmorphMorphs (in category 'submorphs - accessing') ----- - ----- Method: ViewerFlapTab>>allNonSubmorphMorphs (in category 'submorphs-accessing') ----- allNonSubmorphMorphs "Return a collection containing all morphs in this morph which are not currently in the submorph containment hierarchy. Especially the non-showing pages in BookMorphs." ^ flapShowing ifTrue: [#()] ifFalse: [Array with: referent]! From commits at source.squeak.org Fri Feb 26 14:48:04 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 26 Feb 2021 14:48:04 0000 Subject: [squeak-dev] The Trunk: ToolBuilder-Morphic-mt.273.mcz Message-ID: Marcel Taeumel uploaded a new version of ToolBuilder-Morphic to project The Trunk: http://source.squeak.org/trunk/ToolBuilder-Morphic-mt.273.mcz ==================== Summary ==================== Name: ToolBuilder-Morphic-mt.273 Author: mt Time: 26 February 2021, 3:48:03.094955 pm UUID: 85920c43-33dc-0844-8f7b-2a6f21f1d548 Ancestors: ToolBuilder-Morphic-mt.272 Complements Morphic-mt.1726 =============== Diff against ToolBuilder-Morphic-mt.272 =============== Item was changed: ----- Method: MorphicToolBuilder>>buildPluggableDialog: (in category 'widgets optional') ----- buildPluggableDialog: aSpec | widget | widget := self dialogClass new. self register: widget id: aSpec name. widget model: aSpec model. "Set child dependent layout properties. The pane morph holds the special contents." widget paneMorph wantsPaneSplitters: (aSpec wantsResizeHandles ifNil: [true]). self setLayoutHintsFor: widget paneMorph spec: aSpec. widget paneMorph layoutInset: (aSpec padding ifNil: [ProportionalSplitterMorph gripThickness]). widget paneMorph cellGap: (aSpec spacing ifNil: [ProportionalSplitterMorph gripThickness]). + widget morphicLayerNumber: widget class dialogLayer. widget paneMorph wantsPaneSplitters ifTrue: [ widget paneMorph addCornerGrips"addEdgeGrips". widget paneMorph grips do: [:ea | ea showHandle: true]]. "Now create the children." panes := OrderedCollection new. aSpec children isSymbol ifTrue: [ widget getChildrenSelector: aSpec children. widget update: aSpec children] ifFalse: [ self buildAll: aSpec children in: widget paneMorph]. "Now create the buttons." aSpec buttons isSymbol ifTrue: [ widget getButtonsSelector: aSpec buttons. widget update: aSpec buttons] ifFalse: [ self buildAll: aSpec buttons in: widget buttonRowMorph. widget updateButtonProperties]. aSpec title ifNotNil: [:label | label isSymbol ifTrue:[widget getTitleSelector: label; update: label] ifFalse:[widget title: label]]. aSpec message ifNotNil: [:label | label isSymbol ifTrue:[widget getMessageSelector: label; update: label] ifFalse:[widget message: label]]. "Interaction behavior." aSpec autoCancel ifNotNil: [:b | widget autoCancel: b]. aSpec exclusive ifNotNil: [:b | widget exclusive: b]. widget closeDialogSelector: aSpec closeAction. self buildHelpFor: widget spec: aSpec. "Everything is shrink-wrapped around the pane morph." widget paneMorph extent: (aSpec extent ifNil:[widget initialExtent]) + (widget paneMorph layoutInset * 2) asPoint. ^ widget! Item was changed: ----- Method: MorphicToolBuilder>>buildPluggableWindow: (in category 'widgets required') ----- buildPluggableWindow: aSpec | widget | aSpec layout == #proportional ifFalse:[ "This needs to be implemented - probably by adding a single pane and then the rest" ^self error: 'Not implemented'. ]. widget := (self windowClassFor: aSpec) new. self register: widget id: aSpec name. widget model: aSpec model. "Set child dependent layout properties." widget wantsPaneSplitters: (aSpec wantsResizeHandles ifNil: [true]). MorphicProject worldGridEnabled ifTrue: [ "Snap both #position and #extent to grid." aSpec horizontalResizing ifNil: [aSpec horizontalResizing: #spaceFill]. aSpec verticalResizing ifNil: [aSpec verticalResizing: #spaceFill]]. self setLayoutHintsFor: widget spec: aSpec. widget layoutInset: (aSpec padding ifNil: [ProportionalSplitterMorph gripThickness]). widget cellGap: (aSpec spacing ifNil: [ProportionalSplitterMorph gripThickness]). + widget morphicLayerNumber: widget class windowLayer. "Now create the children." panes := OrderedCollection new. aSpec children isSymbol ifTrue: [ widget getChildrenSelector: aSpec children. widget update: aSpec children] ifFalse: [ self buildAll: aSpec children in: widget]. widget setUpdatablePanesFrom: panes. aSpec label ifNotNil: [:label| label isSymbol ifTrue:[widget getLabelSelector: label] ifFalse:[widget setLabel: label]]. aSpec multiWindowStyle notNil ifTrue: [widget savedMultiWindowState: (SavedMultiWindowState on: aSpec model)]. widget closeWindowSelector: aSpec closeAction. self buildHelpFor: widget spec: aSpec. widget bounds: (RealEstateAgent initialFrameFor: widget initialExtent: (aSpec extent ifNil:[widget initialExtent]) world: self currentWorld). widget refreshWindowColor. ^ widget! Item was changed: + ----- Method: PluggableDialogWindow>>delete (in category 'submorphs - add/remove') ----- - ----- Method: PluggableDialogWindow>>delete (in category 'submorphs-add/remove') ----- delete self model okToClose ifFalse: [^ self]. self closeDialogSelector ifNotNil: [:sel | self model perform: sel]. self model windowIsClosing; release. self model: nil. super delete.! From commits at source.squeak.org Fri Feb 26 14:48:35 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 26 Feb 2021 14:48:35 0000 Subject: [squeak-dev] The Trunk: Tools-mt.1026.mcz Message-ID: Marcel Taeumel uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-mt.1026.mcz ==================== Summary ==================== Name: Tools-mt.1026 Author: mt Time: 26 February 2021, 3:48:32.727955 pm UUID: 46a85c1d-6c6a-6f49-a7a4-e59bd45cce2a Ancestors: Tools-mt.1025 Complements Morphic-mt.1726 =============== Diff against Tools-mt.1025 =============== Item was changed: ----- Method: FileList2 class>>morphicViewProjectSaverFor: (in category 'blue ui') ----- morphicViewProjectSaverFor: aProject " (FileList2 morphicViewProjectSaverFor: Project current) openInWorld " | window aFileList buttons treePane pane2 textColor1 option treeExtent buttonData buttonRow | textColor1 := Color r: 0.742 g: 0.839 b: 1.0. aFileList := self new directory: ServerDirectory projectDefaultDirectory. aFileList dirSelectionBlock: self hideSqueakletDirectoryBlock. window := AlignmentMorphBob1 newColumn. window hResizing: #shrinkWrap; vResizing: #shrinkWrap. aFileList modalView: window. window setProperty: #FileList toValue: aFileList; wrapCentering: #center; cellPositioning: #topCenter; borderWidth: 1; borderColor: (Color r: 0.9 g: 0.801 b: 0.2); useRoundedCorners. buttonData := Preferences enableLocalSave ifTrue: [{ {'Save'. #okHit. 'Save in the place specified below, and in the Squeaklets folder on your local disk'. Color lightGreen}. {'Save on local disk only'. #saveLocalOnlyHit. 'saves in the Squeaklets folder'. Color lightGreen}. {'Cancel'. #cancelHit. 'return without saving'. Color lightRed} }] ifFalse: [{ {'Save'. #okHit. 'Save in the place specified below, and in the Squeaklets folder on your local disk'. Color lightGreen}. {'Cancel'. #cancelHit. 'return without saving'. Color lightRed} }]. buttons := buttonData collect: [ :each | (self blueButtonText: each first textColor: textColor1 color: each fourth inWindow: window) setBalloonText: each third translated; hResizing: #shrinkWrap; on: #mouseUp send: each second to: aFileList ]. option := aProject world valueOfProperty: #SuperSwikiPublishOptions ifAbsent: [#initialDirectoryList]. aProject world removeProperty: #SuperSwikiPublishOptions. treeExtent := Project current world height < 500 ifTrue: [ 350 at 150 ] ifFalse: [ 350 at 300 ]. (treePane := aFileList morphicDirectoryTreePaneFiltered: option) extent: treeExtent; retractable: false; borderWidth: 0. window addARowCentered: { window fancyText: 'Publish This Project' translated font: Preferences standardEToysTitleFont color: textColor1 }. buttonRow := OrderedCollection new. buttons do: [:button | buttonRow add: button] separatedBy: [buttonRow add: ((Morph new extent: 30 at 5) color: Color transparent)]. " addARowCentered: { buttons first. (Morph new extent: 30 at 5) color: Color transparent. buttons second. (Morph new extent: 30 at 5) color: Color transparent. buttons third };" window addARowCentered: buttonRow; addARowCentered: { (window inAColumn: {(ProjectViewMorph on: aProject) lock}) layoutInset: 4}; addARowCentered: { window fancyText: 'Please select a folder' translated font: Preferences standardEToysFont color: textColor1 }; addARow: { ( window inAColumn: { (pane2 := window inARow: {window inAColumn: {treePane}}) useRoundedCorners; layoutInset: 0; borderWidth: 1; borderColor: (Color r: 0.6 g: 0.7 b: 1) } ) layoutInset: 10 }. window fullBounds. window fillWithRamp: (Color r: 1 g: 0.85 b: 0.975) oriented: 0.65. pane2 fillWithRamp: (Color r: 0.85 g: 0.9 b: 1) oriented: (0.7 @ 0.35). " buttons do: [ :each | each fillWithRamp: ColorTheme current dialogButtonsRampOrColor oriented: (0.75 @ 0). ]. " + window morphicLayerNumber: window class dialogLayer. - window setProperty: #morphicLayerNumber toValue: 11. aFileList postOpen. window adoptPaneColor: (Color r: 0.548 g: 0.677 b: 1.0). ^ window ! From commits at source.squeak.org Fri Feb 26 14:52:53 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 26 Feb 2021 14:52:53 0000 Subject: [squeak-dev] The Trunk: PreferenceBrowser-mt.112.mcz Message-ID: Marcel Taeumel uploaded a new version of PreferenceBrowser to project The Trunk: http://source.squeak.org/trunk/PreferenceBrowser-mt.112.mcz ==================== Summary ==================== Name: PreferenceBrowser-mt.112 Author: mt Time: 26 February 2021, 3:52:51.660955 pm UUID: 267f5452-97da-f34b-8104-f181caa03604 Ancestors: PreferenceBrowser-mt.111 Complements Morphic-mt.1726 =============== Diff against PreferenceBrowser-mt.111 =============== Item was changed: ----- Method: PreferenceWizardMorph>>initialize (in category 'initialization') ----- initialize super initialize. isFullScreen := false. self hasLowPerformance ifTrue: [self color: self defaultColor] ifFalse: [self color: (self defaultColor alpha: 0.75)]. self setProperty: #indicateKeyboardFocus toValue: #never. self changeProportionalLayout; layoutInset: 20; cellGap: 10; cellPositioning: #center; + disableLayout: true; + morphicLayerNumber: self class dialogLayer + 1. - disableLayout: true. self addKeyboardCaptureFilter: self.! Item was removed: - ----- Method: PreferenceWizardMorph>>morphicLayerNumber (in category 'layout') ----- - morphicLayerNumber - - ^ 1! From commits at source.squeak.org Fri Feb 26 15:01:22 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 26 Feb 2021 15:01:22 0000 Subject: [squeak-dev] The Trunk: 60Deprecated-mt.89.mcz Message-ID: Marcel Taeumel uploaded a new version of 60Deprecated to project The Trunk: http://source.squeak.org/trunk/60Deprecated-mt.89.mcz ==================== Summary ==================== Name: 60Deprecated-mt.89 Author: mt Time: 26 February 2021, 4:01:21.309077 pm UUID: 05ea8570-9a8e-aa44-901d-ffeaac3e325f Ancestors: 60Deprecated-mt.88 Soften the previous deprecation to not lock up the image during the image. =============== Diff against 60Deprecated-mt.88 =============== Item was changed: ----- Method: Morph>>addMorphInFrontOfLayer: (in category '*60Deprecated-WiW support') ----- addMorphInFrontOfLayer: aMorph + self flag: #deprecated. "Use #addMorphFrontInLayer: instead". - self deprecated: 'Use #addMorphFrontInLayer: instead.'. ^ self addMorphFrontInLayer: aMorph! Item was changed: ----- Method: Morph>>morphicLayerNumberWithin: (in category '*60Deprecated-WiW support') ----- morphicLayerNumberWithin: anOwner + self flag: #deprecated. "Use #morphicLayerNumber instead". - self deprecated: 'Use #morphicLayerNumber instead.'. ^ self morphicLayerNumber! From commits at source.squeak.org Fri Feb 26 15:03:47 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 26 Feb 2021 15:03:47 0000 Subject: [squeak-dev] The Trunk: 60Deprecated-mt.90.mcz Message-ID: Marcel Taeumel uploaded a new version of 60Deprecated to project The Trunk: http://source.squeak.org/trunk/60Deprecated-mt.90.mcz ==================== Summary ==================== Name: 60Deprecated-mt.90 Author: mt Time: 26 February 2021, 4:03:45.796077 pm UUID: 4019283c-bb5b-5a46-ae48-8b90d0d891e2 Ancestors: 60Deprecated-mt.89 Next try to no lock up the image while updating. Use a method that is definitely existing. =============== Diff against 60Deprecated-mt.89 =============== Item was changed: ----- Method: Morph>>addMorphInFrontOfLayer: (in category '*60Deprecated-WiW support') ----- addMorphInFrontOfLayer: aMorph self flag: #deprecated. "Use #addMorphFrontInLayer: instead". + ^ self addMorphFront: aMorph! - ^ self addMorphFrontInLayer: aMorph! From commits at source.squeak.org Fri Feb 26 15:06:42 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 26 Feb 2021 15:06:42 0000 Subject: [squeak-dev] The Trunk: 60Deprecated-mt.91.mcz Message-ID: Marcel Taeumel uploaded a new version of 60Deprecated to project The Trunk: http://source.squeak.org/trunk/60Deprecated-mt.91.mcz ==================== Summary ==================== Name: 60Deprecated-mt.91 Author: mt Time: 26 February 2021, 4:06:40.619077 pm UUID: 6d65b8cc-da01-2d49-9774-79687ef96ebd Ancestors: 60Deprecated-mt.90 Sigh. The last one produced an endless recursion. =============== Diff against 60Deprecated-mt.90 =============== Item was changed: ----- Method: Morph>>addMorphInFrontOfLayer: (in category '*60Deprecated-WiW support') ----- addMorphInFrontOfLayer: aMorph self flag: #deprecated. "Use #addMorphFrontInLayer: instead". + ^ self privateAddMorph: aMorph atIndex: 1! - ^ self addMorphFront: aMorph! From commits at source.squeak.org Fri Feb 26 15:11:15 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Fri, 26 Feb 2021 15:11:15 0000 Subject: [squeak-dev] The Trunk: Morphic-mt.1727.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.1727.mcz ==================== Summary ==================== Name: Morphic-mt.1727 Author: mt Time: 26 February 2021, 4:11:09.467077 pm UUID: abe6e8cd-15b2-204c-bd96-9f85ade5304c Ancestors: Morphic-mt.1726 Minor tweak in the conversion script for flaps. =============== Diff against Morphic-mt.1726 =============== Item was changed: + (PackageInfo named: 'Morphic') postscript: 'PasteUpMorph allSubInstancesDo: [:m | m isFlap ifTrue: [m morphicLayerNumber: Morph navigatorLayer]]. - (PackageInfo named: 'Morphic') postscript: 'PasteUpMorph allInstances do: [:m | m isFlap ifTrue: [m morphicLayerNumber: Morph navigatorLayer]]. TheWorldMainDockingBar updateInstances. SystemProgressMorph reset. self currentWorld reorderSubmorphsInLayers.'! From bruce.oneel at pckswarms.ch Fri Feb 26 16:34:49 2021 From: bruce.oneel at pckswarms.ch (Bruce O'Neel) Date: Fri, 26 Feb 2021 17:34:49 +0100 Subject: [squeak-dev] Squeak-related Talks this Friday In-Reply-To: References: Message-ID: <1614357289-a56b358b68c1860af9c7f67f3774a427@pckswarms.ch> Hi, Is it possible that the talks were recorded, and, if so that we can see them? Thanks! cheers bruce -------------- next part -------------- An HTML attachment was scrubbed... URL: From lproven at gmail.com Fri Feb 26 16:42:32 2021 From: lproven at gmail.com (Liam Proven) Date: Fri, 26 Feb 2021 17:42:32 +0100 Subject: [squeak-dev] Squeak-related Talks this Friday In-Reply-To: <1614357289-a56b358b68c1860af9c7f67f3774a427@pckswarms.ch> References: <1614357289-a56b358b68c1860af9c7f67f3774a427@pckswarms.ch> Message-ID: On Fri, 26 Feb 2021 at 17:35, Bruce O'Neel wrote: > Is it possible that the talks were recorded, and, if so that we can see them? Whoops. What he said! I only saw the announcement now. :-( -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From ken.dickey at whidbey.com Sat Feb 27 00:46:14 2021 From: ken.dickey at whidbey.com (ken.dickey at whidbey.com) Date: Fri, 26 Feb 2021 16:46:14 -0800 Subject: [squeak-dev] seL4 Microkernel: How small can the shim be? Message-ID: <2e1c7a819dbffc813b8b7210055e8ef3@whidbey.com> Liam wrote: > I do not know much about the whole L4 family but what little I know some of the existing OSes based upon them were very vaguely Unix-ish. That's precisely what I'm trying to move away from. • I do not know if SEL4 has working multiprocessor support. I know that QNX does, which demonstrates that a Unix-like true microkernel can do this; but I also believe that Minix 3 so far lacks one, and lacks some APIs needed for POSIX and xNix compatibility. This is not an easy thing to do. .. Right. I am thinking of expanding outward from Genode ( https://genode.org/about/index ), start with a small (non-Unix) OS which runs on (some of) x86/ARM64/RISC-V which can be used as a bootstrap for Smalltalk->Native runtime, then replace services written in C to services written in Smalltalk initially with the same API, but later re-imagined. An ultra-secure OS which has the right basics for hotplug/live updates. Add eMail & Web browsing after getting core St GUI up. This is pretty much a scratch effort. Some C at first, particularly in the microkernel (e.g. seL4) but this is minimal and kinda like changing FPGA gates. We are probably "agreeing loudly" on most of this, particularly given my ignorance of Oberon. Later, -KenD From tim at rowledge.org Sat Feb 27 19:42:46 2021 From: tim at rowledge.org (tim Rowledge) Date: Sat, 27 Feb 2021 11:42:46 -0800 Subject: [squeak-dev] seL4 Microkernel: How small can the shim be? In-Reply-To: <2e1c7a819dbffc813b8b7210055e8ef3@whidbey.com> References: <2e1c7a819dbffc813b8b7210055e8ef3@whidbey.com> Message-ID: <81CC89CC-EA56-40CF-82B3-EA4BC690FA9D@rowledge.org> This might be of some interest - https://hackaday.com/2021/02/24/real-time-os-basics-picking-the-right-rtos-when-you-need-one/ Also - if you're interested in minimal OS with easy low-level access you could do worse than investigating RISC OS. Get a Pi, download the package from riscos direct )https://www.riscosdev.com/direct/) and play. > On 2021-02-26, at 4:46 PM, ken.dickey at whidbey.com wrote: > > Liam wrote: > >> I do not know much about the whole L4 family but what little I know > some of the existing OSes based upon them were very vaguely Unix-ish. > That's precisely what I'm trying to move away from. > > • I do not know if SEL4 has working multiprocessor support. I know > that QNX does, which demonstrates that a Unix-like true microkernel > can do this; but I also believe that Minix 3 so far lacks one, and > lacks some APIs needed for POSIX and xNix compatibility. This is not > an easy thing to do. > .. > > Right. I am thinking of expanding outward from Genode ( https://genode.org/about/index ), start with a small (non-Unix) OS which runs on (some of) x86/ARM64/RISC-V which can be used as a bootstrap for Smalltalk->Native runtime, then replace services written in C to services written in Smalltalk initially with the same API, but later re-imagined. An ultra-secure OS which has the right basics for hotplug/live updates. Add eMail & Web browsing after getting core St GUI up. > > This is pretty much a scratch effort. Some C at first, particularly in the microkernel (e.g. seL4) but this is minimal and kinda like changing FPGA gates. > > We are probably "agreeing loudly" on most of this, particularly given my ignorance of Oberon. > > Later, > -KenD > > tim -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim Strange OpCodes: RCR: Rewind Card Reader From commits at source.squeak.org Sun Feb 28 12:39:22 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sun, 28 Feb 2021 12:39:22 0000 Subject: [squeak-dev] The Inbox: Kernel-jar.1375.mcz Message-ID: A new version of Kernel was added to project The Inbox: http://source.squeak.org/inbox/Kernel-jar.1375.mcz ==================== Summary ==================== Name: Kernel-jar.1375 Author: jar Time: 28 February 2021, 1:39:18.242036 pm UUID: 5fa0cf53-5852-2949-b7f0-a13d8729925b Ancestors: Kernel-codefrau.1374 Fix Process class >> #forContext:priority: potentially crashing image =============== Diff against Kernel-codefrau.1374 =============== Item was changed: ----- Method: Process class>>forContext:priority: (in category 'instance creation') ----- forContext: aContext priority: anInteger "Answer an instance of me that has suspended aContext at priority anInteger." | newProcess | newProcess := self new. + newProcess suspendedContext: aContext asContext. - newProcess suspendedContext: aContext. newProcess priority: anInteger. ^newProcess! From m at jaromir.net Sun Feb 28 12:42:45 2021 From: m at jaromir.net (Jaromir Matas) Date: Sun, 28 Feb 2021 06:42:45 -0600 (CST) Subject: [squeak-dev] The Inbox: Kernel-jar.1375.mcz In-Reply-To: References: Message-ID: <1614516165164-0.post@n4.nabble.com> #forContext:priority: may cause image crash when supplying e.g. a block instead of a context: (save your image first!) create a new process: p := Process forContext: ["whatever"] priority: Processor activePriority and then try to start a Process Browser or just do-it: p isTerminated The thing is both Process Browser and #isTerminated send `suspendedContext isBottomContext` and that fails, starting a debugger and in some cases windows start popping up... I guess the easiest and safest fix is to send #asContext to the aContext argument in #forContext:priority: If not then a condition has to be added to make sure the aContext argument really is a context. regards, ----- ^[^ Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From lproven at gmail.com Sun Feb 28 13:11:43 2021 From: lproven at gmail.com (Liam Proven) Date: Sun, 28 Feb 2021 14:11:43 +0100 Subject: [squeak-dev] seL4 Microkernel: How small can the shim be? In-Reply-To: <81CC89CC-EA56-40CF-82B3-EA4BC690FA9D@rowledge.org> References: <2e1c7a819dbffc813b8b7210055e8ef3@whidbey.com> <81CC89CC-EA56-40CF-82B3-EA4BC690FA9D@rowledge.org> Message-ID: On Sat, 27 Feb 2021 at 20:42, tim Rowledge wrote: > > Also - if you're interested in minimal OS with easy low-level access you could do worse than investigating RISC OS. Get a Pi, download the package from riscos direct )https://www.riscosdev.com/direct/) and play. I am well aware of RISC OS. I distributed some fractal generators for RISC OS back in the 1980s. :-) I have a RPi 3B+ running RISC OS Direct sitting right next to me. In fact, I have already been trying to explain some of the limitations of RISC OS to the people running the Cloverleaf kickstarter campaign. I wrote some of it up in a blog post, here: https://liam-on-linux.livejournal.com/73983.html This generated a bit of discussion on HackerNews, but as usual, lots of heat but little light. https://news.ycombinator.com/item?id=24735766 I still play around with RISC OS today. The reasons that I do not think it is a suitable candidate for new efforts are: • It is not a clean simple design: it is an old, complex one; • It is mostly ARM assembler and not even slightly portable; even moving it to new ARM hardware is hard; • It is technically very limited, with little memory protection, very limited CLI-only pre-emptive multitasking, no support for threads or SMP; • It is 32-bit only and the only realistic way of doing a 64-bit version will be using some kind of VM or emulation Other interesting lightweight vintage OSes which are now FOSS: • Atari ST TOS/Mint: https://aranym.github.io/afros.html • A relatively early version of Sinclair QDOS, Minerva: https://github.com/janbredenbeek/Minerva4Q68 • The final version of the Sinclair OS, rewritten for Atari hardware, SMSQ/e: http://www.wlenerz.com/smsqe/ • A FOSS re-implementation of the original Amiga OS: https://aros.sourceforge.io/ But all of these are compromised, limited designs, hard to port, hard or impossible to modernise while retaining any compatibility. Really, seriously, this talk was based on _over_ a decade of research and study. My choices were not casual ones or lightly considered! :-) I was not merely looking for a lightweight OS. I had a demanding list of criteria. I looked for: • a clean, simple OS, with SMP support, that supported pre-emption, memory management etc. • in a type-safe language, with a native-object-code compiler — not JITTed, not using a VM or runtime • and a readable language, not something far outside the Algol family of imperative HLLs • that was portable across different architectures • that was FOSS and could be forked • that was documented and had a user community who knew it • that can be built with FOSS tools (which RISC OS fails, for instance) • which is or was used by non-specialists for general purpose computing • which can usefully access the Internet • which runs on commodity hardware • which does not have a strongly filesystem-centric design that would not fit a PMEM-only computer (i.e. not an xNix) If anyone else has any candidates that meet all of these, I would very much like to know. It took a lot of searching and I don't know anything else that ticks all the boxes. -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From lewis at mail.msen.com Sun Feb 28 14:31:18 2021 From: lewis at mail.msen.com (David T. Lewis) Date: Sun, 28 Feb 2021 09:31:18 -0500 Subject: [squeak-dev] seL4 Microkernel: How small can the shim be? In-Reply-To: References: <2e1c7a819dbffc813b8b7210055e8ef3@whidbey.com> <81CC89CC-EA56-40CF-82B3-EA4BC690FA9D@rowledge.org> Message-ID: <20210228143118.GA62558@shell.msen.com> Hi Lian, I'm not sure if you are aware, but Tim is one of the original core VM developers and is the author of the RISC OS VM for Squeak. Here are a few links of interest: http://squeakvm.org/riscos/ http://www.rowledge.org/tim/squeak/ http://squeakvm.org/cgi-bin/viewvc.cgi/squeak/trunk/platforms/RiscOS/ http://source.squeak.org/VMMaker In addition to the official VM releases that Tim provided, the source code is all still on line in a Subversion repository at squeakvm.org (platform source code) and in the VMMaker repository at source.squeak.org (for the VM code written in Smalltalk). Dave On Sun, Feb 28, 2021 at 02:11:43PM +0100, Liam Proven wrote: > On Sat, 27 Feb 2021 at 20:42, tim Rowledge wrote: > > > > Also - if you're interested in minimal OS with easy low-level access you could do worse than investigating RISC OS. Get a Pi, download the package from riscos direct )https://www.riscosdev.com/direct/) and play. > > I am well aware of RISC OS. I distributed some fractal generators for > RISC OS back in the 1980s. :-) I have a RPi 3B+ running RISC OS Direct > sitting right next to me. > > In fact, I have already been trying to explain some of the limitations > of RISC OS to the people running the Cloverleaf kickstarter campaign. > > I wrote some of it up in a blog post, here: > https://liam-on-linux.livejournal.com/73983.html > > This generated a bit of discussion on HackerNews, but as usual, lots > of heat but little light. > https://news.ycombinator.com/item?id=24735766 > > I still play around with RISC OS today. The reasons that I do not > think it is a suitable candidate for new efforts are: > ??? It is not a clean simple design: it is an old, complex one; > ??? It is mostly ARM assembler and not even slightly portable; even > moving it to new ARM hardware is hard; > ??? It is technically very limited, with little memory protection, very > limited CLI-only pre-emptive multitasking, no support for threads or > SMP; > ??? It is 32-bit only and the only realistic way of doing a 64-bit > version will be using some kind of VM or emulation > > Other interesting lightweight vintage OSes which are now FOSS: > ??? Atari ST TOS/Mint: https://aranym.github.io/afros.html > ??? A relatively early version of Sinclair QDOS, Minerva: > https://github.com/janbredenbeek/Minerva4Q68 > ??? The final version of the Sinclair OS, rewritten for Atari hardware, > SMSQ/e: http://www.wlenerz.com/smsqe/ > ??? A FOSS re-implementation of the original Amiga OS: > https://aros.sourceforge.io/ > > But all of these are compromised, limited designs, hard to port, hard > or impossible to modernise while retaining any compatibility. > > Really, seriously, this talk was based on _over_ a decade of research > and study. My choices were not casual ones or lightly considered! :-) > > I was not merely looking for a lightweight OS. I had a demanding list > of criteria. > > I looked for: > ??? a clean, simple OS, with SMP support, that supported pre-emption, > memory management etc. > ??? in a type-safe language, with a native-object-code compiler ??? not > JITTed, not using a VM or runtime > ??? and a readable language, not something far outside the Algol family > of imperative HLLs > ??? that was portable across different architectures > ??? that was FOSS and could be forked > ??? that was documented and had a user community who knew it > ??? that can be built with FOSS tools (which RISC OS fails, for instance) > ??? which is or was used by non-specialists for general purpose computing > ??? which can usefully access the Internet > ??? which runs on commodity hardware > ??? which does not have a strongly filesystem-centric design that would > not fit a PMEM-only computer (i.e. not an xNix) > > If anyone else has any candidates that meet all of these, I would very > much like to know. It took a lot of searching and I don't know > anything else that ticks all the boxes. > > -- > Liam Proven ??? Profile: https://about.me/liamproven > Email: lproven at cix.co.uk ??? gMail/gTalk/gHangouts: lproven at gmail.com > Twitter/Facebook/LinkedIn/Flickr: lproven ??? Skype: liamproven > UK: +44 7939-087884 ??? ??R (+ WhatsApp/Telegram/Signal): +420 702 829 053 > From ken.dickey at whidbey.com Sun Feb 28 16:16:21 2021 From: ken.dickey at whidbey.com (ken.dickey at whidbey.com) Date: Sun, 28 Feb 2021 08:16:21 -0800 Subject: [squeak-dev] [RE] seL4 Microkernel: How small can the shim be? Message-ID: Liam wrote: > I was not merely looking for a lightweight OS. I had a demanding list of criteria. > I looked for: • a clean, simple OS, with SMP support, that supported pre-emption, memory management etc. • in a type-safe language, with a native-object-code compiler — not JITTed, not using a VM or runtime • and a readable language, not something far outside the Algol family of imperative HLLs • that was portable across different architectures • that was FOSS and could be forked • that was documented and had a user community who knew it • that can be built with FOSS tools (which RISC OS fails, for instance) • which is or was used by non-specialists for general purpose computing • which can usefully access the Internet • which runs on commodity hardware • which does not have a strongly filesystem-centric design that would not fit a PMEM-only computer (i.e. not an xNix) I think you have specified a null set. Alan Kay said: "The best way to predict the future is to invent it." You have described the world you want to move into. My only suggestion here is to look at OSs which are easily ported. I would look at RISC-V because the kind of solution you are looking for will probably appear there first. Within "type-strict", you might consider a Rust or Haskell oSs. [I think Smalltalk is "type-safe", every object knows its class and trying to access element 41 of a 10 element array gives DNU, but I suspect this is not your definition]. For small, FreeRTOS and PharOS (https://sourceforge.net/projects/rtospharos/) look interesting. From Wikipedia entry on RISC-V: "Available RISC-V software tools include a GNU Compiler Collection (GCC) toolchain (with GDB, the debugger), an LLVM toolchain, the OVPsim simulator (and library of RISC-V Fast Processor Models), the Spike simulator, and a simulator in QEMU (RV32GC/RV64GC). Operating system support exists for the Linux kernel, FreeBSD, and NetBSD, but the supervisor-mode instructions were unstandardized prior to June 2019,[14] so this support is provisional. The preliminary FreeBSD port to the RISC-V architecture was upstreamed in February 2016, and shipped in FreeBSD 11.0.[96][74] Ports of Debian[97] and Fedora[98] are stabilizing (both only support 64-bit RISC-V, with no plans to support 32-bit version). A port of Das U-Boot exists.[99] UEFI Spec v2.7 has defined the RISC-V binding and a TianoCore port has been done by HPE engineers[100] and is expected to be upstreamed. There is a preliminary port of the seL4 microkernel.[101][102] Hex Five released the first Secure IoT Stack for RISC-V with FreeRTOS support.[103] Also xv6, a modern reimplementation of Sixth Edition Unix in ANSI C used for pedagogical purposes in MIT, was ported. Pharos RTOS has been ported to 64-bit RISC-V[104] (including time and memory protection). Also see Comparison of real-time operating systems. " Note also OSDev.org. Good on ya, -KenD From gettimothy at zoho.com Sun Feb 28 17:41:54 2021 From: gettimothy at zoho.com (gettimothy) Date: Sun, 28 Feb 2021 12:41:54 -0500 Subject: [squeak-dev] =?utf-8?b?VW5pY29kZSBDaGFyYWN0ZXIg4oCcw6DigJ0gKFUr?= =?utf-8?q?00E0=29___and_XTreams-Parsing_and_just_ignore_the__combining_ma?= =?utf-8?q?rk_sequences=3F?= Message-ID: <177e9bb7af2.ba5ff96b115726.7556830597676651370@zoho.com> Hi folks, TL;DR in XTreams-Parsing do I need to add support to account for the "combining mark" as described in this regex tutorial here: https://www.regular-expressions.info/unicode.html The Unicode code point U+0300 (grave accent) is a "combining mark" Any code point that is not a combining mark can be followed by any number of combining marks. This sequence, like U+0061 U+0300 above, is displayed as a single grapheme on the screen. per: https://www.compart.com/en/unicode/U+00E0   “à” can be encoded several ways: UTF-8 Encoding: 0xC3 0xA0 UTF-16 Encoding: 0x00E0 UTF-32 Encoding: 0x000000E0 I assume that the sequence 0xC3 0xA0  is the combination the regex dude refers to. Here are some relevant Printit (values render correctly in Squeak with unifont installed, not so much in the browser where I print them) Character codePoint:224 Character value: 16r0000E0 Character value: 16r0061 Character value: 16r0300 (Character value: 16r0061) asString , (Character value: 16r0300) asString Escape: backslash character: character hexes: hexes backslash = '\' ifTrue: [character = $s ifTrue: [^Character space]. character = $t ifTrue: [^Character tab]. character = $n ifTrue: [^Character cr]. character = $r ifTrue: [^Character lf]. character = $x ifTrue: [^('16r', (String withAll: hexes)) asNumber asCharacter]]. ^character Character value: 16r00C3 Character value: 16r00A0 (Character value: 16r00C1) asString , (Character value: 16r00A0) asString The reason I ask is that just as Character does not (nor should it?) support combining marks Neither does XTreams-Parsing...from the PEG grammar and the relevant callback I have the following rules: Escape <- BACKSLASH [x] [0-9A-F]{6}  / BACKSLASH [nrts\-\\\[\]\''\"] / EscapeError EscapeError <- BACKSLASH . with callback: Escape: backslash character: character hexes: hexes backslash = '\' ifTrue: [character = $s ifTrue: [^Character space]. character = $t ifTrue: [^Character tab]. character = $n ifTrue: [^Character cr]. character = $r ifTrue: [^Character lf]. character = $x ifTrue: [^('16r', (String withAll: hexes)) asNumber asCharacter]]. ^character which you can see does not support capture of the pair 0x00C3 0x00A0 to return “à” I am strongly leaning towards ignoring the pairs and assuming that all characters such as above are part of the extension. Thoughts appreciated. thx -------------- next part -------------- An HTML attachment was scrubbed... URL: From tim at rowledge.org Sun Feb 28 18:32:19 2021 From: tim at rowledge.org (tim Rowledge) Date: Sun, 28 Feb 2021 10:32:19 -0800 Subject: [squeak-dev] seL4 Microkernel: How small can the shim be? In-Reply-To: References: <2e1c7a819dbffc813b8b7210055e8ef3@whidbey.com> <81CC89CC-EA56-40CF-82B3-EA4BC690FA9D@rowledge.org> Message-ID: > On 2021-02-28, at 5:11 AM, Liam Proven wrote: > > I am well aware of RISC OS. I distributed some fractal generators for > RISC OS back in the 1980s. :-) I have a RPi 3B+ running RISC OS Direct > sitting right next to me. Good; not enough people know of it. I was involved before it was even a Thing, and kept using as my main work system (even coercing assorted research labs in Silicon Valley to support me in this insanity) until about 2010. > I wrote some of it up in a blog post, here: > https://liam-on-linux.livejournal.com/73983.html I'd dispute a few of your assertions there but, yeah, mostly. I don't think one could 'improve' RISC OS into a usefully modern OS but I do think one could create a modern OS with the 'spirit' of RISC OS. And nobody would use it. :-( > I still play around with RISC OS today. The reasons that I do not > think it is a suitable candidate for new efforts are: [snip] Pretty much the case. It *was* a simple design, but grew .... complicated, over the decades. > > Other interesting lightweight vintage OSes which are now FOSS: Mention not these primitive abacus's. > I was not merely looking for a lightweight OS. I had a demanding list > of criteria. > > I looked for: > • a clean, simple OS, with SMP support, that supported pre-emption, > memory management etc. > • in a type-safe language, with a native-object-code compiler — not > JITTed, not using a VM or runtime > • and a readable language, not something far outside the Algol family > of imperative HLLs > • that was portable across different architectures > • that was FOSS and could be forked > • that was documented and had a user community who knew it > • that can be built with FOSS tools (which RISC OS fails, for instance) > • which is or was used by non-specialists for general purpose computing > • which can usefully access the Internet > • which runs on commodity hardware > • which does not have a strongly filesystem-centric design that would > not fit a PMEM-only computer (i.e. not an xNix) Well, as Ken says, that's pretty much an empty set. I'd certainly not accept the 'not jitted' criterion since I am going to stand on my claim that it would make it much easier to write and maintain a flexible system. I'd also point out that the OS per se has nothing at all to do with whether an in-use system is suited to general users or experts - that's the domain of the software running on top of/in the OS. With sufficient work and inspiration one could even make Windows tolerable at the user level. If you can find a way to engage a few tens of millions of plausible currency units then there may be avenues to success. Some of us on this very list have seriously tried in the past but if you have any way to get it done... fabulous! tim -- tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim Strange OpCodes: STOP: No Op From commits at source.squeak.org Sun Feb 28 18:58:46 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sun, 28 Feb 2021 18:58:46 0000 Subject: [squeak-dev] The Inbox: Kernel-jar.1376.mcz Message-ID: A new version of Kernel was added to project The Inbox: http://source.squeak.org/inbox/Kernel-jar.1376.mcz ==================== Summary ==================== Name: Kernel-jar.1376 Author: jar Time: 28 February 2021, 7:58:42.007459 pm UUID: d063e740-7836-a94a-9796-488741d2b2b6 Ancestors: Kernel-codefrau.1374 Fix Process >> #isTerminated inconsistent behavior - for discussion =============== Diff against Kernel-codefrau.1374 =============== Item was changed: ----- Method: Process>>isTerminated (in category 'testing') ----- isTerminated "Answer if the receiver is terminated, or at least terminating." self isActiveProcess ifTrue: [^ false]. ^suspendedContext isNil + or: ["If the suspendedContext is the bottomContext and the pc is at the endPC, + then there is nothing more to do." - or: ["If the suspendedContext is the bottomContext it is the block in Process>>newProcess. - If so, and the pc is at the endPC, the block has already sent and returned - from value and there is nothing more to do." suspendedContext isBottomContext + and: [suspendedContext pc >= suspendedContext endPC + or: [suspendedContext closure - and: [suspendedContext closure ifNil: [suspendedContext methodClass == Process and: [suspendedContext selector == #terminate]] + ifNotNil: [false]]]]! - ifNotNil: [suspendedContext pc >= suspendedContext closure endPC]]]! From m at jaromir.net Sun Feb 28 19:08:37 2021 From: m at jaromir.net (Jaromir Matas) Date: Sun, 28 Feb 2021 13:08:37 -0600 (CST) Subject: [squeak-dev] The Inbox: Kernel-jar.1376.mcz In-Reply-To: References: Message-ID: <1614539317095-0.post@n4.nabble.com> Hi, the following example shows a slight inconsistency in the process terminantion logic: p := Process forContext: ([] asContextWithSender: thisContext) priority: 40 p isTerminated --> false p terminate p isTerminated --> false I'm aware the example is nonsensical but I guess the terminate => isTerminated logic should be followed anyway. I propose the following change in the #isTerminated condition. The idea is if suspendedContext is the bottomContext and pc >= endPC then it should be considered terminated regardless of whether there is or isn't a closure. The rest of the condition remains intact. All tests green. I also suggest a new wording of the comment (the bottomContext block doesn't necessarily need to be the block in BlockClosure>>newProcess so I removed the note). The suggested version: isTerminated "Answer if the receiver is terminated, or at least terminating." self isActiveProcess ifTrue: [^ false]. ^suspendedContext isNil or: ["If the suspendedContext is the bottomContext and the pc is at the endPC, then there is nothing more to do." suspendedContext isBottomContext and: [suspendedContext pc >= suspendedContext endPC or: [suspendedContext closure ifNil: [suspendedContext methodClass == Process and: [suspendedContext selector == #terminate]] ifNotNil: [false]]]] ----- ^[^ Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From m at jaromir.net Sun Feb 28 22:48:38 2021 From: m at jaromir.net (Jaromir Matas) Date: Sun, 28 Feb 2021 16:48:38 -0600 (CST) Subject: [squeak-dev] The Inbox: Compiler-mt.456.mcz In-Reply-To: References: Message-ID: <1614552518445-0.post@n4.nabble.com> > > > Hi all! > > I would like to merge into Trunk. But I > still need a nice test case. Should be independent from the JIT. Maybe a > simple setter? > > foobar: value >     >    instVar := value > > ... > > [ test instVar should be 42 already ] forkAt: current + 1. > self foobar: 42. > > ?? > Hi Marcel, is it even possible to test #valueNoContextSwitch? I'm trying to understand what would that require: you'd like to catch a higher priority process trying to interrupt (preempt) a block activation between the #valueNoContextSwitch send and the first context switching point inside the block - right? Like a non-primitive send etc. So it's a very short period of time you're targeting before the first switching point. I was thinking along the lines of: x := 0. [1 milliSecond wait. x := x+1000000] forkAt:41. [[x:=x+1. x<1000000] whileTrue] valueNoContextSwitch. x but x returns e.g. 1084476 meaning whileTrue must be a context switching point (because it's a backward jump?) and 1 millisecond is a desperately long period... My question - is this at least the right understanding? If yes, could you think of any time consuming operations that would not contain any switching points? To get past the 1 msec? I'm really curious. Thanks! ----- ^[^ Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html From commits at source.squeak.org Sun Feb 28 23:15:42 2021 From: commits at source.squeak.org (commits at source.squeak.org) Date: Sun, 28 Feb 2021 23:15:42 0000 Subject: [squeak-dev] The Trunk: Kernel-jar.1375.mcz Message-ID: Eliot Miranda uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-jar.1375.mcz ==================== Summary ==================== Name: Kernel-jar.1375 Author: jar Time: 28 February 2021, 1:39:18.242036 pm UUID: 5fa0cf53-5852-2949-b7f0-a13d8729925b Ancestors: Kernel-codefrau.1374 Fix Process class >> #forContext:priority: potentially crashing image =============== Diff against Kernel-codefrau.1374 =============== Item was changed: ----- Method: Process class>>forContext:priority: (in category 'instance creation') ----- forContext: aContext priority: anInteger "Answer an instance of me that has suspended aContext at priority anInteger." | newProcess | newProcess := self new. + newProcess suspendedContext: aContext asContext. - newProcess suspendedContext: aContext. newProcess priority: anInteger. ^newProcess! From lproven at gmail.com Sun Feb 28 23:31:15 2021 From: lproven at gmail.com (Liam Proven) Date: Mon, 1 Mar 2021 00:31:15 +0100 Subject: [squeak-dev] seL4 Microkernel: How small can the shim be? In-Reply-To: <20210228143118.GA62558@shell.msen.com> References: <2e1c7a819dbffc813b8b7210055e8ef3@whidbey.com> <81CC89CC-EA56-40CF-82B3-EA4BC690FA9D@rowledge.org> <20210228143118.GA62558@shell.msen.com> Message-ID: On Sun, 28 Feb 2021 at 15:31, David T. Lewis wrote: > > Hi Lian, > > I'm not sure if you are aware, but Tim is one of the original core > VM developers and is the author of the RISC OS VM for Squeak. Here > are a few links of interest: [...] Oh my word! No, I was not. Actually I did not even realise that Squeak ran on RISC OS at all. That's quite an achievement. As I understand it, the current version of RISC OS Direct on the Raspberry Pi 4 can access 4GB of RAM and is up there, performance-wise, with the fastest RISC OS boxes ever made. It allows significantly larger programs, too -- I am not sure of the maximum WimpSlot but I think it's a gig or 2 now. I suspect Squeak would run rather well on that. -- Liam Proven – Profile: https://about.me/liamproven Email: lproven at cix.co.uk – gMail/gTalk/gHangouts: lproven at gmail.com Twitter/Facebook/LinkedIn/Flickr: lproven – Skype: liamproven UK: +44 7939-087884 – ČR (+ WhatsApp/Telegram/Signal): +420 702 829 053 From eliot.miranda at gmail.com Sun Feb 28 23:35:16 2021 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sun, 28 Feb 2021 15:35:16 -0800 Subject: [squeak-dev] The Inbox: Kernel-jar.1376.mcz In-Reply-To: <1614539317095-0.post@n4.nabble.com> References: <1614539317095-0.post@n4.nabble.com> Message-ID: Hi Jaromir, On Sun, Feb 28, 2021 at 11:08 AM Jaromir Matas wrote: > Hi, the following example shows a slight inconsistency in the process > terminantion logic: > > p := Process forContext: ([] asContextWithSender: thisContext) priority: > 40 > > p isTerminated --> false > > p terminate > > p isTerminated --> false > > > I'm aware the example is nonsensical but I guess the terminate => > isTerminated logic should be followed anyway. > > I propose the following change in the #isTerminated condition. The idea is > if suspendedContext is the bottomContext and pc >= endPC then it should be > considered terminated regardless of whether there is or isn't a closure. > The > rest of the condition remains intact. All tests green. > > I also suggest a new wording of the comment (the bottomContext block > doesn't > necessarily need to be the block in BlockClosure>>newProcess so I removed > the note). > > The suggested version: > > isTerminated > "Answer if the receiver is terminated, or at least terminating." > self isActiveProcess ifTrue: [^ false]. > ^suspendedContext isNil > or: ["If the suspendedContext is the bottomContext and the pc is > at the endPC, > then there is nothing more to do." > suspendedContext isBottomContext > and: [suspendedContext pc >= suspendedContext endPC > or: [suspendedContext closure > ifNil: [suspendedContext > methodClass == Process > and: > [suspendedContext selector == #terminate]] > ifNotNil: [false]]]] > > > I like this. But isn't this a little bit better? isTerminated "Answer if the receiver is terminated, or at least terminating." self isActiveProcess ifTrue: [^ false]. ^suspendedContext isNil or: ["If the suspendedContext is the bottomContext and the pc is at the endPC, then there is nothing more to do." suspendedContext isBottomContext and: [suspendedContext pc >= suspendedContext endPC or: [suspendedContext closure isNil and: [suspendedContext methodClass == Process and: [suspendedContext selector == #terminate]]]]] I'm also tempted to state in a comment why being in other than a block in Process>>#terminate implies the methods is essentially done terminating. And there in lies the rub, to quote Shakespeare. Would a hack like adding a first temporary in Process>>#terminate called e.g. terminationStatus and having Process>>terminate assign to it when termination is essentially complete be better? e.g. isTerminated "Answer if the receiver is terminated, or at least terminating." self isActiveProcess ifTrue: [^ false]. ^suspendedContext isNil or: ["If the suspendedContext is the bottomContext and the pc is at the endPC, then there is nothing more to do." suspendedContext isBottomContext and: [suspendedContext pc >= suspendedContext endPC or: [suspendedContext closure isNil and: [suspendedContext methodClass == Process and: [suspendedContext selector == #terminate and: [(suspendedContext localAt: 1) == #terminated]]]]]] terminate "Stop the process that the receiver represents forever. Unwind to execute pending ensure:/ifCurtailed: blocks before terminating. If the process is in the middle of a critical: critical section, release it properly. N.B. terminationStatus is for the benefit of Process>>#isTerminated." | terminationStatus ctxt unwindBlock oldList | self isActiveProcess ifTrue: [ctxt := thisContext. [ctxt := ctxt findNextUnwindContextUpTo: nil. ctxt ~~ nil] whileTrue: [(ctxt tempAt: 2) ifNil: ["N.B. Unlike Context>>unwindTo: we do not set complete (tempAt: 2) to true." unwindBlock := ctxt tempAt: 1. thisContext terminateTo: ctxt. unwindBlock value]]. >>> terminationStatus := #terminated. thisContext terminateTo: nil. self suspend. "If the process is resumed this will provoke a cannotReturn: error. Would self debug: thisContext title: 'Resuming a terminated process' be better?" ^self]. "Always suspend the process first so it doesn't accidentally get woken up. N.B. If oldList is a LinkedList then the process is runnable. If it is a Semaphore/Mutex et al then the process is blocked, and if it is nil then the process is already suspended." oldList := self suspend. suspendedContext ifNotNil: ["Release any method marked with the pragma. The argument is whether the process is runnable." self releaseCriticalSection: (oldList isNil or: [oldList class == LinkedList]). "If terminating a process halfways through an unwind, try to complete that unwind block first." (suspendedContext findNextUnwindContextUpTo: nil) ifNotNil: [:outer| (suspendedContext findContextSuchThat:[:c| c closure == (outer tempAt: 1)]) ifNotNil: [:inner| "This is an unwind block currently under evaluation" suspendedContext runUntilErrorOrReturnFrom: inner]]. >>> terminationStatus := #terminated. ctxt := self popTo: suspendedContext bottomContext. ctxt == suspendedContext bottomContext ifFalse: [self debug: ctxt title: 'Unwind error during termination']. "Set the context to its endPC for the benefit of isTerminated." ctxt pc: ctxt endPC] ----- > ^[^ Jaromir > -- > Sent from: http://forum.world.st/Squeak-Dev-f45488.html > _,,,^..^,,,_ best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: