cache PhysicsJoint* attributes before PhysicsWorld update (#19108)

* use cache

* add unlikely

* fix pbxproj file

* remove unused methods
This commit is contained in:
Arnold 2018-10-19 18:11:50 +08:00 committed by minggo
parent 2952eb2dbe
commit 6da19d5eaf
4 changed files with 173 additions and 30 deletions

View File

@ -7723,7 +7723,7 @@
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
INFOPLIST_FILE = "$(SRCROOT)/../tests/cpp-tests/proj.mac/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
USER_HEADER_SEARCH_PATHS = "$(inherited) $(SRCROOT)/../external/glfw3/include/mac $(SRCROOT)/../external/freetype2/include/mac/freetype2";
USER_HEADER_SEARCH_PATHS = "$(inherited) $(SRCROOT)/../external/glfw3/include/mac $(SRCROOT)/../external/freetype2/include/mac/freetype2 $(SRCROOT)/../tests/cpp-tests/Classes";
};
name = Debug;
};
@ -7739,7 +7739,7 @@
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
INFOPLIST_FILE = "$(SRCROOT)/../tests/cpp-tests/proj.mac/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
USER_HEADER_SEARCH_PATHS = "$(inherited) $(SRCROOT)/../external/glfw3/include/mac $(SRCROOT)/../external/freetype2/include/mac/freetype2";
USER_HEADER_SEARCH_PATHS = "$(inherited) $(SRCROOT)/../external/glfw3/include/mac $(SRCROOT)/../external/freetype2/include/mac/freetype2 $(SRCROOT)/../tests/cpp-tests/Classes";
VALIDATE_PRODUCT = YES;
};
name = Release;

View File

