Author Topic: OnNetworkRead/WriteObject? Serializable support  (Read 2595 times)

toqueteos

  • Newbie
  • *
  • Thank You
  • -Given: 4
  • -Receive: 0
  • Posts: 13
    • View Profile
OnNetworkRead/WriteObject? Serializable support
« on: December 09, 2013, 12:47:32 PM »
Is there any way to define/implement an interface on a class/enum/struct so it can be sent through TNet?

I've searched on the forums but found just two posts, one reveals nothing, the other says enums must be sent as string/int and ensure they are properly casted back and forth.
« Last Edit: December 10, 2013, 06:09:11 PM by toqueteos »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Serializable support
« Reply #1 on: December 10, 2013, 01:34:13 AM »
Yup you can add it to the list of supported data types. Look inside TNUnityTools.cs:

CanBeSerialized, WriteObject, ReadObject

toqueteos

  • Newbie
  • *
  • Thank You
  • -Given: 4
  • -Receive: 0
  • Posts: 13
    • View Profile
Re: Serializable support
« Reply #2 on: December 10, 2013, 11:05:14 AM »
Yup you can add it to the list of supported data types. Look inside TNUnityTools.cs:

CanBeSerialized, WriteObject, ReadObject
Mmm.. Not what I was expecting but it works. Thanks Aren.

Any chances of getting support for something like Unity's builtin OnSerializeNetworkView in the future?

EDIT: CanBeSerialized and WriteObject already do check typeof whatever is passed in, something like this interface should be easy to adapt.

Wherever you like, inside TNet namespace:
  1. public interface TNSerializable
  2. {
  3.     object OnNetworkReadObject(BinaryReader br);
  4.     void OnNetworkWriteObject(BinaryWriter bw);
  5. }

CanBeSerialized:
  1. if (type == typeof(TNSerializable)) return true;
  2. if (type == typeof(TNSerializable[])) return true;

WriteObject:
  1. else if (type == typeof(TNSerializable))
  2. {
  3.     bw.Write('z');
  4.     tns.OnNetworkWriteObject(bw);
  5. }
  6. else if (type == typeof(TNSerializable[]))
  7. {
  8.     TNSerializable[] arr = (TNSerializable[])obj;
  9.     bw.Write('Z');
  10.     bw.Write(arr.Length);
  11.     for (int i = 0, imax = arr.Length; i < imax; ++i) arr[i].OnNetworkWriteObject(bw);
  12. }

I'm stuck on the reading part.

ReadObject:
  1. case 'z':
  2. {
  3.     // If only we could just call whatever.OnNetworkReadObject(br).
  4.     // We don't know what to read from here:
  5.     ??? bytes = reader.Read???();
  6.     TNSerializable tns = (TNSerializable)bytes; // Will this work? Probably not.
  7.     obj = tns;
  8.     break;
  9. }
  10. case 'Z':
  11. {
  12.     int elements = reader.ReadInt32();
  13.     TNSerializable[] arr = new TNSerializable[elements];
  14.     for (int b = 0; b < elements; ++b) arr[b] = ???
  15.     obj = arr;
  16.     break;
  17. }

« Last Edit: December 10, 2013, 06:15:15 PM by toqueteos »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: OnNetworkRead/WriteObject? Serializable support
« Reply #3 on: December 10, 2013, 11:31:25 PM »
No, it won't work. You need to write out your class/struct each simple data type at a time, and then read it back exactly the same -- just like I did with everything else in that file.

You'd have to do exact same thing with OnSerializeNetworkView.

I recommend just using RFC calls instead. If your struct contains an int, a bool, and a string, your RFC would look like:
  1. [RFC] void MyFunc (int a, bool b, string c) { ... }