Beware of the default implementations of Stackable Traits

I have been plagued with the strangest code problem tonight. One type of sketch I’ve been doing lately is interesting visuals with my name, similar to the title bar at http://roberthodgin.com/; if you visit my website you’ll see the first one I did. It makes sense to write a subclass of PApplet to hold common code related to this type of sketch. I’ve also fallen quite deeply in love with Scala’s stackable trait pattern, and it makes sense to make my subclass into a stackable trait, since the code mostly gave me convenience methods for creating an RShape out of my name (I…
scala> println(res3);
I have been plagued with the strangest code problem tonight. One type of sketch I’ve been doing lately is interesting visuals with my name, similar to the title bar at http://roberthodgin.com/; if you visit my website you’ll see the first one I did. It makes sense to write a subclass of PApplet to hold common code related to this type of sketch. I’ve also fallen quite deeply in love with Scala’s stackable trait pattern, and it makes sense to make my subclass into a stackable trait, since the code mostly gave me convenience methods for creating an RShape out of my name (I’m using geomerative in order to turn my name into a collection of shapes). The basic code goes like this:

trait NameApplet extends PApplet {
    ... //stuff

    abstract override def draw() {
      super.draw();
      ... //other stuff
    }

    ... //stuff other than the other stuff
}

Harmless enough, right? For those of you who don’t want to read the article, the basic idea behind the stackable trait is that I’ll create some concrete subclass and mix-in the NameApplet, e.g. class MySketch extends PApplet with NameApplet. The “abstract override” modifier for the draw method simply means that super will refer to the first concrete implementation of draw that comes before the mix-in, so calling “super.draw()” in this case will call PApplet’s draw method. That wasn’t the best explanation so you should probably just read the article :P. Anyways, I wanted a grid of particles whose size depended on how close they were to my name, so today’s sketch mixed in NameApplet. (I actually extended NameApplet, since I had no other mixins so super was bound to PApplet anyways).

object Jun30 extends NameApplet {
...
    override def draw() {
       ...
       super.draw(); //I call super.draw in order to get the "other stuff"
    }
...
}

(Tangent: as I learned very recently, it’s actually an awful idea to declare a Scala object that is a subclass of Applet since nothing will be able to instantiate it, meaning you can’t put it online)
After I had the basics down, I did a preliminary run to see what it looked like. My draw() method ran ONCE, and then everything stopped. I put in debugs to no avail; it looked like everything ran fine for exactly one frame, and then just decided to stop. It was very frustrating to debug something so seemingly straightforward. (But we’ve all been there, right?)

Long story short, I discovered that the call to super.draw() in Jun30 was causing the problem. At this point the “other stuff” in NameApplet’s draw() was a single if statement that always evaluated to false, so the problem must’ve been the call to super.draw() in NameApplet’s draw method. Taking a look at the source code for PApplet, the default implementation of the draw method was indeed the culprit:

public void draw() {
    // if no draw method, then shut things down
    //System.out.println("no draw method, goodbye");
    finished = true;
  }

FFFUUUUUUU

In retrospect, this is something I should’ve checked at the very beginning. The default draw method stops the applet so as to allow for Basic Mode in the PDE. Of course, I wasn’t thinking about the PApplet implementation of draw() when writing NameApplet’s draw(). But if we learn from anything, it’s going to be our mistakes and frustrations. I’m certainly going to think about what super.xxxx is doing when writing stackable traits from now on.

P.S. Sorry for being gone these past few days; I’ll try to post daily and hopefully put up some finished sketches w/ source code on xzhang.no-ip.org soon.

Advertisements


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s