×

Discussion Board

Results 1 to 8 of 8
  1. #1
    Registered User
    Join Date
    Apr 2003
    Posts
    5

    Animation with callSerially

    Hi

    I am using Display.callSerially(Runnable r) to synch a game canvas with the event stream. Can anyone tell me how callSerially is implemented on the NOKIA phones/emulators?

    My problem is that I have more than one runnable canvas, one for each interactive screen in my game. Only one is ever running at any given time, but when the second is running, the run() method of the first is also mysteriously called every event cycle.

    The code works fine on other emulators/phones. My hunch is that callSerially(r) on NOKIA adds r to a list of runnables that is maintained through the life of the MIDlet (instead of being purged every event cycle), so every runnable that was ever passed into callSerially() has its run() method called whenever callSerially is executed in the future.

    The spec says "The run() method will be called exactly once for each call to callSerially()." which doesn't precisely rule out what I'm seeing here. The run() method for every runnable ever passed to callSerially in the lifetime of the MIDLet will be called exactly once for each subsequent call to callSerially().

    Does anyone know if this is the way things are? I can see it might be useful, but there is no way to remove a runnable (I tried calling callSerially(null)).

    I will try to develop a small example to demonstrate.

    Thanks,

    Mike

  2. #2
    Regular Contributor
    Join Date
    Mar 2003
    Posts
    393
    Posting an example to demonstrate the issue will be useful. Following is a link to a piece of code that uses callSerially(Runnable r) in a similar manner. I have not tested but you could try the approach

    http://discussion.forum.nokia.com/fo...allSerially%2A

    Other possibilities:
    Have you tried setting the first Runnable Canvas object to null after making a copy of it?

    [N]/Forum Nokia

  3. #3
    Registered User
    Join Date
    Apr 2003
    Posts
    5

    Example Code

    Here is my (truncated) code example:

    public class NokiaTest extends MIDlet
    {
    private Display display;
    private TestCanvas aCanvas;
    private TestCanvas bCanvas;
    public static final int ACANVAS_EXIT = 1;
    public static final int BCANVAS_EXIT = 2;
    public boolean running = true;

    public NokiaTest() {
    display = Display.getDisplay(this);
    aCanvas = new TestCanvas(this,ACANVAS_EXIT,"A Canvas");
    bCanvas = new TestCanvas(this,BCANVAS_EXIT,"B Canvas");
    }

    public void startApp() throws MIDletStateChangeException {
    running = true;
    display.setCurrent( aCanvas );
    aCanvas.run();
    }

    public void exitCanvas(int status) {
    System.out.println("Exit Canvas "+status);
    running = true;
    if (status == ACANVAS_EXIT){
    display.setCurrent( bCanvas );
    bCanvas.run();
    } else {
    display.setCurrent( aCanvas );
    aCanvas.run();
    }
    }
    }

    public class TestCanvas extends Canvas implements Runnable {
    public int exitStatus;
    public String displayString;
    private Display display;
    private NokiaTest midlet;

    public TestCanvas(NokiaTest _midlet, int _exitStatus, String _displayString) {
    midlet = _midlet;
    display = Display.getDisplay(midlet);
    exitStatus = _exitStatus;
    displayString = _displayString;
    }

    public void run() {
    System.out.println(displayString);
    if ( midlet.running ) {
    repaint();
    display.callSerially(this);
    } else {
    midlet.exitCanvas(exitStatus);
    }
    }

    public void keyReleased(int keyCode) {
    midlet.running = false;
    }

    public final void paint(Graphics g) {
    g.drawString(displayString,NokiaTest.getRandom(0,getWidth()),NokiaTest.getRandom(0,getHeight()),NokiaTest.anchor);
    }

    }

    I missed out as much code as I could for brevity. This is cut from a working example, which I can post or send if you want.

    So the midlet creates two canvases, each with a different display string. The animation displays the string at a random point on the screen. When a key is pressed, running is set to false, the run() loop stops, the midlet checks the Canvas's exit status, and sets the other canvas running.

    Simple, except that on NOKIA emulators, bCanvas run() is only ever executed once, the screen stops repainting, then the aCanvas run() loops again (you can see the output of System.out.println().

    In my original game code, the two canvases were completely different classes.

    I have spent a lot of time moving things around and, through trial and error, almost gotten it to work, but I'd rather someone tell me exactly what I'm doing wrong, and how I should expect callSerially() to work.

    Thanks

    Mike

  4. #4
    Regular Contributor
    Join Date
    Mar 2003
    Posts
    393
    I tried your piece of code on S40 Concept and S60 Concept and 3300 emulators. On S40 it does not respond to the key presses, on S60 it works smoothly and a little slow on the 3300. The key events are not being scheduled because of painting events one after the other in the same thread as the midlet, which deteriorates performance. Use the approach in the attachment which does not use callSerially() and uses only one Canvas object but you can modify it to suit your needs.

    How to modify?

    In the attached Counter example you could modify and pass an argument to callbackPaintDone() to decide whether it is the paint that calls this callback or the keypress and then display.setCurrent() a different canvas object in the case of a keypress. Note that

    synchronized(this){
    wait(1);
    }

    in the callback provides the short delay so that your program can respond to keypresses.

    Let me know if this solves your problem.

    [N]/Forum Nokia
    Attached Files Attached Files

  5. #5
    Registered User
    Join Date
    Apr 2003
    Posts
    5

    callSerially - what's the point?

    Hi

    I thought that the whole point of callSerially was to avoid using a call to wait().

    I have read through plenty of J2ME game source to realize that most people throw in a wait(10) to allow time for the system to process key presses and paint requests. By serializing your own code in the run() method with the event stream, you are supposed to be able to avoid this, no?

    The last thing any serious game developer wants to do in his main loop is to sit around doing nothing. It's frustrating to spend a great deal of effort optimizing every last scrap of code in order to squeeze out the most performance possible, and then be forced to waste 10 or 40 milliseconds per frame doing nothing.

    I understand that wait(1) is only a single millisecond, but my experience is that if you're just hoping the system processes UI events (such as key presses) in that millisecond, you will be forced to experiment with other (higher) numbers when you move to the hardware, then you'll be waiting longer, when you want to be doing the opposite.

    I tried my code on the 3410, 3510, 6310 and 7210 emulators. The 3410 painted the screen once then stopped. The other three did as I previously described - they ran until a key press, painted canvas B a single time (running it's run() method once) then continued running canvas A's run() method, which seems like a bug. Intercepting key presses was never the issue.

    Thanks for your help, but I really need to know how callSerially works or should work on NOKIA phones/emulators. If I can't use callSerially, I'll try serviceRepaints instead - anything to avoid a call to wait().

    Hopefully this information will be useful to other game programmers.

    Mike

  6. #6
    Regular Contributor
    Join Date
    Mar 2003
    Posts
    393
    Your code works fine when I tried on the S60 and 3300 emulators. I'll try it with the rest.

    Can you attach the Java files you are using?


    [N]/Forum Nokia

  7. #7
    Registered User
    Join Date
    Apr 2003
    Posts
    5

    Test Source Code

    Hi

    I don't seem to have the ability to attach files to replies. I am also unable to email you the files, as your profile hides your email address.

    M

  8. #8
    Regular Contributor
    Join Date
    Mar 2003
    Posts
    393
    Paste the whole code that you are testing with

    [N]/Forum Nokia

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •