vexe / VFW

MIT License
492 stars 67 forks source link

uAction and other delegates don't serialise using FastSave #71

Closed hymerman closed 8 years ago

hymerman commented 8 years ago

Is FastSave supposed to be able to save any kind of delegates, including VFW's own?

I tried this simple test (Under Unity 5.3.0f4; save in a file under an 'Editor' directory and use Window->Editor Test Runner), and I get an exception:

using System;
using NUnit.Framework;

namespace VFW.Tests
{
    public class VFWTests
    {

        class SerializeDelegateTestClassContainer
        {
            public Vexe.Runtime.Types.uAction actionTestMember = new Vexe.Runtime.Types.uAction();

            [NonSerialized]
            public bool actionWasCalled = false;
            public void ActionTarget() { actionWasCalled = true; }
        }

        [Test]
        public void SerializeDelegateVFW()
        {
            SerializeDelegateTestClassContainer testContainer = new SerializeDelegateTestClassContainer();
            testContainer.actionTestMember.Add(testContainer.ActionTarget);

            var serialised = Vexe.FastSave.Save.ObjectToMemory(testContainer);

            var deserialised = Vexe.FastSave.Load.ObjectFromMemory<SerializeDelegateTestClassContainer>(serialised);

            Assert.NotNull(deserialised);
            Assert.NotNull(deserialised.actionTestMember);

            deserialised.actionTestMember.Invoke();

            Assert.AreEqual(true, deserialised.actionWasCalled);
        }
    }
}

The exception:

System.Exception : Generating constructor for type: System.Reflection.MonoMethodNo empty constructor found!

---
at Vexe.Runtime.Extensions.FastReflection.GenCtor[Object] (System.Type type, System.Type[] paramTypes) [0x00074] in F:\projects\TestSerialization\TestSerialization\Assets\VFW\Plugins\Vexe\Runtime\Library\Extensions\FastReflection.cs:322
at Vexe.Runtime.Extensions.FastReflection.DelegateForCtor[Object] (System.Type type, System.Type[] paramTypes) [0x00082] in F:\projects\TestSerialization\TestSerialization\Assets\VFW\Plugins\Vexe\Runtime\Library\Extensions\FastReflection.cs:49
at Vexe.Runtime.Extensions.FastReflection.DelegateForCtor (System.Type type, System.Type[] ctorParamTypes) [0x00000] in F:\projects\TestSerialization\TestSerialization\Assets\VFW\Plugins\Vexe\Runtime\Library\Extensions\FastReflection.cs:61
at BX20Serializer.ReflectiveSerializer.GetInstance (System.IO.Stream stream, System.Type type) [0x00000] in F:\projects\TestSerialization\TestSerialization\Assets\VFW\Plugins\Vexe\Runtime\FastSave\Serializer\BinaryX20\Serializers\ReflectiveSerializer.cs:17
at BX20Serializer.BinaryX20.Deserialize_Standard (System.IO.Stream stream, System.Type type, System.Object& instance) [0x000d4] in F:\projects\TestSerialization\TestSerialization\Assets\VFW\Plugins\Vexe\Runtime\FastSave\Serializer\BinaryX20\BinaryX20.cs:519
... etc ...
vexe commented 8 years ago

No not really. It's not really worth the extra complexity. Most if not all the times I found myself in a much better position just reconnecting the delegates values in initialization. In-inspector delegates are over-rated imo (good luck rewiring everything after Unity screws up your .scene files...)

That said, you could write a custom serializer for e.g. a VFW delegate and serialize the MethodInfo like this https://github.com/vexe/FastSerializer/blob/master/FastSerializer/Serializers/MetadataSerializers.cs - but the tricky part is always the 'target' object, because it could be a UnityEngine.Object (e.g. a MonoBehaviour) - what do you do then? ... you'd have to have some kind of storage of MonoBehaviours where each has a unique Id and [de]serialize the id. I believe I'm doing something similar in order to persist in-scene references so you could check that out as well.

hymerman commented 8 years ago

Fair enough, thanks for the pointers!

I'll try to do this since I have the whole game state under one object, and certain sub-objects have delegates that call methods on other sub-objects (as scheduled events), which would be difficult to hook up again.