/* License
*
* Copyright 1994-2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/
package j2medeveloper;
import java.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStore;
public class FSM implements CommandListener {
MIDlet midlet;
Display display;
private String FSM_RSTORE = "FSM_RSTORE";
// Finite states
public final static int FSM_STATE_UNDEFINED = -1;
public final static int FSM_STATE_STARTED = 1;
public final static int FSM_STATE_PAUSED = 2;
public final static int FSM_STATE_DESTROYED = 3;
public final static int FSM_STATE_RESTARTED = 4;
public final static int FSM_STATE_READY = 5;
public final static int FSM_STATE1 = 6;
public final static int FSM_STATE2 = 7;
protected static int mPreviousState = FSM_STATE_UNDEFINED;
protected static int mCurrentState = FSM_STATE_UNDEFINED;
// Application Screens
private javax.microedition.lcdui.List readyScreen;
private javax.microedition.lcdui.List state1Screen;
private javax.microedition.lcdui.List state2Screen;
// Screen commands
public static Command CMD_READY_SCREEN_EXIT = null;
public static Command CMD_READY_SCREEN_GOSTATE1 = null;
public static Command CMD_READY_SCREEN_GOSTATE2 = null;
public static Command CMD_STATE1_SCREEN_OK = null;
public static Command CMD_STATE2_SCREEN_OK = null;
public FSM(MIDlet midlet, Display display) {
this.midlet = midlet;
this.display = display;
}
/*
* Start of FSM transition function
*/
/**
* This is the finite state machine (FSM) for the MIDlet. This machine
* supports returning to a previous state from the paused and destroyed
* states.
*
*@param currentState current FSM state.
*@param transitionState transition FSM state.
*/
public void transition(int currentState, int transitionState) {
System.out.println("FSM.transition");
System.out.println(" currentState is " + currentState);
System.out.println(" transitionState is " + transitionState);
try {
// The next switch statement implements the acceptor,
// recognizer, and transducer, for decoding an input state
// and transitioning to a new state.
switch (transitionState) {
case FSM_STATE_STARTED:
;
System.out.println("FSM_STATE_START");
// The started state is a fresh state, and requires
// proper application initialization such as
// allocating any required objects.
// Here initialize any required objects
// ...
// Initialize screens.
initializeScreens();
// Load current state from record store.
loadState();
// Transition to previous state.
if (mCurrentState == FSM_STATE_UNDEFINED) {
transition(transitionState, FSM_STATE_READY);
} else {
transition(mPreviousState, mCurrentState);
}
return;
// need not remember this state.
case FSM_STATE_READY:
System.out.println("FSM_STATE_READY");
// Here do application-specific ready processing.
// In our example we just display the initial
// application screen.
display.setCurrent(readyScreen);
break;
case FSM_STATE_RESTARTED:
System.out.println("FSM_STATE_RESTART");
// This state is invoked when from paused state.
// All prev. objects should still be around, so
// there is no need to reinitialize. Just load the
// state, and return to previous state.
// Load current state from record store.
loadState();
// Transition to previous state.
transition(mPreviousState, mCurrentState);
return;
// no need to remember; so to return
// go to real previous state.
case FSM_STATE_PAUSED:
System.out.println("FSM_STATE_PAUSED");
// Typically a transition to the paused state
// indicates the application is suspended, and
// resources remain in memory as is, so returning
// from paused only requires going back to previous
// state.
return;
case FSM_STATE_DESTROYED:
System.out.println("FSM_STATE_DESTROYED");
// Here do application cleanup such as closing
// connections, exiting threads, and so on.
// ...
return;
// No need to remember destroyed state.
case FSM_STATE1:
System.out.println("FSM_STATE1");
// Here do application-specific processing.
// In this example we just display a screen.
display.setCurrent(state1Screen);
break;
case FSM_STATE2:
System.out.println("FSM_STATE2");
// Here do application-specific processing.
// In this example we just display a screen.
display.setCurrent(state2Screen);
break;
default:
return;
// Unrecognized symbols; reject.
}
// switch (transitionState)
// Complete state transition...
mPreviousState = currentState;
mCurrentState = transitionState;
// Preserve application state
persistState();
} catch (Exception e) {
System.out.println("FSM Exception: " + e);
}
}
/*
* End of FSM Transition Function
*/
/**
* Command Listener.
*
*@param c is the LCDUI Command.
*@param d is the source Displayable.
*/
public void commandAction(final Command c, Displayable d) {
try {
///////////////////////
// Main Screen Commands
///////////////////////
if (c == CMD_READY_SCREEN_EXIT) {
transition(mCurrentState, FSM_STATE_DESTROYED);
} else if (c == CMD_READY_SCREEN_GOSTATE1) {
transition(mCurrentState, FSM_STATE1);
} else if (c == CMD_READY_SCREEN_GOSTATE2) {
transition(mCurrentState, FSM_STATE2);
} else if (c == CMD_STATE1_SCREEN_OK) {
transition(mCurrentState, FSM_STATE_READY);
} else if (c == CMD_STATE2_SCREEN_OK) {
transition(mCurrentState, FSM_STATE_READY);
}
} catch (Exception e) {
}
}
private void initializeScreens() {
CMD_READY_SCREEN_EXIT = new Command("Exit", Command.SCREEN, 1);
CMD_READY_SCREEN_GOSTATE1 = new Command("Go to State 1",
Command.SCREEN, 1);
CMD_READY_SCREEN_GOSTATE2 = new Command("Go to State 2",
Command.SCREEN, 1);
CMD_STATE1_SCREEN_OK = new Command("Back", Command.SCREEN, 1);
CMD_STATE2_SCREEN_OK = new Command("Back", Command.SCREEN, 1);
readyScreen = new javax.microedition.lcdui.List("Ready Screen",
List.IMPLICIT);
readyScreen.append("Ready Screen Item 1", null);
readyScreen.append("Ready Screen Item 2", null);
readyScreen.append("Ready Screen Item n", null);
readyScreen.addCommand(CMD_READY_SCREEN_EXIT);
readyScreen.addCommand(CMD_READY_SCREEN_GOSTATE1);
readyScreen.addCommand(CMD_READY_SCREEN_GOSTATE2);
readyScreen.setCommandListener(this);
state1Screen = new javax.microedition.lcdui.List(
"State1 Screen", List.IMPLICIT);
state1Screen.append("State 1 Screen Item 1", null);
state1Screen.append("State 1 Screen Item 2", null);
state1Screen.append("State 1 Screen Item n", null);
state1Screen.addCommand(CMD_STATE1_SCREEN_OK);
state1Screen.setCommandListener(this);
state2Screen = new javax.microedition.lcdui.List(
"State2 Screen", List.IMPLICIT);
state2Screen.append("State 2 Screen Item 1", null);
state2Screen.append("State 2 Screen Item 2", null);
state2Screen.append("State 2 Screen Item n", null);
state2Screen.addCommand(CMD_STATE2_SCREEN_OK);
state2Screen.setCommandListener(this);
}
private void persistState() {
RecordStore pStateStore = null;
DataOutputStream dos;
ByteArrayOutputStream baos;
try {
RecordStore.deleteRecordStore(FSM_RSTORE);
} catch (RecordStoreException e) {
}
try {
pStateStore = RecordStore.openRecordStore(FSM_RSTORE, true);
baos = new ByteArrayOutputStream();
dos = new DataOutputStream(baos);
dos.writeInt(mPreviousState);
dos.writeInt(mCurrentState);
pStateStore.addRecord(baos.toByteArray(), 0, baos.size());
System.out.println("App. State Saved...");
} catch (IOException ioe) {
//... Handle the exception
System.out.println("IOException " + ioe);
} catch (RecordStoreException rse) {
//... Handle the exception
System.out.println("RecordStoreException " + rse);
} catch (Exception e) {
//... Handle the exception
System.out.println("Exception " + e);
} finally {
try {
if (pStateStore != null) {
pStateStore.closeRecordStore();
}
} catch (Exception ignore) {
// Ignore
System.out.println("Exception is " + ignore);
}
}
}
private void loadState() {
RecordStore pStateStore = null;
DataInputStream dis;
ByteArrayInputStream bais;
try {
pStateStore = RecordStore.openRecordStore(FSM_RSTORE, false);
/*
* Deserialize data
*/
bais = new ByteArrayInputStream(pStateStore.getRecord(1));
dis = new DataInputStream(bais);
mPreviousState = dis.readInt();
mCurrentState = dis.readInt();
System.out.println("App. State Loaded...");
} catch (IOException ioe) {
//... Handle the exception
System.out.println("IOException " + ioe);
} catch (RecordStoreException rse) {
//... Handle the exception
System.out.println("RecordStoreException " + rse);
} catch (Exception e) {
//... Handle the exception
System.out.println("Exception " + e);
} finally {
try {
if (pStateStore != null) {
pStateStore.closeRecordStore();
}
} catch (Exception ignore) {
// Ignore
System.out.println("Exception is " + ignore);
}
}
}
}
/*
* End of FSM.java
*/