示例#1
0
        /// <summary>
        /// Register serialization & deserialization mechanisms for transmitting the given class by ID.
        /// The given class does not need to implements its own serialization logic.
        /// </summary>
        public static void RegisterSerializerAndDeserializer(Type type)
        {
            int id = NetworkableId <Type> .ToId(type);

            Debug.Log("Using id " + id + " for tagging of class " + type.Name + " in network messages when sending/receiving NetworkableById types");

            // Construct SerializerAndDeserializer<type>

            Type serializerAndDeserializerType            = typeof(SerializerAndDeserializer <>);
            Type serializerAndDeserializerTypeSpecialized = serializerAndDeserializerType.MakeGenericType(type);

            // Find a method Serialize(StreamBuffer, object) in SerializerAndDeserializer<type>

            MethodInfo serializeMethodInfo = serializerAndDeserializerTypeSpecialized.GetMethod("Serialize", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public, null, new Type[] { typeof(StreamBuffer), typeof(object) }, null);

            Assert.IsNotNull(serializeMethodInfo, "Unable to find virtual Serialize(StreamBuffer, object) method in " + serializerAndDeserializerTypeSpecialized.Name);
            SerializeStreamMethod serializer = (SerializeStreamMethod)Delegate.CreateDelegate(typeof(SerializeStreamMethod), serializeMethodInfo);

            // Find a method Deserialize(StreamBuffer, short) in SerializerAndDeserializer<type>

            MethodInfo deserializeMethodInfo = serializerAndDeserializerTypeSpecialized.GetMethod("Deserialize", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public, null, new Type[] { typeof(StreamBuffer), typeof(short) }, null);

            Assert.IsNotNull(serializeMethodInfo, "Unable to find static Deserialize(StreamBuffer, short) method in " + serializerAndDeserializerTypeSpecialized.Name);
            DeserializeStreamMethod deserializer = (DeserializeStreamMethod)Delegate.CreateDelegate(typeof(DeserializeStreamMethod), deserializeMethodInfo);

            // Register serializer and deserializer methods for class

            bool success = PhotonPeer.RegisterType(type, (byte)id, serializer, deserializer);

            Assert.IsTrue(success, "Failed registering new serialization type for " + type.Name + " with code " + id);
        }
示例#2
0
        public void TearDown()
        {
            // Unregister Photon serializer/deserializer callbacks for the types

            PhotonRegisterSerializers registerSerializers = new PhotonRegisterSerializers();

            registerSerializers.DeregisterSerializer(typeof(NullMembers));
            registerSerializers.DeregisterSerializer(typeof(ConcreteChildById));
            registerSerializers.DeregisterSerializer(typeof(AbstractBaseById));
            registerSerializers.DeregisterSerializer(typeof(ConcreteChildByValue));
            registerSerializers.DeregisterSerializer(typeof(AbstractBaseByValue));

            // Deregister types & destroy type registries

            NetworkableId <Type> .Remove(typeof(NullMembers));

            NetworkableId <Type> .Remove(typeof(AbstractBaseById));

            NetworkableId <Type> .Remove(typeof(ConcreteChildById));

            NetworkableId <AbstractBaseById> .Destroy();

            NetworkableId <ConcreteChildById> .Destroy();

            NetworkableIdRegistry.DestroyRootRegistry(typeof(AbstractBaseById));

            NetworkableId <Type> .Remove(typeof(AbstractBaseByValue));

            NetworkableId <Type> .Remove(typeof(ConcreteChildByValue));

            NetworkableId <Type> .Destroy();

            NetworkableIdRegistry.DestroyRootRegistry(typeof(Type));
        }
