I've been looking into whether anyone has found any documentation or figured out how to get object pooling to work with AoT compilation (which is required for iOS and WebGL for Unity) to work.
I've found this answer from Marc Gravell here, which describes how to get the factory to use your object pool, but this doesn't seem to work if you're using the AoT precompiler and calling code like this:
public static T DeserializeProtoObject<T>(byte[] bytes)
{
using (MemoryStream m = new MemoryStream(bytes))
{
return (T)m_serializer.DeserializeWithLengthPrefix(m, null, typeof(T),ProtoBuf.PrefixStyle.Fixed32,0);
}
}
where m_serializer was created with the precompiler using code that looks like:
var model = TypeModel.Create();
model.Add(typeof(PlayerUpdate), true);
model.AllowParseableTypes = true;
model.AutoAddMissingTypes = true;
model.Compile("IOGameProtoBufSerializer", "IOGameProtoBufSerializer.dll");
It looks like model has a SetDefaultFactory() function, but I'm not sure how to use it. Any tips from those in the know?
My next step is to download the source and dig through that.
Thanks for any help.
Edit: looks like I found the example source after downloading the full protobuf-net repo from here: https://github.com/mgravell/protobuf-net
For those who want to do the same thing here is the actual source showing an example of how to use the default constructor:
using Xunit;
using ProtoBuf;
using ProtoBuf.Meta;
using System;
using System.Threading;
using System.Reflection;
namespace Examples.Issues
{
public class SO14532116
{
[Fact]
public void Execute()
{
var model = TypeModel.Create();
model.AutoCompile = false;
model.SetDefaultFactory(typeof(SO14532116).GetMethod("ObjectMaker"));
int oldCount = Count;
Test(model, "Runtime");
model.CompileInPlace();
Test(model, "CompileInPlace");
Test(model.Compile(), "CompileInPlace");
model.Compile("SO14532116", "SO14532116.dll");
PEVerify.AssertValid("SO14532116.dll");
int newCount = Count;
Assert.Equal(oldCount + 3, newCount);
}
[ProtoContract]
public class Foo
{
[ProtoMember(1)]
public int X {get;set;}
public static Foo Create(int x = 0)
{
return new Foo(x);
}
public Foo(int x) { X = x; }
}
private void Test(TypeModel model, string p)
{
var obj = Foo.Create(123);
int oldCount = Count;
var clone = (Foo)model.DeepClone(obj);
int newCount = Count;
Assert.Equal(oldCount + 1, newCount);
Assert.Equal(123, clone.X);
}
private static int count;
public static int Count
{
get { return Interlocked.CompareExchange(ref count, 0, 0); }
}
public static object ObjectMaker(Type type)
{
object obj;
if(type == typeof(Foo))
{
obj = Foo.Create();
} else {
obj = Activator.CreateInstance(type);
}
Interlocked.Increment(ref count);
return obj;
}
}
}