Jugando con JSON y la arquitectura de datos.

Es divertido trabajar con datos, y más en Java. No tienes que preocuparte de nada, la memoria se controla sola. Pero se echan en falta los ptrs.
Se han creado las clases Machine y Room que contendrán los datos correspondientes a cada una.
Ambas tienen sistemas de serialización a JSON. La Machine utiliza el por defecto y Room tiene uno propio.
La Screen BackEndTest realiza algunas pruebas de todo esto.
Aún queda muchas opciones de diseño que discutir...
This commit is contained in:
2022-05-10 20:45:11 +02:00
parent 7948331f20
commit 29d2bfd990
5 changed files with 245 additions and 31 deletions
+28 -8
View File
@@ -1,5 +1,7 @@
package uberelectron.gameSystems; package uberelectron.gameSystems;
import com.badlogic.gdx.utils.Null;
import java.util.HashMap; import java.util.HashMap;
public class Machine public class Machine
@@ -7,12 +9,30 @@ public class Machine
/*------------- /*-------------
* Constructors * Constructors
* -------------*/ * -------------*/
public Machine(String id) public Machine()
{ {
this.id = id; this.machineID = "null";
attributes = new HashMap<>(); this.esDeRecursos = false;
this.attributes = new HashMap<String, Integer>();
} }
public Machine(String machineID)
{
this.machineID = machineID;
this.esDeRecursos = false;
this.attributes = new HashMap<>();
}
/*----------------
* Getters/Setters
* -------------*/
public String getMachineID() { return machineID; }
public void setMachineID(String machineID) { this.machineID = machineID; }
public boolean isEsDeRecursos() { return esDeRecursos; }
public void setEsDeRecursos(boolean esDeRecursos) { this.esDeRecursos = esDeRecursos; }
/*------------- /*-------------
* Methods * Methods
* -------------*/ * -------------*/
@@ -28,13 +48,13 @@ public class Machine
attributes.put(name, newValue); attributes.put(name, newValue);
} }
public int GetAtributeValue(String name) public @Null int GetAtributeValue(String name)
{ {
Integer value = attributes.get(name); Integer value = attributes.get(name);
if(value == null) if(value == null)
{ {
System.err.println("El atributo solicitado no existe: " + name System.err.println("El atributo solicitado no existe: " + name
+ " en la maquina " + id); + " en la maquina " + machineID);
} }
return value; return value;
} }
@@ -44,15 +64,15 @@ public class Machine
* Variables * Variables
* -------------*/ * -------------*/
String id; String machineID;
public HashMap<String, Integer> attributes; public HashMap<String, Integer> attributes;
/* /*
Permite a la room saber debe realizar comprobación con la capacidad máxima... Permite a la room saber si se debe realizar comprobación con la capacidad máxima...
Lo sé, es muy cutre, pero te callas. Lo sé, es muy cutre, pero te callas.
Piensa en algo mejor, no te jode... Piensa en algo mejor, no te jode...
*/ */
boolean maquinaRecursos; boolean esDeRecursos;
} }
@@ -3,7 +3,7 @@ package uberelectron.gameSystems;
import java.util.HashMap; import java.util.HashMap;
/*** /***
* Esta clase carga los datos de las maquinas desde el JSON de datos y almacena los "prefabs" de las mismas. * Esta clase carga los datos de las máquinas desde el JSON de datos y almacena los "prefabs" de las mismas.
*/ */
public class MachineLoader public class MachineLoader
{ {
@@ -21,17 +21,17 @@ public class MachineLoader
* -------------*/ * -------------*/
/** /**
* Carga del archivo JSON indicado los datos de cada m�quina. * Carga del archivo JSON indicado con los datos de cada máquina.
* @param path Ubicaci�n del JSON * @param path Ubicación del JSON
*/ */
public void LoadFile(String path) public void LoadFile(String path)
{ {
//TODO //TODO: Itera por las máquinas, cargándolas.
} }
public void AddMachine(Machine machineToAdd) public void AddMachine(Machine machineToAdd)
{ {
machineMap.put(machineToAdd.id, machineToAdd); machineMap.put(machineToAdd.machineID, machineToAdd);
} }
public Machine GetMachine(String machineID) public Machine GetMachine(String machineID)
@@ -39,7 +39,7 @@ public class MachineLoader
Machine mc = machineMap.get(machineID); Machine mc = machineMap.get(machineID);
if(mc == null) if(mc == null)
{ {
System.err.println("El mapa no contiene una m�quina de ID: " + machineID); System.err.println("El mapa no contiene una máquina de ID: " + machineID);
} }
return mc; return mc;
} }
+135 -16
View File
@@ -1,22 +1,43 @@
package uberelectron.gameSystems; package uberelectron.gameSystems;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.JsonValue;
import java.util.HashMap; import java.util.HashMap;
public class Room /*ToDo: Quizás se podría añadir un contador del número de máquinas puestas,
de esta forma, si no quedan huecos, ComprobarMaquina() retorna false. No es necesario serializarlo.
*/
public class Room implements Json.Serializable
{ {
/*------------- /*-------------
* Constructors * Constructors
* -------------*/ * -------------*/
public Room()
{
//¿Puedo suponer que será suficientemente inteligente el JSON?
//Como gestionamos la deserialization manualmente, los que tenemos que ser inteligentes somos nosotros.
//En vez de hacer deserialization directamente,
// MachineLoader puede leer los datos manualmente sin necesidad de crear una clase,
// y construir el objeto pasándolos a un constructor...
}
public Room(String roomName, int width, int height) public Room(String roomName, int width, int height)
{ {
this.roomName = roomName; this.roomName = roomName;
this.width = width; this.roomSize = new Vector2(width, height);
this.height = height;
bgData = new int[height][width]; bgData = new int[height][width];
machineData = new Machine[height][width]; machineData = new Machine[height][width];
this.recursosMaximos = new HashMap<>();
this.recursosOcupados = new HashMap<>();
//También habría que cargar los atributos desde algún sitio... //También habría que cargar los atributos desde algún sitio...
LoadRoom(); LoadRoom();
@@ -25,7 +46,7 @@ public class Room
/*------------- /*-------------
* Methods * Methods
* -------------*/ * -------------*/
private void LoadRoom() public void LoadRoom()
{ {
bgData = new int[][] bgData = new int[][]
{ {
@@ -54,21 +75,28 @@ public class Room
return; return;
} }
for(String key : machineToAdd.attributes.keySet()) //Debería ser algo así. Pero hay que añadir atributos para poder probar...
{ // for(String key : machineToAdd.attributes.keySet())
int newCapacidad = capacidadOcupada.get(key) + machineToAdd.GetAtributeValue(key); // {
capacidadOcupada.put(key, newCapacidad); // int newCapacidad = recursosOcupados.get(key) + machineToAdd.GetAtributeValue(key);
} // recursosOcupados.put(key, newCapacidad);
// }
machineData[y][x] = machineToAdd; machineData[y][x] = machineToAdd;
} }
public boolean ComprobarCapacidad(String atribute, int valorComprobar) //He estado pensando en como va esto.
//(Hay que tener en cuenta que no los almacenamos, los generamos al cargar las máquinas).
// Podemos usar Atributo y Atributo_max y almacenar todos en un único HashMap.
// También podemos tener dos HashMap, uno para los atributos y otro para los máximos.
// Con unos if-else comprobamos/añadimos en el que corresponda según sea la máquina.
public boolean ComprobarCapacidad(String attribute, int valorComprobar)
{ {
Integer max = capacidadMaxima.get(atribute + "_max");
Integer max = recursosMaximos.get(attribute);
if(max == null) if(max == null)
{ {
System.err.println("El atributo " + atribute + "_max no existe en la sala " + roomName); System.err.println("El atributo " + attribute + "_max no existe en la sala " + roomName);
} }
if(valorComprobar <= max) if(valorComprobar <= max)
{ {
@@ -79,6 +107,12 @@ public class Room
public boolean ComprobarMaquina(Machine maquinaComprobar) public boolean ComprobarMaquina(Machine maquinaComprobar)
{ {
//En principio, las máquinas de recursos siempre se pueden poner.
if(maquinaComprobar.esDeRecursos)
{
return true;
}
//Se procesarían los atributos para comprobar si se puede añadir la máquina. //Se procesarían los atributos para comprobar si se puede añadir la máquina.
for(String key : maquinaComprobar.attributes.keySet()) for(String key : maquinaComprobar.attributes.keySet())
{ {
@@ -97,16 +131,101 @@ public class Room
* Variables * Variables
* -------------*/ * -------------*/
String roomName; String roomName;
int width; // int width;
int height; // int height;
Vector2 roomSize;
int[][] bgData; int[][] bgData;
Machine[][] machineData; Machine[][] machineData;
//Únicamente, para probar la serialización como array.
String[][] machineData_Test;
//Atributos de la sala. //Atributos de la sala.
//nombreAtributo //nombreAtributo
HashMap<String, Integer> capacidadOcupada; HashMap<String, Integer> recursosOcupados;
//nombreAtributo_max //nombreAtributo_max
HashMap<String, Integer> capacidadMaxima; HashMap<String, Integer> recursosMaximos;
boolean esOnline = false;
//ToDo: Esto hay que moverlo a RoomLoader y ponerlo como Json.Serializer<Room> pues en RoomLoader tenemos un ptr a Game.MachineLoader
// y por tanto podemos pedir las máquinas directamente. La otra forma es que Game sea un Singleton...
@Override
public void write(Json json)
{
//Crearlo como un objeto puede venir bien si lo vamos a tener junto a otros datos externos.
// Hay que tener cuidado no rompamos el Read.
//json.writeObjectStart("Room");
json.writeValue("RoomName", roomName);
json.writeValue("RoomSize", roomSize);
json.writeValue("BackgroundData", bgData);
//Datos de máquinas.
json.writeArrayStart("MaquinasData");
for(int y = 0; y < machineData.length; y++)
{
json.writeArrayStart();
for(int x = 0; x < machineData[y].length; x++)
{
//Sólo nos interesa el ID de la máquina,
Machine mc = machineData[y][x];
if(mc == null)
{
json.writeValue(null);
} else {
json.writeValue(mc.machineID);
}
}
json.writeArrayEnd();
}
json.writeArrayEnd();
//json.writeObjectEnd();
//En principio, los recursos ocupados/disponibles los podemos reconstruir al cargar a
// partir de las máquinas que haya.
}
@Override
public void read(Json json, JsonValue jsonData)
{
//jsonData = jsonData.child();
roomName = jsonData.get("RoomName").asString();
roomSize = new Vector2();
roomSize.x = jsonData.get("RoomSize").get("x").asFloat();
roomSize.y = jsonData.get("RoomSize").get("y").asFloat();
//ToDo: En principio, bgData es el tamaño de la sala (el grid de máquinas) + 2 (para paredes).
bgData = new int[(int)roomSize.y][(int)roomSize.x];
for(int y = 0; y < bgData.length; y++)
{
bgData[y] = jsonData.get("BackgroundData").get(y).asIntArray();
}
machineData = new Machine[(int)roomSize.y][(int)roomSize.x];
machineData_Test = new String[(int)roomSize.y][(int)roomSize.x];
//ToDO: Revisar si el bucle de JsonValue.java es más eficiente.
for (int y = 0; y < machineData.length; y++)
{
//Obtenemos el array de esta "y".
JsonValue yData = jsonData.get("MaquinasData").get(y);
// yData = yData.child;
//
// for (; yData != null; yData = yData.next)
// {
// String val = yData.asString();
// }
for(int x = 0; x < machineData[y].length; x++)
{
//ToDo: En vez de guardar al String, se debería obtener un ptr a la máquina en cuestión desde MachineLoader.
machineData_Test[y][x] = yData.get(x).asString();
}
}
//Luego cargamos el resto... Si es que lo hay.
}
} }
@@ -0,0 +1,74 @@
package uberelectron.testgame;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.utils.Json;
import uberelectron.gameSystems.Machine;
import uberelectron.gameSystems.Room;
public class BackEndTest implements Screen
{
final testGame game;
public BackEndTest(final testGame game)
{
this.game = game;
Machine testMach = new Machine();
testMach.setMachineID("base_raspi_mk1");
testMach.AddAtribute("Test", 5);
testMach.AddAtribute("Otro", -2);
testMach.setEsDeRecursos(true);
Json json = new Json();
String text = json.toJson(testMach);
System.out.println(json.prettyPrint(text));
Machine mkLoad = json.fromJson(Machine.class, text);
Room testRoom = new Room("testRoom", 8, 5);
testRoom.LoadRoom();
testRoom.AddMachine(5,3, testMach);
testRoom.AddMachine(6,3, mkLoad);
String textRoom = json.toJson(testRoom);
System.out.println(json.prettyPrint(textRoom));
Room loadedRoom = json.fromJson(Room.class, textRoom);
System.out.println("Pues eso...");
}
@Override
public void show() {}
@Override
public void render(float delta)
{
}
@Override
public void resize(int width, int height) {}
@Override
public void pause() {}
@Override
public void resume() {}
@Override
public void hide() {}
@Override
public void dispose()
{
}
}
+2 -1
View File
@@ -23,7 +23,8 @@ public class testGame extends Game
LoadTileSets(); LoadTileSets();
this.setScreen(new TileMapTest(this)); //this.setScreen(new TileMapTest(this));
this.setScreen(new BackEndTest(this));
//img = new Texture("badlogic.jpg"); //img = new Texture("badlogic.jpg");
} }