Quais são as boas soluções para serialização em C ++? [fechadas]

18

Estou curioso para saber quais soluções os desenvolvedores de jogos criaram para serializar os diferentes tipos de dados com os quais lidam em seus jogos. Vocês usam alguma hierarquia monolítica do GameObject que abriga uma interface de serialização para tipos derivados, usam uma solução personalizada baseada em RTTI, realizam a serialização explícita de fluxo para determinadas classes ou usam algumas das soluções de código aberto (boost :: serialization, s11n, etc).

Mark
fonte
1
Acho que a serialização na programação de desenvolvimento de jogos é um tópico importante, mas não gosto dessa pergunta. O que você está tentando fazer? Quais problemas específicos você está tentando resolver? Em vez disso, eu o convertei em um wiki da comunidade, para que ele se parecesse mais com um formato de discussão.
Tetrad
Eu acho que seria bom aplicar alguma formatação a isso, (veja a questão do controle de versão).
Jesse Dorsey

Respostas:

9

Os buffers de protocolo do Google podem ser uma boa abordagem para serializar objetos c ++. Pode ser necessário criar alguns objetos intermediários como parte do processo de serialização, mas também funciona em várias plataformas e idiomas.

Ben Zeigler
fonte
1
Estou usando e é fácil se você pode automatizar a geração de código no seu sistema de compilação. Embora uma vantagem realmente excelente seja o fato de permitir a transferência de dados em máquinas remotas sem considerar a plataforma usada, é otimizado para isso, para que os objetos gerados não sejam grandes.
#
10

Em nosso jogo, simplesmente usamos o boost.serilization , é fácil de usar e muito rápido, mas, na minha opinião, é útil apenas para jogos de salvamento . Se você tentar criar caracteres, eu recomendo que você use algo baseado em XML'ish ou JSON, porque eles são fáceis de ler e editáveis, mesmo que você não tenha o editor.

awildturtok
fonte
Eu já vi o boost :: serialization usado com êxito também para comunicação cliente / servidor. No entanto, o AFAIK é baseado em fluxo, portanto, não é exatamente tolerante à versão. Isso pode não ser um diferencial para a comunicação cliente / servidor, mas se você o usar para jogos salvos, qualquer alteração nas estruturas de dados do jogo torna o carregamento de jogos salvos mais antigos uma impossibilidade virtual (o suporte ao carregamento de versões mais antigas de objetos se torna uma tarefa real )
Mike Strobel
2
@ MikeStrobel Recentemente, estava analisando alguns kits de serialização e json e me deparei com esse comentário. O boost :: serialization suporta explicitamente o controle de versão. As chamadas serializadas podem receber um número de versão e, em seguida, cabe ao usuário implementar a lógica básica de ramificação (if (version> 1.0) ...). No geral, parece bastante robusto.
M2tM
Pena que não parece suportar alocador / deleter personalizado.
precisa saber é o seguinte
1
Acabei de portar da serialização de impulso para o cereal. O porto estava notavelmente suave . Funcionou como um encanto. O cereal suporta xml, json, binário e binário portátil . A razão pela qual eu carreguei cereal foi a última. Eu precisava de arquivos binários portáteis porque executo um servidor ao qual os clientes (por enquanto, mac, iOS e Android) se conectam. Fiquei muito feliz com a serialização de impulso, mas acho que alguns dos recursos do cereal vão um pouco mais longe, como a serialização binária portátil mencionada. Para buffers de protocolo de interoperabilidade de linguagem e isso é melhor.
Germán Diago
Por docs boost.serialization não é seguro para threads. O Cereal também não usa uma API semelhante.
Hi-Angel
3

Eu gosto bastante de JSON para serialização. É bem simples de analisar e existem bibliotecas gratuitas disponíveis, como http://jsoncpp.sourceforge.net/ . Nunca fui fã de boost ou RTTI em C ++. O Tinyxml também funciona bem para serialização e desserialização de xml. http://www.grinninglizard.com/tinyxml/ Por fim, não quero gastar mais tempo do que preciso para serialização.

Steven Behnke
fonte
2

O Google FlatBuffers é uma biblioteca eficiente de serialização de plataforma cruzada para C ++, com suporte para Java e Go. Foi criado no Google especificamente para o desenvolvimento de jogos e outros aplicativos críticos para o desempenho.

Está disponível como código aberto sob a licença Apache, v2.

Kimi
fonte
1

O XDS foi projetado apenas para esse fim, oferece os benefícios do XML durante o desenvolvimento e os benefícios de uma representação binária compacta no momento da distribuição.

user16
fonte
Não sei ao certo o que torna o XDS diferente dos buffers de protocolo do Google? Eles parecem servir ao mesmo propósito, exceto que o XDS foi o primeiro.
jacmoe
Você certamente quer dizer XSD e não XDS? codesynthesis.com/products/xsd Eu queria postar uma resposta sobre isso para completar a lista.
precisa saber é o seguinte
1

Se você estiver em uma plataforma Linux, poderá usar diretamente a json.hbiblioteca para serialização. Aqui está o código de exemplo que me deparei. Fonte: Json Serializer

//============================================================================
// 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
fonte
0

Os buffers jsonCpp e Protocol são boas opções. Que eu saiba, ambos apenas permitirão estruturas de árvore em série prontas para uso (corrija-me se estiver errado). boost :: serialization pode lidar com gráficos arbitrários, mas não possui um bom formato de texto como o json (acho que existe um formato xml)

Pessoalmente, acho que a abordagem para serialização json adotada pelo Dojo é a melhor
http://docs.dojocampus.org/dojox/json/ref

Eu fiz minha própria versão em c ++ usando jsoncpp, que também desserializa objetos digitados (eu tenho uma grande fábrica para todos os meus tipos). Ele me permite fazer uma cena a partir de uma coleção de arquivos json que podem ser referenciados de qualquer maneira que eu quiser.

Jonathan Fischoff
fonte