私はクラスGameStateを次のように持っています。このゲームのシリアル化の無限ループをlibGdxで修正する方法はありますか?
public class GameState
{
private Array<Fleet> fleets;
private Array<Planet> planets;
private Array<Player> players;
//Constructors, methods, yada yada
}
私のFleetクラスは、非常に単純化されたフォーマットです。 公共クラスフリート { プライベートアレイ発送; プライベートプレーヤーの所有者。
public Fleet(Player owner)
{
this.owner = owner;
this.ships = new Array<Ship>();
}
//Methods
}
簡体Player
クラス。私はJSON形式に私のゲームを保存するためにlibGdx Json.toJson(state);
を使用
public class Player
{
private Array<Fleet> fleets;
public Player()
{
fleets = new Array<Fleet>();
}
}
。
私は自分の情報を直接参照に保存しましたが、これは若干の問題を引き起こしました。最初に、GameState
のデータへの各参照は、シリアル化されると、Jsonリーダーによってそれ自体のインスタンスとして読み取られることです。だから、もし私がGameState x
をシリアル化したら、それを逆シリアル化して、Array
のFleet
をGameStateに入れてplanets
に移動し、players
に移動します。 fleets
に格納されているインスタンスへの元の参照の1つが見つかるたびに、それをそれ自身のインスタンスとして扱います。
これは、新しいゲームを読み込む前に、2つの参照が同じメモリを指していることを意味しますが、保存して再読み込みした後は、別々のメモリを指します。また、Fleet
はShip
のリストを保持しており、各Ship
はその親のフィールドの形で参照番号fleet
を保持しているため、Json
シリアライザとデシリアライザは無限ループに投げ込まれます。
最も簡単アプローチであるように見えたとして私はthisを実行しようとしましたが、ネイサンは受け入れ答えではなく、最も効率的なアプローチで指摘したように。
この問題を簡単に再現するにはどうすればよいですか?
GameStateクラス
public class GameState
{
public Array<Player> players;
public GameState()
{
this.players = new Array<Player>();
players.add(new Player());
players.add(new Player());
}
}
プレーヤークラス
public class Player
{
public Array<Fleet> fleets;
public Player()
{
fleets = new Array<Fleet>();
}
public void addFleet(Fleet fleet)
{
fleets.add(fleet);
}
}
フリートクラス
public class Fleet()
{
public Player owner;
public Fleet(Player owner)
{
this.owner = owner;
this.owner.fleets.add(this);
}
}
MainGameクラス
public class MainGame extends Game
{
@Override
public void create()
{
GameState state = new GameState();
state.fleets.add(new Fleet(state.players.get(0)));
state.fleets.add(new Fleet(state.players.get(1)));
Json json = new Json();
String infiniteLoopOrStackOverflowErrorHappensHere = json.toJson(state);
state = json.fromJson(infiniteLoopOrStackOverflowErrorHappensHere);
}
}
これまたはStackOverflowエラーから無限ループが発生するはずです。
答えをありがとう。私はこのようなことをすることに決めました。関連するIDを、各プレーヤーが所有する艦隊のようなもののIDを保持する 'DeserializationData'クラスに格納します。私はJson.Serializableを使ってシリアライズとデシリアライズをカスタマイズしました。 –