示例#3
0
    public void DeregisterSerializer(Type type)
    {
        // Photon 1.80 lacks a Photon.DeregisterType() function. This undoes the actions of Photon.RegisterType() as implemented in Photon 1.80.

        byte typeId = (byte)NetworkableId <Type> .ToId(type);

        // Invoke Protocol.CodeDict.Remove(typeId)
        FieldInfo codeDictField = typeof(Protocol).GetField("CodeDict", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);

        Assert.IsNotNull(codeDictField, "Photon internals have changed; Protocol.CodeDict no longer exists");
        object codeDict = codeDictField.GetValue(null);

        Assert.IsNotNull(codeDict, "Photon internals have changed; Protocol.CodeDict no longer exists");
        MethodInfo codeDictRemoveMethodInfo = codeDict.GetType().GetMethod("Remove");

        Assert.IsNotNull(codeDictRemoveMethodInfo, "Photon internals have changed; Protocol.CodeDict is no longer a Dictionary");
        codeDictRemoveMethodInfo.Invoke(codeDict, new object[] { (byte)typeId });

        // Invoke Protocol.TypeDict.Remove(typeId)
        FieldInfo typeDictField = typeof(Protocol).GetField("TypeDict", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);

        Assert.IsNotNull(typeDictField, "Photon internals have changed; Protocol.TypeDict no longer exists");
        object typeDict = typeDictField.GetValue(null);

        Assert.IsNotNull(typeDict, "Photon internals have changed; Protocol.TypeDict no longer exists");
        MethodInfo typeDictRemoveMethodInfo = typeDict.GetType().GetMethod("Remove");

        Assert.IsNotNull(typeDictRemoveMethodInfo, "Photon internals have changed; Protocol.TypeDict is no longer a Dictionary");
        typeDictRemoveMethodInfo.Invoke(typeDict, new object[] { type });
    }
示例#4
0
        public void SetUp()
        {
            NetworkableId <Type> .Create(null);

            // Assign IDs for all networkable types

            NetworkableId <Type> .AddWithId(typeof(AbstractBaseByValue), 128);

            NetworkableId <Type> .AddWithId(typeof(ConcreteChildByValue), 129);

            NetworkableId <Type> .AddWithId(typeof(AbstractBaseById), 130);

            NetworkableId <Type> .AddWithId(typeof(ConcreteChildById), 131);

            NetworkableId <Type> .AddWithId(typeof(NullMembers), 132);

            // Items that get networked by ID need to have an ID hierarchy setup

            NetworkableId <AbstractBaseById> .Create(null);

            NetworkableId <ConcreteChildById> .Create(typeof(AbstractBaseById));

            // Register Photon serializer/deserializer callbacks for the types

            PhotonRegisterSerializers registerSerializers = new PhotonRegisterSerializers();

            registerSerializers.RegisterSerializersForDefaultObjectType(typeof(AbstractBaseByValue));
            registerSerializers.RegisterSerializersForValueType(typeof(ConcreteChildByValue));
            registerSerializers.RegisterSerializersForDefaultObjectType(typeof(AbstractBaseById));
            registerSerializers.RegisterSerializersForIdType(typeof(ConcreteChildById));
            registerSerializers.RegisterSerializersForValueType(typeof(NullMembers));
        }
示例#5
0
        /// <summary>
        /// Register serialization & deserialization mechanisms for transmitting an abstract base class by value.
        /// The given class does not need to implements its own serialization logic.
        /// </summary>
        public static void RegisterSerializerAndDeserializer(Type type)
        {
            int id = NetworkableId <Type> .ToId(type);

            Debug.Log("Using id " + id + " for tagging of class " + type.Name + " in network messages when sending/receiving NetworkableByValue types");

            bool success = PhotonPeer.RegisterType(type, (byte)id, SerializerAndDeserializer.Serialize, SerializerAndDeserializer.Deserialize);

            Assert.IsTrue(success, "Failed registering new serialization type for " + type.Name + " with code " + id);
        }
示例#6
0
            public static short Serialize(StreamBuffer outBuffer, object customObject)
            {
                int length = 0;
                T   obj    = (T)customObject;
                int id     = NetworkableId <T> .ToId(obj);

                Protocol.Serialize(id, serializationBuffer, ref length);
                outBuffer.Write(serializationBuffer, 0, length);
                Debug.Log("Serializing object of type " + typeof(T).Name + " with id " + id);
                return((short)length);
            }
示例#7
0
            public static object Deserialize(StreamBuffer inBuffer, short length)
            {
                inBuffer.Read(deserializationBuffer, 0, deserializationBuffer.Length);

                int offset = 0;
                int id;

                Protocol.Deserialize(out id, deserializationBuffer, ref offset);
                Debug.Log("Deserializing object of type " + typeof(T).Name + " with id " + id);
                T obj = NetworkableId <T> .FromId(id);

                return(obj);
            }
示例#8
0
        public void TestSerializationByIdBaseType()
        {
            ConcreteChildById concreteObj = new ConcreteChildById(12345678, 87654321);

            NetworkableId <ConcreteChildById> .Add(concreteObj);

            byte[]            buffer       = Protocol.Serialize((AbstractBaseById)concreteObj);
            ConcreteChildById concreteObj2 = (ConcreteChildById)Protocol.Deserialize(buffer);

            Assert.That(concreteObj2, Is.EqualTo(concreteObj));

            NetworkableId <ConcreteChildById> .Remove(concreteObj);
        }
