Uploaded to www.rart.com/j2me-presentation/html_Source/ March 19, 2002

The Abstract Class UniverseME

This class provides the template for a Rart universe in the J2ME environment

This version has been tested with j2mewtk 1.0.2 and 1.0.3

/* 
 * @UniverseME    1.0  010915 
 * 
 * © A-Square, Inc.   
 * 1648 Waters Edge Lane, Reston Virginia, 20190, USA  
 */
package rartme;

import javax.microedition.lcdui.*;

/**
 * UniverseME
 * An abstract class defining the common properties of all RartME universes
 *
 * @version 1.0  010915 
 *
 * @author Jan Aminoff
 *
 * This abstract class allows the RartRunners to control the execution of any 
 * universe extending Universe. It is the key to the Rart concept as 
 * implemented in Java and forms an integral part of the Rart Development Kit.
 *
 *
 * Released as part of RartME 1.0, September 2001
 * 
 */

public abstract class UniverseME{
	
	// Section 1	Identifying the universe
	// ------------------------------------------------------------------------
	
	
	/**				 
	 * provides the name of the universe using no more than 20 letters.
	 * Note: The name is an unrestricted string that will appear in 
	 * descriptions etc. and is not necessarily the same as the class name.
	 */
	protected  abstract String getName();
	
	/**
	 * Up to 350 (70 for ME) characters describing the universe.
	 */ 
	protected abstract String getDescription();
	
	/**
	 * provides name of Rartist, using no more than 24 characters.	
	 */
	protected abstract String getRartist();		 
	
	

	
	// Section 2	What the universe does	  
	// ------------------------------------------------------------------------
	/** 
	 * used by the RartRunner class (RRME) to initialize the universe.
	 * It is used initially when the universe is executed the first time.
	 * The sample universes all have init() methods that allow restart using a
	 * reset() method, that follows a setParam() method taking care of 
	 * uParameters using default values or set in the JAD file.
	 * The reset() method may also be used if some parameter has changed and
	 * the reasonable way to manage the change is to restart the universe.	  
	 */
	 public abstract void init();				
	
	/**
 	 * The main cycle that will be executed over and over. Basically it uses
	 * the Graphics context g to draw and redraw the screen (or part of the 
	 * screen)with the appropriate changes. 
	 * Normally, it is expected that g actually is associated with an
	 * off screen image for double buffering. For ME, some devices provide 
	 * automatic doublebuffering. Even if it is not provided automatically the
	 * RRME runner, forces doublebuffering to take place. If not successful the 
	 * variable manbuff will be false.
	 *
	 * cycle(g) is invoked periodically with the priod determined by the 
	 * uParameter with the index CYCLETIME by the RartRunners. 
	 * The Rartist provides anything that shows on the screen in the
	 * cycle(g) method. See the examples.
	 */
	public abstract void cycle(Graphics g);
		
	/**
	 * In the Rart system all interaction between a universe and it's observer
	 * takes place by way of parameters from the class uParameter. A uParameter
	 * carries with itself it's current value a maximum and minimum value as
	 * well as description. If a user has changed a uParameter defined for a
	 * universe the manageChange method contains the code needed to incorporate
	 * the change in the executing universe. This code may or may not include a
	 * restart of the universe.
	 *
	 * @param uP 	uParameter whose new value is considered and accomodated.
	 * @see uParameter class
	 */
	public abstract void manageChange(uParameter p);  

	/**
	 * as an aid to debugging the rartme program DebugME can be used to provide
	 * varying levels of output according to dblevel 0 to 5 inclusive
	 * dblevel can be set individually and manually in each rartme class. It
	 * can also be set as a property in the JAD file as, for example
  	 * DEBUG_LEVEL:3 in which case the value, 3 in the example, is propagated 
	 * throughout the the system and actually made available to the universe, 
	 * set by RartCanvas using the following public method.
	 *
	 * @param 	lvl		lvl an integer bttween 0 and 5 inclusive
	 * @see 		DebugME
	 */
	public void setDebugLevel(int lvl){
		dblevel = lvl;
	}
	protected int dblevel;

	// Section 3	uParameters as used in the universe
	
	/*
	 * The uParameters are the mechanism whereby the observer changes the 
	 * universe within the limits set by the Rartist. There are up to 9 
	 * parameters in a Rart universe. They are indexed with a parameter 
	 * index from 1 through 9. (Parameter index UNIV is used 
	 * within the RartRunners only)
	 */
	// ------------------------------------------------------------------------

	public static final int	 NUMBER_OF_PARAMETERS = 10;
	
	// uParameter indicies are named according to anticipated use:
	
	public static final int UNIV=0;			// Used to communicate within RRs
	public static final int VIEWSIZE=1;		// Used for size of window
	public static final int CYCLETIME=2;	// Used for cycletime
	public static final int NUMBER=3;		// Used for number of objects
	public static final int PARA4=4;
	public static final int PARA5=5;
	public static final int PARA6=6;
	public static final int PARA7=7;
	public static final int PARA8=8;
	public static final int PARA9=9;
	
	// to allow setting of the parameters we also need the index as string
	
