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; }
void FObjectReplicator::StartReplicating( class UActorChannel * InActorChannel ) { check( OwningChannel == NULL ); OwningChannel = InActorChannel; // Cache off netGUID so if this object gets deleted we can close it ObjectNetGUID = OwningChannel->Connection->PackageMap->GetObjectNetGUID( GetObject() ); if ( !ObjectNetGUID.IsValid() ) { ObjectNetGUID = OwningChannel->Connection->PackageMap->AssignNewNetGUID( GetObject() ); check( !ObjectNetGUID.IsDefault() && ObjectNetGUID.IsValid() ); } TempBitWriter = new FNetBitWriter( OwningChannel->Connection->PackageMap, 0 ); // Allocate retirement list. // SetNum now constructs, so this is safe Retirement.SetNum( ObjectClass->ClassReps.Num() ); // figure out list of replicated object properties for ( UProperty* Prop = ObjectClass->PropertyLink; Prop != NULL; Prop = Prop->PropertyLinkNext ) { if ( Prop->PropertyFlags & CPF_Net ) { if ( IsCustomDeltaProperty( Prop ) ) { for ( int32 i = 0; i < Prop->ArrayDim; i++ ) { Retirement[Prop->RepIndex + i].CustomDelta = 1; } } if ( Prop->GetPropertyFlags() & CPF_Config ) { for ( int32 i = 0; i < Prop->ArrayDim; i++ ) { Retirement[Prop->RepIndex + i].Config = 1; } } } } }
void FObjectReplicator::StartReplicating( class UActorChannel * InActorChannel ) { check( OwningChannel == NULL ); if ( GetObject() == NULL ) { UE_LOG(LogRep, Error, TEXT("StartReplicating: Object == NULL")); return; } OwningChannel = InActorChannel; // Cache off netGUID so if this object gets deleted we can close it ObjectNetGUID = OwningChannel->Connection->Driver->GuidCache->GetOrAssignNetGUID( GetObject() ); check( !ObjectNetGUID.IsDefault() && ObjectNetGUID.IsValid() ); // Allocate retirement list. // SetNum now constructs, so this is safe Retirement.SetNum( ObjectClass->ClassReps.Num() ); // figure out list of replicated object properties for ( UProperty* Prop = ObjectClass->PropertyLink; Prop != NULL; Prop = Prop->PropertyLinkNext ) { if ( Prop->PropertyFlags & CPF_Net ) { if ( IsCustomDeltaProperty( Prop ) ) { for ( int32 i = 0; i < Prop->ArrayDim; i++ ) { Retirement[Prop->RepIndex + i].CustomDelta = 1; } } if ( Prop->GetPropertyFlags() & CPF_Config ) { for ( int32 i = 0; i < Prop->ArrayDim; i++ ) { Retirement[Prop->RepIndex + i].Config = 1; } } } } }
static void GetLifetimeBlueprintReplicationList( const AActor* ThisActor, const UBlueprintGeneratedClass* MyClass, TArray< FLifetimeProperty > & OutLifetimeProps ) { if ( MyClass == NULL ) { return; } uint32 PropertiesLeft = MyClass->NumReplicatedProperties; for ( TFieldIterator<UProperty> It( MyClass, EFieldIteratorFlags::ExcludeSuper ); It && PropertiesLeft > 0; ++It ) { UProperty * Prop = *It; if ( Prop != NULL && Prop->GetPropertyFlags() & CPF_Net ) { PropertiesLeft--; OutLifetimeProps.Add( FLifetimeProperty( Prop->RepIndex ) ); } } return GetLifetimeBlueprintReplicationList( ThisActor, Cast< UBlueprintGeneratedClass >( MyClass->GetSuperStruct() ), OutLifetimeProps ); }
void CallJavascriptFunction(Handle<Context> context, Handle<Value> This, UFunction* SignatureFunction, Handle<Function> func, void* Parms) { SCOPE_CYCLE_COUNTER(STAT_JavascriptFunctionCallToJavascript); auto isolate = context->GetIsolate(); HandleScope handle_scope(isolate); auto Buffer = reinterpret_cast<uint8*>(Parms); enum { MaxArgs = 32 }; Handle<Value> argv[MaxArgs]; int argc = 0; TFieldIterator<UProperty> Iter(SignatureFunction); for (; Iter && argc < MaxArgs && (Iter->PropertyFlags & (CPF_Parm | CPF_ReturnParm)) == CPF_Parm; ++Iter) { UProperty* Param = *Iter; argv[argc++] = ReadProperty(isolate, Param, Buffer, FNoPropertyOwner()); } UProperty* ReturnParam = nullptr; for (; Iter; ++Iter) { UProperty* Param = *Iter; if (Param->GetPropertyFlags() & CPF_ReturnParm) { ReturnParam = Param; break; } } TryCatch try_catch; auto value = func->Call(This, argc, argv); if (try_catch.HasCaught()) { FV8Exception::Report(try_catch); } bool bHasAnyOutParams = false; if (SignatureFunction && SignatureFunction->HasAnyFunctionFlags(FUNC_HasOutParms)) { // Iterate over input parameters for (TFieldIterator<UProperty> It(SignatureFunction); It && (It->PropertyFlags & (CPF_Parm | CPF_ReturnParm)) == CPF_Parm; ++It) { // This is 'out ref'! if ((It->PropertyFlags & (CPF_ConstParm | CPF_OutParm)) == CPF_OutParm) { bHasAnyOutParams = true; break; } } } if (bHasAnyOutParams) { FIsolateHelper I(isolate); if (value.IsEmpty() || !value->IsObject()) { I.Throw(TEXT("...")); return; } auto Object = value->ToObject(); // Iterate over parameters again for (TFieldIterator<UProperty> It(SignatureFunction); It; ++It) { UProperty* Param = *It; auto PropertyFlags = Param->GetPropertyFlags(); // pass return parameter as '$' if (PropertyFlags & CPF_ReturnParm) { auto sub_value = Object->Get(I.Keyword("$")); WriteProperty(isolate, ReturnParam, Buffer, sub_value); } // rejects 'const T&' and pass 'T&' as its name else if ((PropertyFlags & (CPF_ConstParm | CPF_OutParm)) == CPF_OutParm) { auto sub_value = Object->Get(I.Keyword(Param->GetName())); if (!sub_value.IsEmpty()) { // value can be null if isolate is in trouble WriteProperty(isolate, Param, Buffer, sub_value); } } } } else { if (ReturnParam) { WriteProperty(isolate, ReturnParam, Buffer, value); } } }
UProperty* FCSharpWrapperGenerator::GetWrapperArgsAndReturnType( const UFunction* Function, FString& OutFormalInteropArgs, FString& OutActualInteropArgs, FString& OutFormalManagedArgs, FString& OutActualManagedArgs ) { OutFormalInteropArgs = TEXT("UObjectHandle self"); OutActualInteropArgs = NativeThisPointer; OutFormalManagedArgs.Empty(); OutActualManagedArgs.Empty(); UProperty* returnValue = nullptr; for (TFieldIterator<UProperty> paramIt(Function); paramIt; ++paramIt) { UProperty* param = *paramIt; if (param->GetPropertyFlags() & CPF_ReturnParm) { returnValue = param; } else { FString argName = param->GetName(); FString argInteropType = GetPropertyInteropType(param); FString argAttrs = GetPropertyInteropTypeAttributes(param); FString argMods = GetPropertyInteropTypeModifiers(param); OutFormalInteropArgs += TEXT(","); if (!argAttrs.IsEmpty()) { OutFormalInteropArgs += TEXT(" "); OutFormalInteropArgs += argAttrs; } if (!argMods.IsEmpty()) { OutFormalInteropArgs += TEXT(" "); OutFormalInteropArgs += argMods; } OutFormalInteropArgs += FString::Printf( TEXT(" %s %s"), *argInteropType, *argName ); OutActualInteropArgs += TEXT(","); if (!argMods.IsEmpty()) { OutActualInteropArgs += TEXT(" "); OutActualInteropArgs += argMods; } OutActualInteropArgs += TEXT(" "); if (param->IsA<UObjectProperty>()) { OutActualInteropArgs += TEXT("(UObjectHandle)"); } OutActualInteropArgs += argName; if (!OutFormalManagedArgs.IsEmpty()) { OutFormalManagedArgs += TEXT(", "); } if (!argMods.IsEmpty()) { OutFormalManagedArgs += argMods + TEXT(" "); } FString ArgManagedType = GetPropertyManagedType(param); OutFormalManagedArgs += FString::Printf(TEXT("%s %s"), *ArgManagedType, *argName); if (!OutActualManagedArgs.IsEmpty()) { OutActualManagedArgs += TEXT(", "); } OutActualManagedArgs += argName; } } return returnValue; }