¿Cuáles son buenas soluciones para la serialización en C ++? [cerrado]

18

Tengo curiosidad por saber qué soluciones han desarrollado los desarrolladores de juegos para serializar los diferentes tipos de datos que manejan para sus juegos. ¿Ustedes usan alguna jerarquía monolítica de GameObject que alberga una interfaz de serialización para tipos derivados, usan una especie de solución personalizada basada en RTTI, realizan serialización de flujo explícito para ciertas clases o usan algunas de las soluciones de código abierto (boost :: serialization, s11n, etc)

Mark
fuente
1
Creo que la serialización en la programación de desarrollo de juegos es un tema importante, pero no me gusta esta pregunta. ¿Qué está usted tratando de hacer? ¿Qué problemas específicos estás tratando de resolver? En lugar de eso, lo convertí en un wiki de la comunidad para que sea más un formato de discusión.
Tetrad
Creo que sería bueno aplicar un poco de formateo a esto (ala pregunta de control de versiones).
Jesse Dorsey

Respuestas:

9

Los buffers de protocolo de Google pueden ser un enfoque bastante bueno para serializar objetos c ++. Puede que tenga que hacer algunos objetos intermedios como parte del proceso de serialización, pero también funciona en muchas plataformas e idiomas.

Ben Zeigler
fuente
1
Lo estoy usando y es fácil si puede automatizar la generación de código en su sistema de compilación. Aunque una ventaja realmente excelente es que le permite transferir datos en máquinas remotas sin tener en cuenta la plataforma utilizada, y está optimizado para eso, por lo que los objetos generados no son grandes.
Klaim
10

En nuestro juego simplemente usamos boost.serilization , es fácil de usar y muy rápido, pero en mi opinión es útil para los juegos guardados. Si intentas crear personajes, te recomiendo algo basado en XML o JSON, porque son fáciles de leer y editar incluso si no tienes el editor.

awildturtok
fuente
He visto boost :: serialización utilizada con éxito para la comunicación cliente / servidor también. Sin embargo, AFAIK está basado en transmisión, por lo que no es exactamente tolerante a la versión. Puede que eso no sea un factor decisivo para la comunicación cliente / servidor, pero si lo usa para juegos guardados, cualquier cambio en las estructuras de datos del juego hace que cargar juegos guardados más antiguos sea una imposibilidad virtual (el soporte para cargar versiones de objetos más antiguos se convierte en una tarea real )
Mike Strobel el
2
@ MikeStrobel Recientemente estuve revisando algunos kits de serialización y json y encontré este comentario. boost :: serialization admite explícitamente el control de versiones. Las llamadas en serie pueden recibir un número de versión y luego corresponde al usuario implementar la lógica de ramificación básica (if (versión> 1.0) ...). En general parece bastante robusto.
M2tM
Es una pena que no parezca compatible con el asignador / eliminador personalizado.
JamesAMD
1
Acabo de pasar de la serialización de impulso al cereal. El puerto fue notablemente suave . Funcionó a las mil maravillas. Cereal admite xml, json, binario y binario portátil . La razón por la que me porté al cereal fue la última. Necesitaba archivos binarios portátiles porque ejecuto un servidor al que se conectan los clientes (por ahora una Mac, pronto iOS y Android). Estaba bastante contento con la serialización de impulso, pero creo que algunas de las características del cereal lo llevan un paso más allá de una mejor manera, como la mencionada serialización binaria portátil. Para las memorias intermedias de protocolo de interoperabilidad de lenguaje, es mejor.
Germán Diago
Por documentos boost.serialization no es seguro para subprocesos. Tampoco lo es Cereal que usa una API similar.
Hola Ángel,
3

Prefiero JSON para la serialización. Es bastante simple de analizar y hay bibliotecas gratuitas disponibles, como http://jsoncpp.sourceforge.net/ Nunca he sido fanático de boost o RTTI en C ++. Tinyxml también funciona bien para la serialización y deserialización xml. http://www.grinninglizard.com/tinyxml/ En última instancia, no quiero tener que pasar más tiempo del necesario para la serialización.

