Skip to main content

Posts

Change events are special

I just spent a few hours chasing a very mysterious bug, where an event handler was properly called the first time, but never again. This was a rather unspecial on:in: handler: onFooInBar <on: foo in: bar> ... After initialization it was properly registered in the event map, but at some point the event map entry just vanished. There also was another on: handler which did some stuff whenever bar changed. To "call" that stuff, we just signaled a barChanged event somewhere else: self signal: #barChanged. It turned out this innocuously looking line was responsible for the trashed on:in: handler! What happened? Well, an on:in: handler must always be registered to the object that currently is occupying the bar field. But what if bar changes? Then we must unregister the foo handler in the old bar , and re-register it with the new bar . That's why the system installs a barChanged handler behind the scenes, which normally receives the new and old values of bar ...

About Scripts

We were looking into another Croquet performance problem the other day so we fired up a message tally (world menu - debug - start MessageTally). Curiously enough, 70 percent was taken by ScriptScheduler>>runActiveScripts ! Unfortunately, the tally did not further differentiate this item. But what are scripts, anyway? Everyone knows that Smalltalk is all about objects and messages, so what the heck are scripts? Well, Croquet and Tweak are not just using Smalltalk as you know it (and the underlying Squeak still is pretty much vanilla Smalltalk-80), but instead improve on it by implementing a new enriched object system. There still are objects (the entities of the system) and messages (their means of communication). But where in Smalltalk methods are invoked synchronously by a message send, we now have asynchronous method invocations as well, which are called "scripts". Synchronous in this context means that the sender sends a message, which invokes a method in the receiv...

Lend me a Hand

The last Tweak updates broke our Tweak-based Croquet application, objects did not respond to clicks anymore. I first suspected changes in Croquet, but the latest updates there didn't look suspicious. But neither did the last couple of Tweak updates. Investigating further and sprinkling debug output here and there I discovered that pointer events were offset. Moving the Croquet window to the upper left corner confirmed this, all of a sudden everything worked normally. What was happening? Well, living in a shared world isn't easy. Morphic, Croquet, and Tweak interact very closely in the TeapotMorph , which bridges between those three worlds. Without Tweak (that is, without calling initializeTweakWorld in your initializeDefaultSpace method), the TeapotMorph uses the regular Morphic event dispatching mechanism which leads to calling the event handling methods keyDown: , mouseDown: etc. which in turn dispatch the events to the activeCamera , that is, into the Croquet world. When...

Dynamic Textures

We've been wondering for a while, why screen updates are more expensive than expected in the Tweak overlay. Now I debugged into this and it turns out we're uploading the whole texture even if only a small part was changed. The relevant code is in OGLTextureManager>>uploadTexture:dirtyRect: . A partial upload using glTexSubImage2D() is only performed if the texture in use is not static. Having found out what's going on it's easy to fix, a one-line change in TeapotMorph>>glRenderTweakCostume:on: does the trick: texCache isStatic: false. As simple as that - I just posted the update.

Profiling + Vector Math = Performance

So there was a student who implemented a flocking simulation for a virtual fishtank using Croquet. Worked fine with 20 fishes. With 50 fishes it became rather sluggish. Putting in more than 100 fishes the framerate could be measured in seconds per frame. So the rendering in Croquet is too slow, right? Not quite. There are two things you have to keep in mind when it comes to performance: When in doubt, measure. You are in doubt. So we fired up a message tally (world menu - debug - start MessageTally). Turns out only 12 percent of the time were spent in rendering. So it's not the rendering at all. A whopping 80 percent was taken by the flock's step methods. The leaves of the message tally showed that 15 percent of the time went into each of the methods #x , #y , and #z ! So we looked at the code. Every fish was told to swim in the main direction of its neighbors, that is the fishes within a certain radius. Processing continued only for those fishes in range. Sounds quite reas...