Skip to content

Commit

Permalink
Merge pull request #147 from JacobDomagala/144-consider-using-stdvect…
Browse files Browse the repository at this point in the history
…or-or-stdarray-instead-of-stddeque-for-time-rewinding

[#144]: Add StateList struct to replace using std::deque
  • Loading branch information
JacobDomagala authored Oct 26, 2023
2 parents 2ec6d15 + da5d404 commit 37d79bc
Show file tree
Hide file tree
Showing 14 changed files with 149 additions and 139 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/code_quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
echo "#!/bin/bash
root_dir=\${1}
build_dir=\${2}
pip install conan==1.59.0
pip install conan==1.59.0 --break-system-packages
conan install \$root_dir --install-folder=build --build=missing --settings=build_type=Release -c tools.system.package_manager:mode=install
wget https://sdk.lunarg.com/sdk/download/1.3.216.0/linux/vulkansdk-linux-x86_64-1.3.216.0.tar.gz
tar xf vulkansdk-linux-x86_64-1.3.216.0.tar.gz -C \$root_dir/dependencies
Expand All @@ -32,4 +32,4 @@ jobs:
apt_pckgs: xorg-dev python3-pip
verbose: true
cppcheck_args: |
--enable=all --suppress=functionStatic --suppress=unusedFunction --inline-suppr --inconclusive
--enable=all --suppress=missingIncludeSystem --suppress=functionStatic --suppress=unusedFunction --inline-suppr --inconclusive
49 changes: 49 additions & 0 deletions engine/core/state_list.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#pragma once

#include "common.hpp"

namespace looper {

template < typename StateT > struct StateList
{
int32_t
GetNumFrames() const
{
return numFrames_;
}

const StateT&
PeekLastState() const
{
auto lastIdx = (lastIdx_ == 0) ? lastFrame_ : lastIdx_;
return frames_.at(static_cast< uint32_t >(lastIdx - 1));
}

const StateT&
GetLastState()
{
lastIdx_ = (lastIdx_ == 0) ? lastFrame_ : lastIdx_;
const auto& frame = frames_.at(static_cast< uint32_t >(lastIdx_ - 1));

lastIdx_--;
numFrames_--;
return frame;
}

void
PushState(const StateT& newState)
{
frames_.at(static_cast< uint32_t >(lastIdx_++)) = newState;
lastIdx_ = (lastIdx_ == lastFrame_) ? 0 : lastIdx_;
numFrames_++;
}

private:
std::array< StateT, NUM_FRAMES_TO_SAVE > frames_ = {};
int32_t numFrames_ = {};
int32_t firstIdx_ = {};
int32_t lastIdx_ = {};
const int32_t lastFrame_ = NUM_FRAMES_TO_SAVE - 1;
};

} // namespace looper
154 changes: 71 additions & 83 deletions engine/game/animatable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,54 +26,51 @@ Animatable::GetAnimationType() const
void
Animatable::UpdateAnimationPoint()
{
m_currentAnimationState.m_isReverse ? --m_currentAnimationState.m_currentAnimationPoint
: ++m_currentAnimationState.m_currentAnimationPoint;
currentState_.m_isReverse ? --currentState_.m_currentAnimationPoint
: ++currentState_.m_currentAnimationPoint;

auto updateReverseAnimation = [this]() {
m_currentAnimationState.m_currentAnimationBegin =
m_currentAnimationState.m_currentAnimationPoint->m_end;
currentState_.m_currentAnimationBegin = currentState_.m_currentAnimationPoint->m_end;

if (m_currentAnimationState.m_currentAnimationPoint != m_animationPoints.begin())
if (currentState_.m_currentAnimationPoint != m_animationPoints.begin())
{
auto previousStep = std::prev(m_currentAnimationState.m_currentAnimationPoint);
m_currentAnimationState.m_currentAnimationEnd = previousStep->m_end;
auto previousStep = std::prev(currentState_.m_currentAnimationPoint);
currentState_.m_currentAnimationEnd = previousStep->m_end;
}
else
{
m_currentAnimationState.m_currentAnimationEnd = m_animationStartPosition;
currentState_.m_currentAnimationEnd = m_animationStartPosition;
}
};

// If forward pass is finished
if (m_currentAnimationState.m_currentAnimationPoint == m_animationPoints.end())
if (currentState_.m_currentAnimationPoint == m_animationPoints.end())
{
// For reversable animations start going back
if (m_type == Animatable::ANIMATION_TYPE::REVERSABLE)
{
m_currentAnimationState.m_isReverse = true;
--m_currentAnimationState.m_currentAnimationPoint;
currentState_.m_isReverse = true;
--currentState_.m_currentAnimationPoint;

updateReverseAnimation();
}
// For loop animation position on the end
else
{
ResetAnimation();
m_currentAnimationState.m_animationFinished = true;
currentState_.m_animationFinished = true;
}
}
else
{
if (m_currentAnimationState.m_isReverse)
if (currentState_.m_isReverse)
{
updateReverseAnimation();
}
else
{
m_currentAnimationState.m_currentAnimationBegin =
m_currentAnimationState.m_currentAnimationEnd;
m_currentAnimationState.m_currentAnimationEnd =
m_currentAnimationState.m_currentAnimationPoint->m_end;
currentState_.m_currentAnimationBegin = currentState_.m_currentAnimationEnd;
currentState_.m_currentAnimationEnd = currentState_.m_currentAnimationPoint->m_end;
}
}
}
Expand All @@ -86,21 +83,21 @@ Animatable::SetCorrectAnimationPoint(time::milliseconds& updateTime)
ResetAnimation();

auto animationDurationMs =
time::Timer::ConvertToMs(m_currentAnimationState.m_currentAnimationPoint->m_timeDuration);
time::Timer::ConvertToMs(currentState_.m_currentAnimationPoint->m_timeDuration);

if (updateTime >= animationDurationMs)
{
do
{
updateTime -= animationDurationMs;
animationValue += m_currentAnimationState.m_currentAnimationEnd
- m_currentAnimationState.m_currentAnimationBegin;
animationValue +=
currentState_.m_currentAnimationEnd - currentState_.m_currentAnimationBegin;

UpdateAnimationPoint();
animationDurationMs =
time::Timer::ConvertToMs(m_currentAnimationState.m_currentAnimationPoint->m_timeDuration);
time::Timer::ConvertToMs(currentState_.m_currentAnimationPoint->m_timeDuration);
} while (updateTime >= animationDurationMs
&& m_currentAnimationState.m_currentAnimationPoint != m_animationPoints.begin());
&& currentState_.m_currentAnimationPoint != m_animationPoints.begin());
}

