FString FScriptCodeGeneratorBase::GenerateFunctionDispatch(UFunction* Function) { FString Params; const bool bHasParamsOrReturnValue = (Function->Children != NULL); if (bHasParamsOrReturnValue) { Params += TEXT("\tstruct FDispatchParams\r\n\t{\r\n"); for (TFieldIterator<UProperty> ParamIt(Function); ParamIt; ++ParamIt) { UProperty* Param = *ParamIt; Params += FString::Printf(TEXT("\t\t%s %s;\r\n"), *GetPropertyTypeCPP(Param, CPPF_ArgumentOrReturnValue), *Param->GetName()); } Params += TEXT("\t} Params;\r\n"); int32 ParamIndex = 0; for (TFieldIterator<UProperty> ParamIt(Function); ParamIt; ++ParamIt, ++ParamIndex) { UProperty* Param = *ParamIt; Params += FString::Printf(TEXT("\tParams.%s = %s;\r\n"), *Param->GetName(), *InitializeFunctionDispatchParam(Function, Param, ParamIndex)); } } Params += FString::Printf(TEXT("\tstatic UFunction* Function = Obj->FindFunctionChecked(TEXT(\"%s\"));\r\n"), *Function->GetName()); if (bHasParamsOrReturnValue) { Params += TEXT("\tcheck(Function->ParmsSize == sizeof(FDispatchParams));\r\n"); Params += TEXT("\tObj->ProcessEvent(Function, &Params);\r\n"); } else { Params += TEXT("\tObj->ProcessEvent(Function, NULL);\r\n"); } return Params; }
bool FScriptCodeGeneratorBase::CanExportFunction(const FString& ClassNameCPP, UClass* Class, UFunction* Function) { // We don't support delegates and non-public functions if ((Function->FunctionFlags & FUNC_Delegate)) { return false; } // Reject if any of the parameter types is unsupported yet for (TFieldIterator<UProperty> ParamIt(Function); ParamIt; ++ParamIt) { UProperty* Param = *ParamIt; if (Param->IsA(UArrayProperty::StaticClass()) || Param->ArrayDim > 1 || Param->IsA(UDelegateProperty::StaticClass()) || Param->IsA(UMulticastDelegateProperty::StaticClass()) || Param->IsA(UWeakObjectProperty::StaticClass()) || Param->IsA(UInterfaceProperty::StaticClass())) { return false; } } return true; }
FString FLuaScriptCodeGenerator::ExportFunction(const FString& ClassNameCPP, UClass* Class, UFunction* Function) { FString GeneratedGlue = GenerateWrapperFunctionDeclaration(ClassNameCPP, Class, Function); GeneratedGlue += TEXT("\r\n{\r\n"); UProperty* ReturnValue = NULL; UClass* FuncSuper = NULL; if (Function->GetOwnerClass() != Class) { // Find the base definition of the function if (ExportedClasses.Contains(Function->GetOwnerClass()->GetFName())) { FuncSuper = Function->GetOwnerClass(); } } FString FunctionBody; if (FuncSuper == NULL) { FunctionBody += FString::Printf(TEXT("\t%s\r\n"), *GenerateObjectDeclarationFromContext(ClassNameCPP, Class)); FunctionBody += GenerateFunctionDispatch(Function); FString FunctionCallArguments; FString ReturnValueDeclaration; for (TFieldIterator<UProperty> ParamIt(Function); !ReturnValue && ParamIt; ++ParamIt) { UProperty* Param = *ParamIt; if (Param->GetPropertyFlags() & CPF_ReturnParm) { ReturnValue = Param; } } FString ReturnValueName; if (ReturnValue) { ReturnValueName = FString::Printf(TEXT("Params.%s"), *ReturnValue->GetName()); } FunctionBody += FString::Printf(TEXT("\t%s\r\n"), *GenerateReturnValueHandler(ClassNameCPP, Class, Function, ReturnValue, *ReturnValueName)); } else { FunctionBody = FString::Printf(TEXT("\treturn %s_%s(InScriptContext);\r\n"), *FuncSuper->GetName(), *Function->GetName()); } GeneratedGlue += FunctionBody; GeneratedGlue += TEXT("}\r\n\r\n"); auto& Exports = ClassExportedFunctions.FindOrAdd(Class); Exports.Add(Function->GetFName()); return GeneratedGlue; }
bool FLuaScriptCodeGenerator::CanExportFunction(const FString& ClassNameCPP, UClass* Class, UFunction* Function) { bool bExport = FScriptCodeGeneratorBase::CanExportFunction(ClassNameCPP, Class, Function); if (bExport) { for (TFieldIterator<UProperty> ParamIt(Function); bExport && ParamIt; ++ParamIt) { UProperty* Param = *ParamIt; bExport = IsPropertyTypeSupported(Param); } } return bExport; }