@ -34,6 +34,83 @@
NS_CC_BEGIN
template<typename T>
class Optional {
public:
Optional() {}
Optional(T d) :_isSet(true), _data(d) {}
Optional(const Optional &t) : _isSet(t._isSet), _data(t._data) {}
//bool isNull() const { return !_isSet; }
//bool isDefineded() const { return _isSet; }
//bool isEmpty() const { return !_isSet; }
T get() const { CCASSERT(_isSet, "data should be set!"); return _data; }
void set(T d) { _isSet = true; _data = d; }
private:
bool _isSet = false;
T _data;
};
class WriteCache {
public:
Optional<Vec2> _grooveA;
Optional<Vec2> _grooveB;
Optional<Vec2> _anchr1;
Optional<Vec2> _anchr2;
Optional<float> _min;
Optional<float> _max;
Optional<float> _distance;
Optional<float> _restLength;
Optional<float> _restAngle;
Optional<float> _stiffness;
Optional<float> _damping;
Optional<float> _angle;
Optional<float> _phase;
Optional<float> _ratchet;
Optional<float> _ratio;
Optional<float> _rate;
};
#if (defined(__GNUC__) && __GNUC__ >= 4) || defined(__clang__)
#define LIKELY(x) (__builtin_expect((x), 1))
#define UNLIKELY(x) (__builtin_expect((x), 0))
#else
#define LIKELY(x) (x)
#define UNLIKELY(x) (x)
#endif
#define CC_PJOINT_CACHE_READ(field) \
do { \
if(UNLIKELY(_initDirty)) \
{ \
return _writeCache->field.get(); \
} \
}while(0)
#define CC_PJOINT_CACHE_WRITE2(field, method, arg, convertedArg) \
do { \
if(UNLIKELY(_initDirty)) \
{ \
_writeCache->field.set(arg); \
delay([this, arg]() { \
method(_cpConstraints.front(), convertedArg); \
}); \
} \
else \
{ \
method(_cpConstraints.front(), convertedArg); \
} \
}while(0)
#define CC_PJOINT_CACHE_WRITE(field, method, arg) \
CC_PJOINT_CACHE_WRITE2(field, method, arg, arg)
PhysicsJoint::PhysicsJoint()
: _bodyA(nullptr)
, _bodyB(nullptr)
@ -45,7 +122,7 @@ PhysicsJoint::PhysicsJoint()
, _maxForce(PHYSICS_INFINITY)
, _initDirty(true)
{
_writeCache = new WriteCache();
}
PhysicsJoint::~PhysicsJoint()
@ -58,6 +135,8 @@ PhysicsJoint::~PhysicsJoint()
cpConstraintFree(joint);
}
_cpConstraints.clear();
delete _writeCache;
}
bool PhysicsJoint::init(cocos2d::PhysicsBody *a, cocos2d::PhysicsBody *b)
@ -99,6 +178,15 @@ bool PhysicsJoint::initJoint()
return ret;
}
void PhysicsJoint::flushDelayTasks()
{
for (auto tsk : _delayTasks)
{
tsk();
}
_delayTasks.clear();
}
void PhysicsJoint::setEnable(bool enable)
{
if (_enable != enable)
@ -137,11 +225,24 @@ void PhysicsJoint::removeFormWorld()
void PhysicsJoint::setMaxForce(float force)
{
if(_initDirty)
{
delay([this, force]() {
_maxForce = force;
for (auto joint : _cpConstraints)
{
cpConstraintSetMaxForce(joint, force);
}
});
}
else
{
_maxForce = force;
for (auto joint : _cpConstraints)
{
cpConstraintSetMaxForce(joint, force);
}
}
}
PhysicsJointFixed* PhysicsJointFixed::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr)
@ -285,42 +386,46 @@ bool PhysicsJointLimit::createConstraints()
float PhysicsJointLimit::getMin() const
{
CC_PJOINT_CACHE_READ(_min);
return PhysicsHelper::cpfloat2float(cpSlideJointGetMin(_cpConstraints.front()));
}
void PhysicsJointLimit::setMin(float min)
{
cpSlideJointSetMin(_cpConstraints.front(), min);
CC_PJOINT_CACHE_WRITE(_min, cpSlideJointSetMin, min);
}
float PhysicsJointLimit::getMax() const
{
CC_PJOINT_CACHE_READ(_max);
return PhysicsHelper::cpfloat2float(cpSlideJointGetMax(_cpConstraints.front()));
}
void PhysicsJointLimit::setMax(float max)
{
cpSlideJointSetMax(_cpConstraints.front(), max);
CC_PJOINT_CACHE_WRITE(_max, cpSlideJointSetMax, max);
}
Vec2 PhysicsJointLimit::getAnchr1() const
{
CC_PJOINT_CACHE_READ(_anchr1);
return PhysicsHelper::cpv2point(cpSlideJointGetAnchorA(_cpConstraints.front()));
}
void PhysicsJointLimit::setAnchr1(const Vec2& anchr)
{
cpSlideJointSetAnchorA(_cpConstraints.front(), PhysicsHelper::point2cpv(anchr));
CC_PJOINT_CACHE_WRITE2(_anchr1, cpSlideJointSetAnchorA, anchr, PhysicsHelper::point2cpv(anchr));
}
Vec2 PhysicsJointLimit::getAnchr2() const
{
CC_PJOINT_CACHE_READ(_anchr2);
return PhysicsHelper::cpv2point(cpSlideJointGetAnchorB(_cpConstraints.front()));
}
void PhysicsJointLimit::setAnchr2(const Vec2& anchr)
{
cpSlideJointSetAnchorB(_cpConstraints.front(), PhysicsHelper::point2cpv(anchr));
CC_PJOINT_CACHE_WRITE2(_anchr2, cpSlideJointSetAnchorB, anchr, PhysicsHelper::point2cpv(anchr));
}
PhysicsJointDistance* PhysicsJointDistance::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2)
@ -358,12 +463,13 @@ bool PhysicsJointDistance::createConstraints()
float PhysicsJointDistance::getDistance() const
{
CC_PJOINT_CACHE_READ(_distance);
return PhysicsHelper::cpfloat2float(cpPinJointGetDist(_cpConstraints.front()));
}
void PhysicsJointDistance::setDistance(float distance)
{
cpPinJointSetDist(_cpConstraints.front(), distance);
CC_PJOINT_CACHE_WRITE(_distance, cpPinJointSetDist, distance);
}
PhysicsJointSpring* PhysicsJointSpring::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2, float stiffness, float damping)
@ -406,52 +512,57 @@ bool PhysicsJointSpring::createConstraints()
Vec2 PhysicsJointSpring::getAnchr1() const
{
CC_PJOINT_CACHE_READ(_anchr1);
return PhysicsHelper::cpv2point(cpDampedSpringGetAnchorA(_cpConstraints.front()));
}
void PhysicsJointSpring::setAnchr1(const Vec2& anchr)
{
cpDampedSpringSetAnchorA(_cpConstraints.front(), PhysicsHelper::point2cpv(anchr));
CC_PJOINT_CACHE_WRITE2(_anchr1, cpDampedSpringSetAnchorA, anchr, PhysicsHelper::point2cpv(anchr));
}
Vec2 PhysicsJointSpring::getAnchr2() const
{
CC_PJOINT_CACHE_READ(_anchr2);
return PhysicsHelper::cpv2point(cpDampedSpringGetAnchorB(_cpConstraints.front()));
}
void PhysicsJointSpring::setAnchr2(const Vec2& anchr)
{
cpDampedSpringSetAnchorB(_cpConstraints.front(), PhysicsHelper::point2cpv(anchr));
CC_PJOINT_CACHE_WRITE2(_anchr2, cpDampedSpringSetAnchorB, anchr, PhysicsHelper::point2cpv(anchr));
}
float PhysicsJointSpring::getRestLength() const
{
CC_PJOINT_CACHE_READ(_restLength);
return PhysicsHelper::cpfloat2float(cpDampedSpringGetRestLength(_cpConstraints.front()));
}
void PhysicsJointSpring::setRestLength(float restLength)
{
cpDampedSpringSetRestLength(_cpConstraints.front(), restLength);
CC_PJOINT_CACHE_WRITE(_restLength, cpDampedSpringSetRestLength, restLength);
}
float PhysicsJointSpring::getStiffness() const
{
CC_PJOINT_CACHE_READ(_stiffness);
return PhysicsHelper::cpfloat2float(cpDampedSpringGetStiffness(_cpConstraints.front()));
}
void PhysicsJointSpring::setStiffness(float stiffness)
{
cpDampedSpringSetStiffness(_cpConstraints.front(), stiffness);
CC_PJOINT_CACHE_WRITE(_stiffness, cpDampedSpringSetStiffness, stiffness);
}
float PhysicsJointSpring::getDamping() const
{
CC_PJOINT_CACHE_READ(_damping);
return PhysicsHelper::cpfloat2float(cpDampedSpringGetDamping(_cpConstraints.front()));
}
void PhysicsJointSpring::setDamping(float damping)
{
cpDampedSpringSetDamping(_cpConstraints.front(), damping);
CC_PJOINT_CACHE_WRITE(_damping, cpDampedSpringSetDamping, damping);
}
PhysicsJointGroove* PhysicsJointGroove::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& grooveA, const Vec2& grooveB, const Vec2& anchr2)
@ -491,32 +602,35 @@ bool PhysicsJointGroove::createConstraints()
Vec2 PhysicsJointGroove::getGrooveA() const
{
CC_PJOINT_CACHE_READ(_grooveA);
return PhysicsHelper::cpv2point(cpGrooveJointGetGrooveA(_cpConstraints.front()));
}
void PhysicsJointGroove::setGrooveA(const Vec2& grooveA)
{
cpGrooveJointSetGrooveA(_cpConstraints.front(), PhysicsHelper::point2cpv(grooveA));
CC_PJOINT_CACHE_WRITE2(_grooveA, cpGrooveJointSetGrooveA, grooveA, PhysicsHelper::point2cpv(grooveA));
}
Vec2 PhysicsJointGroove::getGrooveB() const
{
CC_PJOINT_CACHE_READ(_grooveB);
return PhysicsHelper::cpv2point(cpGrooveJointGetGrooveB(_cpConstraints.front()));
}
void PhysicsJointGroove::setGrooveB(const Vec2& grooveB)
{
cpGrooveJointSetGrooveB(_cpConstraints.front(), PhysicsHelper::point2cpv(grooveB));
CC_PJOINT_CACHE_WRITE2(_grooveB, cpGrooveJointSetGrooveB, grooveB, PhysicsHelper::point2cpv(grooveB));
}
Vec2 PhysicsJointGroove::getAnchr2() const
{
CC_PJOINT_CACHE_READ(_anchr2);
return PhysicsHelper::cpv2point(cpGrooveJointGetAnchorB(_cpConstraints.front()));
}
void PhysicsJointGroove::setAnchr2(const Vec2& anchr2)
{
cpGrooveJointSetAnchorB(_cpConstraints.front(), PhysicsHelper::point2cpv(anchr2));
CC_PJOINT_CACHE_WRITE2(_anchr2, cpGrooveJointSetAnchorB, anchr2, PhysicsHelper::point2cpv(anchr2));
}
PhysicsJointRotarySpring* PhysicsJointRotarySpring::construct(PhysicsBody* a, PhysicsBody* b, float stiffness, float damping)
@ -555,32 +669,35 @@ bool PhysicsJointRotarySpring::createConstraints()
float PhysicsJointRotarySpring::getRestAngle() const
{
CC_PJOINT_CACHE_READ(_restAngle);
return PhysicsHelper::cpfloat2float(cpDampedRotarySpringGetRestAngle(_cpConstraints.front()));
}
void PhysicsJointRotarySpring::setRestAngle(float restAngle)
{
cpDampedRotarySpringSetRestAngle(_cpConstraints.front(), restAngle);
CC_PJOINT_CACHE_WRITE(_restAngle, cpDampedRotarySpringSetRestAngle, restAngle);
}
float PhysicsJointRotarySpring::getStiffness() const
{
CC_PJOINT_CACHE_READ(_stiffness);
return PhysicsHelper::cpfloat2float(cpDampedRotarySpringGetStiffness(_cpConstraints.front()));
}
void PhysicsJointRotarySpring::setStiffness(float stiffness)
{
cpDampedRotarySpringSetStiffness(_cpConstraints.front(), stiffness);
CC_PJOINT_CACHE_WRITE(_stiffness, cpDampedRotarySpringSetStiffness, stiffness);
}
float PhysicsJointRotarySpring::getDamping() const
{
CC_PJOINT_CACHE_READ(_damping);
return PhysicsHelper::cpfloat2float(cpDampedRotarySpringGetDamping(_cpConstraints.front()));
}
void PhysicsJointRotarySpring::setDamping(float damping)
{
cpDampedRotarySpringSetDamping(_cpConstraints.front(), damping);
CC_PJOINT_CACHE_WRITE(_damping, cpDampedRotarySpringSetDamping, damping);
}
PhysicsJointRotaryLimit* PhysicsJointRotaryLimit::construct(PhysicsBody* a, PhysicsBody* b, float min, float max)
@ -624,22 +741,24 @@ bool PhysicsJointRotaryLimit::createConstraints()
float PhysicsJointRotaryLimit::getMin() const
{
CC_PJOINT_CACHE_READ(_min);
return PhysicsHelper::cpfloat2float(cpRotaryLimitJointGetMin(_cpConstraints.front()));
}
void PhysicsJointRotaryLimit::setMin(float min)
{
cpRotaryLimitJointSetMin(_cpConstraints.front(), min);
CC_PJOINT_CACHE_WRITE(_min, cpRotaryLimitJointSetMin, min);
}
float PhysicsJointRotaryLimit::getMax() const
{
CC_PJOINT_CACHE_READ(_max);
return PhysicsHelper::cpfloat2float(cpRotaryLimitJointGetMax(_cpConstraints.front()));
}
void PhysicsJointRotaryLimit::setMax(float max)
{
cpRotaryLimitJointSetMax(_cpConstraints.front(), max);
CC_PJOINT_CACHE_WRITE(_max, cpRotaryLimitJointSetMax, max);
}
PhysicsJointRatchet* PhysicsJointRatchet::construct(PhysicsBody* a, PhysicsBody* b, float phase, float ratchet)
@ -678,32 +797,35 @@ bool PhysicsJointRatchet::createConstraints()
float PhysicsJointRatchet::getAngle() const
{
CC_PJOINT_CACHE_READ(_angle);
return PhysicsHelper::cpfloat2float(cpRatchetJointGetAngle(_cpConstraints.front()));
}
void PhysicsJointRatchet::setAngle(float angle)
{
cpRatchetJointSetAngle(_cpConstraints.front(), angle);
CC_PJOINT_CACHE_WRITE(_angle, cpRatchetJointSetAngle, angle);
}
float PhysicsJointRatchet::getPhase() const
{
CC_PJOINT_CACHE_READ(_phase);
return PhysicsHelper::cpfloat2float(cpRatchetJointGetPhase(_cpConstraints.front()));
}
void PhysicsJointRatchet::setPhase(float phase)
{
cpRatchetJointSetPhase(_cpConstraints.front(), phase);
CC_PJOINT_CACHE_WRITE(_phase, cpRatchetJointSetPhase, phase);
}
float PhysicsJointRatchet::getRatchet() const
{
CC_PJOINT_CACHE_READ(_ratchet);
return PhysicsHelper::cpfloat2float(cpRatchetJointGetRatchet(_cpConstraints.front()));
}
void PhysicsJointRatchet::setRatchet(float ratchet)
{
cpRatchetJointSetRatchet(_cpConstraints.front(), ratchet);
CC_PJOINT_CACHE_WRITE(_ratchet, cpRatchetJointSetRatchet, ratchet);
}
PhysicsJointGear* PhysicsJointGear::construct(PhysicsBody* a, PhysicsBody* b, float phase, float ratio)
@ -742,22 +864,24 @@ bool PhysicsJointGear::createConstraints()
float PhysicsJointGear::getPhase() const
{
CC_PJOINT_CACHE_READ(_phase);
return PhysicsHelper::cpfloat2float(cpGearJointGetPhase(_cpConstraints.front()));
}
void PhysicsJointGear::setPhase(float phase)
{
cpGearJointSetPhase(_cpConstraints.front(), phase);
CC_PJOINT_CACHE_WRITE(_phase, cpGearJointSetPhase, phase);
}
float PhysicsJointGear::getRatio() const
{
CC_PJOINT_CACHE_READ(_ratio);
return PhysicsHelper::cpfloat2float(cpGearJointGetRatio(_cpConstraints.front()));
}
void PhysicsJointGear::setRatio(float ratio)
{
cpGearJointSetRatio(_cpConstraints.front(), ratio);
CC_PJOINT_CACHE_WRITE(_ratio, cpGearJointSetRatio, ratio);
}
PhysicsJointMotor* PhysicsJointMotor::construct(PhysicsBody* a, PhysicsBody* b, float rate)
@ -794,12 +918,13 @@ bool PhysicsJointMotor::createConstraints()
float PhysicsJointMotor::getRate() const
{
CC_PJOINT_CACHE_READ(_rate);
return PhysicsHelper::cpfloat2float(cpSimpleMotorGetRate(_cpConstraints.front()));
}
void PhysicsJointMotor::setRate(float rate)
{
cpSimpleMotorSetRate(_cpConstraints.front(), rate);
CC_PJOINT_CACHE_WRITE(_rate, cpSimpleMotorSetRate, rate);
}
NS_CC_END

