You Are Here:

Community: Developer Discussion Boards

#1 Old Major problem with delegation to Canvas - 2003-10-05, 21:17

Join Date: Aug 2003
Posts: 50
Location: Cracow, Poland
Send a message via ICQ to bartekn
bartekn
Offline
Regular Contributor
Hi all!

I've been developing a Java game for the MIDP platform for a while. When I was about to port my game to other phones I didn't want to create different versions for different phones. Instead, I tried to use a generic solution and I designed a few classes.

A typical game must have at least one class that extends Canvas (or FullCanvas in case of Nokia's phones). Therefore if porting to another device a class extending device's specific class must be refactoried.

I designed LightCanvas class which has a reference to a Canvas (the real Canvas which is used to draw on). LightCanvas has similiar methods to Canvas class but it doesn't extend it. Every class in my game that extended Canvas or FullCanvas has been refactoried to extend LightCanvas.

I designed an abstract factory (MIDletPlatform) with createCanvas(LightCanvas lightCanvas) method that creates a device specific class e.g. FullCanvas and wraps the lightCanvas into it.

The LightCanvas class:
Code:
public abstract class LightCanvas {

  private Canvas canvas;

  protected LightCanvas() {
    canvas = MIDletPlatform.getInstance().createCanvas(this);
  }

  public abstract void paint(Graphics g);

  public void keyPressed(int keyCode) {
    //do nothing
  }

  public void keyReleased(int keyCode) {
    //do nothing
  }

  public void repaint() {
    canvas.repaint();
  }

  public void serviceRepaints() {
    canvas.serviceRepaints();
  }

   //other methods that delegate to canvas methods
   ...

}
A method from MIDletPlatform class:
Code:
  public Canvas createCanvas(LightCanvas canvas) {
    try {
      HeavyCanvas heavyCanvas = (HeavyCanvas)Class.forName("pl.ganimedes.midp.device.nokia.NokiaCanvas").newInstance();
      heavyCanvas.setCanvas(canvas);
      return (Canvas)heavyCanvas;
    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException("Cannot create heavy canvas: " + e);
    }    
  }
Here is one of HeavyCanvases: NokiaCanvas that just delegates to a light canvas.
Code:
public class NokiaCanvas extends FullCanvas implements HeavyCanvas {

  private LightCanvas canvas;

  public void setCanvas(LightCanvas canvas) {
    this.canvas = canvas;
  }

  protected void paint(Graphics g) {
    canvas.paint(g);
  }

  protected void keyPressed(int keyCode) {
    canvas.keyPressed(keyCode);
  }

  protected void keyReleased(int keyCode) {
    canvas.keyReleased(keyCode);
  }

}
Here is a sample code:
Code:
class MyLightCanvas extends LightCanvas {
   public void paint(Graphics g) {
     //a code that draws something 
     ...
   }
   
   ...
}

aDisplay.setCurrent(MIDletPlatform.getInstance().createCanvas(new MyLightCanvas()));
And everything works fine except one thing: when I call repaint() and then serviceRepaints() within my MyLightCanvas the screen isn't refreshed even though LightCanvas delegates to the real canvas. I wonder why it doesn't work... I tried on different emulators and none of them worked as expected. The only emulator that works is mine ;-) Maybe it's because the serviceRepaints is declared in Canvas as final. Or maybe the devices have a bug...

Has anyone encountered a similar problem?

I'm looking forward to your feedback! Thanks in advance!
Reply With Quote

#2 Old 2003-10-06, 00:26

Join Date: May 2003
Posts: 151
Danack
Offline
Regular Contributor
bartekn wrote:
>I designed LightCanvas class which has a reference to a Canvas
>(the real Canvas which is used to draw on). LightCanvas has
>blah blah blah blah blah blah blah blah blah blah to extend
>LightCanvas.


This approach is just too heavyweight for mobile phones - It is a much better solution to use preprocessing on your source files to include phone specific stuff.

I use Antenna (http://antenna.sourceforge.net) which quite frankly rocks and so can do:

//#ifdef NOKIA
class GameCanvas extends FullCanvas
//#else
class GameCanvas extends Canvas
//#endif
{


}


This also avoids having to have multiple copies of the code in the same midlet to cater for different phones....
Reply With Quote

#3 Old 2003-10-06, 19:47

Join Date: Aug 2003
Posts: 50
Location: Cracow, Poland
Send a message via ICQ to bartekn
bartekn
Offline
Regular Contributor
Thanks for pointing out a quite nice tool, Antenna. I wish I had knew about that tool earlier.

However, I don't agree with you that using my solution is THAT heavy weight. I want my game to run on different phones without providing different versions of JARs (of course it's not possible for all phones, especially for color and B/W devices).

As a matter of fact both solutions have advantages and disadvantages ;-)
Reply With Quote

#4 Old 2003-10-08, 12:40

Join Date: Mar 2003
Posts: 69
Location: Silicon Scally
bigredswitch
Offline
Dude!
To save you some time: I wrote something similar a while ago, for exactly the same reason. Anyway, it worked quite well on the emulators... then I tried it on real phones - most models failed to install the midlet because, I suspect, it referenced non-existent classes. If the midlet had any class that called or extended the Siemens API, for example, it wouldn't install on a Nokia or Motorola handset. I decided in the end just to go with different builds (I use CodeWarrior, so it's quite easy to substitute classes tailored for different phones).

Carl.
Reply With Quote

#5 Old 2003-10-08, 12:51

Join Date: Aug 2003
Posts: 50
Location: Cracow, Poland
Send a message via ICQ to bartekn
bartekn
Offline
Regular Contributor
Hmmm... strange indeed. I thought that class loaders are supposed to load classes if, and only if, a class is needed, not all of them at once.

There is one thing that must be pointed out here - you can't use directly a device specific class, this class should be looked up by name i.e. Class.forName(...).

BTW: I found a bug in my framework, now it works fine. I tested it on Nokia phones and various emulators... I haven't tested it on real phones other than Nokia, but I'll do it soon.
Reply With Quote

#6 Old 2003-10-08, 12:57

Join Date: Mar 2003
Posts: 69
Location: Silicon Scally
bigredswitch
Offline
Dude!
I suspect there's some verifying and checking going off when the midlet is installed. Motorola phones, IIRC, do a whole load of stuff to the contents of the jar (like separating the classes and data) on install (which explains why it takes so long).

Carl.
Reply With Quote

#7 Old 2003-10-08, 18:21

Join Date: Mar 2003
Posts: 2,280
Location: Israel
shmoove
Offline
Forum Nokia Champion
Quote:
Hmmm... strange indeed. I thought that class loaders are supposed to load classes if, and only if, a class is needed, not all of them at once.
Actually, I remember reading that the default J2ME behaviour is exactly that: all the classes are loaded on application startup.

shmoove
Reply With Quote

#8 Old 2003-10-08, 18:39

Join Date: Aug 2003
Posts: 50
Location: Cracow, Poland
Send a message via ICQ to bartekn
bartekn
Offline
Regular Contributor
@shmoove - where did you read it? I'm really interested in it.
Reply With Quote

#9 Old 2003-10-08, 18:46

Join Date: Mar 2003
Posts: 2,280
Location: Israel
shmoove
Offline
Forum Nokia Champion
I don't remember exactly where, but I remember it was during my baby steps in J2ME, so it was probably one of the documents linked from sun's site.
I'll check through my documentation and see if I can find it.

shmoove
Reply With Quote
Reply « Previous Thread | Next Thread »
Display Modes
Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules

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

vB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Forum Jump

Rate This

 
Bookmark this page: DeliciousDiggFacebookGoogleYahooStumbleUponRedditDiigoTechnocratiTwitter  Share this page Share this page Print this Page Print this page Invite a friend Invite a friend
京ICP备05048969号    Email Newsletters Press Terms & Conditions Privacy Policy Sitemap Contact Us © 2009 Nokia 
RDF Facets: qdcZidentifierQSxhttpE3aE2fE2fdiscussionE2eforumE2enokiaE2ecomhttpE3aE2fE2fdiscussionE2eforumE2enokiaE2ecomE2fforumE2fshowthreadE2ephpE3ftE3d18645X qdcZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qdcZtypeQUqfntypeZCommunityContentQ qdcZtypeQUqfntypeZE44iscussionQ qdcZtypeQUqfntypeZE44iscussionContentQ qdcZtypeQUqfntypeZE52esourceQ qdcZtypeQUqfntypeZWebpageQ qdcZtypeQUqmarsZManagedE52esourceQ qdcZtypeQUqwebZInformationE52esourceQ qdcZtypeQUqwebZPageQ qdcZtypeQUqwebZE52esourceQ qdcZtypeQUqrdfsZE52esourceQ qfnZtopicQUqfnTopicZentertainmentQ qfnZtopicQUqfnTopicZj2meQ qfnZtopicQUqfnTopicZjavaQ qfnZtopicQUqfnTopicZmediaQ qfnZtypeQUqfntypeZCommunityContentQ qfnZtypeQUqfntypeZE44iscussionQ qfnZtypeQUqfntypeZE44iscussionContentQ qfnZtypeQUqfntypeZE52esourceQ qfnZtypeQUqfntypeZWebpageQ qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX qrdfZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qrdfZtypeQUqfntypeZCommunityContentQ qrdfZtypeQUqfntypeZE44iscussionQ qrdfZtypeQUqfntypeZE44iscussionContentQ qrdfZtypeQUqfntypeZE52esourceQ qrdfZtypeQUqfntypeZWebpageQ qrdfZtypeQUqmarsZManagedE52esourceQ qrdfZtypeQUqwebZInformationE52esourceQ qrdfZtypeQUqwebZPageQ qrdfZtypeQUqwebZE52esourceQ qrdfZtypeQUqrdfsZE52esourceQ