<body><div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000">
                                        Hi Christoph,<div><br></div><div>preamble and postscript are per package. I suppose that all FrameRateMorph instances are stepping. I would rather not add a global variable to pass information between scripts.</div><div><br></div><div>Also, morphs do not step between code loading and postscript evaluation. So you should be fine with a single postscript:</div><div><br></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">FrameRateMorph allInstances do: [:frm|</span><br style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">   frm stopStepping.</span><br style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">   frm instVarNamed: #lastDisplayTime put: DateAndTime now.</span></div><div>   frm startStepping<span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">].</span></div><div><br></div><div>Best,</div><div>Marcel</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 05.09.2019 00:42:55 schrieb Thiede, Christoph <christoph.thiede@student.hpi.uni-potsdam.de>:</p><div style="font-family:Arial,Helvetica,sans-serif">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
<div id="divtagdefaultwrapper" style="font-size: 12pt;color: #000000;font-family: Calibri,Helvetica,sans-serif" dir="ltr">
<p>Thank you very much for the tutorial!</p>
<p><br>
</p>
<p>I would not assume that all morphs are currently stepping. What would be the best way to pass information (a list of stopped morphs) from prescript to postscript?</p>
<p>A class var? SmalltalkImage? Is there any Metacello cache for things like that?</p>
<p><br>
</p>
<p>Best,</p>
<p>Christoph</p>
<div id="Signature">
<div name="divtagdefaultwrapper" style="font-family: Calibri,Arial,Helvetica,sans-serif;font-size: ;margin: 0">
<div><span style="font-size: 10pt;color: #808080"></span></div>
</div>
</div>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><span style="font-family: Calibri, sans-serif;color: #000000"><b>Von:</b> Squeak-dev <squeak-dev-bounces@lists.squeakfoundation.org> im Auftrag von Chris Cunningham <cunningham.cb@gmail.com><br>
<b>Gesendet:</b> Mittwoch, 4. September 2019 23:27:15<br>
<b>An:</b> The general-purpose Squeak developers list<br>
<b>Betreff:</b> Re: [squeak-dev] The Inbox: MorphicExtras-ct.260.mcz</span>
<div> </div>
</div>
<div>
<div dir="ltr">A nicer way to do this is to use the preamble and postscript.  With your version loaded (and changed to use DateAndTime), in the Morphic browser, choose the Scripts button (
<div><img alt="image.png" width="83" height="31" src="cid:ii_k05rh1pq0"></img>).  Then choose "edit preamble" to edit the preamble script.</div>
<div><br>
</div>
<div>Then, add the script to the window that pops up and save it.</div>
<div><br>
</div>
<div>The script might look something like:</div>
FrameRateMorph allInstances do: [:frm|<br>
   frm stopStepping.<br>
   frm instVarNamed: #lastDisplayTime put: DateAndTime now.<br>
   ].
<div><br>
</div>
<div>Then, choose scripts again and edit postscript.  In that editor, add code that start the stepping again.  (Also, you'll need to remove the old postscript - it actively fails.)</div>
<div><br>
</div>
<div>Then, save the new version and test it.</div>
<div><br>
</div>
<div>Scripts are nice for one-shot updates.</div>
<div><br>
</div>
<div>-cbc</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Wed, Sep 4, 2019 at 12:06 PM Thiede, Christoph <<a href="mailto:Christoph.Thiede@student.hpi.uni-potsdam.de">Christoph.Thiede@student.hpi.uni-potsdam.de</a>> wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<div id="gmail-m_6092616263550255330divtagdefaultwrapper" style="font-size: 12pt;color: rgb(0,0,0);font-family: Calibri,Helvetica,sans-serif" dir="ltr">
<p>Hi, thanks for feedback!</p>
<p><br>
</p>
<p>I have no experience with upgrade scripts, how can we keep the code clean? Is it possible to have Metacello load a temporary version first and then load the final version, or are there any better patterns?</p>
<p><br>
</p>
<p>For a temporary version, we could prepend the following code to the #step method:</p>
<p><br>
</p>
<p><span style="font-size: 12pt">self updateInterval ifNil: [</span><br>
</p>
<div><span style="white-space:pre-wrap"></span>"Upgrade existing instance"</div>
<div><span style="white-space:pre-wrap"></span>lastDisplayTime := DateAndTime new.</div>
<div><span style="white-space:pre-wrap"></span>self updateInterval: 500 milliSeconds].</div>
<div><br>
</div>
<div>Probably it would be a bad idea to have the method recompile itself after executing the upgrade part? ;)</div>
<br>
<p></p>
<p>Best,</p>
<p>Christoph</p>
<p><br>
</p>
<p>PS: Yes, there was no special reason to use TimeStamp, except of [TimeStamp name size < DateAndTime name size] :)</p>
<div id="gmail-m_6092616263550255330Signature">
<div name="divtagdefaultwrapper">
<div><span style="font-size: 10pt;color: #808080"></span></div>
</div>
</div>
</div>
<hr style="display:inline-block;width:98%">
<div id="gmail-m_6092616263550255330divRplyFwdMsg" dir="ltr"><span style="font-family: Calibri, sans-serif;color: #000000"><b>Von:</b> Squeak-dev <<a href="mailto:squeak-dev-bounces@lists.squeakfoundation.org" target="_blank">squeak-dev-bounces@lists.squeakfoundation.org</a>>
 im Auftrag von Chris Cunningham <<a href="mailto:cunningham.cb@gmail.com" target="_blank">cunningham.cb@gmail.com</a>><br>
