mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-04-27 23:13:38 +00:00
perf: stop heap-allocating mob restriction state and Path nodes
Inlines restrictCenter and leashRestrictionGoal as value members and stores Path nodes by value, removing per-mob and per-path malloc churn.
This commit is contained in:
parent
fe77d9c2a0
commit
45c85fcf79
|
|
@ -26,25 +26,20 @@ AttributeModifier* PathfinderMob::SPEED_MODIFIER_FLEEING =
|
|||
AttributeModifier::OPERATION_MULTIPLY_TOTAL))
|
||||
->setSerialize(false);
|
||||
|
||||
PathfinderMob::PathfinderMob(Level* level) : Mob(level) {
|
||||
path = nullptr;
|
||||
attackTarget = nullptr;
|
||||
holdGround = false;
|
||||
fleeTime = 0;
|
||||
|
||||
restrictRadius = -1;
|
||||
restrictCenter = new Pos(0, 0, 0);
|
||||
addedLeashRestrictionGoal = false;
|
||||
leashRestrictionGoal = new MoveTowardsRestrictionGoal(this, 1.0f);
|
||||
}
|
||||
PathfinderMob::PathfinderMob(Level* level)
|
||||
: Mob(level),
|
||||
path(nullptr),
|
||||
attackTarget(nullptr),
|
||||
holdGround(false),
|
||||
fleeTime(0),
|
||||
restrictCenter(0, 0, 0),
|
||||
restrictRadius(-1),
|
||||
leashRestrictionGoal(this, 1.0f),
|
||||
addedLeashRestrictionGoal(false) {}
|
||||
|
||||
bool PathfinderMob::shouldHoldGround() { return false; }
|
||||
|
||||
PathfinderMob::~PathfinderMob() {
|
||||
delete path;
|
||||
delete restrictCenter;
|
||||
delete leashRestrictionGoal;
|
||||
}
|
||||
PathfinderMob::~PathfinderMob() { delete path; }
|
||||
|
||||
void PathfinderMob::serverAiStep() {
|
||||
if (fleeTime > 0) {
|
||||
|
|
@ -264,15 +259,15 @@ bool PathfinderMob::isWithinRestriction() {
|
|||
|
||||
bool PathfinderMob::isWithinRestriction(int x, int y, int z) {
|
||||
if (restrictRadius == -1) return true;
|
||||
return restrictCenter->distSqr(x, y, z) < restrictRadius * restrictRadius;
|
||||
return restrictCenter.distSqr(x, y, z) < restrictRadius * restrictRadius;
|
||||
}
|
||||
|
||||
void PathfinderMob::restrictTo(int x, int y, int z, int radius) {
|
||||
restrictCenter->set(x, y, z);
|
||||
restrictCenter.set(x, y, z);
|
||||
restrictRadius = radius;
|
||||
}
|
||||
|
||||
Pos* PathfinderMob::getRestrictCenter() { return restrictCenter; }
|
||||
Pos* PathfinderMob::getRestrictCenter() { return &restrictCenter; }
|
||||
|
||||
float PathfinderMob::getRestrictRadius() { return restrictRadius; }
|
||||
|
||||
|
|
@ -305,7 +300,7 @@ void PathfinderMob::tickLeash() {
|
|||
}
|
||||
|
||||
if (!addedLeashRestrictionGoal) {
|
||||
goalSelector.addGoal(2, leashRestrictionGoal, false);
|
||||
goalSelector.addGoal(2, &leashRestrictionGoal, false);
|
||||
getNavigation()->setAvoidWater(false);
|
||||
addedLeashRestrictionGoal = true;
|
||||
}
|
||||
|
|
@ -332,7 +327,7 @@ void PathfinderMob::tickLeash() {
|
|||
|
||||
} else if (!isLeashed() && addedLeashRestrictionGoal) {
|
||||
addedLeashRestrictionGoal = false;
|
||||
goalSelector.removeGoal(leashRestrictionGoal);
|
||||
goalSelector.removeGoal(&leashRestrictionGoal);
|
||||
getNavigation()->setAvoidWater(true);
|
||||
clearRestriction();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@
|
|||
#include <memory>
|
||||
|
||||
#include "Mob.h"
|
||||
#include "minecraft/Pos.h"
|
||||
#include "minecraft/world/entity/Entity.h"
|
||||
#include "minecraft/world/entity/Mob.h"
|
||||
#include "minecraft/world/entity/ai/goal/MoveTowardsRestrictionGoal.h"
|
||||
|
||||
class Level;
|
||||
class Path;
|
||||
class AttributeModifier;
|
||||
class Goal;
|
||||
class Pos;
|
||||
|
||||
class PathfinderMob : public Mob {
|
||||
public:
|
||||
|
|
@ -32,9 +32,9 @@ protected:
|
|||
int fleeTime;
|
||||
|
||||
private:
|
||||
Pos* restrictCenter;
|
||||
Pos restrictCenter;
|
||||
float restrictRadius;
|
||||
Goal* leashRestrictionGoal;
|
||||
MoveTowardsRestrictionGoal leashRestrictionGoal;
|
||||
bool addedLeashRestrictionGoal;
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ class Node {
|
|||
friend class EnderDragon;
|
||||
|
||||
public:
|
||||
const int x, y, z;
|
||||
int x, y, z;
|
||||
|
||||
private:
|
||||
const int hash;
|
||||
int hash;
|
||||
|
||||
protected:
|
||||
int heapIdx;
|
||||
|
|
|
|||
|
|
@ -1,31 +1,12 @@
|
|||
#include "Path.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "minecraft/world/entity/Entity.h"
|
||||
#include "minecraft/world/level/pathfinder/Node.h"
|
||||
#include "minecraft/world/phys/Vec3.h"
|
||||
|
||||
Path::~Path() {
|
||||
for (size_t i = 0; i < nodes.size(); i++) delete nodes[i];
|
||||
}
|
||||
|
||||
Path::Path(std::vector<Node*>& nodes) {
|
||||
index = 0;
|
||||
|
||||
length = nodes.size();
|
||||
// 4J - copying these nodes over from a std::vector<Node*> (which is an
|
||||
// array of Node
|
||||
// * references) to just a straight array of Nodes, so that this Path is no
|
||||
// longer dependent of Nodes allocated elsewhere and can handle its own
|
||||
// destruction Note: cameFrom pointer will be useless now but that isn't
|
||||
// used once this is just a path
|
||||
this->nodes = std::vector<Node*>(length);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
this->nodes[i] = new Node();
|
||||
memcpy(this->nodes[i], nodes[i], sizeof(Node));
|
||||
}
|
||||
Path::Path(std::vector<Node*>& src)
|
||||
: nodes(src.size()), index(0), length(static_cast<int>(src.size())) {
|
||||
for (int i = 0; i < length; i++) nodes[i] = *src[i];
|
||||
}
|
||||
|
||||
void Path::next() { index++; }
|
||||
|
|
@ -34,12 +15,12 @@ bool Path::isDone() { return index >= length; }
|
|||
|
||||
Node* Path::last() {
|
||||
if (length > 0) {
|
||||
return nodes[length - 1];
|
||||
return &nodes[length - 1];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Node* Path::get(int i) { return nodes[i]; }
|
||||
Node* Path::get(int i) { return &nodes[i]; }
|
||||
|
||||
int Path::getSize() { return length; }
|
||||
|
||||
|
|
@ -50,25 +31,25 @@ int Path::getIndex() { return index; }
|
|||
void Path::setIndex(int index) { this->index = index; }
|
||||
|
||||
Vec3 Path::getPos(std::shared_ptr<Entity> e, int index) {
|
||||
double x = nodes[index]->x + (int)(e->bbWidth + 1) * 0.5;
|
||||
double y = nodes[index]->y;
|
||||
double z = nodes[index]->z + (int)(e->bbWidth + 1) * 0.5;
|
||||
double x = nodes[index].x + (int)(e->bbWidth + 1) * 0.5;
|
||||
double y = nodes[index].y;
|
||||
double z = nodes[index].z + (int)(e->bbWidth + 1) * 0.5;
|
||||
return Vec3(x, y, z);
|
||||
}
|
||||
|
||||
Vec3 Path::currentPos(std::shared_ptr<Entity> e) { return getPos(e, index); }
|
||||
|
||||
Vec3 Path::currentPos() {
|
||||
return Vec3(nodes[index]->x, nodes[index]->y, nodes[index]->z);
|
||||
return Vec3(nodes[index].x, nodes[index].y, nodes[index].z);
|
||||
}
|
||||
|
||||
bool Path::sameAs(Path* path) {
|
||||
if (path == nullptr) return false;
|
||||
if (path->nodes.size() != nodes.size()) return false;
|
||||
for (int i = 0; i < nodes.size(); ++i)
|
||||
if (nodes[i]->x != path->nodes[i]->x ||
|
||||
nodes[i]->y != path->nodes[i]->y ||
|
||||
nodes[i]->z != path->nodes[i]->z)
|
||||
for (size_t i = 0; i < nodes.size(); ++i)
|
||||
if (nodes[i].x != path->nodes[i].x ||
|
||||
nodes[i].y != path->nodes[i].y ||
|
||||
nodes[i].z != path->nodes[i].z)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,13 +13,16 @@ class Path {
|
|||
friend class PathFinder;
|
||||
|
||||
private:
|
||||
std::vector<Node*> nodes;
|
||||
// Nodes are stored by value. The vector is sized once in the constructor
|
||||
// and never resized, so Node* returned by get()/last() remain valid for
|
||||
// the lifetime of the Path.
|
||||
std::vector<Node> nodes;
|
||||
int index;
|
||||
int length;
|
||||
|
||||
public:
|
||||
Path(std::vector<Node*>& nodes);
|
||||
~Path();
|
||||
~Path() = default;
|
||||
|
||||
void next();
|
||||
bool isDone();
|
||||
|
|
@ -30,7 +33,6 @@ public:
|
|||
int getIndex();
|
||||
void setIndex(int index);
|
||||
Vec3 getPos(std::shared_ptr<Entity> e, int index);
|
||||
std::vector<Node*> Getarray();
|
||||
Vec3 currentPos(std::shared_ptr<Entity> e);
|
||||
Vec3 currentPos();
|
||||
bool sameAs(Path* path);
|
||||
|
|
|
|||
Loading…
Reference in a new issue