Problems with pushStyle/popStyle accessed within Threads

Hi, my Android app is crashing because of an error "too many popStyle without pushStyle". I have triple-checked, and every single popStyle in my code is accompanied with a pushStyle before! Since I am using many Threads, even though only one controls the "redraw()" (in a noLoop() style), I am under the feeling that the only reason I could possibly get this error is because there could be async calls to pushStyle and popStyle in my code, somehow.

I don't really know how to debug this, so I am asking for suggestions?

Also, I came up with the idea of overriding pushStyle() and popStyle() as follows. Please let me know if this is a good or very bad idea...

private boolean stylePushed=false;

public void pushStyle(){
    stylePushed=true;
    super.pushStyle();
}

public void popStyle(){
    if(stylePushed){
        super.popStyle();
        stylePushed=false;
    }
}

Thanks

Answers

  • edited March 2015

    I guess, I can also modify the code above by replacing the boolean with an int, such as:

    private int stylePushedCount=0;
    
    public void pushStyle(){
    stylePushedCount++;
    super.pushStyle();
    }
    
    public void popStyle(){
    if(stylePushedCount>0){
        super.popStyle();
        stylePushedCount--;
    }
    }
    

    That way it allows for multiple push before multiple pop?

  • edited March 2015

    General advise for threading w/ Processing:

    • Never directly draw to the canvas from another Thread.
    • Instead setup global boolean variables in order to flag sketch's draw() to do that instead.
    • Alternatively, have an individual PGraphics for the Thread.
    • Then use image() within sketch's draw() to display those PGraphics.
  • As I said, I run the PApplet in the noLoop(); mode, and I never use loop(), but just redraw(), inside only one thread. Are you saying that calling redraw() creates its own thread?

  • edited March 2015

    Are you saying that calling redraw() creates its own Thread?
    Since I am using many Threads,...

    • Nope. But you contradict yourself stating you're using multiple Thread instances. Dunno where!
    • A regular noLoop()/redraw() combo by itself is Thread safe.
    • However, if other threads are directly drawing to canvas, they'll certainly happen at "wrong" times.
    • The only safer place to draw to canvas is inside sketch's draw() callback.
    • Or by registering pre() & post() custom methods via registerMethod().

    https://processing.org/reference/javadoc/core/processing/core/PApplet.html#registerMethod(java.lang.String, java.lang.Object)

  • Well, in theory, I tried to make sure that every method that does some kind of drawing is eventually called within the draw() callback, itself called by redraw() in only one of my Threads.

    However, since I am getting this error, my guess is that the only explanation is that the theory afore mentioned doesn't hold, but I don't know where to start debugging.

  • Answer ✓
    • Even pushStyle() & popStyle() are canvas related API functions.
    • So we can't use them outside Processing's "Animation" Thread either!
    • If you really need to use Processing canvas API, instantiate 1 separate PGraphics for each Thread!
  • "I don't know where to start debugging"
    Using println() is often surprisingly efficient when dealing with threads...

  • edited March 2015

    I was able to remove all unnecessary threads and it surely works better now, regarding styles... I actually changed my code to only make calculations with millis() rather than just by frameCounts and other draw() related values. I did not know that in Fisica/Box2D, we could pass a specific number of seconds in the method world.step(), so I can now take the delay into account when calling step() in the draw() method.

    However, I feel like it created a bug that I had at the very beginning: saccades from time to time. Should I reimplement some kinds of threads? I read it's related to garbage collection. How can I control that?

    The game is available here:
    http://goo.gl/xmdglz

Sign In or Register to comment.