1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-22 02:12:45 +01:00

rwlib/rwengine: Use AnimationPtr instead of Animation*

Should fix these memory leaks:
==31441== 3,694,699 (17,248 direct, 3,677,451 indirect) bytes in 196 blocks are definitely lost in loss record 2,720 of 2,723
==31441==    at 0x4C2F1CA: operator new(unsigned long) (vg_replace_malloc.c:334)
==31441==    by 0x81D98E: LoaderIFP::loadFromMemory(char*) (LoaderIFP.cpp:69)
==31441==    by 0x7BE5D2: GameData::loadIFP(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (GameData.cpp:506)
==31441==    by 0x7B9B4A: GameData::load() (GameData.cpp:59)
==31441==    by 0x7590C5: RWGame::RWGame(Logger&, int, char**) (RWGame.cpp:51)
==31441==    by 0x749175: main (main.cpp:13)
==31441==
==31441== 5,298,984 (1,080 direct, 5,297,904 indirect) bytes in 15 blocks are definitely lost in loss record 2,722 of 2,723
==31441==    at 0x4C2F1CA: operator new(unsigned long) (vg_replace_malloc.c:334)
==31441==    by 0x820253: __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> > >::allocate(unsigned long, void const*) (new_allocator.h:111)
==31441==    by 0x820175: std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> > > >::allocate(std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> > >&, unsigned long) (alloc_traits.h:436)
==31441==    by 0x81FFB4: std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> > >::_M_get_node() (stl_tree.h:588)
==31441==    by 0x81FE03: std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> >* std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> > >::_M_create_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> const&>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> const&) (stl_tree.h:642)
==31441==    by 0x81FC26: std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> >* std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> > >::_Alloc_node::operator()<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> const&>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> const&) const (stl_tree.h:556)
==31441==    by 0x81F620: std::_Rb_tree_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> > std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> > >::_M_insert_<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> const&, std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> > >::_Alloc_node>(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> const&, std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> > >::_Alloc_node&) (stl_tree.h:1753)
==31441==    by 0x81EDFD: std::pair<std::_Rb_tree_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> >, bool> std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> > >::_M_insert_unique<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> const&>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> const&) (stl_tree.h:2096)
==31441==    by 0x81E9F0: std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, AnimationBone*, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> > >::insert(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, AnimationBone*> const&) (stl_map.h:796)
==31441==    by 0x81E0BB: LoaderIFP::loadFromMemory(char*) (LoaderIFP.cpp:132)
==31441==    by 0x7BE5D2: GameData::loadIFP(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (GameData.cpp:506)
==31441==    by 0x7E4060: GameWorld::loadCutscene(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (GameWorld.cpp:692)
This commit is contained in:
Anonymous Maarten 2017-09-13 02:37:24 +02:00 committed by Daniel Evans
parent 5ff31db04f
commit c2da40d0a0
14 changed files with 36 additions and 31 deletions

View File

@ -2,7 +2,9 @@
#define RWENGINE_DATA_ANIMGROUP_HPP #define RWENGINE_DATA_ANIMGROUP_HPP
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
#include "rw/types.hpp"
#include <rw/forward.hpp>
#include <rw/types.hpp>
struct Animation; struct Animation;
@ -195,7 +197,7 @@ struct AnimCycleInfo {
/// Flags /// Flags
uint32_t flags; uint32_t flags;
/// The actual animation /// The actual animation
Animation* anim = nullptr; AnimationPtr anim = nullptr;
AnimCycleInfo(const std::string& name = "", uint32_t flags = 0) AnimCycleInfo(const std::string& name = "", uint32_t flags = 0)
: name(name), flags(flags) { : name(name), flags(flags) {
@ -208,7 +210,7 @@ struct AnimGroup {
/* Animations */ /* Animations */
AnimCycleInfo animations_[static_cast<uint32_t>(AnimCycle::_CycleCount)]; AnimCycleInfo animations_[static_cast<uint32_t>(AnimCycle::_CycleCount)];
Animation* animation(AnimCycle cycle) const { AnimationPtr animation(AnimCycle cycle) const {
return animations_[static_cast<uint32_t>(cycle)].anim; return animations_[static_cast<uint32_t>(cycle)].anim;
} }

View File

@ -27,7 +27,7 @@ class Animator {
* animations * animations
*/ */
struct AnimationState { struct AnimationState {
Animation* animation; AnimationPtr animation;
/// Timestamp of the last frame /// Timestamp of the last frame
float time; float time;
/// Speed multiplier /// Speed multiplier
@ -50,14 +50,14 @@ class Animator {
public: public:
Animator(ClumpPtr model); Animator(ClumpPtr model);
Animation* getAnimation(unsigned int slot) { AnimationPtr getAnimation(unsigned int slot) {
if (slot < animations.size()) { if (slot < animations.size()) {
return animations[slot].animation; return animations[slot].animation;
} }
return nullptr; return nullptr;
} }
void playAnimation(unsigned int slot, Animation* anim, float speed, void playAnimation(unsigned int slot, AnimationPtr anim, float speed,
bool repeat) { bool repeat) {
if (slot >= animations.size()) { if (slot >= animations.size()) {
animations.resize(slot + 1); animations.resize(slot + 1);

View File

@ -66,7 +66,7 @@ bool LoaderIFP::loadFromMemory(char* data) {
/*NAME* n =*/read<NAME>(data, dataI); /*NAME* n =*/read<NAME>(data, dataI);
std::string animname = readString(data, dataI); std::string animname = readString(data, dataI);
Animation* animation = new Animation; auto animation = std::make_shared<Animation>();
animation->duration = 0.f; animation->duration = 0.f;
animation->name = animname; animation->name = animname;

View File

@ -8,6 +8,8 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "rw/forward.hpp"
struct AnimationKeyframe { struct AnimationKeyframe {
glm::quat rotation; glm::quat rotation;
glm::vec3 position; glm::vec3 position;
@ -105,7 +107,7 @@ public:
std::string name; std::string name;
}; };
std::map<std::string, Animation*> animations; AnimationSet animations;
bool loadFromMemory(char* data); bool loadFromMemory(char* data);
}; };

View File

@ -122,8 +122,8 @@ glm::vec3 CharacterObject::updateMovementAnimation(float dt) {
return glm::vec3(); return glm::vec3();
} }
Animation* movementAnimation = animations->animation(AnimCycle::Idle); AnimationPtr movementAnimation = animations->animation(AnimCycle::Idle);
Animation* currentAnim = animator->getAnimation(AnimIndexMovement); AnimationPtr currentAnim = animator->getAnimation(AnimIndexMovement);
bool isActionHappening = bool isActionHappening =
(animator->getAnimation(AnimIndexAction) != nullptr); (animator->getAnimation(AnimIndexAction) != nullptr);
float animationSpeed = 1.f; float animationSpeed = 1.f;
@ -173,7 +173,7 @@ glm::vec3 CharacterObject::updateMovementAnimation(float dt) {
movementAnimation = animations->animation(AnimCycle::Walk); movementAnimation = animations->animation(AnimCycle::Walk);
} }
} else { } else {
// Keep walkin // Keep walking
movementAnimation = animations->animation(AnimCycle::Walk); movementAnimation = animations->animation(AnimCycle::Walk);
} }
} }
@ -533,7 +533,7 @@ void CharacterObject::resetToAINode() {
} }
} }
void CharacterObject::playActivityAnimation(Animation* animation, bool repeat, void CharacterObject::playActivityAnimation(AnimationPtr animation, bool repeat,
bool blocked) { bool blocked) {
RW_CHECK(animator != nullptr, "No Animator"); RW_CHECK(animator != nullptr, "No Animator");
animator->playAnimation(AnimIndexAction, animation, 1.f, repeat); animator->playAnimation(AnimIndexAction, animation, 1.f, repeat);
@ -554,7 +554,7 @@ void CharacterObject::playCycle(AnimCycle cycle) {
flags & AnimCycleInfo::Repeat); flags & AnimCycleInfo::Repeat);
} }
void CharacterObject::playCycleAnimOverride(AnimCycle cycle, Animation* anim) { void CharacterObject::playCycleAnimOverride(AnimCycle cycle, AnimationPtr anim) {
auto flags = animations->flags(cycle); auto flags = animations->flags(cycle);
cycle_ = cycle; cycle_ = cycle;

View File

@ -185,7 +185,7 @@ public:
* This allows controller activities to play their own animations and * This allows controller activities to play their own animations and
* controll blending with movement. * controll blending with movement.
*/ */
void playActivityAnimation(Animation* animation, bool repeat, void playActivityAnimation(AnimationPtr animation, bool repeat,
bool blocking); bool blocking);
/** /**
* @brief activityFinished removes activity animation * @brief activityFinished removes activity animation
@ -205,7 +205,7 @@ public:
* This sets the same state as playCycle, but provides an alternate * This sets the same state as playCycle, but provides an alternate
* animation to play. * animation to play.
*/ */
void playCycleAnimOverride(AnimCycle cycle, Animation* anim); void playCycleAnimOverride(AnimCycle cycle, AnimationPtr anim);
AnimCycle getCurrentCycle() const { AnimCycle getCurrentCycle() const {
return cycle_; return cycle_;

View File

@ -8115,7 +8115,7 @@ void opcode_02e6(const ScriptArguments& args, const ScriptObject object, const S
auto cutscene = args.getObject<CutsceneObject>(0); auto cutscene = args.getObject<CutsceneObject>(0);
std::string animName = arg2; std::string animName = arg2;
std::transform(animName.begin(), animName.end(), animName.begin(), ::tolower); std::transform(animName.begin(), animName.end(), animName.begin(), ::tolower);
Animation* anim = args.getWorld()->data->animations[animName]; auto anim = args.getWorld()->data->animations[animName];
if( anim ) { if( anim ) {
cutscene->animator->playAnimation(AnimIndexMovement, anim, 1.f, false); cutscene->animator->playAnimation(AnimIndexMovement, anim, 1.f, false);
} }
@ -8322,7 +8322,7 @@ void opcode_02f5(const ScriptArguments& args, const ScriptObject object, const S
GameObject* head = args.getObject<CutsceneObject>(0); GameObject* head = args.getObject<CutsceneObject>(0);
std::string animName = args[1].string; std::string animName = args[1].string;
std::transform(animName.begin(), animName.end(), animName.begin(), ::tolower); std::transform(animName.begin(), animName.end(), animName.begin(), ::tolower);
Animation* anim = args.getWorld()->data->animations[animName]; auto anim = args.getWorld()->data->animations[animName];
if( anim ) { if( anim ) {
head->animator->playAnimation(AnimIndexMovement, anim, 1.f, false); head->animator->playAnimation(AnimIndexMovement, anim, 1.f, false);
} }

View File

@ -1,10 +1,12 @@
#ifndef RWLIB_FORWARD_HPP #ifndef RWLIB_FORWARD_HPP
#define RWLIB_FORWARD_HPP #define RWLIB_FORWARD_HPP
#include <map>
#include <memory> #include <memory>
#include <vector> #include <vector>
// Forward Declarations // Forward Declarations
struct Animation;
class Clump; class Clump;
class ModelFrame; class ModelFrame;
struct Geometry; struct Geometry;
@ -12,11 +14,14 @@ class Atomic;
class Clump; class Clump;
// Pointer types // Pointer types
using AnimationPtr = std::shared_ptr<Animation>;
using ModelFramePtr = std::shared_ptr<ModelFrame>; using ModelFramePtr = std::shared_ptr<ModelFrame>;
using GeometryPtr = std::shared_ptr<Geometry>; using GeometryPtr = std::shared_ptr<Geometry>;
using AtomicPtr = std::shared_ptr<Atomic>; using AtomicPtr = std::shared_ptr<Atomic>;
using AtomicList = std::vector<AtomicPtr>;
using ClumpPtr = std::shared_ptr<Clump>; using ClumpPtr = std::shared_ptr<Clump>;
#endif /* FORWARD_HPP */ // Collections
using AtomicList = std::vector<AtomicPtr>;
typedef std::map<std::string, AnimationPtr> AnimationSet;
#endif /* FORWARD_HPP */

View File

@ -30,10 +30,6 @@
#define WORLD_GRID_WIDTH (WORLD_GRID_SIZE / WORLD_CELL_SIZE) #define WORLD_GRID_WIDTH (WORLD_GRID_SIZE / WORLD_CELL_SIZE)
#define WORLD_GRID_CELLS (WORLD_GRID_WIDTH * WORLD_GRID_WIDTH) #define WORLD_GRID_CELLS (WORLD_GRID_WIDTH * WORLD_GRID_WIDTH)
struct Animation;
typedef std::map<std::string, Animation*> AnimationSet;
namespace RWTypes { namespace RWTypes {
/** /**

View File

@ -4,7 +4,7 @@
#include <QAbstractItemModel> #include <QAbstractItemModel>
#include <loaders/LoaderIFP.hpp> #include <loaders/LoaderIFP.hpp>
typedef std::vector<std::pair<std::string, Animation*>> AnimationList; typedef std::vector<std::pair<std::string, AnimationPtr>> AnimationList;
class AnimationListModel : public QAbstractListModel { class AnimationListModel : public QAbstractListModel {
Q_OBJECT Q_OBJECT

View File

@ -22,7 +22,7 @@ public:
signals: signals:
void selectedAnimationChanged(Animation* anim); void selectedAnimationChanged(AnimationPtr anim);
public slots: public slots:
void selectedIndexChanged(const QModelIndex& current); void selectedIndexChanged(const QModelIndex& current);

View File

@ -75,6 +75,6 @@ void ModelViewer::loadAnimations(const QString& file) {
animationWidget->setAnimations(anims); animationWidget->setAnimations(anims);
} }
void ModelViewer::playAnimation(Animation* anim) { void ModelViewer::playAnimation(AnimationPtr anim) {
viewerWidget->currentObject()->animator->playAnimation(0, anim, 1.f, true); viewerWidget->currentObject()->animator->playAnimation(0, anim, 1.f, true);
} }

View File

@ -51,7 +51,7 @@ public slots:
void showObject(uint16_t object); void showObject(uint16_t object);
void loadAnimations(const QString& file); void loadAnimations(const QString& file);
void playAnimation(Animation* anim); void playAnimation(AnimationPtr anim);
}; };
#endif #endif

View File

@ -9,7 +9,7 @@ BOOST_AUTO_TEST_SUITE(AnimationTests)
#if RW_TEST_WITH_DATA #if RW_TEST_WITH_DATA
BOOST_AUTO_TEST_CASE(test_matrix) { BOOST_AUTO_TEST_CASE(test_matrix) {
{ {
Animation animation; auto animation = std::make_shared<Animation>();
/** Models are currently needed to relate animation bones <=> model /** Models are currently needed to relate animation bones <=> model
* frame #s. */ * frame #s. */
@ -17,8 +17,8 @@ BOOST_AUTO_TEST_CASE(test_matrix) {
Animator animator(test_model); Animator animator(test_model);
animation.duration = 1.f; animation->duration = 1.f;
animation.bones["player"] = new AnimationBone{ animation->bones["player"] = new AnimationBone{
"player", "player",
0, 0,
0, 0,
@ -29,7 +29,7 @@ BOOST_AUTO_TEST_CASE(test_matrix) {
{glm::quat(), glm::vec3(0.f, 1.f, 0.f), glm::vec3(), 1.0f, 1}, {glm::quat(), glm::vec3(0.f, 1.f, 0.f), glm::vec3(), 1.0f, 1},
}}; }};
animator.playAnimation(0, &animation, 1.f, false); animator.playAnimation(0, animation, 1.f, false);
animator.tick(0.0f); animator.tick(0.0f);