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;
import com.badlogic.gdx.utils.Null;
import java.util.HashMap;
public class Machine
@@ -7,12 +9,30 @@ public class Machine
/*-------------
* Constructors
* -------------*/
public Machine(String id)
public Machine()
{
this.id = id;
attributes = new HashMap<>();
this.machineID = "null";
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
* -------------*/
@@ -28,13 +48,13 @@ public class Machine
attributes.put(name, newValue);
}
public int GetAtributeValue(String name)
public @Null int GetAtributeValue(String name)
{
Integer value = attributes.get(name);
if(value == null)
{
System.err.println("El atributo solicitado no existe: " + name
+ " en la maquina " + id);
+ " en la maquina " + machineID);
}
return value;
}
@@ -44,15 +64,15 @@ public class Machine
* Variables
* -------------*/
String id;
String machineID;
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.
Piensa en algo mejor, no te jode...
*/
boolean maquinaRecursos;
boolean esDeRecursos;
}
@@ -3,7 +3,7 @@ package uberelectron.gameSystems;
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
{
@@ -21,17 +21,17 @@ public class MachineLoader
* -------------*/
/**
* Carga del archivo JSON indicado los datos de cada m�quina.
* @param path Ubicaci�n del JSON
* Carga del archivo JSON indicado con los datos de cada máquina.
* @param path Ubicación del JSON
*/
public void LoadFile(String path)
{
//TODO
//TODO: Itera por las máquinas, cargándolas.
}
public void AddMachine(Machine machineToAdd)
{
machineMap.put(machineToAdd.id, machineToAdd);
machineMap.put(machineToAdd.machineID, machineToAdd);
}
public Machine GetMachine(String machineID)
@@ -39,7 +39,7 @@ public class MachineLoader
Machine mc = machineMap.get(machineID);
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;
}
+135 -16
View File
@@ -1,22 +1,43 @@
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;
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
* -------------*/
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)
{
this.roomName = roomName;
this.width = width;
this.height = height;
this.roomSize = new Vector2(width, height);
bgData = new int[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...
LoadRoom();
@@ -25,7 +46,7 @@ public class Room
/*-------------
* Methods
* -------------*/
private void LoadRoom()
public void LoadRoom()
{
bgData = new int[][]
{
@@ -54,21 +75,28 @@ public class Room
return;
}
for(String key : machineToAdd.attributes.keySet())
{
int newCapacidad = capacidadOcupada.get(key) + machineToAdd.GetAtributeValue(key);
capacidadOcupada.put(key, newCapacidad);
}
//Debería ser algo así. Pero hay que añadir atributos para poder probar...
// for(String key : machineToAdd.attributes.keySet())
// {
// int newCapacidad = recursosOcupados.get(key) + machineToAdd.GetAtributeValue(key);
// recursosOcupados.put(key, newCapacidad);
// }
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)
{
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)
{
@@ -79,6 +107,12 @@ public class Room
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.
for(String key : maquinaComprobar.attributes.keySet())
{
@@ -97,16 +131,101 @@ public class Room
* Variables
* -------------*/
String roomName;
int width;
int height;
// int width;
// int height;
Vector2 roomSize;
int[][] bgData;
Machine[][] machineData;
//Únicamente, para probar la serialización como array.
String[][] machineData_Test;
//Atributos de la sala.
//nombreAtributo
HashMap<String, Integer> capacidadOcupada;
HashMap<String, Integer> recursosOcupados;
//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();
this.setScreen(new TileMapTest(this));
//this.setScreen(new TileMapTest(this));
this.setScreen(new BackEndTest(this));
//img = new Texture("badlogic.jpg");
}