MCPcopy Create free account
hub / github.com/URLab-Sim/UnrealRoboticsLab / EndPlay

Method EndPlay

Source/URLab/Private/MuJoCo/Core/AMjManager.cpp:398–492  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

396}
397
398void AAMjManager::EndPlay(const EEndPlayReason::Type EndPlayReason)
399{
400 // Stop the physics async thread BEFORE Super::EndPlay so PostStep
401 // callbacks don't race into resources child components tear down.
402 // Bounded wait: a pathological mj_step can take many seconds; an
403 // unbounded Wait() would freeze PIE-stop. On timeout we detach and
404 // leak m_model/m_data to avoid use-after-free in the still-running
405 // step (one-time per session).
406 bool bAsyncExited = true;
407 if (PhysicsEngine)
408 {
409 PhysicsEngine->bShouldStopTask = true;
410 // Wake the worker if parked on the step-request event so it
411 // observes bShouldStopTask without burning the Wait timeout.
412 if (PhysicsEngine->StepRequestEvent)
413 PhysicsEngine->StepRequestEvent->Trigger();
414 if (PhysicsEngine->AsyncPhysicsFuture.IsValid())
415 {
416 constexpr double kShutdownTimeoutSec = 3.0;
417 bAsyncExited = PhysicsEngine->AsyncPhysicsFuture.WaitFor(
418 FTimespan::FromSeconds(kShutdownTimeoutSec));
419 if (!bAsyncExited)
420 {
421 UE_LOG(LogURLab, Warning,
422 TEXT("Physics async thread did not exit within %.1fs — detaching. ")
423 TEXT("mj_step is likely stuck; MuJoCo resources will leak for this session ")
424 TEXT("to avoid a use-after-free in the still-running step."),
425 kShutdownTimeoutSec);
426 }
427 }
428 PhysicsEngine->ClearCallbacks();
429 }
430
431 // Manager-owned transports aren't UActorComponents, so EndPlay
432 // doesn't propagate to them; explicit TransportShutdown required.
433 for (TObjectPtr<UURLabSubscribeTransport>& T : ManagerOwnedSubscribeTransports)
434 {
435 if (T)
436 T->TransportShutdown();
437 }
438 ManagerOwnedSubscribeTransports.Reset();
439 for (TObjectPtr<UURLabPublishTransport>& T : ManagerOwnedPublishTransports)
440 {
441 if (T)
442 T->TransportShutdown();
443 }
444 ManagerOwnedPublishTransports.Reset();
445
446 Super::EndPlay(EndPlayReason);
447 if (Instance == this)
448 Instance = nullptr;
449
450 // Manager-owned servers also tear down the dispatcher itself;
451 // subsystem-owned servers stay alive across PIE cycles.
452 if (BridgeServer)
453 {
454 BridgeServer->UnregisterManager(this);
455 if (BridgeServer->IsOwnedByManager())

Callers

nothing calls this directly

Calls 6

IsValidMethod · 0.80
ClearCallbacksMethod · 0.80
UnregisterManagerMethod · 0.80
TransportShutdownMethod · 0.45
ResetMethod · 0.45
StopMethod · 0.45

Tested by

no test coverage detected