示例#9
0
 static void RegisterNetworkableId(Type type, int id)
 {
     NetworkableId <Type> .AddWithId(type, id);
 }
示例#10
0
    public static void Initialize(NetworkableSettings networkableSettings, RegisterSerializers registerSerializers)
    {
        Assembly currAssembly = Assembly.GetExecutingAssembly();

        Dictionary <Type, Type> typeToRoot = new Dictionary <Type, Type>();

        List <Type> networkable = new List <Type>();
        List <Type> roots       = new List <Type>();
        List <Type> children    = new List <Type>();
        List <Type> needsDefaultObjectSerializers = new List <Type>();
        List <Type> needsReferenceSerializers     = new List <Type>();
        List <Type> needsValueSerializers         = new List <Type>();

        List <Type> loadResourcesAndInitializeIds = new List <Type>();

        foreach (Type type in currAssembly.GetTypes())
        {
            object[] attributesWithInheritance = type.GetCustomAttributes(true);
            bool     isNetworkableById         = Array.Exists <object>(attributesWithInheritance, attribute => attribute is NetworkableById);
            bool     isNetworkableByValue      = Array.Exists <object>(attributesWithInheritance, attribute => attribute is NetworkableByValue);
            bool     isNetworkable             = (isNetworkableById || isNetworkableByValue);

            Assert.IsFalse(isNetworkableById && isNetworkableByValue, "Class " + type.FullName + " is tagged both as NetworkableByValue and NetworkableById. This is not supported.");

            object[] baseAttributesWithInheritance = (type.BaseType != null ? type.BaseType.GetCustomAttributes(true) : new object[0]);
            bool     isBaseNetworkableById         = Array.Exists <object>(baseAttributesWithInheritance, attribute => attribute is NetworkableById);
            bool     isBaseNetworkableByValue      = Array.Exists <object>(baseAttributesWithInheritance, attribute => attribute is NetworkableByValue);
            bool     isBaseNetworkable             = (isBaseNetworkableById || isBaseNetworkableByValue);

            bool isNetworkableRoot = (isNetworkable && !isBaseNetworkable);

            if (isNetworkable)
            {
                networkable.Add(type);

                if (isNetworkableRoot)
                {
                    roots.Add(type);
                }
                else
                {
                    children.Add(type);
                }

                if (isNetworkableByValue && !type.IsAbstract)
                {
                    needsValueSerializers.Add(type);
                }
                else if (isNetworkableById)
                {
                    needsReferenceSerializers.Add(type);
                }
                else
                {
                    needsDefaultObjectSerializers.Add(type);
                }

                if (isNetworkableById && isNetworkableRoot)
                {
                    loadResourcesAndInitializeIds.Add(type);
                }
            }
        }

        foreach (Type type in networkable)
        {
            Type root = type;
            while (!roots.Exists(rootEntry => rootEntry == root))
            {
                root = root.BaseType;
            }

            typeToRoot[type] = root;
        }

        NetworkableId <Type> .Create(null);

        Debug.Log("========= register networkable classes =====");

        RegisterNetworkableTypes(networkable, networkableSettings.PersistentTypeIds);

        Debug.Log("========= setup NetworkableId registries for root classes =====");

        foreach (Type root in roots)
        {
            RegisterNetworkableIdHierarchy(root, null);
        }

        Debug.Log("========= set Networkableid registries for child classes =====");

        foreach (Type child in children)
        {
            RegisterNetworkableIdHierarchy(child, typeToRoot[child]);
        }

        Debug.Log("========= register byValue serializers =====");

        foreach (Type type in needsValueSerializers)
        {
            registerSerializers.RegisterSerializersForValueType(type);
        }

        Debug.Log("========= register byId serializers =====");

        foreach (Type type in needsReferenceSerializers)
        {
            registerSerializers.RegisterSerializersForIdType(type);
        }

        Debug.Log("========= register default-object serializers =====");

        foreach (Type type in needsDefaultObjectSerializers)
        {
            registerSerializers.RegisterSerializersForDefaultObjectType(type);
        }

        Debug.Log("========= register assets that are by-id and present in asset database =====");

        RegisterNetworkableAssets(networkableSettings.PersistentAssetIds);
    }