<body><div id="__MailbirdStyleContent" style="font-size: 12pt;font-family: calibri;color: #000000">
                                        Hi, there.<div><br></div><div>All "global" or "class-side" or "non-morphic" methods should use "Project current world" if required. Else, use "self world". For example "<span style="font-family: tahoma, verdana;font-size: 13px;line-height: 19.5px">MorphHierarchyListMorph>>createContainer" should really use "self world".</span></div><div><span style="font-family: tahoma, verdana;font-size: 13px;line-height: 19.5px"><br></span></div><div><span style="font-family: tahoma, verdana;font-size: 13px;line-height: 19.5px">Best,</span></div><div><span style="font-family: tahoma, verdana;font-size: 13px;line-height: 19.5px">Marcel</span></div><div class="mb_sig"></div><blockquote class="history_container" type="cite" style="border-left-style:solid;border-width:1px; margin-top:20px; margin-left:0px;padding-left:10px;">
                        <p style="color: #AAAAAA; margin-top: 10px;">Am 12.11.2017 16:11:16 schrieb David T. Lewis <lewis@mail.msen.com>:</p>Hi Hannes,<br><br>The "self world" expression works for morphs, and certainly it is easier to read.<br>It may be somewhat slower, although that would not be a concern in most usages.<br><br>My main concern is correctness, because failures in this area can hang up the<br>UI entirely, and errors are difficult to debug.<br><br>When transitioning from one project to another the World variable is set to<br>the new project's world in #finalEnterActions:.  Thus the World global is a<br>shortcut reference to the world of the current project, and that is what leads<br>me to suggest the expression "Project current world".<br><br>Dave<br><br><br>On Sun, Nov 12, 2017 at 04:48:55AM +0100, H. Hirzel wrote:<br>> Eliminsating the access to the global 'World' is fine.<br>> <br>> But what about<br>> <br>>     self world<br>> <br>> instead of<br>> <br>>      Project current world<br>> <br>> Or is it an issue of speed?<br>> <br>> --Hannes<br>> <br>> On 11/11/17, David T. Lewis <lewis@mail.msen.com> wrote:<br>> > I think that it should be possible to eliminate World as a global without<br>> > hurting performance. The code gets more verbose, but it reduces<br>> > opportunities<br>> > for hidden bugs, so I think it is worth the tradeoff.<br>> ><br>> > I have to admit that the subject of "World global elimination" sounds a bit<br>> > ominous, so I decided to put Morphic-dtl.1360 and MorphicExtras-dtl.214 in<br>> > the inbox first ;-)<br>> ><br>> > Are there any objections to proceding in this direction? If not I will move<br>> > the changes to trunk in day or two.<br>> ><br>> > Dave<br>> ><br>> ><br>> ><br>> > On Sat, Nov 11, 2017 at 09:04:49PM +0000, commits@source.squeak.org wrote:<br>> >> David T. Lewis uploaded a new version of Morphic to project The Inbox:<br>> >> http://source.squeak.org/inbox/Morphic-dtl.1360.mcz<br>> >><br>> >> ==================== Summary ====================<br>> >><br>> >> Name: Morphic-dtl.1360<br>> >> Author: dtl<br>> >> Time: 11 November 2017, 4:04:34.153784 pm<br>> >> UUID: 0e1f3870-5f57-4dc6-a1e7-5d8ce68b71b5<br>> >> Ancestors: Morphic-dtl.1359<br>> >><br>> >> World global elimination. Once the current project has been entered,<br>> >> Project current world == World. Begin eliminating references to the global<br>> >> variable World in cases where it is not required.<br>> >><br>> >> =============== Diff against Morphic-dtl.1359 ===============<br>> >><br>> >> Item was changed:<br>> >>   ----- Method: ComplexProgressIndicator>>backgroundWorldDisplay (in<br>> >> category 'as yet unclassified') -----<br>> >>   backgroundWorldDisplay<br>> >><br>> >>          self flag: #bob.                "really need a better way to do this"<br>> >><br>> >>                           "World displayWorldSafely."<br>> >><br>> >>     "ugliness to try to track down a possible error"<br>> >><br>> >><br>> >> +       [Project current world displayWorld] ifError: [ :a :b |<br>> >> -        [World displayWorld] ifError: [ :a :b |<br>> >>                  | f |<br>> >>            stageCompleted := 999.<br>> >>                   f := FileDirectory default fileNamed: 'bob.errors'.<br>> >>              f nextPutAll: a printString,'  ',b printString; cr; cr.<br>> >>                  f nextPutAll: 'worlds equal ',(formerWorld == World) printString; cr;<br>> >> cr.<br>> >>                 f nextPutAll: thisContext longStack; cr; cr.<br>> >>             f nextPutAll: formerProcess suspendedContext longStack; cr; cr.<br>> >>                  f close. Beeper beep.<br>> >>    ].<br>> >>   !<br>> >><br>> >> Item was changed:<br>> >>   ----- Method: Debugger class>>morphicOpenInterrupt:onProcess: (in<br>> >> category '*Morphic-opening') -----<br>> >>   morphicOpenInterrupt: aString onProcess: interruptedProcess<br>> >>    "Open a notifier in response to an interrupt. An interrupt occurs when<br>> >> the user types the interrupt key (cmd-. on Macs, ctrl-c or alt-. on other<br>> >> systems) or when the low-space watcher detects that memory is low."<br>> >>     | debugger |<br>> >>     <primitive: 19=""> "Simulation guard"<br>> >>          debugger := self new.<br>> >>    debugger<br>> >>                 process: interruptedProcess<br>> >>              controller: nil<br>> >>                  context: interruptedProcess suspendedContext.<br>> >>    debugger externalInterrupt: true.<br>> >><br>> >>         Preferences logDebuggerStackToFile ifTrue:<br>> >>               [(aString includesSubstring: 'Space') & (aString includesSubstring:<br>> >> 'low')<br>> >>                    ifTrue: [Smalltalk logError: aString inContext: debugger<br>> >> interruptedContext to: 'LowSpaceDebug.log']<br>> >>                      "logging disabled for 4.3 release, see<br>> >><br>> >>                               http://lists.squeak.org/pipermail/squeak-dev/2011-December/162503.html"<br>> >>                     "ifFalse: [Smalltalk logSqueakError: aString inContext: debugger<br>> >> interruptedContext]"].<br>> >><br>> >> +        Preferences eToyFriendly ifTrue: [Project current world<br>> >> stopRunningAll].<br>> >> -        Preferences eToyFriendly ifTrue: [World stopRunningAll].<br>> >>         ^debugger<br>> >>                openNotifierContents: nil label: aString;<br>> >>                yourself<br>> >>   !<br>> >><br>> >> Item was changed:<br>> >>   ----- Method: Morph>>updateFromResource (in category 'fileIn/out') -----<br>> >>   updateFromResource<br>> >>          | pathName newMorph f |<br>> >>          (pathName := self valueOfProperty: #resourceFilePath) ifNil: [^self].<br>> >>    (pathName asLowercase endsWith: '.morph')<br>> >>                ifTrue:<br>> >>                          [newMorph := (FileStream readOnlyFileNamed: pathName)<br>> >> fileInObjectAndCode.<br>> >>                        (newMorph isMorph)<br>> >>                               ifFalse: [^self error: 'Resource not a single morph']]<br>> >>                   ifFalse:<br>> >>                         [f := Form fromFileNamed: pathName.<br>> >>                      f ifNil: [^self error: 'unrecognized image file format'].<br>> >> +                      newMorph := Project current world drawingClass withForm: f].<br>> >> -                   newMorph := World drawingClass withForm: f].<br>> >>     newMorph setProperty: #resourceFilePath toValue: pathName.<br>> >>       self owner replaceSubmorph: self by: newMorph!<br>> >><br>> >> Item was changed:<br>> >>   ----- Method: MorphHierarchyListMorph>>createContainer (in category<br>> >> 'private') -----<br>> >>   createContainer<br>> >>       "Private - Create a container"<br>> >>         | container |<br>> >>    container := BorderedMorph new.<br>> >> +        container extent: (Project current world extent * (1 / 4 @ (2 / 3)))<br>> >> rounded.<br>> >> -   container extent: (World extent * (1 / 4 @ (2 / 3))) rounded.<br>> >>    container layoutPolicy: TableLayout new.<br>> >>         container hResizing: #rigid.<br>> >>     container vResizing: #rigid.<br>> >>     container<br>> >>                setColor: (Color gray: 0.9)<br>> >>              borderWidth: 1<br>> >>                   borderColor: Color gray.<br>> >>         container layoutInset: 0.<br>> >>        "container useRoundedCorners."<br>> >>         ""<br>> >>     container setProperty: #morphHierarchy toValue: true.<br>> >>    container setNameTo: 'Objects Hierarchy' translated.<br>> >>     ""<br>> >>     ^ container!<br>> >><br>> >> Item was changed:<br>> >>   ----- Method: MorphicProject>>storeSegment (in category 'file in/out')<br>> >> -----<br>> >>   storeSegment<br>> >>    "Store my project out on the disk as an ImageSegment.  Keep the<br>> >> outPointers in memory.  Name it <project name="">.seg.  *** Caller must be<br>> >> holding (Project alInstances) to keep subprojects from going out. ***"<br>> >><br>> >>         | is sizeHint |<br>> >> +        (Project current world == world) ifTrue: [^ false].<br>> >> -    (World == world) ifTrue: [^ false].<br>> >>              "self inform: 'Can''t send the current world out'."<br>> >>    world isInMemory ifFalse: [^ false].  "already done"<br>> >>           world ifNil: [^ false].  world presenter ifNil: [^ false].<br>> >><br>> >>        ScrapBook default emptyScrapBook.<br>> >>        World checkCurrentHandForObjectToPaste.<br>> >>          world releaseSqueakPages.<br>> >>        sizeHint := self projectParameters at: #segmentSize ifAbsent: [0].<br>> >><br>> >>        is := ImageSegment<br>> >>                       copyFromRootsLocalFileFor: {world presenter. world}     "world, and all<br>> >> Players"<br>> >>                        sizeHint: sizeHint.<br>> >><br>> >>       is state = #tooBig ifTrue: [^ false].<br>> >>    is segment size < 2000="" iftrue:=""><br>> >>                  Transcript show: self name, ' only ', is segment size printString,<br>> >>                       'bytes in Segment.'; cr].<br>> >>        self projectParameters at: #segmentSize put: is segment size.<br>> >>    is extract; writeToFile: self name.<br>> >>      ^ true!<br>> >><br>> >> Item was changed:<br>> >>   ----- Method: MorphicProject>>storeSegmentNoFile (in category 'file<br>> >> in/out') -----<br>> >>   storeSegmentNoFile<br>> >>     "For testing.  Make an ImageSegment.  Keep the outPointers in memory.<br>> >> Also useful if you want to enumerate the objects in the segment afterwards<br>> >> (allObjectsDo:)"<br>> >><br>> >>         | is |<br>> >> +         (Project current world == world) ifTrue: [^ self].              " inform: 'Can''t<br>> >> send the current world out'."<br>> >> -       (World == world) ifTrue: [^ self].              " inform: 'Can''t send the current<br>> >> world out'."<br>> >>         world isInMemory ifFalse: [^ self].  "already done"<br>> >>    world ifNil: [^ self].  world presenter ifNil: [^ self].<br>> >><br>> >>          "Do this on project enter"<br>> >>     World flapTabs do: [:ft | ft referent adaptToWorld: World].<br>> >>              "Hack to keep the Menu flap from pointing at my project"<br>> >>       "Preferences setPreference: #useGlobalFlaps toValue: false."<br>> >>           "Utilities globalFlapTabsIfAny do:<br>> >>                  [:aFlapTab | Utilities removeFlapTab: aFlapTab keepInList: false].<br>> >>       Utilities clobberFlapTabList.   "<br>> >>           "project world deleteAllFlapArtifacts."<br>> >>        "self currentWorld deleteAllFlapArtifacts. "<br>> >>           ScrapBook default emptyScrapBook.<br>> >>        World checkCurrentHandForObjectToPaste2.<br>> >><br>> >>          is := ImageSegment<br>> >>                       copyFromRootsLocalFileFor: {world presenter. world}     "world, and all<br>> >> Players"<br>> >>                        sizeHint: 0.<br>> >><br>> >>      is segment size < 800="" iftrue:=""><br>> >>                   Transcript show: self name, ' did not get enough objects'; cr.  ^<br>> >> Beeper beep].<br>> >><br>> >>    is extract.<br>> >>      "is instVarAt: 2 put: is segment clone."              "different memory"!<br>> >><br>> >> Item was changed:<br>> >>   ----- Method: TheWorldMainDockingBar>>startMessageTally (in category<br>> >> 'menu actions') -----<br>> >>   startMessageTally<br>> >> +      | world |<br>> >> +      world := Project current world.<br>> >>          (self confirm: 'MessageTally will start now,<br>> >>   and stop when the cursor goes<br>> >>   to the top of the screen') ifTrue:<br>> >>                  [MessageTally spyOn:<br>> >> +                   [[Sensor peekPosition y > 0] whileTrue: [world doOneCycle]]]!<br>> >> -                       [[Sensor peekPosition y > 0] whileTrue: [World doOneCycle]]]!<br>> >><br>> >> Item was changed:<br>> >>   ----- Method: TheWorldMenu>>startMessageTally (in category 'commands')<br>> >> -----<br>> >>   startMessageTally<br>> >> +         | world |<br>> >> +      world := Project current world.<br>> >> -<br>> >>         (self confirm: 'MessageTally will start now,<br>> >>   and stop when the cursor goes<br>> >>   to the top of the screen') ifTrue:<br>> >>                  [MessageTally spyOn:<br>> >> +                   [[Sensor peekPosition y > 0] whileTrue: [world doOneCycle]]]!<br>> >> -                       [[Sensor peekPosition y > 0] whileTrue: [World doOneCycle]]]!<br>> >><br>> >><br>> ><br>> ><br>> <br><br></project></primitive:></lewis@mail.msen.com>
                        </blockquote>
                                        </div></body>