Reputation: 175
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
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.
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
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.
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”
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
Reputation: 15907
At a certain point, you might need to do a
World doOneCycle
to get the redraw.
Upvotes: 0