vectozavr-shooter/engine/animation/Timeline.cpp

112 lines
3.0 KiB
C++
Raw Normal View History

//
// Created by Иван Ильин on 03.10.2021.
//
#include <list>
2021-10-31 11:39:08 +03:00
#include "Animation.h"
2021-10-17 10:21:10 +03:00
#include "Timeline.h"
#include "../utils/Log.h"
2021-10-31 11:39:08 +03:00
Timeline *Timeline::_instance = nullptr;
2021-10-29 23:44:37 +03:00
bool Timeline::_validInstance = false;
2021-10-17 19:38:16 +03:00
void Timeline::init() {
_instance = new Timeline();
2021-10-29 23:44:37 +03:00
_validInstance = true;
Log::log("Timeline::init(): animation timeline was initialized");
2021-10-17 19:38:16 +03:00
}
2021-10-31 11:39:08 +03:00
void Timeline::animate(const AnimationListTag &listName, std::shared_ptr<Animation> anim) {
if (!_validInstance) {
2021-10-17 19:38:16 +03:00
return;
2021-10-28 16:58:02 +03:00
}
2021-10-17 19:38:16 +03:00
_instance->_animations[listName].emplace_back(anim);
Log::log("Timeline::animate(): add animation in '" + listName.str() + "' list");
2021-10-17 19:38:16 +03:00
}
2021-10-17 19:38:16 +03:00
void Timeline::deleteAllAnimations() {
2021-10-31 11:39:08 +03:00
if (!_validInstance) {
2021-10-17 19:38:16 +03:00
return;
2021-10-28 16:58:02 +03:00
}
2021-10-17 19:38:16 +03:00
int animCounter = 0;
2021-10-31 11:39:08 +03:00
for (auto&[listName, animationList] : _instance->_animations) {
animCounter += animationList.size();
2021-10-17 19:38:16 +03:00
animationList.clear();
}
2021-10-17 19:38:16 +03:00
_instance->_animations.clear();
2021-10-31 11:39:08 +03:00
Log::log("Timeline::deleteAllAnimations(): all " + std::to_string(animCounter) + " animations was deleted");
2021-10-17 19:38:16 +03:00
}
2021-10-31 11:39:08 +03:00
void Timeline::deleteAnimationList(const AnimationListTag &listName) {
if (!_validInstance) {
2021-10-17 19:38:16 +03:00
return;
2021-10-28 16:58:02 +03:00
}
2021-10-17 19:38:16 +03:00
int animCounter = _instance->_animations[listName].size();
2021-10-17 19:38:16 +03:00
_instance->_animations[listName].clear();
_instance->_animations.erase(listName);
2021-10-31 11:39:08 +03:00
Log::log("Timeline::deleteAnimationList(): list '" + listName.str() + "' with " + std::to_string(animCounter) +
" animations was deleted");
2021-10-17 19:38:16 +03:00
}
2021-10-31 11:39:08 +03:00
[[nodiscard]] bool Timeline::isInAnimList(const AnimationListTag &listName) {
if (!_validInstance) {
2021-10-17 19:38:16 +03:00
return false;
2021-10-28 16:58:02 +03:00
}
2021-10-17 19:38:16 +03:00
return !_instance->_animations[listName].empty();
}
void Timeline::update() {
2021-10-31 11:39:08 +03:00
if (!_validInstance) {
2021-10-17 19:38:16 +03:00
return;
2021-10-28 16:58:02 +03:00
}
2021-10-17 19:38:16 +03:00
// TODO: sometimes I catch an exception here: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
2021-10-31 11:39:08 +03:00
for (auto&[listName, animationList] : _instance->_animations) {
2021-10-28 16:58:02 +03:00
if (animationList.empty()) {
/*
* TODO If you delete this line you will not catch an exception.
* Maybe something wrong with std::map::erase()
*/
_instance->_animations.erase(listName);
2021-10-17 19:38:16 +03:00
continue;
2021-10-28 16:58:02 +03:00
}
2021-10-17 19:38:16 +03:00
auto it = animationList.begin();
// If it the front animation is 'a_wait()' we should wait until waiting time is over
if (it.operator*()->waitFor()) {
2021-10-28 16:58:02 +03:00
if (!it.operator*()->updateState()) {
2021-10-17 19:38:16 +03:00
animationList.erase(it);
2021-10-28 16:58:02 +03:00
}
2021-10-17 19:38:16 +03:00
continue;
}
// Otherwise we iterate over all animation until we meet animations.end() or wait animation
while (!animationList.empty() && (it != animationList.end()) && (!it.operator*()->waitFor())) {
2021-10-28 16:58:02 +03:00
if (!it.operator*()->updateState()) {
2021-10-17 19:38:16 +03:00
animationList.erase(it++);
2021-10-28 16:58:02 +03:00
} else {
2021-10-17 19:38:16 +03:00
it++;
2021-10-28 16:58:02 +03:00
}
}
}
}
2021-10-17 19:38:16 +03:00
void Timeline::free() {
Timeline::deleteAllAnimations();
2021-10-29 23:44:37 +03:00
_validInstance = false;
2021-10-17 19:38:16 +03:00
delete _instance;
Log::log("Timeline::free(): pointer to 'Timeline' was freed");
2021-10-17 19:38:16 +03:00
}