Comments (2)
Unfortunately, generics of value types are poorly supported in Unity runtime itself. Using subclass like Int32List : List<int>
might help you.
from msgpack-cli.
Thank you for your advice.
Temporarily I make such a solution. I write it here, maybe would helpful to other man.
For this class:
public class MyData
{
public List<int> a = new List<int>();
//ryaku
}
①First, write a Serializer class ,
public class ListintSerializer : MsgPack.Serialization.MessagePackSerializer<List<int>>
{
public ListintSerializer(SerializationContext ownerContext)
: base(ownerContext)
{
}
protected override void PackToCore(Packer packer, List<int> objectTree0)
{
int[] objectTree = objectTree0.ToArray();
packer.PackArrayHeader(objectTree.Length);
foreach (var item in objectTree)
{
packer.Pack(item);
}
}
protected override List<int> UnpackFromCore(Unpacker unpacker)
{
if (!unpacker.IsArrayHeader)
{
throw SerializationExceptions.NewIsNotArrayHeader();
}
var count = UnpackHelpers.GetItemsCount(unpacker);
var result = new System.Int32[count];
if (!unpacker.IsArrayHeader)
{
throw SerializationExceptions.NewIsNotArrayHeader();
}
for (int i = 0; i < count; i++)
{
System.Int32 item;
if (!unpacker.ReadInt32(out item))
{
throw SerializationExceptions.NewMissingItem(i);
}
result[i] = item;
}
return new List<int>(result);
}
}
Now, once system encode/decode List<int> it will call pack/unpack method written by ourself, this avoid the disadvantages of Unity(IOS platform) poor generic support.
②Then, we register these serializers.
SerializationContext _context = new SerializationContext();
_context.Serializers.RegisterOverride(new ListintSerializer(_context));
_context.Serializers.RegisterOverride(new MyDataSerializerByMpuEXE(_context));
The MyDataSerializerByMpuEXE class was generated by mpu.exe as this↓
mono mpu.exe -s ${path_of_MyData_cs}
Encode/decode of primitive types are similar.
I wrote ListdoubleSerializer,ListfloatSerializer,ListlongSerializer,ListstringSerializer in the same way.
The key is the pack & unpack method, for example , to Long type there is the code:
protected override void PackToCore(Packer packer, List<long> objectTree0)
{
long[] objectTree = objectTree0.ToArray();
packer.PackArrayHeader(objectTree.Length);
foreach (var item in objectTree)
{
packer.Pack(item);
}
}
protected override List<long> UnpackFromCore(Unpacker unpacker)
{
if (!unpacker.IsArrayHeader)
{
throw SerializationExceptions.NewIsNotArrayHeader();
}
var count = UnpackHelpers.GetItemsCount(unpacker);
var result = new System.Int64[count];
if (!unpacker.IsArrayHeader)
{
throw SerializationExceptions.NewIsNotArrayHeader();
}
for (int i = 0; i < count; i++)
{
System.Int64 item;
if (!unpacker.ReadInt64(out item))
{
throw SerializationExceptions.NewMissingItem(i);
}
result[i] = item;
}
return new List<long>(result);
}
If the generic type is an class(not primitive type ), code has a little different.
For this class:
public class MyData2
{
public List<innerData> a = new List<innerData>();
public class innerData
{
public List<int> a = new List<int>();
public innerData(){}
}
}
The serialize would be look like this:
public class ListMyData2_innerDataSerializer : MsgPack.Serialization.MessagePackSerializer<List<MyData2.innerData>>
{
public ListMyData2_innerDataSerializer(SerializationContext ownerContext)
: base(ownerContext)
{
}
protected override void PackToCore(Packer packer, List<MyData2.innerData> objectTree0)
{
//SerializerMgr is my manger class, don't care.
MessagePackSerializer<MyData2.innerData> _itemSerializer = SerializerMgr.Instance._context.GetSerializer<MyData2.innerData>();
MyData2.innerData[] objectTree = objectTree0.ToArray();
packer.PackArrayHeader(objectTree.Length);
foreach (var item in objectTree)
{
_itemSerializer.PackTo(packer, item);
}
}
protected override List<MyData2.innerData> UnpackFromCore(Unpacker unpacker)
{
MessagePackSerializer<MyData2.innerData> _itemSerializer = SerializerMgr.Instance._context.GetSerializer<MyData2.innerData>();
if (!unpacker.IsArrayHeader)
{
throw SerializationExceptions.NewIsNotArrayHeader();
}
var count = UnpackHelpers.GetItemsCount(unpacker);
var result = new List<MyData2.innerData>();
if (!unpacker.IsArrayHeader)
{
throw SerializationExceptions.NewIsNotArrayHeader();
}
for (int i = 0; i < count; i++)
{
if (!unpacker.Read())
{
throw SerializationExceptions.NewMissingItem(i);
}
MyData2.innerData item;
if (!unpacker.IsArrayHeader && !unpacker.IsMapHeader)
{
item = _itemSerializer.UnpackFrom(unpacker);
}
else
{
using (var subtreeUnpacker = unpacker.ReadSubtree())
{
item = _itemSerializer.UnpackFrom(subtreeUnpacker);
}
}
result.Add(item);
}
return result;
}
}
Similarly, we need register our serializers.
_context.Serializers.RegisterOverride(new ListdoubleSerializer(_context));
_context.Serializers.RegisterOverride(new ListfloatSerializer(_context));
_context.Serializers.RegisterOverride(new ListintSerializer(_context));
_context.Serializers.RegisterOverride(new ListlongSerializer(_context));
_context.Serializers.RegisterOverride(new ListstringSerializer(_context));
_context.Serializers.RegisterOverride(new ListMyData2_innerDataSerializer (_context));
Thanks
shuidong
from msgpack-cli.
Related Issues (20)
- Add a non-generic override to SerializerRepository
- EnumMemberAttribute does not work. (expectedly)
- Type Object in MessagePack HOT 1
- GetMemberName() causes NullReferenceException when using MessagePackSerializer.Get<T>() in Xamarin iOS
- [Unity][il2cpp]'class' is not registered in this resolver,resolver.StandardResolver HOT 2
- How to serialize and deserialize a List member in a class HOT 2
- Problem deserializing byte array - InvalidOperationException caused by Decoders.InvalidArrayHeader.Read call HOT 4
- about LZ4 HOT 1
- Unable to cast object of type on netcore HOT 1
- Custom Serialisation docs appear to be out of date. HOT 1
- PackAsync & UnpackAsync not working when passing data continuously using for loop c# HOT 1
- The unpacked value is not expected type HOT 2
- Authenticode Signing? HOT 2
- DateTime serialization and deserialization timezone HOT 3
- Enum Deserialization Not working? HOT 1
- Serializer.Unpack Continuosly Stream of Data => High Memory Usage HOT 3
- Serialization / deserialization speed optimizations HOT 2
- Serialization field order by declaration order HOT 3
- Add additional TFM do dependencies can be optimised HOT 2
- Set additional package metadata
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from msgpack-cli.