Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Trusted Contributor
Posts: 167
Registered: ‎06-30-2011
My Device: n/a
My Carrier: Koodo
Accepted Solution

Persistent (object) confusion!

Hi guys, the QuestionMan here.

 

My game is now nearly complete in functionality and I am at the point where I am trying to:

 

A) store a highscore at the end of the game

B)set up a resume function where if the game is ever exited, blackberry will restart the game at the same point with the same values

 

So today's mission has been 'A' and so far I've only confused myself quite  a lot. I have a few books here and they do mention persistent objects but I fear that even the beginner book descriptions are leaving me confused. I've also looked at the api and although I can get a basic grasp on it I do not know how to implement this.

 

I have the following code snippet that shows what I have right now (its not working):

 

//dayMenu class where all the action happens
   

    public static PersistentObject store;
    public static int[] scoreTest;

 

//lots of coding

 

//on end of game

   scoreTest[1] = dayMenu.cash;
                synchronized(store) {
                    store.setContents(scoreTest);
                    store.commit();
                }

 

//on accessing the highScore screen and class

    dayMenu.store.getContents();
    LabelField highscore1 = new LabelField(" highscore1variable1  " + dayMenu.store);

 

 

Now I'm absolutely sure that this will appear confusing, its the result I had to get rid of all the compiling errors so the program would run. But of course when I hit the end of game, the debugger said there was a nullpoint exception. I know I'm wrong here, but perhaps someone could show me how to fix it? Thanks in advance and hope I get help soon, almost done my first app!    

Trusted Contributor
Posts: 167
Registered: ‎06-30-2011
My Device: n/a
My Carrier: Koodo

Re: Persistent (object) confusion!

I really would love some help on this one guys, I'm very generous with kudos! I'm at a standstill without this knowledge. Thanks!

Developer
Posts: 176
Registered: ‎11-06-2008
My Device: Not Specified

Re: Persistent (object) confusion!

Everyone has their own preference for how they handle the persistent store. Here's what I've used for years and it's never failed me.

 

Note that I just trimmed down some code from one of my apps so I have neither compiled not tested this.

 

This first code shows a PersistentDataStore class I create in all projects. It acts as the single centralized place for reading and writing data to the persistent store.

 

package com.example.mygame;

import net.rim.device.api.system.PersistentObject;
import net.rim.device.api.system.PersistentStore;
import net.rim.device.api.util.StringUtilities;

public class PersistentDataStore
{
  private static PersistentDataStore _instance;

  private PersistentObject _gameStatePersistObject;

  private PersistentDataStore()
  {
    //use a unique key for the store, such as the full class name for what you are storing
_gameStatePersistObject = PersistentStore.getPersistentObject(StringUtilities.stringHashToLong("com.example.mygame.GameState")); } //singleton design pattern
public static synchronized PersistentDataStore getInstance() { if (_instance == null) { _instance = new PersistentDataStore(); } return (_instance); } //get the game state
public synchronized GameState getGameState() { GameState gameState = (GameState) _gameStatePersistObject.getContents(); if (gameState == null) { //the game state was never created and is therefore null, let's make one first
gameState = new GameState();
saveGameState(gameState); } return (gameState); } //save the game state
public synchronized void saveGameState(GameState gameState) { try { _gameStatePersistObject.setContents(gameState); _gameStatePersistObject.commit(); } catch (Exception ex) { //log the error } } }

 

This is an example of a persistable object for storing game data.

As a best practice you should never directly store objects provided by RIM or Java. Instead store your own custom class that wraps those classes. In other words if you want to store a vector then do not directly store the vector. Wrap the vector in a new custom class (just like how I wrap the int array below in the GameState class) and then store the custom class (in this case the GameState).

 

package com.example.mygame;

import net.rim.device.api.util.Persistable;

public class GameState implements Persistable
{
  //I'm not a fan of pointless getter and setter methods so I make simple attributes public
public int[] _highScores = new int[] {}; //put other properties here if you need to store more things public GameState() { } }

 

Here's code on how to use the store.

 

 

//get a persistent store instance from the singleton (this way there's only ever 1 copy that's shared)
PersistentDataStore perDataStore = PersistentDataStore.getInstance(); //get the game state object (one is created and pre-saved if it does not exist)
GameState gameState = perDataStore.getGameState(); //update the game state
gameState._highScore = someNewHighScores; //save the game state
perDataStore.saveGameState(gameState);

 

Trusted Contributor
Posts: 167
Registered: ‎06-30-2011
My Device: n/a
My Carrier: Koodo

Re: Persistent (object) confusion!

[ Edited ]

Hey thanks a lot for the help, I kudoed. So I spent a decent amount of time trying to implement what you showed me there, and unfortunately I think its still above my head. Gotta read up some more on structure I suppose. Anyway,  I ended up using information from this link in case anyone needs it.

 

http://www.scribd.com/doc/46578425/Blackberry-Java-SDK-Development-Guide

Trusted Contributor
Posts: 167
Registered: ‎06-30-2011
My Device: n/a
My Carrier: Koodo

Re: Persistent (object) confusion!

[ Edited ]

Perhaps you could answer one more related question for me though.

 

String[] userinfo = {varNumber+""};
                synchronized(store)
                {
                    store.setContents(userinfo);
                    store.commit();
                }    

 

Why is it that in the line 'store.setContents(userinfo)' userinfo is not userinfo[#] ? I suppose I'm just confused as to how it is saving the data. If I had 5 strings I wanted to store using the above code, how would I go about doing that? Right now I am only able to save 1 string (which works). But I spent a good amount of time tonight trying to implement 5 strings using the same kind of simple coding and its just giving me errors. Thanks for any help

 

I think the major part that is confusing me is I am only creating the 5 strings one at a time (as in a highscore screen where u only need 1 new highscore each game (if that)...all of the examples I've seen show how to store things all at once.

Developer
Posts: 176
Registered: ‎11-06-2008
My Device: Not Specified

Re: Persistent (object) confusion!

You need to be storing objects, not primitives like int. You can store int but it has to be wrapped by some custom class like GameState.

 

If you know you only need 5 then you can do this, each String value is null and you can set them as needed

 

class GameState
{
  public String _value1;
  public String _value2;
  public String _value3;
  public String _value4;
  public String _value5;

  public GameState()
  {
  }
}

 

Trusted Contributor
Posts: 167
Registered: ‎06-30-2011
My Device: n/a
My Carrier: Koodo

Re: Persistent (object) confusion!

[ Edited ]

since my game has a class where the score is created (dayMenu) and another class where the highscores are displayed (highScore) am I supposed to declare PersistentDataStore perDataStore = PersistentDataStore.getInstance(); inside the dayMenu screen or should I make it a public static.

I'm assuming I should declare the following inside the highScore class:

GameState gameState = perDataStore.getGameState();

But what happens when I need to set a highscore? The value is set in dayMenu and I want to get it in highScore, but the gameState variable can only be declared in one...

Thanks again!

 

Developer
Developer
Posts: 1,123
Registered: ‎02-10-2009
My Device: 8130 / 8350 / 9530 / 9550 / 9850 / PlayBook
My Carrier: Verizon

Re: Persistent (object) confusion!

If your PersistentDataStore class is static then you can just get an instance of it in each class that needs it and make the GameState class with a public or private constructor so that it can only be accessed from the PersistentDataStore object. Since the PersistentDataStore is static each class will have the same reference (as long as you don't have a background startup thread).

Trusted Contributor
Posts: 167
Registered: ‎06-30-2011
My Device: n/a
My Carrier: Koodo

Re: Persistent (object) confusion!

So right now I have this in my dayMenu class:

 

public static PersistentDataStore perDataStore = PersistentDataStore.getInstance();
   
public static GameState gameState = perDataStore.getGameState();

 

and in my highScore class I have:

 

dayMenu.perDataStore.getGameState();
   
Dialog.alert("Hi this should be a #" + GameState.highScr1);

 

 

I figured I had to use the getGameState() to fetch the stored high score for it to display, but it isn't working. If I only run the one instance of the game, a high score is saved and displayed, but it is not saving to the storage (I'm only using a simulator at the moment if that matters)    

Developer
Posts: 176
Registered: ‎11-06-2008
My Device: Not Specified

Re: Persistent (object) confusion!

don't cache them in class level variables, just declare and set them when they are needed like this

 

public void saveSomething()
{
  //here's the code to determine what you want to save,
  //let's just say it's an int array called someNewHighScores

  PersistentDataStore perDataStore = PersistentDataStore.getInstance();
  GameState gameState = perDataStore.getGameState();
  gameState._highScore = someNewHighScores;
  perDataStore.saveGameState(gameState);
}