mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-04 02:41:19 +00:00
b4976354a5
When a loading screen appears during the frame processing, the frame number returned by the viewer is incremented and the stats reporting goes into the wrong frame. Pass frame number and stats object from the main thread to avoid this.
100 lines
2.6 KiB
C++
100 lines
2.6 KiB
C++
#include "worker.hpp"
|
|
|
|
#include "luamanagerimp.hpp"
|
|
|
|
#include "apps/openmw/profile.hpp"
|
|
|
|
#include <components/debug/debuglog.hpp>
|
|
#include <components/settings/values.hpp>
|
|
|
|
#include <cassert>
|
|
|
|
namespace MWLua
|
|
{
|
|
Worker::Worker(LuaManager& manager)
|
|
: mManager(manager)
|
|
{
|
|
if (Settings::lua().mLuaNumThreads > 0)
|
|
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();
|
|
}
|
|
}
|
|
|
|
void Worker::allowUpdate(osg::Timer_t frameStart, unsigned frameNumber, osg::Stats& stats)
|
|
{
|
|
if (!mThread)
|
|
return;
|
|
{
|
|
std::lock_guard<std::mutex> lk(mMutex);
|
|
mUpdateRequest = UpdateRequest{ .mFrameStart = frameStart, .mFrameNumber = frameNumber, .mStats = &stats };
|
|
}
|
|
mCV.notify_one();
|
|
}
|
|
|
|
void Worker::finishUpdate(osg::Timer_t frameStart, unsigned frameNumber, osg::Stats& stats)
|
|
{
|
|
if (mThread)
|
|
{
|
|
std::unique_lock<std::mutex> lk(mMutex);
|
|
mCV.wait(lk, [&] { return !mUpdateRequest.has_value(); });
|
|
}
|
|
else
|
|
update(frameStart, frameNumber, stats);
|
|
}
|
|
|
|
void Worker::join()
|
|
{
|
|
if (mThread)
|
|
{
|
|
{
|
|
std::lock_guard<std::mutex> lk(mMutex);
|
|
mJoinRequest = true;
|
|
}
|
|
mCV.notify_one();
|
|
mThread->join();
|
|
}
|
|
}
|
|
|
|
void Worker::update(osg::Timer_t frameStart, unsigned frameNumber, osg::Stats& stats)
|
|
{
|
|
const osg::Timer* const timer = osg::Timer::instance();
|
|
OMW::ScopedProfile<OMW::UserStatsType::Lua> profile(frameStart, frameNumber, *timer, stats);
|
|
|
|
mManager.update();
|
|
}
|
|
|
|
void Worker::run() noexcept
|
|
{
|
|
while (true)
|
|
{
|
|
std::unique_lock<std::mutex> lk(mMutex);
|
|
mCV.wait(lk, [&] { return mUpdateRequest.has_value() || mJoinRequest; });
|
|
if (mJoinRequest)
|
|
break;
|
|
|
|
assert(mUpdateRequest.has_value());
|
|
|
|
try
|
|
{
|
|
update(mUpdateRequest->mFrameStart, mUpdateRequest->mFrameNumber, *mUpdateRequest->mStats);
|
|
}
|
|
catch (const std::exception& e)
|
|
{
|
|
Log(Debug::Error) << "Failed to update LuaManager: " << e.what();
|
|
}
|
|
|
|
mUpdateRequest.reset();
|
|
lk.unlock();
|
|
mCV.notify_one();
|
|
}
|
|
}
|
|
}
|