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

rwengine: make Activity a std::unique_ptr

Should fix this memory leak:
==16721== 120 bytes in 5 blocks are definitely lost in loss record 187 of 264
==16721==    at 0x4C2F1CA: operator new(unsigned long) (vg_replace_malloc.c:334)
==16721==    by 0x8EBA26: DefaultAIController::update(float) (DefaultAIController.cpp:63)
==16721==    by 0x82ED5A: CharacterObject::tick(float) (CharacterObject.cpp:240)
==16721==    by 0x763630: RWGame::tick(float) (RWGame.cpp:506)
==16721==    by 0x763128: RWGame::run() (RWGame.cpp:420)
==16721==    by 0x750394: main (main.cpp:15)
This commit is contained in:
Anonymous Maarten 2017-09-13 18:14:34 +02:00 committed by Daniel Evans
parent e448f610ff
commit eba262b789
7 changed files with 60 additions and 42 deletions

View File

@ -29,9 +29,8 @@ bool CharacterController::updateActivity() {
return false;
}
void CharacterController::setActivity(CharacterController::Activity *activity) {
if (_currentActivity) delete _currentActivity;
_currentActivity = activity;
void CharacterController::setActivity(std::unique_ptr<Activity> activity) {
_currentActivity.swap(activity);
}
void CharacterController::skipActivity() {
@ -43,14 +42,12 @@ void CharacterController::skipActivity() {
setActivity(nullptr);
}
void CharacterController::setNextActivity(
CharacterController::Activity *activity) {
void CharacterController::setNextActivity(std::unique_ptr<Activity> activity) {
if (_currentActivity == nullptr) {
setActivity(activity);
setActivity(std::move(activity));
_nextActivity = nullptr;
} else {
if (_nextActivity) delete _nextActivity;
_nextActivity = activity;
_nextActivity.swap(activity);
}
}
@ -97,13 +94,9 @@ void CharacterController::update(float dt) {
if (updateActivity()) {
character->activityFinished();
if (_currentActivity) {
delete _currentActivity;
_currentActivity = nullptr;
}
_currentActivity = nullptr;
if (_nextActivity) {
setActivity(_nextActivity);
_nextActivity = nullptr;
setActivity(std::move(_nextActivity));
}
}
}
@ -282,7 +275,7 @@ bool Activities::EnterVehicle::update(CharacterObject *character,
// out.
character->playCycle(cycle_pullout);
currentOccupant->controller->setNextActivity(
new Activities::ExitVehicle(true));
std::make_unique<Activities::ExitVehicle>(true));
} else {
character->playCycle(cycle_enter);
character->enterVehicle(vehicle, seat);

View File

@ -3,6 +3,8 @@
#define _CHARACTERCONTROLLER_HPP_
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <memory>
#include <string>
struct AIGraphNode;
@ -61,11 +63,11 @@ protected:
*/
CharacterObject* character;
Activity* _currentActivity;
Activity* _nextActivity;
std::unique_ptr<Activity> _currentActivity;
std::unique_ptr<Activity> _nextActivity;
bool updateActivity();
void setActivity(Activity* activity);
void setActivity(std::unique_ptr<Activity> activity);
float m_closeDoorTimer;
@ -80,12 +82,22 @@ public:
virtual ~CharacterController() {
}
/**
* Get the current Activity.
* Callers may not store the returned pointer.
* @return Activity pointer.
*/
Activity* getCurrentActivity() const {
return _currentActivity;
return _currentActivity.get();
}
/**
* Get the next Activity
* Callers may not store the returned pointer.
* @return Activity pointer.
*/
Activity* getNextActivity() const {
return _nextActivity;
return _nextActivity.get();
}
/**
@ -98,7 +110,7 @@ public:
* @param activity
* @param position
*/
void setNextActivity(Activity* activity);
void setNextActivity(std::unique_ptr<Activity> activity);
/**
* @brief IsCurrentActivity

View File

@ -25,12 +25,12 @@ void DefaultAIController::update(float dt) {
if (leader->getCurrentVehicle() !=
getCharacter()->getCurrentVehicle()) {
skipActivity();
setNextActivity(new Activities::ExitVehicle);
setNextActivity(std::make_unique<Activities::ExitVehicle>());
}
// else we're already in the right spot.
} else {
if (leader->getCurrentVehicle()) {
setNextActivity(new Activities::EnterVehicle(
setNextActivity(std::make_unique<Activities::EnterVehicle>(
leader->getCurrentVehicle(), 1));
} else {
glm::vec3 dir =
@ -42,7 +42,7 @@ void DefaultAIController::update(float dt) {
leader->getPosition() +
(glm::normalize(-dir) * followRadius * 0.7f);
skipActivity();
setNextActivity(new Activities::GoTo(gotoPos));
setNextActivity(std::make_unique<Activities::GoTo>(gotoPos));
}
}
}
@ -60,9 +60,11 @@ void DefaultAIController::update(float dt) {
std::uniform_int_distribution<> d(
0, lastTarget->connections.size() - 1);
targetNode = lastTarget->connections.at(d(re));
setNextActivity(new Activities::GoTo(targetNode->position));
setNextActivity(std::make_unique<Activities::GoTo>(
targetNode->position));
} else if (getCurrentActivity() == nullptr) {
setNextActivity(new Activities::GoTo(targetNode->position));
setNextActivity(std::make_unique<Activities::GoTo>(
targetNode->position));
}
} else {
// We need to pick an initial node

View File

@ -33,7 +33,7 @@ void PlayerController::updateMovementDirection(const glm::vec3& dir,
void PlayerController::exitVehicle() {
if (character->getCurrentVehicle()) {
setNextActivity(new Activities::ExitVehicle());
setNextActivity(std::make_unique<Activities::ExitVehicle>());
}
}
@ -54,7 +54,7 @@ void PlayerController::enterNearestVehicle() {
}
if (nearest) {
setNextActivity(new Activities::EnterVehicle(nearest, 0));
setNextActivity(std::make_unique<Activities::EnterVehicle>(nearest, 0));
}
}
}
@ -69,6 +69,6 @@ glm::vec3 PlayerController::getTargetPosition() {
void PlayerController::jump() {
if (!character->isInWater()) {
setNextActivity(new Activities::Jump());
setNextActivity(std::make_unique<Activities::Jump>());
}
}

View File

@ -624,7 +624,8 @@ void CharacterObject::useItem(bool active, bool primary) {
if (primary) {
if (!currentState.primaryActive && active) {
// If we've just started, activate
controller->setNextActivity(new Activities::UseItem(item));
controller->setNextActivity(
std::make_unique<Activities::UseItem>(item));
} else if (currentState.primaryActive && !active) {
// UseItem will cancel itself upon !primaryActive
}

View File

@ -5365,7 +5365,8 @@ void opcode_01d3(const ScriptArguments& args, const ScriptCharacter character, c
RW_UNUSED(vehicle);
RW_UNUSED(args);
character->controller->skipActivity();
character->controller->setNextActivity(new Activities::ExitVehicle);
character->controller->setNextActivity(
std::make_unique<Activities::ExitVehicle>());(new Activities::ExitVehicle);
}
/**
@ -5378,7 +5379,9 @@ void opcode_01d3(const ScriptArguments& args, const ScriptCharacter character, c
void opcode_01d4(const ScriptArguments& args, const ScriptCharacter character, const ScriptVehicle vehicle) {
RW_UNUSED(args);
character->controller->skipActivity();
character->controller->setNextActivity(new Activities::EnterVehicle(vehicle,Activities::EnterVehicle::ANY_SEAT));
character->controller->setNextActivity(
std::make_unique<Activities::EnterVehicle>(
vehicle,Activities::EnterVehicle::ANY_SEAT));
}
/**
@ -5390,7 +5393,8 @@ void opcode_01d4(const ScriptArguments& args, const ScriptCharacter character, c
*/
void opcode_01d5(const ScriptArguments& args, const ScriptCharacter character, const ScriptVehicle vehicle) {
RW_UNUSED(args);
character->controller->setNextActivity(new Activities::EnterVehicle(vehicle));
character->controller->setNextActivity(
std::make_unique<Activities::EnterVehicle>(vehicle));
}
/**
@ -6170,10 +6174,12 @@ void opcode_0211(const ScriptArguments& args, const ScriptCharacter character, S
if( character->getCurrentVehicle() )
{
// Since we just cleared the Activities, this will become current immediatley.
character->controller->setNextActivity(new Activities::ExitVehicle);
character->controller->setNextActivity(
std::make_unique<Activities::ExitVehicle>());
}
character->controller->setNextActivity(new Activities::GoTo(target));
character->controller->setNextActivity(
std::make_unique<Activities::GoTo>(target));
}
/**
@ -6625,7 +6631,8 @@ void opcode_0237(const ScriptArguments& args, const ScriptGang gangID, const Scr
*/
void opcode_0239(const ScriptArguments& args, const ScriptCharacter character, ScriptVec2 coord) {
auto target = script::getGround(args, glm::vec3(coord, -100.f));
character->controller->setNextActivity(new Activities::GoTo(target, true));
character->controller->setNextActivity(
std::make_unique<Activities::GoTo>(target, true));
}
/**

View File

@ -22,7 +22,7 @@ BOOST_AUTO_TEST_CASE(test_create) {
// Check that Idle activities are instantly displaced.
controller->setNextActivity(
new Activities::GoTo(glm::vec3{1000.f, 0.f, 0.f}));
std::make_unique<Activities::GoTo>(glm::vec3{1000.f, 0.f, 0.f}));
BOOST_CHECK_EQUAL(controller->getCurrentActivity()->name(), "GoTo");
BOOST_CHECK_EQUAL(controller->getNextActivity(), nullptr);
@ -42,7 +42,7 @@ BOOST_AUTO_TEST_CASE(test_activities) {
BOOST_REQUIRE(controller != nullptr);
controller->setNextActivity(
new Activities::GoTo(glm::vec3{10.f, 10.f, 0.f}));
std::make_unique<Activities::GoTo>(glm::vec3{10.f, 10.f, 0.f}));
BOOST_CHECK_EQUAL(controller->getCurrentActivity()->name(), "GoTo");
@ -69,7 +69,8 @@ BOOST_AUTO_TEST_CASE(test_activities) {
auto controller = character->controller;
BOOST_REQUIRE(controller != nullptr);
controller->setNextActivity(new Activities::EnterVehicle(vehicle, 0));
controller->setNextActivity(
std::make_unique<Activities::EnterVehicle>(vehicle, 0));
for (float t = 0.f; t < 0.5f; t += (1.f / 60.f)) {
character->tick(1.f / 60.f);
@ -85,7 +86,8 @@ BOOST_AUTO_TEST_CASE(test_activities) {
BOOST_CHECK_EQUAL(vehicle, character->getCurrentVehicle());
controller->setNextActivity(new Activities::ExitVehicle());
controller->setNextActivity(
std::make_unique<Activities::ExitVehicle>());
for (float t = 0.f; t < 9.0f; t += (1.f / 60.f)) {
character->tick(1.f / 60.f);
@ -95,7 +97,8 @@ BOOST_AUTO_TEST_CASE(test_activities) {
BOOST_CHECK_EQUAL(nullptr, character->getCurrentVehicle());
character->setPosition(glm::vec3(5.f, 0.f, 0.f));
controller->setNextActivity(new Activities::EnterVehicle(vehicle, 0));
controller->setNextActivity(
std::make_unique<Activities::EnterVehicle>(vehicle, 0));
for (float t = 0.f; t < 0.5f; t += (1.f / 60.f)) {
character->tick(1.f / 60.f);