View File

@ -26,6 +26,8 @@
#ifndef __CCPHYSICS_JOINT_H__
#define __CCPHYSICS_JOINT_H__
#include <functional>
#include "base/ccConfig.h"
#if CC_USE_PHYSICS
@ -40,6 +42,8 @@ class Node;
class PhysicsBody;
class PhysicsWorld;
class WriteCache;
/**
* @addtogroup physics
* @{
@ -52,6 +56,8 @@ class PhysicsWorld;
*/
class CC_DLL PhysicsJoint
{
protected:
typedef std::function<void()> DelayTask;
protected:
PhysicsJoint();
virtual ~PhysicsJoint() = 0;
@ -106,14 +112,21 @@ protected:
bool initJoint();
void delay(const DelayTask & task) { _delayTasks.push_back(task); }
void flushDelayTasks();
/** Create constraints for this type joint */
virtual bool createConstraints() { return false; }
std::vector<cpConstraint*> _cpConstraints;
std::vector<DelayTask> _delayTasks;
PhysicsBody* _bodyA;
PhysicsBody* _bodyB;
PhysicsWorld* _world;
WriteCache *_writeCache = nullptr;
bool _enable;
bool _collisionEnable;
bool _destroyMark;
@ -573,6 +586,7 @@ protected:
/** @} */
NS_CC_END
#endif // CC_USE_PHYSICS

View File

@ -701,6 +701,10 @@ void PhysicsWorld::updateJoints()
doRemoveJoint(joint);
}
_delayRemoveJoints.clear();
for (auto joint : _joints) {
joint->flushDelayTasks();
}
}
void PhysicsWorld::removeShape(PhysicsShape* shape)