Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void UObject::ProcessEvent( UFunction* Function, void* Parms )
- {
- checkf(!IsUnreachable(),TEXT("%s Function: '%s'"), *GetFullName(), *Function->GetPathName());
- checkf(!FUObjectThreadContext::Get().IsRoutingPostLoad, TEXT("Cannot call UnrealScript (%s - %s) while PostLoading objects"), *GetFullName(), *Function->GetFullName());
- #if LIGHTWEIGHT_PROCESS_EVENT_COUNTER
- CONDITIONAL_SCOPE_CYCLE_COUNTER(STAT_BlueprintTime, IsInGameThread() && ProcessEventCounter == 0);
- TGuardValue<int32> PECounter(ProcessEventCounter, ProcessEventCounter+1);
- #endif
- #if DO_BLUEPRINT_GUARD
- FBlueprintExceptionTracker& BlueprintExceptionTracker = FBlueprintExceptionTracker::Get();
- TGuardValue<int32> EntryCounter( BlueprintExceptionTracker.ScriptEntryTag, BlueprintExceptionTracker.ScriptEntryTag+1);
- CONDITIONAL_SCOPE_CYCLE_COUNTER(STAT_BlueprintTime, IsInGameThread() && BlueprintExceptionTracker.ScriptEntryTag == 1);
- #endif
- #if TOTAL_OVERHEAD_SCRIPT_STATS
- FBlueprintEventTimer::FScopedVMTimer VMTime;
- #endif // TOTAL_OVERHEAD_SCRIPT_STATS
- // Reject.
- if (IsPendingKill())
- {
- return;
- }
- #if WITH_EDITORONLY_DATA
- // Cannot invoke script events when the game thread is paused for debugging.
- if(GIntraFrameDebuggingGameThread)
- {
- if(GFirstFrameIntraFrameDebugging)
- {
- UE_LOG(LogScriptCore, Warning, TEXT("Cannot call UnrealScript (%s - %s) while stopped at a breakpoint."), *GetFullName(), *Function->GetFullName());
- }
- return;
- }
- #endif // WITH_EDITORONLY_DATA
- if ((Function->FunctionFlags & FUNC_Native) != 0)
- {
- int32 FunctionCallspace = GetFunctionCallspace(Function, Parms, NULL);
- if (FunctionCallspace & FunctionCallspace::Remote)
- {
- CallRemoteFunction(Function, Parms, NULL, NULL);
- }
- if ((FunctionCallspace & FunctionCallspace::Local) == 0)
- {
- return;
- }
- }
- else if (Function->Script.Num() == 0)
- {
- return;
- }
- checkSlow((Function->ParmsSize == 0) || (Parms != NULL));
- #if PER_FUNCTION_SCRIPT_STATS
- const bool bShouldTrackFunction = Stats::IsThreadCollectingData();
- FScopeCycleCounterUObject FunctionScope(bShouldTrackFunction ? Function : nullptr);
- #endif // PER_FUNCTION_SCRIPT_STATS
- #if STATS || ENABLE_STATNAMEDEVENTS
- const bool bShouldTrackObject = GVerboseScriptStats && Stats::IsThreadCollectingData();
- FScopeCycleCounterUObject ContextScope(bShouldTrackObject ? this : nullptr);
- #endif
- #if UE_BLUEPRINT_EVENTGRAPH_FASTCALLS
- // Fast path for ubergraph calls
- int32 EventGraphParams;
- if (Function->EventGraphFunction != nullptr)
- {
- // Call directly into the event graph, skipping the stub thunk function
- EventGraphParams = Function->EventGraphCallOffset;
- Parms = &EventGraphParams;
- Function = Function->EventGraphFunction;
- // Validate assumptions required for this optimized path (EventGraphFunction should have only been filled out if these held)
- checkSlow(Function->ParmsSize == sizeof(EventGraphParams));
- checkSlow(Function->FirstPropertyToInit == nullptr);
- checkSlow(Function->PostConstructLink == nullptr);
- }
- #endif
- // Scope required for scoped script stats.
- {
- uint8* Frame = NULL;
- #if USE_UBER_GRAPH_PERSISTENT_FRAME
- if (Function->HasAnyFunctionFlags(FUNC_UbergraphFunction))
- {
- Frame = Function->GetOuterUClassUnchecked()->GetPersistentUberGraphFrame(this, Function);
- }
- #endif
- const bool bUsePersistentFrame = (NULL != Frame);
- if (!bUsePersistentFrame)
- {
- Frame = (uint8*)FMemory_Alloca(Function->PropertiesSize);
- // zero the local property memory
- FMemory::Memzero(Frame + Function->ParmsSize, Function->PropertiesSize - Function->ParmsSize);
- }
- // initialize the parameter properties
- FMemory::Memcpy(Frame, Parms, Function->ParmsSize);
- // Create a new local execution stack.
- FFrame NewStack(this, Function, Frame, NULL, Function->Children);
- checkSlow(NewStack.Locals || Function->ParmsSize == 0);
- // if the function has out parameters, fill the stack frame's out parameter info with the info for those params
- if ( Function->HasAnyFunctionFlags(FUNC_HasOutParms) )
- {
- FOutParmRec** LastOut = &NewStack.OutParms;
- for ( UProperty* Property = (UProperty*)Function->Children; Property && (Property->PropertyFlags&(CPF_Parm)) == CPF_Parm; Property = (UProperty*)Property->Next )
- {
- // this is used for optional parameters - the destination address for out parameter values is the address of the calling function
- // so we'll need to know which address to use if we need to evaluate the default parm value expression located in the new function's
- // bytecode
- if ( Property->HasAnyPropertyFlags(CPF_OutParm) )
- {
- CA_SUPPRESS(6263)
- FOutParmRec* Out = (FOutParmRec*)FMemory_Alloca(sizeof(FOutParmRec));
- // set the address and property in the out param info
- // note that since C++ doesn't support "optional out" we can ignore that here
- Out->PropAddr = Property->ContainerPtrToValuePtr<uint8>(Parms);
- Out->Property = Property;
- // add the new out param info to the stack frame's linked list
- if (*LastOut)
- {
- (*LastOut)->NextOutParm = Out;
- LastOut = &(*LastOut)->NextOutParm;
- }
- else
- {
- *LastOut = Out;
- }
- }
- }
- // set the next pointer of the last item to NULL to mark the end of the list
- if (*LastOut)
- {
- (*LastOut)->NextOutParm = NULL;
- }
- }
- if (!bUsePersistentFrame)
- {
- for (UProperty* LocalProp = Function->FirstPropertyToInit; LocalProp != NULL; LocalProp = (UProperty*)LocalProp->Next)
- {
- LocalProp->InitializeValue_InContainer(NewStack.Locals);
- }
- }
- // Call native function or UObject::ProcessInternal.
- const bool bHasReturnParam = Function->ReturnValueOffset != MAX_uint16;
- uint8* ReturnValueAddress = bHasReturnParam ? ((uint8*)Parms + Function->ReturnValueOffset) : nullptr;
- Function->Invoke(this, NewStack, ReturnValueAddress);
- if (!bUsePersistentFrame)
- {
- // Destroy local variables except function parameters.!! see also UObject::CallFunctionByNameWithArguments
- // also copy back constructed value parms here so the correct copy is destroyed when the event function returns
- for (UProperty* P = Function->DestructorLink; P; P = P->DestructorLinkNext)
- {
- if (!P->IsInContainer(Function->ParmsSize))
- {
- P->DestroyValue_InContainer(NewStack.Locals);
- }
- else if (!(P->PropertyFlags & CPF_OutParm))
- {
- FMemory::Memcpy(P->ContainerPtrToValuePtr<uint8>(Parms), P->ContainerPtrToValuePtr<uint8>(NewStack.Locals), P->ArrayDim * P->ElementSize);
- }
- }
- }
- }
- #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
- #if WITH_EDITORONLY_DATA
- FBlueprintCoreDelegates::OnScriptExecutionEnd.Broadcast();
- #endif
- #endif
- }
Add Comment
Please, Sign In to add comment