mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-22 14:13:45 +00:00
committed by
Konstantin Pastbin
parent
c9cbb64f12
commit
76ffc99abd
148
libs/drape_frontend/scenario_manager.cpp
Normal file
148
libs/drape_frontend/scenario_manager.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
#include "drape_frontend/scenario_manager.hpp"
|
||||
|
||||
#include "drape_frontend/user_event_stream.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace df
|
||||
{
|
||||
|
||||
ScenarioManager::ScenarioManager(FrontendRenderer * frontendRenderer)
|
||||
: m_frontendRenderer(frontendRenderer)
|
||||
, m_needInterrupt(false)
|
||||
, m_isFinished(false)
|
||||
{
|
||||
ASSERT(m_frontendRenderer != nullptr, ());
|
||||
}
|
||||
|
||||
ScenarioManager::~ScenarioManager()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (m_thread != nullptr)
|
||||
{
|
||||
m_thread->join();
|
||||
m_thread.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void ScenarioManager::Interrupt()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
InterruptImpl();
|
||||
}
|
||||
|
||||
bool ScenarioManager::RunScenario(ScenarioData && scenarioData, ScenarioCallback const & onStartFn, ScenarioCallback const & onFinishFn)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (m_thread != nullptr)
|
||||
{
|
||||
if (m_isFinished)
|
||||
InterruptImpl();
|
||||
else
|
||||
return false; // The only scenario can be executed currently.
|
||||
}
|
||||
|
||||
std::swap(m_scenarioData, scenarioData);
|
||||
m_onStartHandler = onStartFn;
|
||||
m_onFinishHandler = onFinishFn;
|
||||
m_thread = std::make_unique<threads::SimpleThread>(&ScenarioManager::ThreadRoutine, this);
|
||||
#ifdef DEBUG
|
||||
m_threadId = m_thread->get_id();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScenarioManager::IsRunning()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (m_thread == nullptr)
|
||||
return false;
|
||||
|
||||
if (m_isFinished)
|
||||
{
|
||||
InterruptImpl();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScenarioManager::ThreadRoutine()
|
||||
{
|
||||
std::string const scenarioName = m_scenarioData.m_name;
|
||||
if (m_onStartHandler != nullptr)
|
||||
m_onStartHandler(scenarioName);
|
||||
|
||||
for (auto const & action : m_scenarioData.m_scenario)
|
||||
{
|
||||
// Interrupt scenario if it's necessary.
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (m_needInterrupt)
|
||||
{
|
||||
m_needInterrupt = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(action->GetType())
|
||||
{
|
||||
case ActionType::CenterViewport:
|
||||
{
|
||||
CenterViewportAction * centerViewportAction = static_cast<CenterViewportAction *>(action.get());
|
||||
m_frontendRenderer->AddUserEvent(make_unique_dp<SetCenterEvent>(centerViewportAction->GetCenter(),
|
||||
centerViewportAction->GetZoomLevel(),
|
||||
true /* isAnim */,
|
||||
false /* trackVisibleViewport */,
|
||||
nullptr /* parallelAnimCreator */));
|
||||
break;
|
||||
}
|
||||
|
||||
case ActionType::WaitForTime:
|
||||
{
|
||||
WaitForTimeAction * waitForTimeAction = static_cast<WaitForTimeAction *>(action.get());
|
||||
std::this_thread::sleep_for(waitForTimeAction->GetDuration());
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
LOG(LINFO, ("Unknown action in scenario"));
|
||||
}
|
||||
}
|
||||
|
||||
ScenarioCallback handler = nullptr;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
m_scenarioData.m_scenario.clear();
|
||||
m_isFinished = true;
|
||||
if (m_onFinishHandler != nullptr)
|
||||
{
|
||||
handler = m_onFinishHandler;
|
||||
m_onFinishHandler = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (handler != nullptr)
|
||||
handler(scenarioName);
|
||||
}
|
||||
|
||||
void ScenarioManager::InterruptImpl()
|
||||
{
|
||||
if (m_thread == nullptr)
|
||||
return;
|
||||
|
||||
ASSERT_NOT_EQUAL(m_threadId, std::this_thread::get_id(), ());
|
||||
|
||||
if (m_isFinished)
|
||||
{
|
||||
m_thread->join();
|
||||
m_thread.reset();
|
||||
m_isFinished = false;
|
||||
m_needInterrupt = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_needInterrupt = true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace df
|
||||
Reference in New Issue
Block a user