David T. Lewis uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-dtl.979.mcz
==================== Summary ====================
Name: System-dtl.979
Author: dtl
Time: 24 November 2017, 6:12:53.864262 pm
UUID: 7572e3df-ab0e-4ad2-a89b-ee101e2a821c
Ancestors: System-dtl.978
Remove unnecessary references to global World.
=============== Diff against System-dtl.978 ===============
Item was changed:
----- Method: NativeImageSegment>>copySmartRootsExport: (in category 'read/write segment') -----
copySmartRootsExport: rootArray
"Use SmartRefStream to find the object. Make them all roots. Create the segment in memory. Project should be in first five objects in rootArray."
+ | newRoots segSize symbolHolder replacements naughtyBlocks allClasses sizeHint proj dummy world |
- | newRoots segSize symbolHolder replacements naughtyBlocks allClasses sizeHint proj dummy |
"self halt."
+ world := Project current world.
symbolHolder := Symbol allSymbols. "Hold onto Symbols with strong pointers,
so they will be in outPointers"
dummy := ReferenceStream on: (DummyStream on: nil).
"Write to a fake Stream, not a file"
"Collect all objects"
dummy insideASegment: true. "So Uniclasses will be traced"
dummy rootObject: rootArray. "inform him about the root"
dummy nextPut: rootArray.
(proj :=dummy project) ifNotNil: [self dependentsSave: dummy].
allClasses := SmartRefStream new uniClassInstVarsRefs: dummy.
"catalog the extra objects in UniClass inst vars. Put into dummy"
allClasses do: [:cls |
dummy references at: cls class put: false. "put Player5 class in roots"
dummy blockers removeKey: cls class ifAbsent: []].
"refs := dummy references."
arrayOfRoots := self smartFillRoots: dummy. "guaranteed none repeat"
self savePlayerReferences: dummy references. "for shared References table"
replacements := dummy blockers.
dummy project "recompute it" ifNil: [self error: 'lost the project!!'].
dummy project class == DiskProxy ifTrue: [self error: 'saving the wrong project'].
dummy := nil. "Allow dummy to be GC'ed below (bytesLeft)."
naughtyBlocks := arrayOfRoots select: [ :each |
each isContext and: [each hasInstVarRef]].
"since the caller switched ActiveWorld, put the real one back temporarily"
naughtyBlocks isEmpty ifFalse: [
+ world becomeActiveDuring: [world firstHand becomeActiveDuring: [ | goodToGo |
- World becomeActiveDuring: [World firstHand becomeActiveDuring: [ | goodToGo |
goodToGo := (UIManager default
chooseFrom: #('keep going' 'stop and take a look')
title:
'Some block(s) which reference instance variables
are included in this segment. These may fail when
the segment is loaded if the class has been reshaped.
What would you like to do?') = 1.
goodToGo ifFalse: [
naughtyBlocks inspect.
self error: 'Here are the bad blocks'].
]].
].
"Creation of the segment happens here"
"try using one-quarter of memory min: four megs to publish (will get bumped up later if needed)"
sizeHint := (Smalltalk bytesLeft // 4 // 4) min: 1024*1024.
self copyFromRoots: arrayOfRoots sizeHint: sizeHint areUnique: true.
segSize := segment size.
[(newRoots := self rootsIncludingBlockMethods) == nil] whileFalse:
[arrayOfRoots := newRoots.
self copyFromRoots: arrayOfRoots sizeHint: segSize areUnique: true].
"with methods pointed at from outside"
[(newRoots := self rootsIncludingBlocks) == nil] whileFalse:
[arrayOfRoots := newRoots.
self copyFromRoots: arrayOfRoots sizeHint: segSize areUnique: true].
"with methods, blocks from outPointers"
1 to: outPointers size do: [:ii | | outPointer |
outPointer := outPointers at: ii.
(outPointer isBlock
or: [outPointer isContext]) ifTrue: [outPointers at: ii put: nil].
"substitute new object in outPointers"
(replacements includesKey: outPointer) ifTrue:
[outPointers at: ii put: (replacements at: outPointer)]].
proj ifNotNil: [self dependentsCancel: proj].
symbolHolder. "hold onto symbolHolder until the last."!
Item was changed:
----- Method: Preferences class>>loadPreferencesFrom: (in category 'initialization - save/load') -----
loadPreferencesFrom: aFile
| stream params dict desktopColor |
stream := ReferenceStream fileNamed: aFile.
params := stream next.
self assert: (params isKindOf: IdentityDictionary).
params removeKey: #PersonalDictionaryOfPreferences.
dict := stream next.
self assert: (dict isKindOf: IdentityDictionary).
desktopColor := stream next.
stream close.
dict keysAndValuesDo:
[:key :value | (self preferenceAt: key ifAbsent: [nil]) ifNotNil:
[:pref | [pref preferenceValue: value preferenceValue] on: Error do: [ : err | "Ignore preferences which may not be supported anymore."]]].
params keysAndValuesDo: [ :key :value | self setParameter: key to: value ].
Smalltalk isMorphic
+ ifTrue: [ Project current world fillStyle: desktopColor ]
- ifTrue: [ World fillStyle: desktopColor ]
ifFalse: [ self desktopColor: desktopColor. ScheduledControllers updateGray ]!
Item was changed:
----- Method: Preferences class>>mouseOverHalosChanged (in category 'updating - system') -----
mouseOverHalosChanged
+ Project current world wantsMouseOverHalos: self mouseOverHalos!
- World wantsMouseOverHalos: self mouseOverHalos!
Item was changed:
----- Method: Project>>validateProjectNameIfOK: (in category 'menu messages') -----
validateProjectNameIfOK: aBlock
| details |
details := world valueOfProperty: #ProjectDetails.
details ifNotNil: ["ensure project info matches real project name"
details at: 'projectname' put: self name.
].
self doWeWantToRename ifFalse: [^ aBlock value: details].
(Smalltalk at: #EToyProjectDetailsMorph) ifNotNil: [:etpdm |
etpdm
getFullInfoFor: self
ifValid: [:d |
+ Project current world displayWorldSafely.
- World displayWorldSafely.
aBlock value: d
]
expandedFormat: false]
!
Item was changed:
----- Method: ProjectLauncher>>hideSplashMorph (in category 'running') -----
hideSplashMorph
SplashMorph ifNil:[^self].
self showSplash
ifFalse: [^self].
SplashMorph delete.
+ Project current world submorphs do:[:m| m visible: true]. "show all"
- World submorphs do:[:m| m visible: true]. "show all"
!
Item was changed:
----- Method: ProjectLauncher>>prepareForLogin (in category 'eToy login') -----
prepareForLogin
"Prepare for login - e.g., hide everything so only the login morph is visible."
+ | world |
+ world := Project current world.
+ world submorphsDo:[:m|
- World submorphsDo:[:m|
m isLocked ifFalse:[m hide]]. "hide all those guys"
+ world displayWorldSafely.
- World displayWorldSafely.
!
Item was changed:
----- Method: ProjectLauncher>>proceedWithLogin (in category 'eToy login') -----
proceedWithLogin
eToyAuthentificationServer := nil.
+ Project current world submorphsDo:[:m| m show].
- World submorphsDo:[:m| m show].
WorldState addDeferredUIMessage: [self startUpAfterLogin].!
Item was changed:
----- Method: ProjectLauncher>>showSplashMorph (in category 'running') -----
showSplashMorph
+ | world |
SplashMorph ifNil:[^self].
self showSplash
ifFalse: [^self].
+ world := Project current world.
+ world submorphs do:[:m| m visible: false]. "hide all"
+ world addMorphCentered: SplashMorph.
+ world displayWorldSafely.!
- World submorphs do:[:m| m visible: false]. "hide all"
- World addMorphCentered: SplashMorph.
- World displayWorldSafely.!
Item was changed:
----- Method: ResourceManager>>loadCachedResources (in category 'loading') -----
loadCachedResources
"Load all the resources that we have cached locally"
self class reloadCachedResources.
self prioritizedUnloadedResources do:[:loc|
self class lookupCachedResource: loc urlString ifPresentDo:[:stream|
| resource |
resource := resourceMap at: loc ifAbsent:[nil].
self installResource: resource
from: stream
locator: loc.
(resource isForm) ifTrue:[
self formChangedReminder value.
+ Project current world displayWorldSafely].
- World displayWorldSafely].
].
].!
Item was changed:
----- Method: SARInstaller>>fileInMCVersion:withBootstrap: (in category 'private') -----
fileInMCVersion: member withBootstrap: mcBootstrap
"This will use the MCBootstrapLoader to load a (non-compressed) Monticello file (.mc or .mcv)"
| newCS |
self class withCurrentChangeSetNamed: member localFileName
do: [ :cs |
newCS := cs.
mcBootstrap loadStream: member contentStream ascii ].
newCS isEmpty ifTrue: [ ChangeSet removeChangeSet: newCS ].
+ Project current world doOneCycle.
- World doOneCycle.
self installed: member.!
Item was changed:
----- Method: SARInstaller>>fileInMonticelloPackageNamed: (in category 'client services') -----
fileInMonticelloPackageNamed: memberName
"This is to be used from preamble/postscript code to file in zip
members as Monticello packages (.mc)."
| member file mcPackagePanel mcRevisionInfo mcSnapshot mcFilePackageManager mcPackage mcBootstrap newCS |
mcPackagePanel := Smalltalk at: #MCPackagePanel ifAbsent: [ ].
mcRevisionInfo := Smalltalk at: #MCRevisionInfo ifAbsent: [ ].
mcSnapshot := Smalltalk at: #MCSnapshot ifAbsent: [ ].
mcFilePackageManager := Smalltalk at: #MCFilePackageManager ifAbsent: [ ].
mcPackage := Smalltalk at: #MCPackage ifAbsent: [ ].
member := self memberNamed: memberName.
member ifNil: [ ^self errorNoSuchMember: memberName ].
"We are missing MCInstaller, Monticello and/or MonticelloCVS.
If the bootstrap is present, use it. Otherwise interact with the user."
({ mcPackagePanel. mcRevisionInfo. mcSnapshot. mcFilePackageManager. mcPackage } includes: nil)
ifTrue: [
mcBootstrap := self getMCBootstrapLoaderClass.
mcBootstrap ifNotNil: [ ^self fileInMCVersion: member withBootstrap: mcBootstrap ].
(self confirm: ('Monticello support is not installed, but must be to load member named ', memberName, '.
Load it from SqueakMap?'))
ifTrue: [ self class loadMonticello; loadMonticelloCVS.
^self fileInMonticelloPackageNamed: memberName ]
ifFalse: [ ^false ] ].
member extractToFileNamed: member localFileName inDirectory: self directory.
file := (Smalltalk at: #MCFile)
name: member localFileName
directory: self directory.
self class withCurrentChangeSetNamed: file name do: [ :cs | | snapshot info |
newCS := cs.
file readStreamDo: [ :stream |
info := mcRevisionInfo readFrom: stream nextChunk.
snapshot := mcSnapshot fromStream: stream ].
snapshot install.
(mcFilePackageManager forPackage:
(mcPackage named: info packageName))
file: file
].
newCS isEmpty ifTrue: [ ChangeSet removeChangeSet: newCS ].
mcPackagePanel allSubInstancesDo: [ :ea | ea refresh ].
+ Project current world doOneCycle.
- World doOneCycle.
self installed: member.
!
Item was changed:
----- Method: SARInstaller>>fileInMonticelloVersionNamed: (in category 'client services') -----
fileInMonticelloVersionNamed: memberName
"This is to be used from preamble/postscript code to file in zip
members as Monticello version (.mcv) files."
| member newCS mcMcvReader |
mcMcvReader := Smalltalk at: #MCMcvReader ifAbsent: [].
member := self memberNamed: memberName.
member ifNil: [^self errorNoSuchMember: memberName].
"If we don't have Monticello, offer to get it."
mcMcvReader ifNil: [
(self confirm: 'Monticello is not installed, but must be to load member named ', memberName , '.
Load it from SqueakMap?')
ifTrue: [ self class loadMonticello.
^self fileInMonticelloVersionNamed: memberName]
ifFalse: [^false]].
self class withCurrentChangeSetNamed: member localFileName
do:
[:cs |
newCS := cs.
(mcMcvReader versionFromStream: member contentStream ascii) load ].
newCS isEmpty ifTrue: [ChangeSet removeChangeSet: newCS].
+ Project current world doOneCycle.
- World doOneCycle.
self installed: member!
Item was changed:
----- Method: SARInstaller>>fileInMonticelloZipVersionNamed: (in category 'client services') -----
fileInMonticelloZipVersionNamed: memberName
"This is to be used from preamble/postscript code to file in zip
members as Monticello version (.mcz) files."
| member mczInstaller newCS mcMczReader |
mcMczReader := Smalltalk at: #MCMczReader ifAbsent: [].
mczInstaller := Smalltalk at: #MczInstaller ifAbsent: [].
member := self memberNamed: memberName.
member ifNil: [^self errorNoSuchMember: memberName].
"If we don't have Monticello, but have the bootstrap, use it silently."
mcMczReader ifNil: [
mczInstaller ifNotNil: [ ^mczInstaller installStream: member contentStream ].
(self confirm: 'Monticello is not installed, but must be to load member named ', memberName , '.
Load it from SqueakMap?')
ifTrue: [ self class loadMonticello.
^self fileInMonticelloZipVersionNamed: memberName]
ifFalse: [^false]].
self class withCurrentChangeSetNamed: member localFileName
do:
[:cs |
newCS := cs.
(mcMczReader versionFromStream: member contentStream) load ].
newCS isEmpty ifTrue: [ChangeSet removeChangeSet: newCS].
+ Project current world doOneCycle.
- World doOneCycle.
self installed: member!
Item was changed:
----- Method: SARInstaller>>fileInTrueTypeFontNamed: (in category 'client services') -----
fileInTrueTypeFontNamed: memberOrName
| member description |
member := self memberNamed: memberOrName.
member ifNil: [^self errorNoSuchMember: memberOrName].
description := TTFontDescription addFromTTStream: member contentStream.
TTCFont newTextStyleFromTT: description.
+ Project current world doOneCycle.
- World doOneCycle.
self installed: member!
Item was changed:
----- Method: SmalltalkImage>>shrinkAndCleanDesktop (in category 'shrinking') -----
shrinkAndCleanDesktop
+ | world |
+ world := Project current world.
+ world removeAllMorphs.
- World removeAllMorphs.
self shrink.
MorphicProject defaultFill: (Color gray: 0.9).
+ world color: (Color gray: 0.9)!
- World color: (Color gray: 0.9)!
David T. Lewis uploaded a new version of Services-Base to project The Trunk:
http://source.squeak.org/trunk/Services-Base-dtl.63.mcz
==================== Summary ====================
Name: Services-Base-dtl.63
Author: dtl
Time: 24 November 2017, 6:09:46.207676 pm
UUID: 5d6623aa-6db1-45f3-9e1a-2bf881e75ccf
Ancestors: Services-Base-ul.62
Remove unnecessary references to global World.
=============== Diff against Services-Base-ul.62 ===============
Item was changed:
----- Method: Requestor>>getMethodBody (in category 'requests') -----
getMethodBody
+ | m world |
- | m |
m := FillInTheBlankMorph new.
m setQuery: 'Please enter the full body of the method you want to define'
initialAnswer: self class sourceCodeTemplate
answerExtent: 500@250
acceptOnCR: false.
+ world := Project current world.
+ world addMorph: m centeredNear: world activeHand position.
- World addMorph: m centeredNear: World activeHand position.
^ m getUserResponse.!
Item was changed:
----- Method: Requestor>>getSelection (in category 'requests') -----
getSelection
"Sorry to feedle with fillInTheBlankMorph innards, but I had to"
+ | text m world |
- | text m |
text := (MethodReference class: self getClass selector: self getSelector) sourceCode.
m := FillInTheBlankMorph new.
m setQuery: 'Highlight a part of the source code, and accept' initialAnswer: text
answerExtent: 500@250
acceptOnCR: true.
+ world := Project current world.
+ world addMorph: m centeredNear: world activeHand position.
- World addMorph: m centeredNear: World activeHand position.
m getUserResponse.
^ m selection!
Item was changed:
----- Method: ServiceAction>>execute (in category 'executing') -----
execute
+ ^ action valueWithRequestor: Project current world focusedRequestor!
- ^ action valueWithRequestor: World focusedRequestor!
Item was changed:
----- Method: ServiceAction>>executeCondition (in category 'executing') -----
executeCondition
+ ^ [condition valueWithRequestor: Project current world focusedRequestor]
- ^ [condition valueWithRequestor: World focusedRequestor]
on: Error
do: [false]!
David T. Lewis uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-dtl.776.mcz
==================== Summary ====================
Name: Tools-dtl.776
Author: dtl
Time: 24 November 2017, 6:08:14.219652 pm
UUID: c9c948eb-74b4-426b-8378-50d3ed174f81
Ancestors: Tools-tpr.775
Remove unnecessary references to global World.
=============== Diff against Tools-tpr.775 ===============
Item was changed:
----- Method: Debugger>>contents:notifying: (in category 'accessing') -----
contents: aText notifying: aController
"The retrieved information has changed and its source must now be updated.
In this case, the retrieved information is the method of the selected context."
| result selector classOfMethod category h ctxt newMethod |
contextStackIndex = 0 ifTrue:
[^false].
self selectedContext isExecutingBlock ifTrue:
[h := self selectedContext activeHome.
h ifNil:
[self inform: 'Method for block not found on stack, can''t edit and continue'.
^false].
(self confirm: 'I will have to revert to the method from\which this block originated. Is that OK?' withCRs) ifFalse:
[^false].
self resetContext: h changeContents: false.
"N.B. Only reset the contents if the compilation succeeds. If contents are reset
when compilation fails both compiler error message and modifications are lost."
(result := self contents: aText notifying: aController) ifTrue:
[self contentsChanged].
^result].
classOfMethod := self selectedClass.
category := self selectedMessageCategoryName.
selector := self selectedClass newParser parseSelector: aText.
(selector == self selectedMessageName
or: [(self selectedMessageName beginsWith: 'DoIt')
and: [selector numArgs = self selectedMessageName numArgs]]) ifFalse:
[self inform: 'can''t change selector'.
^false].
selector := classOfMethod
compile: aText
classified: category
notifying: aController.
selector ifNil: [^false]. "compile cancelled"
contents := aText.
newMethod := classOfMethod compiledMethodAt: selector.
newMethod isQuick ifTrue:
[self cutBackExecutionToSenderContext].
ctxt := interruptedProcess popTo: self selectedContext.
ctxt == self selectedContext
ifFalse:
[self inform: 'Method saved, but current context unchanged\because of unwind error. Click OK to see error' withCRs]
ifTrue:
[newMethod isQuick ifFalse:
[interruptedProcess
restartTopWith: newMethod;
stepToSendOrReturn].
contextVariablesInspector object: nil].
self resetContext: ctxt.
Smalltalk isMorphic ifTrue:
+ [Project current world
- [World
addAlarm: #changed:
withArguments: #(contentsSelection)
for: self
at: (Time millisecondClockValue + 200)].
^true!
Item was changed:
----- Method: Debugger>>runUntil (in category 'code pane menu') -----
runUntil
"Step until an expression evaluates to other than false, reporting an error if it doesn't evaluate to true.
Remember the expression in an inst var. If shift is pressed when the expression is supplied, don't update the UI.
If shift is pressed while stepping, stop stepping. Using a user interrupt to break out would be more natural
but Squeak currently doesn't provide a UserInterrupt expection. It should do."
| expression receiver context method value lastUpdate updateUI breakOnShift |
expression := UIManager default
request: 'run until expression is true (shift to disable ui update; shift to break).'
initialAnswer: (untilExpression ifNil: 'boolean expression').
(expression isNil or: [expression isEmpty]) ifTrue:
[^self].
updateUI := breakOnShift := Sensor shiftPressed not.
untilExpression := expression.
context := self selectedContext.
receiver := context receiver.
method := receiver class evaluatorClass new
compiledMethodFor: untilExpression
in: context
to: receiver
notifying: nil
ifFail: [^ #failedDoit].
lastUpdate := Time millisecondClockValue.
Cursor execute showWhile:
[[self selectedContext == context
and: [context willReturn not
and: [(value := receiver with: context executeMethod: method) == false]]] whileTrue:
[interruptedProcess completeStep: self selectedContext.
self selectedContext == context ifTrue:
[self resetContext: interruptedProcess stepToSendOrReturn changeContents: false].
Time millisecondClockValue - lastUpdate > 50 ifTrue:
[updateUI ifTrue:
[self changed: #contentsSelection.
+ Project current world displayWorldSafely].
- World displayWorldSafely].
breakOnShift
ifTrue: [Sensor shiftPressed ifTrue:
[self changed: #contentsSelection.
self updateInspectors.
^self]]
ifFalse: [Sensor shiftPressed ifFalse: [breakOnShift := true]].
lastUpdate := Time millisecondClockValue]]].
self changed: #contentsSelection.
self updateInspectors.
(value ~~ false and: [value ~~ true]) ifTrue:
[UIManager default inform: 'expression ', (untilExpression contractTo: 40), ' answered ', (value printString contractTo: 20), '!!!!']!
David T. Lewis uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-dtl.1374.mcz
==================== Summary ====================
Name: Morphic-dtl.1374
Author: dtl
Time: 24 November 2017, 6:04:14.470996 pm
UUID: 239c9e21-1d05-413f-9f42-9c5267e15696
Ancestors: Morphic-dtl.1373, Morphic-tpr.1373
Merge Morphic-tpr.1373 and Morphic-dtl.1373, and update Debugger>>morphicResumeProcess: to remove global World reference
=============== Diff against Morphic-dtl.1373 ===============
Item was changed:
----- Method: Debugger>>morphicResumeProcess: (in category '*Morphic-opening') -----
morphicResumeProcess: aTopView
| processToResume |
processToResume := interruptedProcess.
interruptedProcess := nil. "Before delete, so release doesn't terminate it"
aTopView delete.
+ Project current world displayWorld. "We have to redraw *before* resuming the old process."
- World displayWorld. "We have to redraw *before* resuming the old process."
Smalltalk installLowSpaceWatcher. "restart low space handler"
savedCursor
ifNotNil: [Cursor currentCursor: savedCursor].
processToResume isTerminated ifFalse: [
errorWasInUIProcess
ifTrue: [Project resumeProcess: processToResume]
ifFalse: [processToResume resume]].
"if old process was terminated, just terminate current one"
errorWasInUIProcess == false
ifFalse: [Processor terminateActive]!
Item was changed:
----- Method: DialogWindow>>update: (in category 'updating') -----
update: aspect
aspect == #buttons
ifTrue: [self updateButtonExtent].
+ aspect == #flash
+ ifTrue: [self flash].
+
^ super update: aspect!
David T. Lewis uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-dtl.1373.mcz
==================== Summary ====================
Name: Morphic-dtl.1373
Author: dtl
Time: 22 November 2017, 10:25:57.941315 am
UUID: 2e41d807-bf5a-4f90-84aa-d0ac472bb023
Ancestors: Morphic-dtl.1372
Reorganize Morph>>delete for clarity, and remove reference to global World.
MorphicProject>>finalExitActions and finalEnterActions remove explicit references to global World and allow World be be removed for testing purposes.
=============== Diff against Morphic-dtl.1372 ===============
Item was changed:
----- 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 |
-
- | aWorld |
self removeHalo.
+ (oldWorld := self world) ifNotNil: [
-
- self isInWorld ifTrue: [
self disableSubmorphFocusForHand: self activeHand.
self activeHand
releaseKeyboardFocus: self;
releaseMouseFocus: self].
+ owner ifNotNil: [
+ self privateDelete. "remove from world"
-
- "Preserve world reference for player notificaiton. See below."
- aWorld := self world ifNil: [World].
-
- owner ifNotNil:[
- self privateDelete.
self player ifNotNil: [:player |
+ oldWorld ifNotNil: [
+ player noteDeletionOf: self fromWorld: oldWorld]]].!
- player noteDeletionOf: self fromWorld: aWorld]].!
Item was added:
+ ----- Method: MorphicProject>>clearGlobalState (in category 'enter') -----
+ clearGlobalState
+ "Clean up global state. The global variables World, ActiveWorld, ActiveHand
+ and ActiveEvent provide convenient access to the state of the active project
+ in Morphic. Clear their prior values when leaving an active project. This
+ method may be removed if the use of global state variables is eliminated."
+
+ "If global World is defined, clear it now. The value is expected to be set
+ again as a new project is entered."
+ Smalltalk globals at: #World
+ ifPresent: [ :w | Smalltalk globals at: #World put: nil ].
+ ActiveWorld := ActiveHand := ActiveEvent := nil.
+ !
Item was changed:
----- Method: MorphicProject>>finalEnterActions: (in category 'enter') -----
finalEnterActions: leavingProject
"Perform the final actions necessary as the receiver project is entered"
| navigator armsLengthCmd navType thingsToUnhibernate |
+ "If this image has a global World variable, update it now"
+ Smalltalk globals at: #World
+ ifPresent: [ :w | Smalltalk globals at: #World put: world ].
- World := world. "Signifies Morphic"
world install.
world transferRemoteServerFrom: leavingProject world.
"(revertFlag | saveForRevert | forceRevert) ifFalse: [
(Preferences valueOfFlag: #projectsSentToDisk) ifTrue: [
self storeSomeSegment]]."
"Transfer event recorder to me."
leavingProject isMorphic ifTrue: [
leavingProject world pauseEventRecorder ifNotNil: [:rec |
rec resumeIn: world]].
world triggerOpeningScripts.
self initializeMenus.
self projectParameters
at: #projectsToBeDeleted
ifPresent: [ :projectsToBeDeleted |
self removeParameter: #projectsToBeDeleted.
projectsToBeDeleted do: [:each | each delete]].
Locale switchAndInstallFontToID: self localeID.
thingsToUnhibernate := world valueOfProperty: #thingsToUnhibernate ifAbsent: [#()].
thingsToUnhibernate do: [:each | each unhibernate].
world removeProperty: #thingsToUnhibernate.
navType := ProjectNavigationMorph preferredNavigator.
armsLengthCmd := self parameterAt: #armsLengthCmd ifAbsent: [nil].
navigator := world findA: navType.
(Preferences classicNavigatorEnabled and: [Preferences showProjectNavigator and: [navigator isNil]]) ifTrue:
[(navigator := navType new)
bottomLeft: world bottomLeft;
openInWorld: world].
navigator notNil & armsLengthCmd notNil ifTrue:
[navigator color: Color lightBlue].
armsLengthCmd notNil ifTrue:
[Preferences showFlapsWhenPublishing
ifFalse:
[self flapsSuppressed: true.
navigator ifNotNil: [navigator visible: false]].
armsLengthCmd openInWorld: world].
world reformulateUpdatingMenus.
world presenter positionStandardPlayer.
self assureMainDockingBarPresenceMatchesPreference.
world repairEmbeddedWorlds.!
Item was changed:
----- Method: MorphicProject>>finalExitActions: (in category 'enter') -----
finalExitActions: enteringProject
world triggerClosingScripts.
"Pause sound players, subject to preference settings"
(world hasProperty: #letTheMusicPlay)
ifTrue: [world removeProperty: #letTheMusicPlay]
ifFalse: [SoundService stop].
world sleep.
-
(world findA: ProjectNavigationMorph)
ifNotNil: [:navigator | navigator retractIfAppropriate].
+ self clearGlobalState.
-
- "Clean-up global state."
- World := nil.
- ActiveWorld := ActiveHand := ActiveEvent := nil.
Sensor flushAllButDandDEvents. !
Looking around at places where filenames are used (in relation to the file name dialogs etc) I see some really ‘interesting’ methods relating to filing out source code.
The basic operation is to select the methods to file out (a class, a protocol, selections in a change set etc) and derive a leaf filename (in a couple of places asking the user for that) and then use FileStream class>>#writeSourceCodeFrom:baseName:isSt:useHtml: .
First oddness is that I can only find 1 case where the ‘isSt: is not ‘true’ (ChangeSet>>fileOut), which always makes me wonder if the factoring is sensible.
Second thing is that (almost) all this method does is work out what file extension to use anyway, something that might be better done higher up the call chain anyway.
Third, even when the html flag is true the code is simply dumped, so perhaps there is an old package somewhere that over-rode this to make actual html?
Fourth, the assumption is that `ChangeSet defaultChangeSetDirectory` is always where the user wants the code to go, which seems dubious. There is a Preference for this, though it doesn’t show up in the Preference Browser and it only gets used meaningfully in ChangeSet class>>#promptForDefaultChangeSetDirectoryIfNecessary. Even there the code pretty much guarantees that only the default directory will ever get used. It gets even more dubious in SystemOrganizer>>#fileOut where the base name given is derived explicitly from the state of the default directory, which in the (admittedly rare because of previous issues) case of a non-default destination could cause some interesting confusion of file names. Especially since it will make the leaf name be something like SystemOrganization.1.st.st
So, another fine mess I’ve dug into, Olly.
For the record, my proposal for a putative improvement here would be
- user interface initiated actions should open a file dialog to let the user choose where the file goes and then use…
- no-user-involvement methods that would be given a fully qualified filename and any required parameters, suitable for no-UI usage
tim
--
tim Rowledge; tim(a)rowledge.org; http://www.rowledge.org/tim
Useful random insult:- So dumb, he faxes face up.
---------- Forwarded message ----------
From: Serge Stinckwich <serge.stinckwich(a)gmail.com>
Date: Wed, 22 Nov 2017 14:25:32 +0100
Subject: Re: [Pharo-dev] Advent of code
To: Pharo Development List <pharo-dev(a)lists.pharo.org>
BTW, the Japanese Smalltalk community is doing an advent Calendar every
year:
https://qiita.com/advent-calendar/2016/smalltalk
The 2017 edition is in preparation here:
https://qiita.com/advent-calendar/2017/smalltalk
On Wed, Nov 22, 2017 at 1:29 PM, Stephane Ducasse <stepharo.self(a)gmail.com>
wrote:
> Hi pharoers
>
> I would like to know if you would like to participate to
> http://adventofcode.com/2016
>
> For example we could do the same as
> https://github.com/norvig/pytudes/blob/master/ipynb/
> Advent%20of%20Code.ipynb
>
> Stef
>
>
--
Serge Stinckwich
UMI UMMISCO 209 (IRD/UPMC/UY1)
"Programs must be written for people to read, and only incidentally for
machines to execute."http://www.doesnotunderstand.org/
Marcel Taeumel uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-mt.1119.mcz
==================== Summary ====================
Name: Kernel-mt.1119
Author: mt
Time: 9 November 2017, 11:13:37.82048 am
UUID: a210d4c7-b8eb-e544-a857-2b0bbade9668
Ancestors: Kernel-mt.1118
Improves support for having custom compiler classes for class-side methods. No need to use #respondsTo:. Just provide default implementation of #meta*Class methods in Class. The "super" is important here because the old behavior has been to use a custom compiler for the instance-side only.
=============== Diff against Kernel-mt.1118 ===============
Item was added:
+ ----- Method: Class>>metaCompilerClass (in category 'compiling') -----
+ metaCompilerClass
+ "BE CAREFUL!! If you provide your own class to treat class-side (resp. meta) methods, you MUST account for the #meta*Class selector to use the default implementation in that case. That is, the methods behind #meta*Class MUST always get the default Smalltalk treatment."
+
+ ^ super compilerClass!
Item was added:
+ ----- Method: Class>>metaDecompilerClass (in category 'compiling') -----
+ metaDecompilerClass
+ "BE CAREFUL!! If you provide your own class to treat class-side (resp. meta) methods, you MUST account for the #meta*Class selector to use the default implementation in that case. That is, the methods behind #meta*Class MUST always get the default Smalltalk treatment."
+
+ ^ super decompilerClass!
Item was added:
+ ----- Method: Class>>metaEvaluatorClass (in category 'compiling') -----
+ metaEvaluatorClass
+ "BE CAREFUL!! If you provide your own class to treat class-side (resp. meta) methods, you MUST account for the #meta*Class selector to use the default implementation in that case. That is, the methods behind #meta*Class MUST always get the default Smalltalk treatment."
+
+ ^ super evaluatorClass!
Item was added:
+ ----- Method: Class>>metaFormatterClass (in category 'printing') -----
+ metaFormatterClass
+ "BE CAREFUL!! If you provide your own class to treat class-side (resp. meta) methods, you MUST account for the #meta*Class selector to use the default implementation in that case. That is, the methods behind #meta*Class MUST always get the default Smalltalk treatment."
+
+ ^ super formatterClass!
Item was added:
+ ----- Method: Class>>metaParserClass (in category 'compiling') -----
+ metaParserClass
+ "BE CAREFUL!! If you provide your own class to treat class-side (resp. meta) methods, you MUST account for the #meta*Class selector to use the default implementation in that case. That is, the methods behind #meta*Class MUST always get the default Smalltalk treatment."
+
+ ^ super parserClass!
Item was added:
+ ----- Method: Class>>metaPrettyPrinterClass (in category 'printing') -----
+ metaPrettyPrinterClass
+ "BE CAREFUL!! If you provide your own class to treat class-side (resp. meta) methods, you MUST account for the #meta*Class selector to use the default implementation in that case. That is, the methods behind #meta*Class MUST always get the default Smalltalk treatment."
+
+ ^ super prettyPrinterClass!
Item was changed:
----- Method: Metaclass>>compilerClass (in category 'compiling') -----
compilerClass
+
+ ^ self theNonMetaClass metaCompilerClass!
- "BE CAREFUL!! If you provide your own class to treat class-side (resp. meta) methods, you MUST account for the #meta*Class selector to use the default implementation in that case. That is, the methods behind #meta*Class MUST always get the default Smalltalk treatment."
-
- ^ (self theNonMetaClass respondsTo: #metaCompilerClass)
- ifTrue: [self theNonMetaClass metaCompilerClass]
- ifFalse: [super compilerClass]!
Item was changed:
----- Method: Metaclass>>decompilerClass (in category 'compiling') -----
decompilerClass
+
+ ^ self theNonMetaClass metaDecompilerClass!
- "BE CAREFUL!! If you provide your own class to treat class-side (resp. meta) methods, you MUST account for the #meta*Class selector to use the default implementation in that case. That is, the methods behind #meta*Class MUST always get the default Smalltalk treatment."
-
- ^ (self theNonMetaClass respondsTo: #metaDecompilerClass)
- ifTrue: [self theNonMetaClass metaDecompilerClass]
- ifFalse: [super decompilerClass]!
Item was changed:
----- Method: Metaclass>>evaluatorClass (in category 'compiling') -----
evaluatorClass
+
+ ^ self theNonMetaClass metaEvaluatorClass!
- "BE CAREFUL!! If you provide your own class to treat class-side (resp. meta) methods, you MUST account for the #meta*Class selector to use the default implementation in that case. That is, the methods behind #meta*Class MUST always get the default Smalltalk treatment."
-
- ^ (self theNonMetaClass respondsTo: #metaEvaluatorClass)
- ifTrue: [self theNonMetaClass metaEvaluatorClass]
- ifFalse: [super evaluatorClass]!
Item was changed:
----- Method: Metaclass>>formatterClass (in category 'printing') -----
formatterClass
+
+ ^ self theNonMetaClass metaFormatterClass!
- "BE CAREFUL!! If you provide your own class to treat class-side (resp. meta) methods, you MUST account for the #meta*Class selector to use the default implementation in that case. That is, the methods behind #meta*Class MUST always get the default Smalltalk treatment."
-
- ^ (self theNonMetaClass respondsTo: #metaFormatterClass)
- ifTrue: [self theNonMetaClass metaFormatterClass]
- ifFalse: [super formatterClass]!
Item was changed:
----- Method: Metaclass>>parserClass (in category 'compiling') -----
parserClass
+
+ ^ self theNonMetaClass metaParserClass!
- "BE CAREFUL!! If you provide your own class to treat class-side (resp. meta) methods, you MUST account for the #meta*Class selector to use the default implementation in that case. That is, the methods behind #meta*Class MUST always get the default Smalltalk treatment."
-
- ^ (self theNonMetaClass respondsTo: #metaParserClass)
- ifTrue: [self theNonMetaClass metaParserClass]
- ifFalse: [super parserClass]!
Item was changed:
----- Method: Metaclass>>prettyPrinterClass (in category 'printing') -----
prettyPrinterClass
+
+ ^ self theNonMetaClass metaPrettyPrinterClass!
- "BE CAREFUL!! If you provide your own class to treat class-side (resp. meta) methods, you MUST account for the #meta*Class selector to use the default implementation in that case. That is, the methods behind #meta*Class MUST always get the default Smalltalk treatment."
-
- ^ (self theNonMetaClass respondsTo: #metaPrettyPrinterClass)
- ifTrue: [self theNonMetaClass metaPrettyPrinterClass]
- ifFalse: [super prettyPrinterClass]!
David T. Lewis uploaded a new version of Morphic to project The Inbox:
http://source.squeak.org/inbox/Morphic-dtl.1373.mcz
==================== Summary ====================
Name: Morphic-dtl.1373
Author: dtl
Time: 22 November 2017, 10:25:57.941315 am
UUID: 2e41d807-bf5a-4f90-84aa-d0ac472bb023
Ancestors: Morphic-dtl.1372
Reorganize Morph>>delete for clarity, and remove reference to global World.
MorphicProject>>finalExitActions and finalEnterActions remove explicit references to global World and allow World be be removed for testing purposes.
=============== Diff against Morphic-dtl.1372 ===============
Item was changed:
----- 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 |
-
- | aWorld |
self removeHalo.
+ (oldWorld := self world) ifNotNil: [
-
- self isInWorld ifTrue: [
self disableSubmorphFocusForHand: self activeHand.
self activeHand
releaseKeyboardFocus: self;
releaseMouseFocus: self].
+ owner ifNotNil: [
+ self privateDelete. "remove from world"
-
- "Preserve world reference for player notificaiton. See below."
- aWorld := self world ifNil: [World].
-
- owner ifNotNil:[
- self privateDelete.
self player ifNotNil: [:player |
+ oldWorld ifNotNil: [
+ player noteDeletionOf: self fromWorld: oldWorld]]].!
- player noteDeletionOf: self fromWorld: aWorld]].!
Item was added:
+ ----- Method: MorphicProject>>clearGlobalState (in category 'enter') -----
+ clearGlobalState
+ "Clean up global state. The global variables World, ActiveWorld, ActiveHand
+ and ActiveEvent provide convenient access to the state of the active project
+ in Morphic. Clear their prior values when leaving an active project. This
+ method may be removed if the use of global state variables is eliminated."
+
+ "If global World is defined, clear it now. The value is expected to be set
+ again as a new project is entered."
+ Smalltalk globals at: #World
+ ifPresent: [ :w | Smalltalk globals at: #World put: nil ].
+ ActiveWorld := ActiveHand := ActiveEvent := nil.
+ !
Item was changed:
----- Method: MorphicProject>>finalEnterActions: (in category 'enter') -----
finalEnterActions: leavingProject
"Perform the final actions necessary as the receiver project is entered"
| navigator armsLengthCmd navType thingsToUnhibernate |
+ "If this image has a global World variable, update it now"
+ Smalltalk globals at: #World
+ ifPresent: [ :w | Smalltalk globals at: #World put: world ].
- World := world. "Signifies Morphic"
world install.
world transferRemoteServerFrom: leavingProject world.
"(revertFlag | saveForRevert | forceRevert) ifFalse: [
(Preferences valueOfFlag: #projectsSentToDisk) ifTrue: [
self storeSomeSegment]]."
"Transfer event recorder to me."
leavingProject isMorphic ifTrue: [
leavingProject world pauseEventRecorder ifNotNil: [:rec |
rec resumeIn: world]].
world triggerOpeningScripts.
self initializeMenus.
self projectParameters
at: #projectsToBeDeleted
ifPresent: [ :projectsToBeDeleted |
self removeParameter: #projectsToBeDeleted.
projectsToBeDeleted do: [:each | each delete]].
Locale switchAndInstallFontToID: self localeID.
thingsToUnhibernate := world valueOfProperty: #thingsToUnhibernate ifAbsent: [#()].
thingsToUnhibernate do: [:each | each unhibernate].
world removeProperty: #thingsToUnhibernate.
navType := ProjectNavigationMorph preferredNavigator.
armsLengthCmd := self parameterAt: #armsLengthCmd ifAbsent: [nil].
navigator := world findA: navType.
(Preferences classicNavigatorEnabled and: [Preferences showProjectNavigator and: [navigator isNil]]) ifTrue:
[(navigator := navType new)
bottomLeft: world bottomLeft;
openInWorld: world].
navigator notNil & armsLengthCmd notNil ifTrue:
[navigator color: Color lightBlue].
armsLengthCmd notNil ifTrue:
[Preferences showFlapsWhenPublishing
ifFalse:
[self flapsSuppressed: true.
navigator ifNotNil: [navigator visible: false]].
armsLengthCmd openInWorld: world].
world reformulateUpdatingMenus.
world presenter positionStandardPlayer.
self assureMainDockingBarPresenceMatchesPreference.
world repairEmbeddedWorlds.!
Item was changed:
----- Method: MorphicProject>>finalExitActions: (in category 'enter') -----
finalExitActions: enteringProject
world triggerClosingScripts.
"Pause sound players, subject to preference settings"
(world hasProperty: #letTheMusicPlay)
ifTrue: [world removeProperty: #letTheMusicPlay]
ifFalse: [SoundService stop].
world sleep.
-
(world findA: ProjectNavigationMorph)
ifNotNil: [:navigator | navigator retractIfAppropriate].
+ self clearGlobalState.
-
- "Clean-up global state."
- World := nil.
- ActiveWorld := ActiveHand := ActiveEvent := nil.
Sensor flushAllButDandDEvents. !
Hello all,
I created an entry in SqueakMap for Sprite:
http://map.squeak.org/account/package/a5938177-1b36-48f8-9b47-ffbd827f36f5
... but I am unable to get to a release page: the "edit releases" link
in my account page does no respond (no page refresh, hangs forever).
I can edit releases for all my other packcages though.
Is this a known issue?
Stef