Call a object's or class' function with thread()?

edited May 2017 in Library Questions

I'm trying to use threading to make it so I can display a "loading screen" while something is loading. The main class will draw the loading icon and start a thread to have the Menu Screen start initializing all the images it needs, and when the Menu Screen is done loading everything, it sets a global Done Loading variable to true, and the main class starts drawing it.

But how do I call MenuScreen.initialize() with thread()? It gives me an error in the console that says "There is no public MenuScreen.initialize() method in the class MainClass".

Here's a trimmed version of what I have so far. The main class:

import gifAnimation.*; // used for the loading icon

Screen curScreen;
boolean doneLoading;
Sprite loadingGif;

void setup()
{
  size(600, 600);
  frameRate(30);
  loadingGif = new Sprite(this, "loading flower.gif");
  doneLoading = false;
  curScreen = new MenuScreen();
  thread("MenuScreen.initialize");
}

void draw()
{
  background(50);
  if(doneLoading) curScreen.screenDraw();
  else loadingGif.drawThis(width - 60, height - 60);
}

And the MenuScreen class, which implements a very simple Screen interface that stipulates its initialize() and screenDraw() methods:

class MenuScreen implements Screen
{
  int curSelection; // which selection item the cursor is on right now: new game, load game, etc.
  PImage backgroundImg;
  PImage cursorImg;

  MenuScreen()
  {
  }

  void initialize()
  {
    backgroundImg = loadImage("WelcomeBackground.png");
    cursorImg = loadImage("WelcomeCursor.png");
    doneLoading = true;
  }

  void screenDraw()
  {
    image(backgroundImg, 0, 0, width, height);
    text("Herro wuorld", 50, 50, 200, 200);
  }
}

I've also tried using thread("initialize") in MenuScreen's constructor, but that tries to look for an initialize function in the main class, too. I suppose I could just make the Initialize function a global function, but that doesn't seem like optimal coding standards when all I should need is a proper String for my call to thread()...

Answers

  • Answer ✓

    thread() can only recognize PApplet methods. #-o

    You're better off turning you class into a thread, either by extends Thread or implements Runnable:

    http://docs.Oracle.com/javase/8/docs/api/java/lang/Thread.html

  • I see. Thanks for the information!

  • edited May 2017

    For future readers...

    class MenuScreen now extends Screen (instead of implementing it as an interface), and the superclass Screen now implements Runnable and has initialize() and screenDraw() as blank functions and a run() function that just calls initialize(). Luckily, it calls the subclass' overridden versions of initialize() and screenDraw() all on its own ^_^

    So now as long as each new subclass of Screen that I implement overrides initialize() and screenDraw(), I'm good. Thanks again!

  • It will be great if you could upload an updated version of your MenuScreen class implementing Runnable, if you don't mind.

    Thank you for sharing your solution.

    Kf

  • So now as long as each new subclass of Screen that I implement overrides initialize() and screenDraw(), I'm good. Thanks again!

    You ensure that it happens by making Screen an abstract class, and making initialize() and screenDraw() abstract methods.

  • edited May 2017

    Example -

    abstract class AbstractClass implements Runnable{
    
      void run(){
        println("Executing");
        initialize();
        while(execute()){}
      }
    
      abstract void initialize ();
    
      abstract boolean execute();
    }  
    

    Any subclass of AbstractClass must declare the two abstract methods (unless they're abstract classes themselves).

  • edited June 2017

    It will be great if you could upload an updated version of your MenuScreen class implementing Runnable, if you don't mind.

    Sure, no problem.

    abstract class Screen implements Runnable
    {
    
      void initialize()
      {
        println("Call to superclass Screen.initialize(). This shouldn't be possible, remember to override it with each new screen implementation.");
      }
    
      void screenDraw()
      {
        println("Call to superclass Screen.screenDraw(). This shouldn't be possible, remember to override it with each new screen implementation.");
      }
    
      // it should not be necessary to overload this function
      void run()
      {
        initialize();
      }
    }
    
  • You should declare the functions as abstract, like this -

    abstract class Screen implements Runnable
    {
    
      abstract void initialize();
    
      abstract void screenDraw()
    
      // it should not be necessary to overload this function
      void run()
      {
        initialize();
      }
    }
    
Sign In or Register to comment.