예제 #1
0
        public static LambdaParamaterValueProviderInformation ElementProviderInformationFor(
            LambdaJobDescriptionConstruction lambdaJobDescriptionConstruction, ParameterDefinition parameter, bool withStructuralChanges)
        {
            var moduleDefinition = lambdaJobDescriptionConstruction.ContainingMethod.Module;

            (TypeReference provider, TypeReference providerRuntime) ImportReferencesFor(Type providerType, Type runtimeType, TypeReference typeOfT)
            {
                var provider = moduleDefinition
                               .ImportReference(providerType)
                               .MakeGenericInstanceType(typeOfT);
                var providerRuntime = moduleDefinition.ImportReference(runtimeType).MakeGenericInstanceType(typeOfT);

                return(provider, providerRuntime);
            }

            var parameterType         = parameter.ParameterType;
            var resolvedParameterType = parameterType.Resolve();

            // IComponentData
            if (resolvedParameterType.IsIComponentDataStruct())
            {
                var readOnly = !parameter.ParameterType.IsByReference || HasCompilerServicesIsReadOnlyAttribute(parameter);

                if (resolvedParameterType.IsTagComponentDataStruct())
                {
                    var(provider, providerRuntime) =
                        ImportReferencesFor(
                            typeof(LambdaParameterValueProvider_IComponentData_Tag <>),
                            typeof(LambdaParameterValueProvider_IComponentData_Tag <> .Runtime), parameter.ParameterType.GetElementType());
                    return(new LambdaParamaterValueProviderInformation(provider, providerRuntime, readOnly, parameter.Name, null, false));
                }
                else
                {
                    var(provider, providerRuntime) =
                        ImportReferencesFor(
                            typeof(LambdaParameterValueProvider_IComponentData <>),
                            withStructuralChanges
                                ? typeof(LambdaParameterValueProvider_IComponentData <> .StructuralChangeRuntime)
                            : typeof(LambdaParameterValueProvider_IComponentData <> .Runtime), parameter.ParameterType.GetElementType());
                    return(new LambdaParamaterValueProviderInformation(provider, providerRuntime, readOnly, parameter.Name, null, withStructuralChanges));
                }
            }

            // class IComponentData / UnityEngine.Object
            if (resolvedParameterType.IsIComponentDataClass() || resolvedParameterType.IsUnityEngineObject())
            {
                if (lambdaJobDescriptionConstruction.UsesBurst || lambdaJobDescriptionConstruction.ExecutionMode == ExecutionMode.Schedule)
                {
                    UserError.DC0023(lambdaJobDescriptionConstruction.ContainingMethod, parameterType, lambdaJobDescriptionConstruction.WithCodeInvocationInstruction).Throw();
                }

                bool readOnly = false;
                if (parameter.ParameterType.IsByReference)
                {
                    if (HasCompilerServicesIsReadOnlyAttribute(parameter))
                    {
                        readOnly = true;
                    }
                    else
                    {
                        UserError.DC0024(lambdaJobDescriptionConstruction.ContainingMethod, parameterType, lambdaJobDescriptionConstruction.WithCodeInvocationInstruction).Throw();
                    }
                }

                var(provider, providerRuntime) = ImportReferencesFor(typeof(LambdaParameterValueProvider_ManagedComponentData <>),
                                                                     withStructuralChanges
                        ? typeof(LambdaParameterValueProvider_ManagedComponentData <> .StructuralChangeRuntime)
                        : typeof(LambdaParameterValueProvider_ManagedComponentData <> .Runtime), parameter.ParameterType.GetElementType());
                return(new LambdaParamaterValueProviderInformation(provider, providerRuntime, readOnly, parameter.Name, parameter.ParameterType.GetElementType()));
            }

            // DynamicBuffer<T>
            if (resolvedParameterType.IsDynamicBufferOfT())
            {
                TypeReference typeRef = parameterType;
                if (parameterType is ByReferenceType referenceType)
                {
                    typeRef = referenceType.ElementType;
                }

                GenericInstanceType bufferOfT         = (GenericInstanceType)typeRef;
                TypeReference       bufferElementType = bufferOfT.GenericArguments[0];
                var(provider, providerRuntime) = ImportReferencesFor(typeof(LambdaParameterValueProvider_DynamicBuffer <>),
                                                                     withStructuralChanges
                        ? typeof(LambdaParameterValueProvider_DynamicBuffer <> .StructuralChangeRuntime)
                        : typeof(LambdaParameterValueProvider_DynamicBuffer <> .Runtime), bufferElementType);
                return(new LambdaParamaterValueProviderInformation(provider, providerRuntime, false, parameter.Name));
            }

            // ISharedComponent
            if (resolvedParameterType.IsISharedComponentData())
            {
                if (lambdaJobDescriptionConstruction.ExecutionMode != ExecutionMode.Run || lambdaJobDescriptionConstruction.UsesBurst)
                {
                    UserError.DC0019(lambdaJobDescriptionConstruction.ContainingMethod, parameter.ParameterType.GetElementType(), lambdaJobDescriptionConstruction.WithCodeInvocationInstruction).Throw();
                }

                if (!parameter.HasCompilerServicesIsReadOnlyAttribute() && parameter.ParameterType.IsByReference)
                {
                    UserError.DC0020(lambdaJobDescriptionConstruction.ContainingMethod, parameter.ParameterType.GetElementType(), lambdaJobDescriptionConstruction.WithCodeInvocationInstruction).Throw();
                }

                var(provider, providerRuntime) = ImportReferencesFor(typeof(LambdaParameterValueProvider_ISharedComponentData <>),
                                                                     withStructuralChanges
                        ? typeof(LambdaParameterValueProvider_ISharedComponentData <> .StructuralChangeRuntime)
                        : typeof(LambdaParameterValueProvider_ISharedComponentData <> .Runtime), parameter.ParameterType.GetElementType());
                var newProvider = new LambdaParamaterValueProviderInformation(provider, providerRuntime, false, parameter.Name, parameter.ParameterType.GetElementType(), withStructuralChanges);

                return(newProvider);
            }

            if (resolvedParameterType.TypeReferenceEquals(moduleDefinition.ImportReference(typeof(Entity))))
            {
                var provider = moduleDefinition.ImportReference(typeof(LambdaParameterValueProvider_Entity));
                var runtime  = withStructuralChanges
                    ? moduleDefinition.ImportReference(typeof(LambdaParameterValueProvider_Entity.StructuralChangeRuntime))
                    : moduleDefinition.ImportReference(typeof(LambdaParameterValueProvider_Entity.Runtime));

                return(new LambdaParamaterValueProviderInformation(provider, runtime, true, parameter.Name, null, withStructuralChanges));
            }

            if (resolvedParameterType.FullName == moduleDefinition.TypeSystem.Int32.FullName)
            {
                var    allNames = new[] { "entityInQueryIndex", "nativeThreadIndex" };
                string entityInQueryIndexName = allNames[0];
                string nativeThreadIndexName  = allNames[1];

                if (parameter.Name == entityInQueryIndexName)
                {
                    var provider = moduleDefinition.ImportReference(typeof(LambdaParameterValueProvider_EntityInQueryIndex));
                    var runtime  = withStructuralChanges
                        ? moduleDefinition.ImportReference(typeof(LambdaParameterValueProvider_EntityInQueryIndex.StructuralChangeRuntime))
                        : moduleDefinition.ImportReference(typeof(LambdaParameterValueProvider_EntityInQueryIndex.Runtime));
                    return(new LambdaParamaterValueProviderInformation(provider, runtime, true, parameter.Name));
                }

                if (parameter.Name == nativeThreadIndexName)
                {
                    var provider = moduleDefinition.ImportReference(typeof(LambdaParameterValueProvider_NativeThreadIndex));
                    var runtime  = moduleDefinition.ImportReference(typeof(LambdaParameterValueProvider_NativeThreadIndex.Runtime));
#if !UNITY_DOTSPLAYER
                    var isReadonly = true;
#else
                    // Tiny's Job System currently will set the NativeThreadIndex at the beginning of the function to be Bursted.
                    // This will make Burst Compilation fail due to the NativeThreadIndex being marked as Readonly here. So for now
                    // until we workaround this issue in the Tiny Job System, we disable marking NativeThreadIndex as Readonly.
                    var isReadonly = false;
#endif
                    return(new LambdaParamaterValueProviderInformation(provider, runtime, isReadonly, parameter.Name));
                }

                UserError.DC0014(lambdaJobDescriptionConstruction.ContainingMethod, lambdaJobDescriptionConstruction.WithCodeInvocationInstruction, parameter, allNames).Throw();
            }

            if (resolvedParameterType.IsIBufferElementData())
            {
                UserError.DC0033(lambdaJobDescriptionConstruction.ContainingMethod, parameter.Name, parameter.ParameterType.GetElementType(), lambdaJobDescriptionConstruction.WithCodeInvocationInstruction).Throw();
            }

            if (!resolvedParameterType.GetElementType().IsPrimitive&& resolvedParameterType.GetElementType().IsValueType())
            {
                UserError.DC0021(lambdaJobDescriptionConstruction.ContainingMethod, parameter.Name, parameter.ParameterType.GetElementType(), lambdaJobDescriptionConstruction.WithCodeInvocationInstruction).Throw();
            }

            UserError.DC0005(lambdaJobDescriptionConstruction.ContainingMethod, lambdaJobDescriptionConstruction.WithCodeInvocationInstruction, parameter).Throw();
            return(null);
        }
예제 #2
0
        public static LambdaParamaterValueProviderInformation ElementProviderInformationFor(LambdaJobDescriptionConstruction lambdaJobDescriptionConstruction, ParameterDefinition parameter)
        {
            var moduleDefinition = lambdaJobDescriptionConstruction.ContainingMethod.Module;

            (TypeReference provider, TypeReference providerRuntime) ImportReferencesFor(Type providerType, Type runtimeType, TypeReference typeOfT)
            {
                var provider = moduleDefinition
                               .ImportReference(providerType)
                               .MakeGenericInstanceType(typeOfT);
                var providerRuntime = moduleDefinition.ImportReference(runtimeType).MakeGenericInstanceType(typeOfT);

                return(provider, providerRuntime);
            }

            var parameterType         = parameter.ParameterType;
            var resolvedParameterType = parameterType.Resolve();

            if (resolvedParameterType.IsIComponentDataStruct())
            {
                var readOnly = !parameter.ParameterType.IsByReference || HasCompilerServicesIsReadOnlyAttribute(parameter);
                var(provider, providerRuntime) = ImportReferencesFor(typeof(LambdaParameterValueProvider_IComponentData <>), typeof(LambdaParameterValueProvider_IComponentData <> .Runtime), parameter.ParameterType.GetElementType());
                return(new LambdaParamaterValueProviderInformation(provider, providerRuntime, readOnly));
            }

            if (resolvedParameterType.IsIComponentDataClass() || resolvedParameterType.IsUnityEngineObject())
            {
                if (lambdaJobDescriptionConstruction.UsesBurst)
                {
                    UserError.DC0023(lambdaJobDescriptionConstruction.ContainingMethod, parameterType, lambdaJobDescriptionConstruction.WithCodeInvocationInstruction).Throw();
                }

                bool readOnly = false;
                if (parameter.ParameterType.IsByReference)
                {
                    if (HasCompilerServicesIsReadOnlyAttribute(parameter))
                    {
                        readOnly = true;
                    }
                    else
                    {
                        UserError.DC0024(lambdaJobDescriptionConstruction.ContainingMethod, parameterType, lambdaJobDescriptionConstruction.WithCodeInvocationInstruction).Throw();
                    }
                }

                var(provider, providerRuntime) = ImportReferencesFor(typeof(LambdaParameterValueProvider_ManagedComponentData <>), typeof(LambdaParameterValueProvider_ManagedComponentData <> .Runtime), parameter.ParameterType.GetElementType());
                return(new LambdaParamaterValueProviderInformation(provider, providerRuntime, readOnly, parameter.ParameterType.GetElementType()));
            }

            if (resolvedParameterType.IsDynamicBufferOfT())
            {
                TypeReference typeRef = parameterType;
                if (parameterType is ByReferenceType referenceType)
                {
                    typeRef = referenceType.ElementType;
                }

                GenericInstanceType bufferOfT         = (GenericInstanceType)typeRef;
                TypeReference       bufferElementType = bufferOfT.GenericArguments[0];
                var(provider, providerRuntime) = ImportReferencesFor(typeof(LambdaParameterValueProvider_DynamicBuffer <>), typeof(LambdaParameterValueProvider_DynamicBuffer <> .Runtime), bufferElementType);
                return(new LambdaParamaterValueProviderInformation(provider, providerRuntime, false));
            }

            if (resolvedParameterType.IsISharedComponentData())
            {
                if (lambdaJobDescriptionConstruction.ExecutionMode != ExecutionMode.Run || lambdaJobDescriptionConstruction.UsesBurst)
                {
                    UserError.DC0019(lambdaJobDescriptionConstruction.ContainingMethod, parameter.ParameterType.GetElementType(), lambdaJobDescriptionConstruction.WithCodeInvocationInstruction).Throw();
                }

                if (!parameter.HasCompilerServicesIsReadOnlyAttribute() && parameter.ParameterType.IsByReference)
                {
                    UserError.DC0020(lambdaJobDescriptionConstruction.ContainingMethod, parameter.ParameterType.GetElementType(), lambdaJobDescriptionConstruction.WithCodeInvocationInstruction).Throw();
                }

                var(provider, providerRuntime) = ImportReferencesFor(typeof(LambdaParameterValueProvider_ISharedComponentData <>), typeof(LambdaParameterValueProvider_ISharedComponentData <> .Runtime), parameter.ParameterType.GetElementType());
                var newProvider = new LambdaParamaterValueProviderInformation(provider, providerRuntime, false, parameter.ParameterType.GetElementType());

                return(newProvider);
            }

            if (resolvedParameterType.TypeReferenceEquals(moduleDefinition.ImportReference(typeof(Entity))))
            {
                var provider = moduleDefinition.ImportReference(typeof(LambdaParameterValueProvider_Entity));
                var runtime  = moduleDefinition.ImportReference(typeof(LambdaParameterValueProvider_Entity.Runtime));

                return(new LambdaParamaterValueProviderInformation(provider, runtime, true));
            }

            if (resolvedParameterType.FullName == moduleDefinition.TypeSystem.Int32.FullName)
            {
                var    allNames = new[] { "entityInQueryIndex", "nativeThreadIndex" };
                string entityInQueryIndexName = allNames[0];
                string nativeThreadIndexName  = allNames[1];

                if (parameter.Name == entityInQueryIndexName)
                {
                    var provider = moduleDefinition.ImportReference(typeof(LambdaParameterValueProvider_EntityInQueryIndex));
                    var runtime  = moduleDefinition.ImportReference(typeof(LambdaParameterValueProvider_EntityInQueryIndex.Runtime));
                    return(new LambdaParamaterValueProviderInformation(provider, runtime, true));
                }

                if (parameter.Name == nativeThreadIndexName)
                {
                    var provider = moduleDefinition.ImportReference(typeof(LambdaParameterValueProvider_NativeThreadIndex));
                    var runtime  = moduleDefinition.ImportReference(typeof(LambdaParameterValueProvider_NativeThreadIndex.Runtime));
                    return(new LambdaParamaterValueProviderInformation(provider, runtime, true));
                }

                UserError.DC0014(lambdaJobDescriptionConstruction.ContainingMethod, lambdaJobDescriptionConstruction.WithCodeInvocationInstruction, parameter, allNames).Throw();
            }

            if (!resolvedParameterType.GetElementType().IsPrimitive&& resolvedParameterType.GetElementType().IsValueType)
            {
                UserError.DC0021(lambdaJobDescriptionConstruction.ContainingMethod, parameter.Name, parameter.ParameterType.GetElementType(), lambdaJobDescriptionConstruction.WithCodeInvocationInstruction).Throw();
            }

            UserError.DC0005(lambdaJobDescriptionConstruction.ContainingMethod, lambdaJobDescriptionConstruction.WithCodeInvocationInstruction, parameter).Throw();
            return(null);
        }