<b>Gesendet:</b> Mittwoch, 4. September 2019 18:39:13<br>
<b>An:</b> The general-purpose Squeak developers list<br>
<b>Betreff:</b> Re: [squeak-dev] The Inbox: MorphicExtras-ct.260.mcz</span>
<div> </div>
</div>
<div>
<div dir="ltr">Hi.
<div><br>
<div>I like the changes (especially the switch to DateAndTime), however, if you have a FrameRateMorph open when updating, it raises errors and fails to work (the time to timestamp gives it issues).</div>
</div>
<div><br>
</div>
<div>Any chance you could prescript to fix this?  Maybe either update existing instances with DateAndTimes and stop/start stepping around the update, or closing all instances (although I'm not sure if that is advisable with the comments about 'stand-alone entity'
 in initializeToStandAlone, which implies there are embedded instances).</div>
<div><br>
</div>
<div>-cbc</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Wed, Sep 4, 2019 at 6:54 AM <<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>> wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
A new version of MorphicExtras was added to project The Inbox:<br>
<a href="http://source.squeak.org/inbox/MorphicExtras-ct.260.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/inbox/MorphicExtras-ct.260.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: MorphicExtras-ct.260<br>
Author: ct<br>
Time: 4 September 2019, 3:53:54.175698 pm<br>
UUID: cab65f78-e646-cc40-9d0f-c16114d1bb44<br>
Ancestors: MorphicExtras-mt.259<br>
<br>
Refactor FrameRateMorph: Add accessors for updateInterval and expose measure data. Use TimeStamp instead of Time to avoid clock wrap around.<br>
<br>
=============== Diff against MorphicExtras-mt.259 ===============<br>
<br>
Item was changed:<br>
  StringMorph subclass: #FrameRateMorph<br>
+       instanceVariableNames: 'lastDisplayTime framesSinceLastDisplay updateInterval mSecsPerFrame framesPerSec'<br>
-       instanceVariableNames: 'lastDisplayTime framesSinceLastDisplay'<br>
        classVariableNames: ''<br>
        poolDictionaries: ''<br>
        category: 'MorphicExtras-Demo'!<br>
<br>
Item was added:<br>
+ ----- Method: FrameRateMorph>>framesPerSec (in category 'accessing') -----<br>
+ framesPerSec<br>
+ <br>
+       ^ framesPerSec!<br>
<br>
Item was changed:<br>
  ----- Method: FrameRateMorph>>initialize (in category 'initialization') -----<br>
  initialize<br>
  "initialize the state of the receiver"<br>
        super initialize.<br>
  ""<br>
+       lastDisplayTime := TimeStamp new.<br>
-       lastDisplayTime := 0.<br>
        framesSinceLastDisplay := 0.<br>
+       self updateInterval: 500 milliSeconds.<br>
        self font: (Preferences standardMenuFont emphasized: 1).<br>
  !<br>
<br>
Item was added:<br>
+ ----- Method: FrameRateMorph>>mSecsPerFrame (in category 'accessing') -----<br>
+ mSecsPerFrame<br>
+ <br>
+       ^ mSecsPerFrame!<br>
<br>
Item was changed:<br>
  ----- Method: FrameRateMorph>>step (in category 'stepping and presenter') -----<br>
  step<br>
        "Compute and display (every half second or so) the current framerate"<br>
<br>
+       | now timePassed newContents |<br>
-       | now mSecs mSecsPerFrame framesPerSec newContents |<br>
        framesSinceLastDisplay := framesSinceLastDisplay + 1.<br>
+       now := TimeStamp now.<br>
+       timePassed := now - lastDisplayTime.<br>
+       (timePassed > self updateInterval) ifTrue: <br>
+               [| mSecs |<br>
+               mSecs := timePassed asMilliSeconds.<br>
+               mSecsPerFrame := mSecs // framesSinceLastDisplay.<br>
-       now := Time millisecondClockValue.<br>
-       mSecs := now - lastDisplayTime.<br>
-       (mSecs > 500 or: [mSecs < 0 "clock wrap-around"]) ifTrue: <br>
-               [mSecsPerFrame := mSecs // framesSinceLastDisplay.<br>
                framesPerSec := (framesSinceLastDisplay * 1000) // mSecs.<br>
                newContents := mSecsPerFrame printString, ' mSecs (', framesPerSec printString, ' frame', (framesPerSec = 1 ifTrue: [''] ifFalse: ['s']), '/sec)'.<br>
                self contents: newContents.<br>
                lastDisplayTime := now.<br>
                framesSinceLastDisplay := 0]<br>
        ifFalse:<br>
                ["Ensure at least one pixel is drawn per frame"<br>
                Preferences higherPerformance ifTrue: [self invalidRect: (self position extent: 1@1)]]!<br>
<br>
Item was added:<br>
+ ----- Method: FrameRateMorph>>updateInterval (in category 'accessing') -----<br>
+ updateInterval<br>
+ <br>
+       ^ updateInterval!<br>
<br>
Item was added:<br>
+ ----- Method: FrameRateMorph>>updateInterval: (in category 'accessing') -----<br>
+ updateInterval: aNumber<br>
+ <br>
+       updateInterval := aNumber!<br>
<br>
<br>
</blockquote>
</div>
</div>
</div>
<br>
</blockquote>
</div>
</div>
</div></blockquote>
                                        </div></body>