More work on tangibleCharacter, especially thread synch stuff

This commit is contained in:
2024-02-13 16:49:58 -05:00
parent d11fbca815
commit abb967f20b
7 changed files with 121 additions and 69 deletions

View File

@@ -19,7 +19,6 @@ AIntegrationGameModeBase::AIntegrationGameModeBase()
TangibleManager = NewObject<UlxTangibleManager>();
PlayerId = 0;
EngineSeconds = 0.0;
NextThreadTrigger = 1.0;
//PrimaryActorTick.bCanEverTick = true; // Probably wrong
//PrimaryActorTick.bTickEvenWhenPaused = true; // Probably wrong
//PrimaryActorTick.TickGroup = TG_PrePhysics; // Probably wrong
@@ -27,11 +26,15 @@ AIntegrationGameModeBase::AIntegrationGameModeBase()
SetActorTickInterval(0.0f);
DebugPrintControl::EnableCollection();
ResetToInitialState();
OnWorldPreActorTickHandle = FWorldDelegates::OnWorldPreActorTick.AddUObject(this, &AIntegrationGameModeBase::OnWorldPreActorTick);
OnWorldPostActorTickHandle = FWorldDelegates::OnWorldPostActorTick.AddUObject(this, &AIntegrationGameModeBase::OnWorldPostActorTick);
}
AIntegrationGameModeBase::~AIntegrationGameModeBase()
{
ResetToInitialState();
FWorldDelegates::OnWorldPreActorTick.Remove(OnWorldPreActorTickHandle);
FWorldDelegates::OnWorldPostActorTick.Remove(OnWorldPostActorTickHandle);
}
// This method runs in the background thread,
@@ -76,7 +79,6 @@ void AIntegrationGameModeBase::ResetToInitialState()
// Reset the clocks.
EngineSeconds = 0;
NextThreadTrigger = 1.0;
NextRotateCube = 1.0;
}
@@ -101,41 +103,53 @@ void AIntegrationGameModeBase::UpdateConsoleOutput() {
}
}
void AIntegrationGameModeBase::MaybeTriggerUpdateTask(float deltaseconds) {
if (!Playing) return;
FlxLockedWrapper lockedwrap(LockableWrapper);
if (EngineSeconds >= NextThreadTrigger)
{
LuprexUpdateTask.Trigger();
NextThreadTrigger += 0.05;
}
}
#pragma optimize("", off)
void AIntegrationGameModeBase::UpdateTangibles() {
double radius = 1000.0; // Hardwired for now.
using TanArray = UlxTangibleManager::TanArray;
if (!Playing) return;
FlxLockedWrapper w(LockableWrapper);
PlayerId = w.GetActor();
IdView nearids = w.GetNear(PlayerId, radius, radius, radius);
TangibleManager->UpdateNearAccordingToLuprex(nearids);
TanArray alltans = TangibleManager->GetAllTangibles();
IdArray allids = TangibleManager->GetIds(alltans);
StringViewVec allqueues = w.GetAnimationQueues(allids);
TanArray alltans;
{
FlxLockedWrapper w(LockableWrapper);
PlayerId = w.GetActor();
IdView nearids = w.GetNear(PlayerId, radius, radius, radius);
TangibleManager->UpdateNearAccordingToLuprex(nearids);
alltans = TangibleManager->GetAllTangibles();
IdArray allids = TangibleManager->GetIds(alltans);
StringViewVec allqueues = w.GetAnimationQueues(allids);
for (int i = 0; i < alltans.Num(); i++) {
alltans[i]->UpdateAnimationQueue(allqueues[i]);
}
}
// This is where we run the blueprint code that updates animation
// states. Be aware that the blueprint code could call back
// into the gamemode, which could in turn access the FlxLockedWrapper.
// This is why we've released the FlxLockedWrapper before doing this.
for (int i = 0; i < alltans.Num(); i++) {
alltans[i]->UpdateAnimationQueue(allqueues[i]);
alltans[i]->MaybeExecuteAnimStateChanged();
}
TangibleManager->RecalcNearAccordingToUnreal(PlayerId, radius);
TangibleManager->DeleteFarawayTangibles();
}
void AIntegrationGameModeBase::ExecuteDebuggingCommand(const FString &fs) {
void AIntegrationGameModeBase::InvokeEngioMove(const FString &action, const FVector &xyz) {
FTCHARToUTF8 utf8action(action);
std::string uaction(utf8action.Get(), utf8action.Length());
FlxStreamBuffer sb;
sb.write_string("move"); // Function name within engio
sb.write_simple_dynamic_tag(SimpleDynamicTag::STRING);
sb.write_string(uaction);
sb.write_simple_dynamic_tag(SimpleDynamicTag::VECTOR);
sb.write_fvector(xyz);
std::string_view datapk = sb.view();
FlxLockedWrapper w(LockableWrapper);
int64 player = w.GetActor();
w->play_invoke_engio(w.Get(), player, datapk.size(), datapk.data());
}
void AIntegrationGameModeBase::ExecuteDebuggingCommand(FlxLockedWrapper &w, const FString &fs) {
if (fs == "\\invokeplayer") {
DPrint(TEXT("Trying to invoke 'myfunction' in lua"));
FlxLockedWrapper w(LockableWrapper);
FlxStreamBuffer sb;
sb.write_string("myfunction");
sb.write_simple_dynamic_tag(SimpleDynamicTag::NUMBER);
@@ -167,31 +181,39 @@ void AIntegrationGameModeBase::ConsoleSendInput(const FString& fs)
// lua code contains '\\', we'll catch it instead of passing it
// through. There's no simple solution, though.
if (fs[0] == '\\') {
ExecuteDebuggingCommand(fs);
ExecuteDebuggingCommand(w, fs);
} else {
const TCHAR* fstchar = *fs;
if (sizeof(TCHAR) == 2)
{
std::u16string_view fsview((const char16_t*)fstchar, fs.Len());
std::string utf8 = drvutil::utf16_to_utf8(fsview);
utf8 = utf8 + "\n";
w->play_recv_incoming(w.Get(), 0, utf8.size(), utf8.c_str());
}
FTCHARToUTF8 utf8fs(fs);
std::string ufs(utf8fs.Get(), utf8fs.Length());
ufs = ufs + "\n";
w->play_recv_incoming(w.Get(), 0, ufs.size(), ufs.c_str());
}
}
}
void AIntegrationGameModeBase::OnWorldPreActorTick(UWorld* InWorld, ELevelTick InLevelTick, float deltaseconds)
{
if(Playing && (GetWorld() == InWorld) && (InLevelTick == LEVELTICK_All))
{
LuprexUpdateTask.Wait();
EngineSeconds += deltaseconds;
}
}
void AIntegrationGameModeBase::OnWorldPostActorTick(UWorld* InWorld, ELevelTick InLevelTick, float deltaseconds)
{
if(Playing && (GetWorld() == InWorld) && (InLevelTick == LEVELTICK_All))
{
LuprexUpdateTask.Trigger();
}
}
void AIntegrationGameModeBase::Tick(float deltaseconds)
{
Super::Tick(deltaseconds);
if (Playing)
{
EngineSeconds += deltaseconds;
}
UpdateConsoleOutput();
UpdateTangibles();
MaybeTriggerUpdateTask(deltaseconds);
}
void AIntegrationGameModeBase::BeginPlay()