2022-10-06 01:45:45 +02:00
|
|
|
#include "worker.hpp"
|
|
|
|
|
|
|
|
#include "luamanagerimp.hpp"
|
|
|
|
|
2023-12-26 14:38:39 +01:00
|
|
|
#include "apps/openmw/profile.hpp"
|
2022-10-06 01:45:45 +02:00
|
|
|
|
2023-07-31 15:58:39 +04:00
|
|
|
#include <components/debug/debuglog.hpp>
|
2023-04-25 23:35:51 +02:00
|
|
|
#include <components/settings/values.hpp>
|
2022-10-06 01:45:45 +02:00
|
|
|
|
2024-04-24 11:09:13 +02:00
|
|
|
#include <cassert>
|
2022-10-06 01:45:45 +02:00
|
|
|
|
|
|
|
namespace MWLua
|
|
|
|
{
|
2024-04-24 11:09:13 +02:00
|
|
|
Worker::Worker(LuaManager& manager)
|
2022-10-06 01:45:45 +02:00
|
|
|
: mManager(manager)
|
|
|
|
{
|
2023-04-25 23:35:51 +02:00
|
|
|
if (Settings::lua().mLuaNumThreads > 0)
|
2022-10-06 01:45:45 +02:00
|
|
|
mThread = std::thread([this] { run(); });
|
|
|
|
}
|
|
|
|
|
|
|
|
Worker::~Worker()
|
|
|
|
{
|
|
|
|
if (mThread && mThread->joinable())
|
|
|
|
{
|
|
|
|
Log(Debug::Error)
|
|
|
|
<< "Unexpected destruction of LuaWorker; likely there is an unhandled exception in the main thread.";
|
|
|
|
join();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-24 11:09:13 +02:00
|
|
|
void Worker::allowUpdate(osg::Timer_t frameStart, unsigned frameNumber, osg::Stats& stats)
|
2022-10-06 01:45:45 +02:00
|
|
|
{
|
|
|
|
if (!mThread)
|
|
|
|
return;
|
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> lk(mMutex);
|
2024-04-24 11:09:13 +02:00
|
|
|
mUpdateRequest = UpdateRequest{ .mFrameStart = frameStart, .mFrameNumber = frameNumber, .mStats = &stats };
|
2022-10-06 01:45:45 +02:00
|
|
|
}
|
|
|
|
mCV.notify_one();
|
|
|
|
}
|
|
|
|
|
2024-04-24 11:09:13 +02:00
|
|
|
void Worker::finishUpdate(osg::Timer_t frameStart, unsigned frameNumber, osg::Stats& stats)
|
2022-10-06 01:45:45 +02:00
|
|
|
{
|
|
|
|
if (mThread)
|
|
|
|
{
|
|
|
|
std::unique_lock<std::mutex> lk(mMutex);
|
2024-04-24 11:09:13 +02:00
|
|
|
mCV.wait(lk, [&] { return !mUpdateRequest.has_value(); });
|
2022-10-06 01:45:45 +02:00
|
|
|
}
|
|
|
|
else
|
2024-04-24 11:09:13 +02:00
|
|
|
update(frameStart, frameNumber, stats);
|
2022-10-06 01:45:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Worker::join()
|
|
|
|
{
|
|
|
|
if (mThread)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> lk(mMutex);
|
|
|
|
mJoinRequest = true;
|
|
|
|
}
|
|
|
|
mCV.notify_one();
|
|
|
|
mThread->join();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-24 11:09:13 +02:00
|
|
|
void Worker::update(osg::Timer_t frameStart, unsigned frameNumber, osg::Stats& stats)
|
2022-10-06 01:45:45 +02:00
|
|
|
{
|
2024-04-24 11:09:13 +02:00
|
|
|
const osg::Timer* const timer = osg::Timer::instance();
|
|
|
|
OMW::ScopedProfile<OMW::UserStatsType::Lua> profile(frameStart, frameNumber, *timer, stats);
|
2022-10-06 01:45:45 +02:00
|
|
|
|
|
|
|
mManager.update();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Worker::run() noexcept
|
|
|
|
{
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
std::unique_lock<std::mutex> lk(mMutex);
|
2024-04-24 11:09:13 +02:00
|
|
|
mCV.wait(lk, [&] { return mUpdateRequest.has_value() || mJoinRequest; });
|
2022-10-06 01:45:45 +02:00
|
|
|
if (mJoinRequest)
|
|
|
|
break;
|
|
|
|
|
2024-04-24 11:09:13 +02:00
|
|
|
assert(mUpdateRequest.has_value());
|
|
|
|
|
2023-07-31 15:58:39 +04:00
|
|
|
try
|
|
|
|
{
|
2024-04-24 11:09:13 +02:00
|
|
|
update(mUpdateRequest->mFrameStart, mUpdateRequest->mFrameNumber, *mUpdateRequest->mStats);
|
2023-07-31 15:58:39 +04:00
|
|
|
}
|
2024-04-24 11:09:13 +02:00
|
|
|
catch (const std::exception& e)
|
2023-07-31 15:58:39 +04:00
|
|
|
{
|
|
|
|
Log(Debug::Error) << "Failed to update LuaManager: " << e.what();
|
|
|
|
}
|
2022-10-06 01:45:45 +02:00
|
|
|
|
2024-04-24 11:09:13 +02:00
|
|
|
mUpdateRequest.reset();
|
2022-10-06 01:45:45 +02:00
|
|
|
lk.unlock();
|
|
|
|
mCV.notify_one();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|