Jakie są dobre rozwiązania do serializacji w C ++? [Zamknięte]

18

Jestem ciekawy, jakie rozwiązania wymyślili twórcy gier do szeregowania różnych rodzajów danych, z którymi mają do czynienia w swoich grach. Czy używacie jakiejś monolitycznej hierarchii GameObject, która zawiera interfejs serializacji dla typów pochodnych, używacie swego rodzaju niestandardowego rozwiązania opartego na RTTI, wykonujemy jawną serializację strumienia dla niektórych klas, czy też korzystacie z niektórych rozwiązań open source (boost :: seriization, s11n, itp).

100%
źródło
1
Myślę, że serializacja w programowaniu gier jest ważnym tematem, ale nie podoba mi się to pytanie. Co ty próbujesz zrobić? Jakie konkretne problemy próbujesz rozwiązać? Zamiast tego przekonwertowałem go na wiki społeczności, aby był to raczej format dyskusji.
Tetrad
Myślę, że dobrze byłoby zastosować do tego sformatowanie (ala pytanie kontrolne wersji).
Jesse Dorsey

Odpowiedzi:

9

Bufory protokołów od Google mogą być całkiem dobrym podejściem do serializacji obiektów c ++. Być może trzeba będzie utworzyć niektóre obiekty pośredniczące w ramach procesu serializacji, ale działa to również na wielu platformach i językach.

Ben Zeigler
źródło
1
Korzystam z niego i łatwo jest zautomatyzować generowanie kodu w systemie kompilacji. Chociaż naprawdę doskonałą zaletą jest to, że pozwala przesyłać dane na zdalne maszyny, bez względu na używaną platformę, i jest zoptymalizowana do tego, aby generowane obiekty nie były duże.
Klaim
10

W naszej grze po prostu używamy boost.serilization , jest łatwy w użyciu i bardzo szybki, ale moim zdaniem jest po prostu przydatny do zapisywania gier. Jeśli próbujesz tworzyć znaki, polecam ci coś opartego na XML lub JSON, ponieważ są one łatwe do odczytania i edytowania, nawet jeśli nie masz edytora.

awildturtok
źródło
Widziałem też serializację boost :: używaną z powodzeniem do komunikacji klient / serwer. Jednak AFAIK jest oparty na strumieniu, więc nie jest dokładnie tolerancyjny dla wersji. To może nie być przełomem w komunikacji klient / serwer, ale jeśli użyjesz go do zapisanych gier, to każda zmiana w strukturze danych gry powoduje, że ładowanie starszych zapisanych gier jest wirtualną niemożliwością (obsługa ładowania starszych wersji obiektów staje się prawdziwym obowiązkiem ).
Mike Strobel,
2
@MikeStrobel Niedawno przeglądałem kilka serializacji i zestawy Json i natknąłem się na ten komentarz. boost :: seriization wyraźnie obsługuje wersjonowanie. Serializacje mogą otrzymać numer wersji, a następnie to użytkownik musi wdrożyć podstawową logikę rozgałęziania (if (wersja> 1.0) ...). Ogólnie wydaje się dość solidny.
M2tM,
Szkoda, że ​​nie obsługuje niestandardowego narzędzia do przydzielania / usuwania.
JamesAMD
1
Właśnie przeniosłem z serializacji do zbóż. Port był wyjątkowo gładki . Działa jak urok. Cereal obsługuje xml, json, binarny i przenośny binarny . Powodem, dla którego przeniosłem się do płatków, był ostatni. Potrzebowałem przenośnych archiwów binarnych, ponieważ uruchamiam serwer, z którym łączą się klienci (obecnie Mac, wkrótce iOS i Android). Byłem całkiem zadowolony z serializacji doładowania, ale myślę, że niektóre cechy zbóż idą o krok dalej w lepszy sposób, na przykład wspomniana przenośna serializacja binarna. W przypadku buforów protokołów międzyoperacyjnych i takie jest lepsze.
Germán Diago,
Według docs boost.serialization nie jest bezpieczny dla wątków. Cereal nie korzysta również z podobnego API.
Cześć Anioł
3

Wolę JSON do serializacji. Analizowanie jest bardzo proste, a dostępne są bezpłatne biblioteki, takie jak http://jsoncpp.sourceforge.net/. Nigdy nie byłem fanem ulepszeń lub RTTI w C ++. Tinyxml działa również dobrze w przypadku serializacji i deserializacji xml. http://www.grinninglizard.com/tinyxml/ Ostatecznie nie chcę poświęcać więcej czasu niż na serializację.

Steven Behnke
źródło
2

Google FlatBuffers to wydajna międzyplatformowa biblioteka serializacji dla C ++ z obsługą Java i Go. Został stworzony w Google specjalnie do tworzenia gier i innych aplikacji o krytycznym znaczeniu dla wydajności.

Jest dostępny jako open source na licencji Apache v2.

Kimi
źródło
1

XDS został zaprojektowany właśnie do tego celu, zapewnia korzyści XML podczas programowania i zalety kompaktowej reprezentacji binarnej w czasie dystrybucji.

użytkownik 16
źródło
Nie jestem do końca pewien, co odróżnia XDS od buforów protokołu Google? Wydaje się, że służą temu samemu celowi, z tym wyjątkiem, że XDS był pierwszy.
jacmoe
Na pewno masz na myśli XSD, a nie XDS? codeynthesis.com/products/xsd Chciałem opublikować odpowiedź na ten temat, aby uzupełnić listę.
v.oddou
1

Jeśli korzystasz z platformy Linux, możesz bezpośrednio użyć json.hbiblioteki do serializacji. Oto przykładowy kod, z którym się zetknąłem. Źródło: 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
źródło
0

Zarówno bufory jsonCpp, jak i bufory protokołów są dobrym rozwiązaniem. O ile mi wiadomo, oba pozwolą ci na szeregowe struktury drzewek po wyjęciu z pudełka (popraw mnie, jeśli się mylę). serializacja boost :: może obsługiwać dowolne wykresy, ale nie ma ładnego formatu tekstowego, takiego jak json (myślę, że istnieje format xml)

Osobiście uważam, że podejście serializacji json, które przyjęło Dojo, jest najlepsze
http://docs.dojocampus.org/dojox/json/ref

Stworzyłem własną wersję w c ++ przy użyciu jsoncpp, która również deserializuje wpisane obiekty (mam coś w rodzaju dużej fabryki dla wszystkich moich typów). Pozwala mi to zrobić scenę z kolekcji plików json, do których i tak mogę się odwoływać.

Jonathan Fischoff
źródło