	public static final String indexes[]={"UNIV","VIEWSIZE","CYCLETIME",
		 "NUMBER","PARA4","PARA5","PARA6","PARA7","PARA8","PARA9"};
	
		
	//-------------------------------------------------------------------------
	public static String getIndex(int index)
	//-------------------------------------------------------------------------
	// used to get the string associated with the index
	{
			  return indexes[index];
	}
	
   public static uParameter uPs[] = new uParameter[NUMBER_OF_PARAMETERS];
	
	
		 
	
	
	public static final String CycleTimeDescr =
			"Shorter cycletime means speadier animation if your "+
			"computer can keep up!";
	/**
	 * Used to insert a new or modified uParameter in the appropriate spot in the
	 * uPs array, the spot determined by the index of the uParameter.
	 * @param 	uParameter p, the uParameter to be placed.
	 */
	public void adduParameter( uParameter p){
		int idx = p.getIndex();
		if (idx < uPs.length) uPs[idx]=p;	
	 }
	 
	// Section 4	Utility Methods
	
	/* The following methods are useful in developing Rart universes
	 * The simple forms occuring here can be overridden or replaced by
	 * more complex forms if desired.
	 */
	 
	static java.util.Random random = new java.util.Random();
 
	/** 
	 * RND implemented on a system without floating point.
    *
    * @param  integer x
	 * @return  if (x>0), any of integers 0, 1, .. x-1 with equal probability 
	 *			if (x<0), any of integers 0, -1, .. x+1 with equal probability 
    *          
    * @see     Universe in Rart
    */
	public static int RND(int x){
	 	//System.out.println("UniverseME.RND line " + 142+ " x "+x);
		return ((x==0)?0:(SIGN(x)*( random.nextInt()>>>1) % ABS(x)));
	}

	/**
	 * absolute value of integer
	 */
	public static int ABS(int x){
		return ((x>0)? x :  -x);
	}
	/**
	 * Returns signum of integer x, ie -1, if x<0, 1 if x>0 and 0 if x is 0.
	 * unfortunately the following expression yields an exception if x=0:
	 * 	SIGN(x)*10/x, which is too bad.
	 */
	public static int SIGN(int x){
		return ((x>0)? 1:(x<0)? -1:0);
	}
	
	/**
	 * Used for standardized output of text in dialogboxes and may
	 * be used in the same spirit within the universe.
	 * The string may contain \n to force a newline and may go over several
	 * lines. The font is proportional and the style plain. The color of the
	 * text is the current default color in g.
	 * @param	Graphics g, the graphics context
	 * @param	String st, the string to be output
	 * @param	x, the left starting point for the string
	 * @param	y, the top starting point for the string, that with
	 *				embedded \n (new lines) may go over several lines
	 * @param	fontSize, integer given one of the values Font.SIZE_LARGE, 
	 *				Font.SIZE_MEDIUM, or Font.SIZE_SMALL as defined in Font.
	 */
	public static void printString
			(Graphics g, String st, int x, int y, int fontSize){
		String s = st;
		int i = 1;		// index when looking for \n
	 	int ln = 0;		// line number
		Font	font = Font.getFont(Font.FACE_PROPORTIONAL, 
				Font.STYLE_PLAIN, fontSize);
		g.setFont(font);
		int height=font.getHeight()+2;
		while (i>0){
			i=s.indexOf("\n",0);
			if (i>1){
				g.drawString(s.substring(0,i), x, y+ln*height, 
						Graphics.TOP|Graphics.LEFT);
				s=s.substring(i+1,s.length());
				ln++;				
			}else g.drawString( s, x, y+ln*height,
		 				Graphics.TOP|Graphics.LEFT);
		}
	}

	
	// Section 5	Useful variables related to the execution of a universe
	// -------------------------------------------------------------------------
	/*
	 * The size of the display window is available to the universe as 
	 * protected Dimension dimDisplay, and as the public xm, for width,
	 * and ym, for height.
	 * The number of executions as public int nc, (nc is stepped
	 * after each cycle up to 2000000000 when it is reset to avoid overflow).
	 * 
	 */
	 
	public static int xm;   // Width and height of display.
	public static int ym;	// Set in RartCanvas.init
	
	public static int nc;		// Set in RartCanvas.init(). Used to vary the 
					// universe according to the number of cycles executed.
	public static boolean manbuff; // Set in RartCanvas.init().  true if not 
					// automatically doublebuffered and if unable to allocate memory
				 	// for double buffering. Variable of doubtful utility?
	
	public static int numColor;  // Set in RartCanvas.init(). 
	
	// -------------------------------------------------------------------------


	
	
	// Section 6	Methods related to security. 

	// The following methods should normally be of no concern to programmers of
	// a Rart universes.

	// Constructor with only function to avoid having more than one instantiation
	// at a time.	Compare Finalizer Method
	//-------------------------------------------------  
         public UniverseME() throws InstantiationException
	 //-------------------------------------------------	
	 {
                 if (instantiated)
                         throw new InstantiationException("Universe exists already.");
		 
		 instantiated = true;
	 }
         
			 
	 private static boolean instantiated = false;
	  
	 //-------------------------------------------------	
	 public boolean equals(Object o)
	 //-------------------------------------------------	
	 {
		 return false;
	 }
	 
	 //-------------------------------------------------	
	 public void finalize()
	 //-------------------------------------------------	
	 {
		 instantiated = false;
	 }
}  	// end of abstract class UniverseME