Какие хорошие решения для сериализации в C ++? [закрыто]

18

Мне любопытно, какие решения разработчики игр придумали для сериализации различных типов данных, с которыми они имеют дело для своих игр. Ребята, вы используете какую-то монолитную иерархию GameObject, которая содержит интерфейс сериализации для производных типов, используете своего рода решение на основе RTTI, выполняете явную сериализацию потока для определенных классов или используете некоторые решения с открытым исходным кодом (boost :: serialization, s11n, и т.д).

отметка
источник
1
Я думаю, что сериализация в программировании разработки игр - важная тема, но мне не нравится этот вопрос. Что ты пытаешься сделать? Какие конкретные проблемы вы пытаетесь решить? Вместо этого я преобразовал это в вики сообщества, так что это скорее формат обсуждения.
Тетрад
Я думаю, что было бы хорошо, чтобы применить некоторые форматирования для этого (аля вопрос контроля версий).
Джесси Дорси

Ответы:

9

Буферы протокола от Google могут быть очень хорошим подходом для сериализации объектов c ++. Возможно, вам придется создать некоторые промежуточные объекты как часть процесса сериализации, но он также работает на многих платформах и языках.

Ben Zeigler
источник
1
Я использую его, и это легко, если вы можете автоматизировать генерацию кода в вашей системе сборки. Хотя действительно превосходным преимуществом является то, что он позволяет передавать данные на удаленные машины без учета используемой платформы, и он оптимизирован для этого, поэтому сгенерированные объекты невелики.
Klaim 8.10.10
10

Мы в нашей игре просто используем boost.serilization , она проста в использовании и очень быстра, но, на мой взгляд, просто полезна для сохранения игр. Если вы пытаетесь создавать символы, я рекомендую вам что-нибудь на XML'е или на основе JSON, потому что они легко читаются и редактируются, даже если у вас нет редактора.

awildturtok
источник
Я видел, что boost :: serialization также успешно используется для связи клиент-сервер. Тем не менее, AFAIK основывается на потоке, поэтому он не совсем устойчив к версии. Возможно, это не нарушает соглашения о взаимодействии клиент / сервер, но если вы используете его для сохраненных игр, то любое изменение структуры игровых данных делает загрузку старых сохраненных игр виртуальной невозможностью (поддержка загрузки более старых версий объектов становится настоящей рутиной). ).
Майк Штробель
2
@MikeStrobel Недавно я просматривал несколько сериализаций и наборов json и наткнулся на этот комментарий. boost :: serialization явно поддерживает управление версиями. Сериализованные вызовы могут получить номер версии, а затем пользователь может реализовать базовую логику ветвления (если (версия> 1.0) ...). В целом кажется довольно надежным.
M2tM
Позор, кажется, не поддерживает пользовательский распределитель / удаление.
JamesAMD
1
Я только что портировал с повышения сериализации на зерновые. Порт был удивительно гладким . Оно работало завораживающе. Cereal поддерживает xml, json, двоичный и переносимый двоичные файлы . Причина, по которой я портировал зерновые, была последней. Мне нужны были переносимые двоичные архивы, потому что я запускаю сервер, к которому подключаются клиенты (сейчас Mac, скоро iOS и Android). Я был очень доволен ускоренной сериализацией, но я думаю, что некоторые функции зерновых делают его еще лучше, например, упомянутая портативная двоичная сериализация. Для буферов протокола взаимодействия языков и так лучше.
Герман Диаго
Согласно документам boost.serialization не является потокобезопасным. Также Cereal не использует аналогичный API.
Привет, Ангел,
3

Мне скорее нравится JSON для сериализации. Это довольно просто разобрать, и есть бесплатные библиотеки, такие как http://jsoncpp.sourceforge.net/ Я никогда не был фанатом boost или RTTI в C ++. Tinyxml также хорошо работает для сериализации и десериализации xml. http://www.grinninglizard.com/tinyxml/ В конечном счете, я не хочу тратить больше времени, чем на сериализацию.

Стивен Бенке
источник
2

Google FlatBuffers - это эффективная кроссплатформенная библиотека сериализации для C ++ с поддержкой Java и Go. Он был создан в Google специально для разработки игр и других приложений, критичных к производительности.

Он доступен как открытый исходный код под лицензией Apache, v2.

Kimi
источник
1

XDS был разработан специально для этой цели, он дает вам преимущества XML во время разработки и преимущества компактного двоичного представления во время распространения.

user16
источник
Я не совсем уверен, что отличает XDS от буферов протокола Google? Кажется, они служат той же цели, за исключением того, что XDS был первым.
Жакмо
Вы наверняка имеете в виду XSD, а не XDS? codesynthesis.com/products/xsd Я хотел опубликовать ответ об этом, чтобы завершить список.
v.oddou
1

Если вы работаете на платформе Linux, вы можете напрямую использовать json.hбиблиотеку для сериализации. Вот пример кода, с которым я столкнулся. Источник: 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
источник
0

И jsonCpp, и буфер протокола являются хорошими вариантами. Насколько мне известно, оба позволят вам создавать последовательные древовидные структуры из коробки (пожалуйста, исправьте меня, если я ошибаюсь). boost :: serialization может обрабатывать произвольные графы, но не имеет хорошего текстового формата, такого как json (я думаю, что существует формат xml)

Лично я думаю, что подход для сериализации json, который использовал Dojo, является лучшим
http://docs.dojocampus.org/dojox/json/ref

Я сделал свою собственную версию на c ++ с использованием jsoncpp, которая также будет десериализовать типизированные объекты (у меня есть своего рода большая фабрика для всех моих типов). Это позволяет мне сделать сцену из коллекции json-файлов, на которые можно ссылаться в любом случае, пожалуйста.

Джонатан Фишофф
источник