Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. .NET (Core and Framework)
  4. Custom Serialization

Custom Serialization

Scheduled Pinned Locked Moved .NET (Core and Framework)
questioncsharpgame-devjsonarchitecture
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    Gluber
    wrote on last edited by
    #1

    Hi there ! I have a tricky little problem. First I have to elaborate on my custom application architecture. I am desigining a highly extensible game engine which gets almost all functionality out of plugins which are implemented as .NET assemblies. I have a class called "Node" which wraps dynamically loaded classes via their object base class and supports invocation of methods via reflection as well as other things.. Nodes are organized in a hierarchy . Every Node contains a SortedList storing all child nodes, as well as a Node Reference pointing to the Parent node of a given node, as well as an object reference pointing to the wrapped class ( which was imported from the plugin assembly ) Now i want to save the hierarchy to a file via serialization. However i only want to save parts of the hierarchy from a given node. However since there is a parent reference , always the whole hierarchy gets serialized since the serializer walks both ways automatcially. So i want to restrict the serialization of the parent reference in certain cases dynamically. I can'T just add "Noserialze" attribute to the parent reference, since all classes are wrapped in Nodes and there can't be derived classes. Because of that i want to support ISerialize on the Node class to control what gets serialized and stop at a given node. However i do not seem to get that working. In particular how do i have to serialize the SortedList for the child nodes ? This is what i have so far: public void Node.GetObjectData( SerializationInfo info,StreamingContext context ) { info.AddValue("Id",m_identifier ); // Store the node id foreach( Node n in m_children.Values ) { string name = n.Name; info.AddValue ( "Name",name ); info.AddValue ( "Node",n ); } if ( m_parentSerialize ) info.AddValue("Parent",n.Parent ); } However this does not seem to work I also tried calling GetObjectData for the child nodes.. Seems not to work either.. . Any clues ?

    J 1 Reply Last reply
    0
    • G Gluber

      Hi there ! I have a tricky little problem. First I have to elaborate on my custom application architecture. I am desigining a highly extensible game engine which gets almost all functionality out of plugins which are implemented as .NET assemblies. I have a class called "Node" which wraps dynamically loaded classes via their object base class and supports invocation of methods via reflection as well as other things.. Nodes are organized in a hierarchy . Every Node contains a SortedList storing all child nodes, as well as a Node Reference pointing to the Parent node of a given node, as well as an object reference pointing to the wrapped class ( which was imported from the plugin assembly ) Now i want to save the hierarchy to a file via serialization. However i only want to save parts of the hierarchy from a given node. However since there is a parent reference , always the whole hierarchy gets serialized since the serializer walks both ways automatcially. So i want to restrict the serialization of the parent reference in certain cases dynamically. I can'T just add "Noserialze" attribute to the parent reference, since all classes are wrapped in Nodes and there can't be derived classes. Because of that i want to support ISerialize on the Node class to control what gets serialized and stop at a given node. However i do not seem to get that working. In particular how do i have to serialize the SortedList for the child nodes ? This is what i have so far: public void Node.GetObjectData( SerializationInfo info,StreamingContext context ) { info.AddValue("Id",m_identifier ); // Store the node id foreach( Node n in m_children.Values ) { string name = n.Name; info.AddValue ( "Name",name ); info.AddValue ( "Node",n ); } if ( m_parentSerialize ) info.AddValue("Parent",n.Parent ); } However this does not seem to work I also tried calling GetObjectData for the child nodes.. Seems not to work either.. . Any clues ?

      J Offline
      J Offline
      James T Johnson
      wrote on last edited by
      #2

      The way the default serializer works, is it will not serialize an object if it is already serialized, but it will store a value so that when deserialized it will point to the proper object. So you shouldn't have to implement ISerializable. Anyway, in your code the problem is the foreach loop. You are adding the node names and the nodes, but they have the same name each time; so you are adding the data but when you go to deserialize it, you are getting the same data back each time. James Simplicity Rules!

      G 1 Reply Last reply
      0
      • J James T Johnson

        The way the default serializer works, is it will not serialize an object if it is already serialized, but it will store a value so that when deserialized it will point to the proper object. So you shouldn't have to implement ISerializable. Anyway, in your code the problem is the foreach loop. You are adding the node names and the nodes, but they have the same name each time; so you are adding the data but when you go to deserialize it, you are getting the same data back each time. James Simplicity Rules!

        G Offline
        G Offline
        Gluber
        wrote on last edited by
        #3

        Hi ! THanks for you answer. I know that the serializer stores each object only once. But thats not the idea behind my question, because in my graph there are CERTAIN objects that MUST NOT be serialized... This is because e.g high level objects are in the graph like the graphics renderer or sound engine, which can be different on other machines, but still the serialized files should be loadable. So i need the Iserializeable interface. The code i sent in was just some dummy code, here is the REAL CODE now: private Node ( SerializationInfo info, StreamingContext c ) { m_children = new SortedList(); Debug.WriteLine("Deserializing object"); // And finally the node data itself. m_reference = info.GetValue("WrappedObject",typeof(object) ); m_id = (Identifier)info.GetValue("Id",typeof(Identifier) ); Debug.WriteLine(m_id.Name,"Assigned key to"); // Add number of children int numChildren = (int)info.GetValue( "ChildrenCount",typeof(int) ); // Serialize the child nodes first for( int i = 0; i < numChildren; i++ ) { // Generate an index key string nodeName = "Node" + i; Node newNode = (Node)info.GetValue(nodeName,typeof(Node) ); Attach( newNode ); } // Now we store the parent reference. if ( m_parentSerialize ) m_parent = (Node)info.GetValue("NodeParent",typeof(Node) ); } /// /// Serialization method for nodes. This is required /// so that the class tree does not get walked in the /// wrong direction, since we want certain node wrapped /// classes to be kept out of serialization. /// /// Serialization info. /// Serialization context. public void GetObjectData( SerializationInfo info, StreamingContext context ) { Debug.WriteLine(Id.Name,"GetObjectData called for"); // And finally the node data itself. info.AddValue("WrappedObject",m_reference ); info.AddValue("Id",m_id,typeof(Identifier) ); // Add number of children info.AddValue( "ChildrenCount",m_children.Count ); int index = 0; // Serialize the child nodes first foreach( Node n in m_children.Values ) { // Generate an index ke string nodeIndex = "Node" + index; info.AddValue( nodeIndex,n,typeof(Node) ); index ++; } // Now we store the parent reference. if ( m_parentSerialize ) info.AddValue("NodeParent",m_parent,typeof(Node) ); } The problem now is that

        J N 2 Replies Last reply
        0
        • G Gluber

          Hi ! THanks for you answer. I know that the serializer stores each object only once. But thats not the idea behind my question, because in my graph there are CERTAIN objects that MUST NOT be serialized... This is because e.g high level objects are in the graph like the graphics renderer or sound engine, which can be different on other machines, but still the serialized files should be loadable. So i need the Iserializeable interface. The code i sent in was just some dummy code, here is the REAL CODE now: private Node ( SerializationInfo info, StreamingContext c ) { m_children = new SortedList(); Debug.WriteLine("Deserializing object"); // And finally the node data itself. m_reference = info.GetValue("WrappedObject",typeof(object) ); m_id = (Identifier)info.GetValue("Id",typeof(Identifier) ); Debug.WriteLine(m_id.Name,"Assigned key to"); // Add number of children int numChildren = (int)info.GetValue( "ChildrenCount",typeof(int) ); // Serialize the child nodes first for( int i = 0; i < numChildren; i++ ) { // Generate an index key string nodeName = "Node" + i; Node newNode = (Node)info.GetValue(nodeName,typeof(Node) ); Attach( newNode ); } // Now we store the parent reference. if ( m_parentSerialize ) m_parent = (Node)info.GetValue("NodeParent",typeof(Node) ); } /// /// Serialization method for nodes. This is required /// so that the class tree does not get walked in the /// wrong direction, since we want certain node wrapped /// classes to be kept out of serialization. /// /// Serialization info. /// Serialization context. public void GetObjectData( SerializationInfo info, StreamingContext context ) { Debug.WriteLine(Id.Name,"GetObjectData called for"); // And finally the node data itself. info.AddValue("WrappedObject",m_reference ); info.AddValue("Id",m_id,typeof(Identifier) ); // Add number of children info.AddValue( "ChildrenCount",m_children.Count ); int index = 0; // Serialize the child nodes first foreach( Node n in m_children.Values ) { // Generate an index ke string nodeIndex = "Node" + index; info.AddValue( nodeIndex,n,typeof(Node) ); index ++; } // Now we store the parent reference. if ( m_parentSerialize ) info.AddValue("NodeParent",m_parent,typeof(Node) ); } The problem now is that

          J Offline
          J Offline
          James T Johnson
          wrote on last edited by
          #4

          What is the code for Attach, from what I can tell everything looks fine there; and how does m_id and newNode interact? I don't see anything that brings them together. James Simplicity Rules!

          1 Reply Last reply
          0
          • G Gluber

            Hi ! THanks for you answer. I know that the serializer stores each object only once. But thats not the idea behind my question, because in my graph there are CERTAIN objects that MUST NOT be serialized... This is because e.g high level objects are in the graph like the graphics renderer or sound engine, which can be different on other machines, but still the serialized files should be loadable. So i need the Iserializeable interface. The code i sent in was just some dummy code, here is the REAL CODE now: private Node ( SerializationInfo info, StreamingContext c ) { m_children = new SortedList(); Debug.WriteLine("Deserializing object"); // And finally the node data itself. m_reference = info.GetValue("WrappedObject",typeof(object) ); m_id = (Identifier)info.GetValue("Id",typeof(Identifier) ); Debug.WriteLine(m_id.Name,"Assigned key to"); // Add number of children int numChildren = (int)info.GetValue( "ChildrenCount",typeof(int) ); // Serialize the child nodes first for( int i = 0; i < numChildren; i++ ) { // Generate an index key string nodeName = "Node" + i; Node newNode = (Node)info.GetValue(nodeName,typeof(Node) ); Attach( newNode ); } // Now we store the parent reference. if ( m_parentSerialize ) m_parent = (Node)info.GetValue("NodeParent",typeof(Node) ); } /// /// Serialization method for nodes. This is required /// so that the class tree does not get walked in the /// wrong direction, since we want certain node wrapped /// classes to be kept out of serialization. /// /// Serialization info. /// Serialization context. public void GetObjectData( SerializationInfo info, StreamingContext context ) { Debug.WriteLine(Id.Name,"GetObjectData called for"); // And finally the node data itself. info.AddValue("WrappedObject",m_reference ); info.AddValue("Id",m_id,typeof(Identifier) ); // Add number of children info.AddValue( "ChildrenCount",m_children.Count ); int index = 0; // Serialize the child nodes first foreach( Node n in m_children.Values ) { // Generate an index ke string nodeIndex = "Node" + index; info.AddValue( nodeIndex,n,typeof(Node) ); index ++; } // Now we store the parent reference. if ( m_parentSerialize ) info.AddValue("NodeParent",m_parent,typeof(Node) ); } The problem now is that

            N Offline
            N Offline
            Neil Van Note
            wrote on last edited by
            #5

            I could be off the mark here but couldn't you just let serialization happen naturally and mark the fields in the graph that you don't want serialized with [NonSerialized()]? Regards

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups