Які хороші рішення для серіалізації в C ++? [зачинено]


18

Мені цікаво, які рішення розробники ігор придумали для серіалізації різних типів даних, якими вони займаються для своїх ігор. Ви, хлопці, використовуєте якусь монолітну ієрархію GameObject, в якій розміщений інтерфейс серіалізації для похідних типів, використовуйте якесь власне рішення на основі RTTI, виконайте явну серіалізацію потоку для певних класів або використовуйте деякі рішення з відкритим кодом (boost :: serialization, s11n, тощо).


1
Я думаю, що серіалізація в програмуванні розробки ігор є важливою темою, але мені це питання не подобається. Що ви намагаєтесь зробити? Які конкретні проблеми ви намагаєтеся вирішити? Замість цього я перетворив його на вікі спільноти, щоб він був більше форматом обговорення.
Тетрад

Я думаю, що було б добре застосувати до цього формулювання (ала питання контролю версій).
Джессі Дорсі

Відповіді:


9

Буфери протоколів від Google можуть бути досить хорошим підходом для серіалізації об'єктів c ++. Можливо, вам доведеться зробити деякі проміжні об'єкти як частину процесу серіалізації, але він також працює на багатьох платформах та мовах.


1
Я використовую це, і це легко, якщо ви можете автоматизувати генерацію коду у вашій системі збирання. Хоча справді відмінна перевага полягає в тому, що вона дозволяє передавати дані на віддалені машини, не використовуючи платформу, і вона оптимізована для цього, тому створені об'єкти не є великими.
Клайм

10

Ми в нашій грі просто використовуємо boost.serilization , вона проста у використанні та дуже швидка, але, на мою думку, просто корисна для savegames. Якщо ви спробуєте створити символи, я рекомендую вам щось на основі XML'ish чи JSON, оскільки вони легко читатись та редагуватись, навіть якщо у вас немає редактора.


Я бачив boost :: серіалізацію, що успішно використовується і для спілкування клієнт / сервер. Однак AFAIK є потоковим, тому він не є толерантним до версій. Можливо, це не є вимикачем угод для спілкування клієнт / сервер, але якщо ви використовуєте його для збережених ігор, то будь-яка зміна структури ігрових даних робить завантаження старих збережених ігор віртуальною неможливістю (підтримка завантаження старих версій об'єкта стає справжньою справою ).
Майк Стробель

2
@MikeStrobel Нещодавно я переглянув кілька наборів серіалізації та json і натрапив на цей коментар. boost :: serialization явно підтримує версію. Виклики з серіалізацією можуть отримати номер версії, і тоді користувач повинен реалізувати базову логіку розгалуження (якщо (версія> 1.0) ...). В цілому здається досить надійним.
M2tM

Ганьба, схоже, що це не підтримує спеціальний розподільник / видалювач.
JamesAMD

1
Я щойно переніс із посиленої серіалізації на зернові. Порт був надзвичайно гладкий . Це спрацювало як шарм. Зернові підтримують xml, json, бінарний та портативний двійкові файли . Причиною, по якій я порціював зернові, була остання. Мені потрібні були портативні двійкові архіви, оскільки я запускаю сервер, до якого підключаються клієнти (поки що Mac, незабаром iOS та Android). Я був дуже задоволений прискореною серіалізацією, але думаю, що деякі особливості зернових роблять це ще кращим кроком, наприклад, згадана портативна двійкова серіалізація. Для мовних буферних протоколів interop і таке краще.
Герман Діаго

За документи boost.serialization не є безпечною для потоків. Жоден із зернових не використовує аналогічний API.
Привіт-Ангел

3

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


2

Google FlatBuffers - це ефективна міжплатформна бібліотека серіалізації для C ++ із підтримкою Java та Go. Він створений в Google спеціально для розробки ігор та інших критичних для продуктивності програм.

Він доступний як відкритий код за ліцензією Apache, v2.



1

XDS був розроблений саме для цієї мети, він дає вам переваги XML під час розробки та переваги компактного бінарного представлення під час дистрибуції.


Я не дуже впевнений, чим відрізняється XDS від буферів протоколів Google? Вони, схоже, служать тій самій цілі, за винятком того, що XDS був першим.
jacmoe

Ви напевно маєте на увазі XSD, а не XDS? codeynthesis.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;
}

0

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

Особисто я вважаю, що підхід до серіалізації json, який застосував Доджо, є найкращим
http://docs.dojocampus.org/dojox/json/ref

Я створив свою власну версію в c ++, використовуючи jsoncpp, що також десеріалізує набрані об'єкти (у мене є велика фабрика для всіх моїх типів). Це дозволяє мені створити сцену з колекції файлів json, на які можна посилатись будь-коли.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.