diff --git a/Source/FicsItNetworksLua/Private/FINLua/API/LuaEventAPI.cpp b/Source/FicsItNetworksLua/Private/FINLua/API/LuaEventAPI.cpp index a151c046..d73f4e31 100644 --- a/Source/FicsItNetworksLua/Private/FINLua/API/LuaEventAPI.cpp +++ b/Source/FicsItNetworksLua/Private/FINLua/API/LuaEventAPI.cpp @@ -167,10 +167,9 @@ namespace FINLua { queue->Events.RemoveAt(0); return luaFIN_pushEventData(L, event.Sender, event.Data); } - IFINLuaEventSystem& eventSystem = luaFIN_getEventSystem(L); - double currentTime = eventSystem.TimeSinceStart(); + double currentTime = FPlatformTime::Seconds(); if (timeout > currentTime) { - return lua_yieldk(L, 0, NULL, luaPullContinue); + return luaFIN_yield(L, 0, NULL, luaPullContinue, timeout); } return 0; } @@ -179,9 +178,8 @@ namespace FINLua { * @DisplayName Pull */)", pull) { FEventQueue& queue = luaFIN_checkEventQueue(L, 1); - double timeout = luaL_checknumber(L, 2)*1000; - IFINLuaEventSystem& eventSystem = luaFIN_getEventSystem(L); - timeout += eventSystem.TimeSinceStart(); + double timeout = luaL_checknumber(L, 2); + timeout += FPlatformTime::Seconds(); lua_pop(L, 1); lua_pushnumber(L, timeout); return luaPullContinue(L, 0, NULL); @@ -197,7 +195,7 @@ namespace FINLua { return luaFIN_pushEventData(L, event.Sender, event.Data); } } - return lua_yieldk(L, 0, NULL, luaWaitForContinue); + return luaFIN_yield(L, 0, NULL, luaWaitForContinue, TNumericLimits::Max()); } int luaWaitFor(lua_State* L) { return luaWaitForContinue(L, 0, NULL); @@ -312,6 +310,8 @@ namespace FINLua { timeout += FPlatformTime::Seconds(); lua_pop(L, args); lua_pushnumber(L, timeout); + } else { + lua_pushnumber(L, TNumericLimits::Max()); } return luaPullContinue(L, 0, 0); } @@ -416,10 +416,18 @@ namespace FINLua { } int luaWaitForContinue(lua_State* L, int, lua_KContext) { + FFINLuaRuntime& runtime = luaFIN_getRuntime(L); + if (runtime.GetLuaThread() == L) { + IFINLuaEventSystem& eventSystem = luaFIN_getEventSystem(L); + TOptional> event = eventSystem.PullSignal(); + if (event) { + luaFIN_handleEvent(L, event->Key, event->Value); + } + } int key = luaL_checkinteger(L, 2); if (lua_geti(L, 1, key+1) == LUA_TNIL) { lua_pop(L, 1); - return lua_yieldk(L, 0, NULL, luaWaitForContinue); + return luaFIN_yield(L, 0, NULL, luaWaitForContinue, TNumericLimits::Max()); } lua_pushnil(L); lua_seti(L, 1, key+1); @@ -448,6 +456,7 @@ namespace FINLua { luaFIN_pushLuaFutureCFunction(L, luaWaitFor, 2); return 1; } + int luaLoopContinue(lua_State* L, int, lua_KContext) { while (true) { IFINLuaEventSystem& eventSystem = luaFIN_getEventSystem(L); @@ -456,9 +465,10 @@ namespace FINLua { const auto& [sender, signal] = *data; luaFIN_handleEvent(L, sender, signal); } - luaFIN_futureRun(L, 1); + TOptional timeout = TNumericLimits::Max(); + luaFIN_futureRun(L, 1, timeout); if (!data) { - return lua_yieldk(L, 0, 0, luaLoopContinue); + return luaFIN_yield(L, 0, 0, luaLoopContinue, timeout); } } } diff --git a/Source/FicsItNetworksLua/Private/FINLua/API/LuaWorldAPI.cpp b/Source/FicsItNetworksLua/Private/FINLua/API/LuaWorldAPI.cpp index 04fca785..1c099094 100644 --- a/Source/FicsItNetworksLua/Private/FINLua/API/LuaWorldAPI.cpp +++ b/Source/FicsItNetworksLua/Private/FINLua/API/LuaWorldAPI.cpp @@ -8,6 +8,8 @@ #include "FINLuaRuntime.h" #include "FINLuaThreadedRuntime.h" #include "LuaStruct.h" +#include "TimerManager.h" +#include "Async/Async.h" namespace FINLua { LuaModule(R"(/** @@ -74,10 +76,12 @@ namespace FINLua { AFGPlayerController* PlayerController = Cast(players->Get()); if (Player.IsSet() && PlayerController->GetPlayerState()->GetUserName() != *Player) continue; runtime.TickActions.Enqueue([PlayerController, Position]() { - UClass* Class = LoadObject(nullptr, TEXT("/Game/FactoryGame/Character/Player/BP_AttentionPingActor.BP_AttentionPingActor_C")); - AFGAttentionPingActor* PingActor = PlayerController->GetWorld()->SpawnActorDeferred(Class, FTransform(Position)); - PingActor->SetOwningPlayerState(PlayerController->GetPlayerState()); - PingActor->FinishSpawning(FTransform(Position)); + AsyncTask(ENamedThreads::GameThread, [PlayerController, Position]() { + UClass* Class = LoadObject(nullptr, TEXT("/Game/FactoryGame/Character/Player/BP_AttentionPingActor.BP_AttentionPingActor_C")); + AFGAttentionPingActor* PingActor = PlayerController->GetWorld()->SpawnActorDeferred(Class, FTransform(Position)); + PingActor->SetOwningPlayerState(PlayerController->GetPlayerState()); + PingActor->FinishSpawning(FTransform(Position)); + }); }); break; } diff --git a/Source/FicsItNetworksLua/Private/FINLua/FINLuaRuntime.cpp b/Source/FicsItNetworksLua/Private/FINLua/FINLuaRuntime.cpp index c5524025..d799f517 100644 --- a/Source/FicsItNetworksLua/Private/FINLua/FINLuaRuntime.cpp +++ b/Source/FicsItNetworksLua/Private/FINLua/FINLuaRuntime.cpp @@ -67,6 +67,7 @@ void FFINLuaRuntime::Destroy() { lua_close(LuaState); } + Timeout.Reset(), LoadedModules.Empty(); GlobalData.Empty(); GlobalPointers.Empty(); diff --git a/Source/FicsItNetworksLua/Private/FINLua/LuaFuture.cpp b/Source/FicsItNetworksLua/Private/FINLua/LuaFuture.cpp index 332d8899..6a0fd884 100644 --- a/Source/FicsItNetworksLua/Private/FINLua/LuaFuture.cpp +++ b/Source/FicsItNetworksLua/Private/FINLua/LuaFuture.cpp @@ -10,7 +10,7 @@ namespace FINLua { int lua_futureStruct(lua_State* L); int lua_futureStructContinue(lua_State* L, int, lua_KContext); int awaitContinue(lua_State* L, int, lua_KContext); - int luaFIN_futureRun(lua_State* L, int index); + int luaFIN_futureRun(lua_State* L, int index, TOptional& timeout); LuaModule(R"(/** * @LuaModule FutureModule @@ -130,8 +130,8 @@ namespace FINLua { break; } case LUA_YIELD: if (results > 0) { - if (lua_type(L, -results) == LUA_TNUMBER) { - timeout = lua_tonumber(L, results); + if (lua_type(thread, -results) == LUA_TNUMBER) { + timeout = lua_tonumber(thread, results); } } lua_pop(thread, results); @@ -143,7 +143,7 @@ namespace FINLua { return status; } LuaModuleTableFunction(R"(/** - * @LuaFunction bool poll() + * @LuaFunction bool,nil|number poll() * @DisplayName Poll */)", poll) { // TODO: Maybe return timeout @@ -151,7 +151,12 @@ namespace FINLua { lua_State* thread; int status = pollInternal(L, 1, thread, timeout); lua_pushboolean(L, status == LUA_OK); - return 1; + if (timeout) { + lua_pushnumber(L, *timeout); + } else { + lua_pushnil(L); + } + return 2; } LuaModuleTableFunction(R"(/** @@ -221,7 +226,7 @@ namespace FINLua { int joinContinue(lua_State* L, int status, lua_KContext) { bool done = true; - TOptional finalTimeout; + TOptional finalTimeout = TNumericLimits::Max(); int num = lua_gettop(L); for (int i = 1; i <= num; ++i) { if (luaL_testudata(L, i, Future::_Name) == nullptr) continue; @@ -233,10 +238,10 @@ namespace FINLua { lua_replace(L, i); } else { done = false; - if (finalTimeout.IsSet()) { + if (timeout.IsSet() && finalTimeout.IsSet()) { finalTimeout = FMath::Min(*finalTimeout, *timeout); } else { - finalTimeout = timeout; + finalTimeout.Reset(); } } } @@ -324,15 +329,22 @@ namespace FINLua { * * Runs the default task scheduler once. */)", run) { - int numTasksLeft = luaFIN_futureRun(L, lua_upvalueindex(2)); + TOptional timeout; + int numTasksLeft = luaFIN_futureRun(L, lua_upvalueindex(2), timeout); lua_pushinteger(L, numTasksLeft); - return 1; + if (timeout) { + lua_pushnumber(L, *timeout); + } else { + lua_pushnil(L); + } + return 2; } int luaLoopContinue(lua_State* L, int, lua_KContext) { - int numTasksLeft = luaFIN_futureRun(L, -1); + TOptional timeout = TNumericLimits::Max(); + int numTasksLeft = luaFIN_futureRun(L, -1, timeout); if (numTasksLeft > 0) { - return lua_yieldk(L, 0, NULL, &luaLoopContinue); + return luaFIN_yield(L, 0, NULL, &luaLoopContinue, timeout); } return 0; } @@ -509,7 +521,7 @@ namespace FINLua { lua_pop(L, 2); } - int luaFIN_futureRun(lua_State* L, int index) { + int luaFIN_futureRun(lua_State* L, int index, TOptional& timeout) { //lua_getglobal(L, "future"); int num = lua_gettop(L); if (lua_getfield(L, index, "tasks") != LUA_TTABLE) { @@ -521,10 +533,15 @@ namespace FINLua { int shift = 0; for (int i = 1; i <= len; ++i) { lua_geti(L, -1, i); - TOptional timeout; + TOptional timeoutResume; lua_State* thread; - int status = FutureModule::Future::pollInternal(L, -1, thread, timeout); + int status = FutureModule::Future::pollInternal(L, -1, thread, timeoutResume); lua_pop(L, 1); + if (timeoutResume.IsSet() && timeout.IsSet()) { + timeout = FMath::Min(*timeout, *timeoutResume); + } else { + timeout.Reset(); + } if (status == LUA_OK) { shift += 1; } else if (shift > 0) { diff --git a/Source/FicsItNetworksLua/Private/FINLuaProcessor.cpp b/Source/FicsItNetworksLua/Private/FINLuaProcessor.cpp index a081de3c..141688e2 100644 --- a/Source/FicsItNetworksLua/Private/FINLuaProcessor.cpp +++ b/Source/FicsItNetworksLua/Private/FINLuaProcessor.cpp @@ -142,6 +142,10 @@ void UFINLuaProcessor::SetKernel(UFINKernelSystem* InKernel) { Kernel = InKernel; } void UFINLuaProcessor::Tick(float InDelta) { + if (GetKernel()->GetNetwork()->GetSignalCount() > 0) { + Runtime.Runtime.Timeout.Reset(); + } + Runtime.Run(); switch (Runtime.GetStatus()) { diff --git a/Source/FicsItNetworksLua/Public/FINLua/LuaFuture.h b/Source/FicsItNetworksLua/Public/FINLua/LuaFuture.h index 7e2bcbc1..337a266c 100644 --- a/Source/FicsItNetworksLua/Public/FINLua/LuaFuture.h +++ b/Source/FicsItNetworksLua/Public/FINLua/LuaFuture.h @@ -58,5 +58,5 @@ namespace FINLua { */ void luaFIN_addTask(lua_State* L, int index); - int luaFIN_futureRun(lua_State* L, int index); + int luaFIN_futureRun(lua_State* L, int index, TOptional& timeout); }