Gregory Kornblum
Gregory Kornblum

Reputation: 175

Need to sleep in smalltalk for step animation

In smalltalk (squeak environment) i am trying to animate some objects, like make blinking during some other process. But it only works when all other processes are over, so i guess there is not enough time for that (is it?).

I tried "(delay forMilliseconds:500) wait" at some points, but it still did't work, like if delay itself blocks program running.

So how can i sleep instead?

Upvotes: 3

Views: 352

Answers (2)

Tobias
Tobias

Reputation: 3110

The delay actually blocks. That's its responsibility: “halt” the current process for the specified amount of time.

There are some ideas to overcome that.

Morphic Stepping

You can make a Morph receive the #step message in a defined interval:

YourMorph>>step
   "Assuming that myState is an instance variable with accessors"

   self color: (self myState ifTrue: [Color blue] ifFalse: [Color red]).
   self myState: self myState not

The frequency of #step being called is dependent on the #stepTime:

YourMorph>>stepTime

    "Call #step every quarter second"
    ^ 250 "ms"

Also, you can toggle whether your Morph receives #step at all with #startStepping and #stopStepping.

This should allow a quite nice blinking animation

Morphic Alarms

If you need infrequent messages sent to your asynchronously, you can use alarms.

That is, you schedule a message to be sent after a specific amount of time (#addAlarm:after:) or at a specific point in time (#addAlarm:at:).

Assume that your morph wants to get sent the #toggleAThing message after 500 milliseconds, you can do

yourMorph addAlarm: #toggleAThing after: 500 "ms".

Beware that this is a one-shot. It gets only sent once. For periodic messages, stepping is better.

Manual sleeping (beware)

You can actually use delays to induce “later” messages. For that you would enclose the delay in a block and make a new process.

Suppose you want the #toggleAThing message being sent to your object after 350 milliseconds, you could do the following:

[(Delay forMilliseconds: 350) wait.
 yourObject toggleAThing.
] fork.
"Not blocking, continue doing things"

Note that you should read a bit about scheduling in Squeak (for example by reading the implementation of the Process class) before trying that. A better version of this is available as “Future sends”

Future Sends

This is the most general way to receive or send an asynchronous message. You simply specify the time difference until the message is sent and then send it:

(yourObject future: 350 "ms") toggleAThing

Upvotes: 4

Stephan Eggermont
Stephan Eggermont

Reputation: 15907

At a certain point, you might need to do a

World doOneCycle

to get the redraw.

Upvotes: 0

Related Questions