Steven Behnke
fuente
2

Google FlatBuffers es una biblioteca de serialización multiplataforma eficiente para C ++, con soporte para Java y Go. Fue creado en Google específicamente para el desarrollo de juegos y otras aplicaciones críticas para el rendimiento.

Está disponible como código abierto bajo la licencia de Apache, v2.

Kimi
fuente
1

XDS fue diseñado solo para este propósito, le brinda los beneficios de XML durante el desarrollo y los beneficios de una representación binaria compacta en el momento de la distribución.

usuario16
fuente
No estoy realmente seguro de qué hace que XDS sea diferente de los Buffers de protocolo de Google. Parecen tener el mismo propósito, excepto que XDS fue el primero.
jacmoe
¿Seguramente quieres decir XSD y no XDS? codesynthesis.com/products/xsd Quería publicar una respuesta al respecto para completar la lista.
v.oddou
1

Si está en una plataforma Linux, puede usar directamente la json.hbiblioteca para la serialización. Aquí hay un código de muestra que he encontrado. Fuente: Serializador Json

//============================================================================
// Name        : JsonTest.cpp
// Author      : Manis Kumar Khedawat
//============================================================================

#include <iostream>
#include <json/json.h>

using namespace std;

struct objStruct{
    string str;
    int n1;
    int n2;
};

typedef objStruct obj;

void serializeToJson(json_object *jObj,obj* pObj)
{
    /*
    string str;
    int n1;
    int n2;
    */

    // Create json object for every member in struct Obj.

    json_object *jstr = json_object_new_string (pObj->str.c_str());
    json_object *jn1 =json_object_new_int(pObj->n1);
    json_object *jn2 =json_object_new_int(pObj->n2);

    // Add all above created object into jObj

    json_object_object_add(jObj,"str",jstr);
    json_object_object_add(jObj,"n1",jn1);
    json_object_object_add(jObj,"n2",jn2);

    // pObj is Serialzed into jObj
}

void deSerializeToJson(json_object *jObj,obj* pObj)
{
    /*
    string str;
    int n1;
    int n2;
    */

    // Get every member as different json obj from jObj
    json_object *jstr = json_object_object_get (jObj,"str");
    json_object *jn1 =json_object_object_get(jObj,"n1");
    json_object *jn2 =json_object_object_get(jObj,"n2");

    pObj->str=json_object_get_string(jstr);
    pObj->n1=json_object_get_int(jn1);
    pObj->n2=json_object_get_int(jn2);

    // jObj is DeSerialzed into pObj
}

int main() {
    // Lets Create an Object which we will serialze into Json
    obj obj1;
    obj1.n1=3;
    obj1.n2=6;
    obj1.str="This is String";

    // Create a json Object
    json_object* jObj=json_object_new_object();

    // To serialize into Json Object
    // Please Keep in mind , we are passing address of object (pointer) & not object
    serializeToJson(jObj,&obj1);

    obj obj2;
    // To serialize into Json Object
    // Please Keep in mind , we are passing address of object (pointer) & not object
    deSerializeToJson(jObj,&obj2);

    cout<<"String str == "<<obj2.str<<endl;
    cout<<"n1 & n2 : "<<obj2.n1<<" "<<obj2.n2<<endl;

    return 0;
}
Philip Allgaier
fuente
0

Tanto los buffers jsonCpp como los Protocolos son buenas opciones. Que yo sepa, ambos solo le permitirán serializar las estructuras de árbol fuera de la caja (corríjame si me equivoco). boost :: serialization puede manejar gráficos arbitrarios, pero no tiene un buen formato de texto como json (creo que hay un formato xml)

Personalmente, creo que el enfoque para la serialización json que Dojo ha tomado es el mejor
http://docs.dojocampus.org/dojox/json/ref

Hice mi propia versión en c ++ usando jsoncpp, que también deserializará los objetos mecanografiados (tengo una especie de gran fábrica para todos mis tipos). Me permite hacer una escena de una colección de archivos json a los que se puede hacer referencia de todos modos, por favor.

Jonathan Fischoff
fuente