forked from cgvr/DeltaVR
		
	
		
			
				
	
	
		
			121 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using FishNet.CodeGenerating.Helping.Extension;
 | 
						|
using FishNet.CodeGenerating.Processing;
 | 
						|
using FishNet.Object.Synchronizing;
 | 
						|
using FishNet.Object.Synchronizing.Internal;
 | 
						|
using MonoFN.Cecil;
 | 
						|
using MonoFN.Cecil.Rocks;
 | 
						|
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
 | 
						|
namespace FishNet.CodeGenerating.Helping
 | 
						|
{
 | 
						|
    internal class CreatedSyncVarGenerator : CodegenBase
 | 
						|
    {
 | 
						|
        private readonly Dictionary<string, CreatedSyncVar> _createdSyncVars = new Dictionary<string, CreatedSyncVar>();
 | 
						|
 | 
						|
        #region Relfection references.
 | 
						|
        private TypeReference _syncBase_TypeRef;
 | 
						|
        internal TypeReference SyncVar_TypeRef;
 | 
						|
        private MethodReference _syncVar_Constructor_MethodRef;
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Const.
 | 
						|
        private const string GETVALUE_NAME = "GetValue";
 | 
						|
        private const string SETVALUE_NAME = "SetValue";
 | 
						|
        #endregion
 | 
						|
 | 
						|
        /* //feature add and test the dirty boolean changes
 | 
						|
         * eg... instead of base.Dirty()
 | 
						|
         * do if (!base.Dirty()) return false;
 | 
						|
         * See synclist for more info. */
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Imports references needed by this helper.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="moduleDef"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        public override bool ImportReferences()
 | 
						|
        {
 | 
						|
            SyncVar_TypeRef = base.ImportReference(typeof(SyncVar<>)); 
 | 
						|
            MethodDefinition svConstructor = SyncVar_TypeRef.GetFirstConstructor(base.Session, true);
 | 
						|
            _syncVar_Constructor_MethodRef = base.ImportReference(svConstructor);
 | 
						|
 | 
						|
            Type syncBaseType = typeof(SyncBase);
 | 
						|
            _syncBase_TypeRef = base.ImportReference(syncBaseType);
 | 
						|
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets and optionally creates data for SyncVar<typeOfField>
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="dataTr"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        internal CreatedSyncVar GetCreatedSyncVar(FieldDefinition originalFd, bool createMissing)
 | 
						|
        {
 | 
						|
            TypeReference dataTr = originalFd.FieldType;
 | 
						|
            TypeDefinition dataTd = dataTr.CachedResolve(base.Session);
 | 
						|
 | 
						|
            string typeHash = dataTr.FullName + dataTr.IsArray.ToString();
 | 
						|
 | 
						|
            if (_createdSyncVars.TryGetValue(typeHash, out CreatedSyncVar createdSyncVar))
 | 
						|
            {
 | 
						|
                return createdSyncVar;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                if (!createMissing)
 | 
						|
                    return null;
 | 
						|
 | 
						|
                base.ImportReference(dataTd);
 | 
						|
 | 
						|
                GenericInstanceType syncVarGit = SyncVar_TypeRef.MakeGenericInstanceType(new TypeReference[] { dataTr });
 | 
						|
                TypeReference genericDataTr = syncVarGit.GenericArguments[0];
 | 
						|
 | 
						|
                //Make sure can serialize.
 | 
						|
                bool canSerialize = base.GetClass<GeneralHelper>().HasSerializerAndDeserializer(genericDataTr, true);
 | 
						|
                if (!canSerialize)
 | 
						|
                {
 | 
						|
                    base.LogError($"SyncVar {originalFd.Name} data type {genericDataTr.FullName} does not support serialization. Use a supported type or create a custom serializer.");
 | 
						|
                    return null;
 | 
						|
                }
 | 
						|
 | 
						|
                //Set needed methods from syncbase.
 | 
						|
                MethodReference setSyncIndexMr;
 | 
						|
                MethodReference genericSyncVarCtor = _syncVar_Constructor_MethodRef.MakeHostInstanceGeneric(base.Session, syncVarGit);
 | 
						|
 | 
						|
                if (!base.GetClass<NetworkBehaviourSyncProcessor>().SetSyncBaseMethods(_syncBase_TypeRef.CachedResolve(base.Session), out setSyncIndexMr, out _))
 | 
						|
                    return null;
 | 
						|
 | 
						|
                MethodReference setValueMr = null;
 | 
						|
                MethodReference getValueMr = null;
 | 
						|
                foreach (MethodDefinition md in SyncVar_TypeRef.CachedResolve(base.Session).Methods)
 | 
						|
                {
 | 
						|
                    //GetValue.
 | 
						|
                    if (md.Name == GETVALUE_NAME)
 | 
						|
                    {
 | 
						|
                        MethodReference mr = base.ImportReference(md);
 | 
						|
                        getValueMr = mr.MakeHostInstanceGeneric(base.Session, syncVarGit);
 | 
						|
                    }
 | 
						|
                    //SetValue.
 | 
						|
                    else if (md.Name == SETVALUE_NAME)
 | 
						|
                    {
 | 
						|
                        MethodReference mr = base.ImportReference(md);
 | 
						|
                        setValueMr = mr.MakeHostInstanceGeneric(base.Session, syncVarGit);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                if (setValueMr == null || getValueMr == null)
 | 
						|
                    return null;
 | 
						|
 | 
						|
                CreatedSyncVar csv = new CreatedSyncVar(syncVarGit, dataTd, getValueMr, setValueMr, setSyncIndexMr, null, genericSyncVarCtor);
 | 
						|
                _createdSyncVars.Add(typeHash, csv);
 | 
						|
                return csv;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
} |