Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how about relation data ,for example a pointer of object #45

Closed
zyxia opened this issue Apr 3, 2019 · 10 comments
Closed

how about relation data ,for example a pointer of object #45

zyxia opened this issue Apr 3, 2019 · 10 comments
Labels

Comments

@zyxia
Copy link

zyxia commented Apr 3, 2019

No description provided.

@Loki-Astari
Copy link
Owner

Does this cover the issue?

#42

Pointer (and std::unique_ptr<>) are covered automatically for normal simple types. If you have polymorphic types then you need to do a bit more work. See here: https://github.com/Loki-Astari/ThorsSerializer/blob/master/doc/example3.md

If this dies not cover your situation then please provide an example.

@zyxia
Copy link
Author

zyxia commented Apr 4, 2019

for example
i have 2 object.

static int ID = 0;

struct Object
{
   int id; 
   Object()
   {
   	this->id = ID++;
   };
};
 
struct Student :public Object
{  
   Student():Object(){ } 
};
struct ClassRoom :public Object
{
   ClassRoom() :Object()
   { 
   }
   void addStudent(Student& pStudent)
   { 
   	this->students.push_back(pStudent.id);
   }
   std::vector<int> students; 
};

void main()
{

   Student obj;
   obj.age = 20;
   obj.height = 180;
   obj.name = "xia";
   ClassRoom room;
   room.addStudent(obj);
    
}

and the obj and room 's id is diffrent when recreate,
this is normally remapping the relation of room and obj.

how to do it when i use ThorsSerializer

@Loki-Astari
Copy link
Owner

Loki-Astari commented Apr 4, 2019

    #include "ThorSerialize/JsonThor.h"
    #include "ThorSerialize/SerUtil.h"
    #include "ThorSerialize/Traits.h"

    // Your class definitions from above.
    // You should fix Student it is missing some fields.

    ThorsAnvil_MakeTrait(Object, id);
    ThorsAnvil_ExpandTrait(Student, Object, age, height, name);
    ThorsAnvil_ExpandTrait(ClassRoom, Object, students);

    int main()
    {
         Student obj;
         obj.age = 20;
         obj.height = 180;
         obj.name = "xia";
         ClassRoom room;
         room.addStudent(obj);

        // Save state of program
        using ThorsAnvil::Serialize::jsonExport;
        std::cout << jsonExport(room) << "\n";
        std::cout << jsonExport(obj) << "\n";
        std::cout << jsonExport(ID) << "\n";


         // Load State of program
        using ThorsAnvil::Serialize::jsonImport;
        std::cin >> jsonImport(room);
        std::cin >> jsonImport(obj);
        std::cin >> jsonImport(ID);

    }

@zyxia
Copy link
Author

zyxia commented Apr 4, 2019

the point of the problem is "the relation between obj and room",

  1. if obj.id==1 and room.id ==2 and room.students[0].id==1.
  2. and when i load the Serialized text from jsonImport(),the ids mybe
    obj.id==5 and room.id ==6 and room.students[0].id==1.
    the variable id will auto gernerate when create Object every time.
    it is a really familiar situation in game engine.the id cant be same when recreate.
    so when i recreate Object,i need keep the realation of Objects.
    like obj.id==5 and room.id ==6 and room.students[0].id==5.

@Loki-Astari
Copy link
Owner

I solved that problem in the example above.

If you serialize the ID as part of the object it will be restored correctly and thus the reference from room to object will be maintained. The side affect of this is that you need to serialize the global ID so that when you restart the ID is also updated from a consistent state.

Are you asking to run arbitrary user code to re-calculate id?

@Loki-Astari
Copy link
Owner

Loki-Astari commented Apr 4, 2019

it is a really familiar situation in game engine

Sure. But it is only useful if you can use the id to find the object. Which then implies that all the object are stored in a container and the id is used to index into the container to retrieve the object.

In this case you would serialize the container containing all the objects and when you load them back in the correct id will still be correct.

#include "ThorSerialize/JsonThor.h"
#include "ThorSerialize/SerUtil.h"
#include "ThorSerialize/Traits.h"

struct Object;
static std::vector<Object*> store;

struct Object
{
   int id; 
   virtual ~Object()
    {
        store[id] = nullptr;
    }
   Object()
   {
   	this->id = store.size();
        store.push_back(this);
   }
};
ThorsAnvil_MakeTrait(Object, id);
int main()
{
    // Load previous state
    std::cin >> jsonImport(store);


    // Save State on exit
    std::cout << jsonExport(store);
}

@zyxia
Copy link
Author

zyxia commented Apr 4, 2019

Are you asking to run arbitrary user code to re-calculate id?
yes

@Loki-Astari
Copy link
Owner

You need to make the id object a special type. You can then define the normal stream operators for that type to serialize the object and use the macro ThorsAnvil_MakeTraitCustom() to mark it as a normal serialization object.

#include "ThorSerialize/Traits.h"
#include "ThorSerialize/JsonThor.h"

#include <iostream>

int ID = 0;

struct IdObj
{
    IdObj(int id) 
        : id(id)
    {}  
    int id; 
    friend std::ostream& operator<<(std::ostream& str, IdObj const& data) {
        // When streaming to output you must make sure that␣
        // this is valid JSON.
        return str << data.id;
    }   
    friend std::istream& operator>>(std::istream& str, IdObj& data) {
        // When reading the value you must make sure you read everything that
        // you wrote out during streaming.
        str >> data.id;

        // Do the action you want to update the ID to something unique to you
        return str;
    }   
};

struct Object
{
    IdObj id; 
    Object()
        : id(ID++)
    {}  
};

ThorsAnvil_MakeTraitCustom(IdObj);
ThorsAnvil_MakeTrait(Object, id);


using  ThorsAnvil::Serialize::jsonImport;
using  ThorsAnvil::Serialize::jsonExport;

int main()
{
    Object  id; 

    std::cout << jsonExport(id) << "\n";
    std::cin  >> jsonImport(id);
}

Since you have defined the serialization functions you can execute any arbitory code when you read the values in.

@zyxia
Copy link
Author

zyxia commented Apr 5, 2019

in this case,i find that ,it is hard to find a common way to serialization when i need add logic code when deserialization .

@Loki-Astari
Copy link
Owner

Not sure what you are saying.
It is your type that has an asymmetric concept of serialization that is strange. If you look at my example above it solves all the problems (where you have a vector of objects) without the need for extra code. Also this would be the way a standard application would implement the "all objects have id" concept.

Unless you have anything specific you are trying to solve please close the issue as I don't see anything generic that a serialization library should be solving for you here.

@zyxia zyxia closed this as completed Apr 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants