private InjectedFunctionInfo TryGetInjectedFunctionInfo(ManagedUnrealFunctionInfo functionInfo) { InjectedFunctionInfo injectedFunctionInfo; Functions.TryGetValue(functionInfo, out injectedFunctionInfo); return(injectedFunctionInfo); }
private Instruction[] CreateFunctionOutDefaults(ILProcessor processor, ManagedUnrealFunctionInfo functionInfo, MethodDefinition method) { List <Instruction> instructions = new List <Instruction>(); // Set out params to the equivalent of default(XXXX) for (int i = 0; i < functionInfo.Params.Count; ++i) { ManagedUnrealPropertyInfo param = functionInfo.Params[i]; if (param.IsOut) { instructions.AddRange(CreateSetDefaultValue(processor, param.Type.TypeCode, method.Parameters[i])); } } // Add a return var and set it to the equivalent of default(XXXX) if (functionInfo.ReturnProp != null) { TypeReference returnType = assembly.MainModule.ImportEx(ManagedUnrealTypeInfo.GetTypeFromPropertyInfo(functionInfo.ReturnProp)); VariableDefinition returnVar = new VariableDefinition(returnType); method.Body.Variables.Add(returnVar); instructions.AddRange(CreateSetDefaultValue(processor, functionInfo.ReturnProp.Type.TypeCode, returnVar)); instructions.Add(processor.Create(OpCodes.Ldloc, returnVar)); } return(instructions.ToArray()); }
private FieldDefinition AddParamsSizeField(TypeDefinition type, ManagedUnrealFunctionInfo functionInfo) { FieldDefinition field = new FieldDefinition(functionInfo.Name + codeSettings.VarNames.ParamsSize, FieldAttributes.Static | FieldAttributes.Private, int32TypeRef); type.Fields.Add(field); return(field); }
public override void ProcessFunction(ManagedUnrealFunctionInfo functionInfo) { if (!string.IsNullOrEmpty(FunctionName)) { SetInvalidTarget("BlueprintSetter specified on a function with an unexpected function name (shouldn't be used)"); } functionInfo.Flags |= EFunctionFlags.BlueprintCallable; functionInfo.AdditionalFlags |= ManagedUnrealFunctionFlags.BlueprintSetter; }
private FieldDefinition AddOffsetField(TypeDefinition type, ManagedUnrealFunctionInfo functionInfo, ManagedUnrealPropertyInfo paramInfo) { FieldDefinition field = new FieldDefinition(functionInfo.Name + "_" + paramInfo.Name + codeSettings.VarNames.MemberOffset, FieldAttributes.Static | FieldAttributes.Private, int32TypeRef); type.Fields.Add(field); return(field); }
public override void ProcessFunction(ManagedUnrealFunctionInfo functionInfo) { if (!string.IsNullOrEmpty(OriginalName)) { functionInfo.OriginalName = OriginalName; } functionInfo.AdditionalFlags |= ManagedUnrealFunctionFlags.UFunction; functionInfo.Flags |= (EFunctionFlags)Flags; }
private void InjectRPCValidation(TypeDefinition type, ManagedUnrealFunctionInfo functionInfo, MethodDefinition method, InjectedMembers injectedMembers) { string validationMethodName = functionInfo.Name + codeSettings.VarNames.RPCValidate; List <MethodDefinition> validationMethods = new List <MethodDefinition>(); foreach (MethodDefinition methodDef in type.Methods) { if (methodDef.Name == validationMethodName) { validationMethods.Add(methodDef); } } VerifySingleResult(validationMethods, type, "required validation method " + validationMethodName); MethodDefinition validationMethod = validationMethods[0]; ILProcessor processor = method.Body.GetILProcessor(); Instruction branchTarget = method.Body.Instructions[0]; // Roughly compare the function params for the method / validation method bool invalidParams = false; if (method.Parameters.Count != validationMethod.Parameters.Count) { invalidParams = true; } //for (int i = 0; i < method.Parameters.Count; ++i) //{ // // TODO: Compare the params (allow removal of ref/out?) //} if (invalidParams) { throw new RewriteException(type, "RPC validation method signature mismatch " + validationMethodName); } processor.InsertBefore(branchTarget, processor.Create(OpCodes.Ldarg_0)); for (int i = 0; i < method.Parameters.Count; ++i) { processor.InsertBefore(branchTarget, processor.Create(OpCodes.Ldarg, i + 1)); } processor.InsertBefore(branchTarget, processor.Create(OpCodes.Callvirt, validationMethod)); processor.InsertBefore(branchTarget, processor.Create(OpCodes.Brtrue_S, branchTarget)); processor.InsertBefore(branchTarget, processor.Create(OpCodes.Ldstr, validationMethodName)); processor.InsertBefore(branchTarget, processor.Create(OpCodes.Call, rpcValidateFailedMethod)); // Set out parms / return value to default(XXXX) InsertInstructionsBefore(processor, branchTarget, CreateFunctionOutDefaults(processor, functionInfo, method)); processor.InsertBefore(branchTarget, processor.Create(OpCodes.Ret)); method.Body.OptimizeMacros(); }
private InjectedFunctionInfo GetInjectedFunctionInfo(ManagedUnrealFunctionInfo functionInfo) { InjectedFunctionInfo injectedFunctionInfo; if (!Functions.TryGetValue(functionInfo, out injectedFunctionInfo)) { Functions.Add(functionInfo, injectedFunctionInfo = new InjectedFunctionInfo(functionInfo)); } return(injectedFunctionInfo); }
public virtual void ProcessFunctionParams(ManagedUnrealFunctionInfo functionInfo) { foreach (ManagedUnrealPropertyInfo param in functionInfo.Params) { ProcessProperty(param); } if (functionInfo.ReturnProp != null) { ProcessProperty(functionInfo.ReturnProp); } }
private FieldDefinition AddNativePropertyField(TypeDefinition type, ManagedUnrealFunctionInfo functionInfo, ManagedUnrealPropertyInfo paramInfo) { if (!ManagedUnrealTypeInfo.RequiresNativePropertyField(paramInfo, codeSettings.LazyFunctionParamInitDestroy)) { return(null); } FieldDefinition field = new FieldDefinition(functionInfo.Name + "_" + paramInfo.Name + codeSettings.VarNames.PropertyAddress, FieldAttributes.Static | FieldAttributes.Private, ufieldAddressTypeRef); type.Fields.Add(field); return(field); }
private void EmitFunctionParamDestroy(ILProcessor processor, ManagedUnrealFunctionInfo functionInfo, ManagedUnrealPropertyInfo paramInfo, VariableDefinition paramsBuffer, FieldDefinition nativePropertyField) { if (!codeSettings.LazyFunctionParamInitDestroy && ManagedUnrealTypeInfo.PropertyRequiresDestroy(paramInfo)) { // Ensure the checks to include the native field prop are in sync with this function Debug.Assert(nativePropertyField != null); // NativeReflection.DestroyValue_InContainer(XXXX_YYYY_PropertyAddress.Address, ParamsBuffer) EmitLdNativePropertyFieldAddress(processor, nativePropertyField); processor.Emit(OpCodes.Ldloc, paramsBuffer); processor.Emit(OpCodes.Call, reflectionDestroyValue_InContainer); } }
private FieldDefinition AddNativeFunctionField(TypeDefinition type, ManagedUnrealFunctionInfo functionInfo, bool staticField) { FieldAttributes attributes = FieldAttributes.Private; if (staticField) { attributes |= FieldAttributes.Static; } string suffix = staticField ? codeSettings.VarNames.FunctionAddress : codeSettings.VarNames.InstanceFunctionAddress; string fieldName = functionInfo.Name + suffix + (staticField ? string.Empty : "Instance"); FieldDefinition field = new FieldDefinition(fieldName, attributes, intPtrTypeRef); type.Fields.Add(field); return(field); }
private void AddFunctionInvokerAttribute(MethodDefinition method, ManagedUnrealFunctionInfo functionInfo) { for (int i = method.CustomAttributes.Count - 1; i >= 0; i--) { // Type comparison doesn't seem to work. TODO: look into if (method.CustomAttributes[i].AttributeType.FullName == functionInvokerAttributeTypeRef.FullName) { method.CustomAttributes.RemoveAt(i); break; } } CustomAttribute functionInvokerAttribute = new CustomAttribute(functionInvokerAttributeTypeCtor); method.CustomAttributes.Add(functionInvokerAttribute); functionInvokerAttribute.ConstructorArguments.Clear(); functionInvokerAttribute.ConstructorArguments.Add(new CustomAttributeArgument(stringTypeRef, functionInfo.Path)); }
private MethodDefinition WriteDelegateInvoker(TypeDefinition type, MethodDefinition signature, ManagedUnrealTypeInfo typeInfo, ManagedUnrealFunctionInfo functionInfo, InjectedMembers injectedMembers) { MethodDefinition method = CopyMethod(signature, false); method.HasThis = true; method.Attributes = MethodAttributes.Private; method.Name = "Invoker"; type.Methods.Add(method); MethodReference isBoundGetter = assembly.MainModule.ImportEx(GetTypeFromTypeDefinition(type).GetMethod("get_IsBound")); FieldDefinition functionIsValid = AddIsValidField(type, functionInfo); FieldDefinition functionAddressField = AddNativeFunctionField(type, functionInfo); FieldDefinition paramsSizeField = AddParamsSizeField(type, functionInfo); injectedMembers.SetFunctionIsValid(functionInfo, functionIsValid); injectedMembers.SetFunctionAddress(functionInfo, functionAddressField); injectedMembers.SetFunctionParamsSize(functionInfo, paramsSizeField); ILProcessor processor = method.Body.GetILProcessor(); processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Callvirt, isBoundGetter); Instruction branchPosition = processor.Body.Instructions[processor.Body.Instructions.Count - 1]; Dictionary <ManagedUnrealPropertyInfo, ParameterDefinition> parameters = GetParamsFromMethod(type, functionInfo, method, injectedMembers, true); WriteNativeFunctionInvokerBody(type, typeInfo, functionInfo, method, injectedMembers, parameters, processor, true, false); int branchTargetIndex = processor.Body.Instructions.Count; // Set out parms / return value to default(XXXX) EmitFunctionOutDefaults(processor, functionInfo, method); processor.Emit(OpCodes.Ret); processor.InsertAfter(branchPosition, processor.Create(OpCodes.Brfalse, processor.Body.Instructions[branchTargetIndex])); FinalizeMethod(method); return(method); }
public override void ProcessFunction(ManagedUnrealFunctionInfo functionInfo) { // Network replicated functions are always events functionInfo.Flags |= EFunctionFlags.Event; functionInfo.Flags |= EFunctionFlags.Net; if (Reliable) { functionInfo.Flags |= EFunctionFlags.NetReliable; } if (WithValidation) { functionInfo.Flags |= EFunctionFlags.NetValidate; } switch (Endpoint) { case RPCEndpoint.Client: functionInfo.Flags |= EFunctionFlags.NetClient; break; case RPCEndpoint.Server: functionInfo.Flags |= EFunctionFlags.NetServer; break; case RPCEndpoint.Multicast: functionInfo.Flags |= EFunctionFlags.NetMulticast; break; } switch (ServiceType) { case RPCServiceType.Request: functionInfo.Flags |= EFunctionFlags.NetRequest; break; case RPCServiceType.Response: functionInfo.Flags |= EFunctionFlags.NetResponse; break; } }
public void AddInvoker(ManagedUnrealFunctionInfo functionInfo, IntPtr function) { if (managedInvokersByFunctionInfo == null) { managedInvokersByFunctionInfo = new Dictionary <ManagedUnrealFunctionInfo, UFunction.FuncInvokerManaged>(); managedInvokersByAddress = new Dictionary <IntPtr, UFunction.FuncInvokerManaged>(); Dictionary <string, ManagedUnrealFunctionInfo> functionsByPath = new Dictionary <string, ManagedUnrealFunctionInfo>(); foreach (ManagedUnrealFunctionInfo funcInfo in TypeInfo.Functions) { functionsByPath[funcInfo.Path] = funcInfo; } BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly; foreach (MethodInfo method in Type.GetMethods(bindingFlags)) { UFunctionInvokerAttribute functionInvokerAttribute = method.GetCustomAttribute <UFunctionInvokerAttribute>(false); if (functionInvokerAttribute != null && !string.IsNullOrEmpty(functionInvokerAttribute.Path)) { ManagedUnrealFunctionInfo funcInfo; if (functionsByPath.TryGetValue(functionInvokerAttribute.Path, out funcInfo)) { UFunction.FuncInvokerManaged invoker = (UFunction.FuncInvokerManaged)Delegate.CreateDelegate( typeof(UFunction.FuncInvokerManaged), method); managedInvokersByFunctionInfo[funcInfo] = invoker; } } } } UFunction.FuncInvokerManaged managedInvoker; if (managedInvokersByFunctionInfo.TryGetValue(functionInfo, out managedInvoker)) { managedInvokersByAddress.Add(function, managedInvoker); } }
public override void ProcessFunction(ManagedUnrealFunctionInfo functionInfo) { functionInfo.Flags |= EFunctionFlags.Event; functionInfo.Flags |= EFunctionFlags.BlueprintEvent; functionInfo.IsBlueprintImplementable = true; }
public override void ProcessFunction(ManagedUnrealFunctionInfo functionInfo) { functionInfo.Flags |= EFunctionFlags.Event; functionInfo.Flags |= EFunctionFlags.BlueprintEvent; }
public override void ProcessFunction(ManagedUnrealFunctionInfo functionInfo) { functionInfo.Flags |= EFunctionFlags.BlueprintCallable; functionInfo.Flags |= EFunctionFlags.BlueprintPure; }
public override void ProcessFunction(ManagedUnrealFunctionInfo functionInfo) { functionInfo.Flags |= EFunctionFlags.BlueprintAuthorityOnly; }
public override void ProcessFunction(ManagedUnrealFunctionInfo functionInfo) { functionInfo.Flags |= EFunctionFlags.BlueprintCosmetic; }
public FieldDefinition GetFunctionIsValid(ManagedUnrealFunctionInfo functionInfo) { InjectedFunctionInfo injectedFunctionInfo = TryGetInjectedFunctionInfo(functionInfo); return(injectedFunctionInfo != null ? injectedFunctionInfo.IsValid : null); }
private void EmitFunctionOutDefaults(ILProcessor processor, ManagedUnrealFunctionInfo functionInfo, MethodDefinition method) { AppendInstructions(processor, CreateFunctionOutDefaults(processor, functionInfo, method)); }
public override void ProcessFunction(ManagedUnrealFunctionInfo functionInfo) { functionInfo.Flags |= EFunctionFlags.Exec; }
public FieldDefinition GetFunctionAddressPerInstance(ManagedUnrealFunctionInfo functionInfo) { InjectedFunctionInfo injectedFunctionInfo = TryGetInjectedFunctionInfo(functionInfo); return(injectedFunctionInfo != null ? injectedFunctionInfo.FunctionAddressPerInstance : null); }
public InjectedFunctionInfo(ManagedUnrealFunctionInfo functionInfo) { FunctionInfo = functionInfo; Params = new Dictionary <ManagedUnrealPropertyInfo, InjectedFunctionParamInfo>(); }
public override void ProcessFunction(ManagedUnrealFunctionInfo functionInfo) { functionInfo.AdditionalFlags |= ManagedUnrealFunctionFlags.UFunction; functionInfo.Flags |= (EFunctionFlags)Flags; }
private static void SetAllMetaData(IntPtr obj, ManagedUnrealReflectionBase field, UMeta.Target target) { if (!FBuild.WithEditor || !metaDataEnabled || field == null || string.IsNullOrEmpty(field.Path)) { return; } IntPtr outermost = Native_UObjectBaseUtility.GetOutermost(obj); IntPtr metadata = outermost == IntPtr.Zero ? IntPtr.Zero : Native_UPackage.GetMetaData(outermost); if (metadata == IntPtr.Zero) { return; } Dictionary <FName, string> values = null; if (!metaDataMap.TryGetValue(field.Path.ToLower(), out values)) { values = new Dictionary <FName, string>(); } switch (target) { // Class / interface case UMeta.Target.Class: case UMeta.Target.Interface: // See GetMetadataKeyword (Engine\Source\Programs\UnrealHeaderTool\Private\BaseParser.cpp) // "NotBlueprintable" removes "NotBlueprintable" and adds "IsBlueprintBase=false" // "Blueprintable" and adds "IsBlueprintBase=true" // "BlueprintInternalUseOnly" adds "BlueprintType" if (!values.ContainsKey(UMeta.GetKeyName(MDClass.IsBlueprintBase))) { if (values.ContainsKey(UMeta.GetKeyName(MDClass.Blueprintable))) { values[UMeta.GetKeyName(MDClass.IsBlueprintBase)] = "true"; } else if (values.ContainsKey(UMeta.GetKeyName(MDClass.NotBlueprintable))) { values[UMeta.GetKeyName(MDClass.IsBlueprintBase)] = "false"; } } MetaDataMergeClassCategories(metadata, obj, values); break; case UMeta.Target.Function: ManagedUnrealFunctionInfo functionInfo = field as ManagedUnrealFunctionInfo; if (functionInfo.IsOverride && functionInfo.IsBlueprintEvent) { values[UMeta.GetKeyName(MDFunc.BlueprintInternalUseOnly)] = "true"; } break; } SetMetaDataBlueprintability(values, target, field as ManagedUnrealTypeInfo); if (values.Count > 0) { using (TArrayUnsafe <FName> keysUnsafe = new TArrayUnsafe <FName>()) using (TArrayUnsafe <string> valuesUnsafe = new TArrayUnsafe <string>()) { keysUnsafe.AddRange(values.Keys.ToArray()); valuesUnsafe.AddRange(values.Values.ToArray()); Native_UMetaData.SetObjectValues(metadata, obj, keysUnsafe.Address, valuesUnsafe.Address); } } }
private FieldDefinition AddNativeFunctionField(TypeDefinition type, ManagedUnrealFunctionInfo functionInfo) { return(AddNativeFunctionField(type, functionInfo, true)); }
public FieldDefinition GetFunctionParamsSize(ManagedUnrealFunctionInfo functionInfo) { InjectedFunctionInfo injectedFunctionInfo = TryGetInjectedFunctionInfo(functionInfo); return(injectedFunctionInfo != null ? injectedFunctionInfo.ParamsSize : null); }