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:
parent
e448f610ff
commit
eba262b789
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>());
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user