return animationValue;
Expand All @@ -109,22 +106,21 @@ Animatable::SetCorrectAnimationPoint(time::milliseconds& updateTime)
glm::vec2
Animatable::CalculateNextStep(time::milliseconds updateTime) const
{
const auto startPosition = m_currentAnimationState.m_currentAnimationBegin;
const auto destination = m_currentAnimationState.m_currentAnimationEnd;
const auto startPosition = currentState_.m_currentAnimationBegin;
const auto destination = currentState_.m_currentAnimationEnd;
const auto animationDurationMs =
time::Timer::ConvertToMs(m_currentAnimationState.m_currentAnimationPoint->m_timeDuration);
time::Timer::ConvertToMs(currentState_.m_currentAnimationPoint->m_timeDuration);

const auto timeLeft = static_cast< float >(
(animationDurationMs - m_currentAnimationState.m_currentTimeElapsed).count());
const auto timeLeft =
static_cast< float >((animationDurationMs - currentState_.m_currentTimeElapsed).count());

// Make sure we don't divide by 0
const auto sizeOfStep =
(timeLeft > 0.0f) ? (static_cast< float >(updateTime.count()) / timeLeft) : 0.0f;

const auto currentAnimationSectonLength = destination - startPosition;
const auto currentAnimationStepSize =
(currentAnimationSectonLength - m_currentAnimationState.m_currentAnimationDistance)
* sizeOfStep;
(currentAnimationSectonLength - currentState_.m_currentAnimationDistance) * sizeOfStep;

return currentAnimationStepSize;
}
Expand All @@ -135,9 +131,9 @@ Animatable::AnimateInCurrentSection(time::milliseconds updateTime)
auto animationValue = CalculateNextStep(updateTime);

