diff options
Diffstat (limited to 'xbmc/utils/MovingSpeed.cpp')
-rw-r--r-- | xbmc/utils/MovingSpeed.cpp | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/xbmc/utils/MovingSpeed.cpp b/xbmc/utils/MovingSpeed.cpp new file mode 100644 index 0000000..1e4269e --- /dev/null +++ b/xbmc/utils/MovingSpeed.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2022 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "MovingSpeed.h" + +#include "utils/MathUtils.h" +#include "utils/TimeUtils.h" +#include "utils/log.h" + +void UTILS::MOVING_SPEED::CMovingSpeed::AddEventConfig(uint32_t eventId, + float acceleration, + float maxVelocity, + uint32_t resetTimeout) +{ + EventCfg eventCfg{acceleration, maxVelocity, resetTimeout}; + m_eventsData.emplace(eventId, EventData{eventCfg}); +} + +void UTILS::MOVING_SPEED::CMovingSpeed::AddEventConfig(uint32_t eventId, EventCfg event) +{ + m_eventsData.emplace(eventId, EventData{event}); +} + +void UTILS::MOVING_SPEED::CMovingSpeed::AddEventMapConfig(MapEventConfig& configs) +{ + for (auto& cfg : configs) + { + AddEventConfig(static_cast<uint32_t>(cfg.first), cfg.second); + } +} + +void UTILS::MOVING_SPEED::CMovingSpeed::Reset() +{ + m_currentEventId = 0; + for (auto& eventPair : m_eventsData) + { + Reset(eventPair.first); + } +} + +void UTILS::MOVING_SPEED::CMovingSpeed::Reset(uint32_t eventId) +{ + auto mapIt = m_eventsData.find(eventId); + if (mapIt == m_eventsData.end()) + { + CLog::LogF(LOGWARNING, "Cannot reset Event ID {} configuration", eventId); + } + else + { + EventData& event = mapIt->second; + event.m_currentVelocity = 1.0f; + event.m_lastFrameTime = 0; + } +} + +float UTILS::MOVING_SPEED::CMovingSpeed::GetUpdatedDistance(uint32_t eventId) +{ + auto mapEventIt = m_eventsData.find(eventId); + + if (mapEventIt == m_eventsData.end()) + { + CLog::LogF(LOGDEBUG, "No event set for event ID {}", eventId); + return 0; + } + + EventData& eventData = mapEventIt->second; + EventCfg& eventCfg = eventData.m_config; + + uint32_t currentFrameTime{CTimeUtils::GetFrameTime()}; + uint32_t deltaFrameTime{currentFrameTime - eventData.m_lastFrameTime}; + float distance = (eventCfg.m_delta == 0.0f) ? 1.0f : eventCfg.m_delta; + + if (eventData.m_lastFrameTime != 0 && deltaFrameTime > eventCfg.m_resetTimeout) + { + // If the delta time exceed the timeout then reset values + Reset(eventId); + } + else if (m_currentEventId != eventId) + { + // If the event id is changed then reset values + Reset(eventId); + } + else if (eventData.m_lastFrameTime != 0) + { + // Calculate the new speed based on time so as not to depend on the frame rate + eventData.m_currentVelocity += + eventCfg.m_acceleration * (static_cast<float>(deltaFrameTime) / 1000); + + if (eventCfg.m_maxVelocity > 0 && eventData.m_currentVelocity > eventCfg.m_maxVelocity) + eventData.m_currentVelocity = eventCfg.m_maxVelocity; + + distance = eventData.m_currentVelocity * (static_cast<float>(deltaFrameTime) / 1000); + if (eventCfg.m_delta > 0.0f) + distance = MathUtils::RoundF(distance, eventCfg.m_delta); + } + + m_currentEventId = eventId; + eventData.m_lastFrameTime = currentFrameTime; + return distance; +} + +UTILS::MOVING_SPEED::EventType UTILS::MOVING_SPEED::ParseEventType(std::string_view eventType) +{ + if (eventType == "up") + return EventType::UP; + else if (eventType == "down") + return EventType::DOWN; + else if (eventType == "left") + return EventType::LEFT; + else if (eventType == "right") + return EventType::RIGHT; + else + { + CLog::LogF(LOGERROR, "Unsupported event type \"{}\"", eventType); + return EventType::NONE; + } +} |