// Object position after adding animation step
m_currentAnimationState.m_currentAnimationPosition += animationValue;
m_currentAnimationState.m_currentAnimationDistance += animationValue;
m_currentAnimationState.m_currentTimeElapsed += updateTime;
currentState_.m_currentAnimationPosition += animationValue;
currentState_.m_currentAnimationDistance += animationValue;
currentState_.m_currentTimeElapsed += updateTime;

return animationValue;
}
Expand All @@ -156,24 +152,23 @@ Animatable::Animate(time::milliseconds updateTime)
{
auto animateBy = glm::vec2();

m_currentAnimationState.m_animationFinished = false;
currentState_.m_animationFinished = false;

auto currentAnimationStepSize = AnimateInCurrentSection(updateTime);
if (m_currentAnimationState.m_currentTimeElapsed
< m_currentAnimationState.m_currentAnimationPoint->m_timeDuration)
if (currentState_.m_currentTimeElapsed < currentState_.m_currentAnimationPoint->m_timeDuration)
{
animateBy = currentAnimationStepSize;
}
else
{
m_currentAnimationState.m_currentTimeElapsed = time::milliseconds(0);
m_currentAnimationState.m_currentAnimationDistance = glm::vec2(0.0f, 0.0f);
currentState_.m_currentTimeElapsed = time::milliseconds(0);
currentState_.m_currentAnimationDistance = glm::vec2(0.0f, 0.0f);

if (m_currentAnimationState.m_isReverse
&& m_animationPoints.begin() == m_currentAnimationState.m_currentAnimationPoint)
if (currentState_.m_isReverse
&& m_animationPoints.begin() == currentState_.m_currentAnimationPoint)
{
ResetAnimation();
m_currentAnimationState.m_animationFinished = true;
currentState_.m_animationFinished = true;
}
else
{
Expand All @@ -187,9 +182,9 @@ Animatable::Animate(time::milliseconds updateTime)
glm::vec2
Animatable::SingleAnimate(time::milliseconds updateTime)
{
if (m_currentAnimationState.m_animationFinished)
if (currentState_.m_animationFinished)
{
m_currentAnimationState.m_animationFinished = false;
currentState_.m_animationFinished = false;
return glm::vec2{};
}

Expand All @@ -200,8 +195,8 @@ AnimationPoint
Animatable::CreateAnimationNode(Object::ID parentID, const glm::vec2& position)
{
const auto nodePosition = m_animationPoints.empty()
? position
: m_animationPoints.back().m_end + glm::vec2(20.0f, 20.0f);
? position
: m_animationPoints.back().m_end + glm::vec2(20.0f, 20.0f);
auto newNode = AnimationPoint(parentID, nodePosition, time::seconds(2));
AddAnimationNode(newNode);

Expand Down Expand Up @@ -246,8 +241,7 @@ Animatable::DeleteAnimationNode(Object::ID animationID)
}
else
{
Logger::Warn("Attempting to remove non existing node with ID={}",
animationID);
Logger::Warn("Attempting to remove non existing node with ID={}", animationID);
}
}

Expand Down Expand Up @@ -290,16 +284,11 @@ Animatable::Update(bool isReverse)
{
if (isReverse)
{
m_currentAnimationState = m_animationStatesQueue.back();
m_animationStatesQueue.pop_back();
currentState_ = statesQueue_.GetLastState();
}
else
{
m_animationStatesQueue.push_back(m_currentAnimationState);
if (m_animationStatesQueue.size() >= NUM_FRAMES_TO_SAVE)
{
m_animationStatesQueue.pop_front();
}
statesQueue_.PushState(currentState_);
}
}

Expand All @@ -311,52 +300,51 @@ Animatable::UpdateNodes()
void
Animatable::ResetAnimation()
{
m_currentAnimationState.m_currentAnimationPoint = m_animationPoints.begin();
m_currentAnimationState.m_currentAnimationBegin = m_animationStartPosition;
m_currentAnimationState.m_currentAnimationEnd =
m_animationPoints.empty() ? m_animationStartPosition
: m_currentAnimationState.m_currentAnimationPoint->m_end;
m_currentAnimationState.m_currentAnimationPosition = m_animationStartPosition;
m_currentAnimationState.m_currentAnimationDistance = glm::vec2(0.0f, 0.0f);
m_currentAnimationState.m_isReverse = false;
m_currentAnimationState.m_animationFinished = false;
m_currentAnimationState.m_currentTimeElapsed = time::milliseconds(0);
m_currentAnimationState.m_totalTimeElapsed = time::milliseconds(0);
currentState_.m_currentAnimationPoint = m_animationPoints.begin();
currentState_.m_currentAnimationBegin = m_animationStartPosition;
currentState_.m_currentAnimationEnd = m_animationPoints.empty()
? m_animationStartPosition
: currentState_.m_currentAnimationPoint->m_end;
currentState_.m_currentAnimationPosition = m_animationStartPosition;
currentState_.m_currentAnimationDistance = glm::vec2(0.0f, 0.0f);
currentState_.m_isReverse = false;
currentState_.m_animationFinished = false;
currentState_.m_currentTimeElapsed = time::milliseconds(0);
currentState_.m_totalTimeElapsed = time::milliseconds(0);
}

void
Animatable::UpdateAnimationData()
{
if (m_currentAnimationState.m_isReverse)
if (currentState_.m_isReverse)
{
if (m_currentAnimationState.m_currentAnimationPoint != m_animationPoints.begin())
if (currentState_.m_currentAnimationPoint != m_animationPoints.begin())
{
m_currentAnimationState.m_currentAnimationEnd =
std::prev(m_currentAnimationState.m_currentAnimationPoint)->m_end;
currentState_.m_currentAnimationEnd =
std::prev(currentState_.m_currentAnimationPoint)->m_end;
}
else
{
m_currentAnimationState.m_currentAnimationEnd = m_animationStartPosition;
currentState_.m_currentAnimationEnd = m_animationStartPosition;
}

m_currentAnimationState.m_currentAnimationBegin =
m_currentAnimationState.m_currentAnimationPoint->m_end;
currentState_.m_currentAnimationBegin = currentState_.m_currentAnimationPoint->m_end;
}
else
{
if (m_currentAnimationState.m_currentAnimationPoint != m_animationPoints.begin())
if (currentState_.m_currentAnimationPoint != m_animationPoints.begin())
{
m_currentAnimationState.m_currentAnimationBegin =
std::prev(m_currentAnimationState.m_currentAnimationPoint)->m_end;
currentState_.m_currentAnimationBegin =
std::prev(currentState_.m_currentAnimationPoint)->m_end;
}
else
{
m_currentAnimationState.m_currentAnimationBegin = m_animationStartPosition;
currentState_.m_currentAnimationBegin = m_animationStartPosition;
}

m_currentAnimationState.m_currentAnimationEnd =
m_animationPoints.empty() ? m_animationStartPosition
: m_currentAnimationState.m_currentAnimationPoint->m_end;
currentState_.m_currentAnimationEnd = m_animationPoints.empty()
? m_animationStartPosition
: currentState_.m_currentAnimationPoint->m_end;
}
}

Expand Down Expand Up @@ -389,12 +377,12 @@ Animatable::SetAnimationStartLocation(const glm::vec2& position)
{
m_animationStartPosition = position;

if (m_currentAnimationState.m_currentAnimationPoint == m_animationPoints.begin())
if (currentState_.m_currentAnimationPoint == m_animationPoints.begin())
{
m_currentAnimationState.m_currentAnimationBegin = m_animationStartPosition;
m_currentAnimationState.m_currentAnimationPosition = m_animationStartPosition;
m_currentAnimationState.m_currentAnimationDistance = glm::vec2(0.0f, 0.0f);
m_currentAnimationState.m_currentTimeElapsed = time::milliseconds(0);
currentState_.m_currentAnimationBegin = m_animationStartPosition;
currentState_.m_currentAnimationPosition = m_animationStartPosition;
currentState_.m_currentAnimationDistance = glm::vec2(0.0f, 0.0f);
currentState_.m_currentTimeElapsed = time::milliseconds(0);
}
}

Expand Down
Loading

0 comments on commit 37d79bc

Please sign in to comment.