diff --git a/src/celengine/axisarrow.cpp b/src/celengine/axisarrow.cpp index 19e1c634..543e2ca6 100644 --- a/src/celengine/axisarrow.cpp +++ b/src/celengine/axisarrow.cpp @@ -442,7 +442,7 @@ VelocityVectorArrow::VelocityVectorArrow(const Body& _body) : Vector3d VelocityVectorArrow::getDirection(double tdb) const { - const TimelinePhase* phase = body.getTimeline()->findPhase(tdb); + auto phase = body.getTimeline()->findPhase(tdb); return phase->orbitFrame()->getOrientation(tdb).conjugate() * phase->orbit()->velocityAtTime(tdb); } @@ -490,7 +490,7 @@ SpinVectorArrow::SpinVectorArrow(const Body& _body) : Vector3d SpinVectorArrow::getDirection(double tdb) const { - const TimelinePhase* phase = body.getTimeline()->findPhase(tdb); + auto phase = body.getTimeline()->findPhase(tdb); return phase->bodyFrame()->getOrientation(tdb).conjugate() * phase->rotationModel()->angularVelocityAtTime(tdb); } diff --git a/src/celengine/body.cpp b/src/celengine/body.cpp index 42b3e84a..f55a0207 100644 --- a/src/celengine/body.cpp +++ b/src/celengine/body.cpp @@ -217,7 +217,7 @@ void Body::markUpdated() } -const ReferenceFrame* Body::getOrbitFrame(double tdb) const +const ReferenceFrame::SharedConstPtr& Body::getOrbitFrame(double tdb) const { return timeline->findPhase(tdb)->orbitFrame(); } @@ -229,7 +229,7 @@ const Orbit* Body::getOrbit(double tdb) const } -const ReferenceFrame* Body::getBodyFrame(double tdb) const +const ReferenceFrame::SharedConstPtr& Body::getBodyFrame(double tdb) const { return timeline->findPhase(tdb)->bodyFrame(); } @@ -544,9 +544,9 @@ UniversalCoord Body::getPosition(double tdb) const { Vector3d position = Vector3d::Zero(); - const TimelinePhase* phase = timeline->findPhase(tdb); + auto phase = timeline->findPhase(tdb); Vector3d p = phase->orbit()->positionAtTime(tdb); - ReferenceFrame* frame = phase->orbitFrame(); + auto frame = phase->orbitFrame(); while (frame->getCenter().getType() == Selection::Type_Body) { @@ -569,7 +569,7 @@ UniversalCoord Body::getPosition(double tdb) const */ Quaterniond Body::getOrientation(double tdb) const { - const TimelinePhase* phase = timeline->findPhase(tdb); + auto phase = timeline->findPhase(tdb); return phase->rotationModel()->orientationAtTime(tdb) * phase->bodyFrame()->getOrientation(tdb); } @@ -578,9 +578,9 @@ Quaterniond Body::getOrientation(double tdb) const */ Vector3d Body::getVelocity(double tdb) const { - const TimelinePhase* phase = timeline->findPhase(tdb); + auto phase = timeline->findPhase(tdb); - ReferenceFrame* orbitFrame = phase->orbitFrame(); + auto orbitFrame = phase->orbitFrame(); Vector3d v = phase->orbit()->velocityAtTime(tdb); v = orbitFrame->getOrientation(tdb).conjugate() * v + orbitFrame->getCenter().getVelocity(tdb); @@ -599,11 +599,11 @@ Vector3d Body::getVelocity(double tdb) const */ Vector3d Body::getAngularVelocity(double tdb) const { - const TimelinePhase* phase = timeline->findPhase(tdb); + auto phase = timeline->findPhase(tdb); Vector3d v = phase->rotationModel()->angularVelocityAtTime(tdb); - ReferenceFrame* bodyFrame = phase->bodyFrame(); + auto bodyFrame = phase->bodyFrame(); v = bodyFrame->getOrientation(tdb).conjugate() * v; if (!bodyFrame->isInertial()) { @@ -622,7 +622,7 @@ Vector3d Body::getAngularVelocity(double tdb) const */ Matrix4d Body::getLocalToAstrocentric(double tdb) const { - const TimelinePhase* phase = timeline->findPhase(tdb); + auto phase = timeline->findPhase(tdb); Vector3d p = phase->orbitFrame()->convertToAstrocentric(phase->orbit()->positionAtTime(tdb), tdb); return Eigen::Transform(Translation3d(p)).matrix(); } @@ -633,7 +633,7 @@ Matrix4d Body::getLocalToAstrocentric(double tdb) const Vector3d Body::getAstrocentricPosition(double tdb) const { // TODO: Switch the iterative method used in getPosition - const TimelinePhase* phase = timeline->findPhase(tdb); + auto phase = timeline->findPhase(tdb); return phase->orbitFrame()->convertToAstrocentric(phase->orbit()->positionAtTime(tdb), tdb); } @@ -642,7 +642,7 @@ Vector3d Body::getAstrocentricPosition(double tdb) const */ Quaterniond Body::getEclipticToFrame(double tdb) const { - const TimelinePhase* phase = timeline->findPhase(tdb); + auto phase = timeline->findPhase(tdb); return phase->bodyFrame()->getOrientation(tdb); } @@ -652,7 +652,7 @@ Quaterniond Body::getEclipticToFrame(double tdb) const */ Quaterniond Body::getEclipticToEquatorial(double tdb) const { - const TimelinePhase* phase = timeline->findPhase(tdb); + auto phase = timeline->findPhase(tdb); return phase->rotationModel()->equatorOrientationAtTime(tdb) * phase->bodyFrame()->getOrientation(tdb); } @@ -662,7 +662,7 @@ Quaterniond Body::getEclipticToEquatorial(double tdb) const */ Quaterniond Body::getEclipticToBodyFixed(double tdb) const { - const TimelinePhase* phase = timeline->findPhase(tdb); + auto phase = timeline->findPhase(tdb); return phase->rotationModel()->orientationAtTime(tdb) * phase->bodyFrame()->getOrientation(tdb); } @@ -672,7 +672,7 @@ Quaterniond Body::getEclipticToBodyFixed(double tdb) const // meridian, and z-axis at a right angle the xy plane. Quaterniond Body::getEquatorialToBodyFixed(double tdb) const { - const TimelinePhase* phase = timeline->findPhase(tdb); + auto phase = timeline->findPhase(tdb); return phase->rotationModel()->spin(tdb); } diff --git a/src/celengine/body.h b/src/celengine/body.h index 0452058e..02131a68 100644 --- a/src/celengine/body.h +++ b/src/celengine/body.h @@ -202,9 +202,9 @@ class Body : public CatEntry FrameTree* getFrameTree() const; FrameTree* getOrCreateFrameTree(); - const ReferenceFrame* getOrbitFrame(double tdb) const; + const ReferenceFrame::SharedConstPtr& getOrbitFrame(double tdb) const; const Orbit* getOrbit(double tdb) const; - const ReferenceFrame* getBodyFrame(double tdb) const; + const ReferenceFrame::SharedConstPtr& getBodyFrame(double tdb) const; const RotationModel* getRotationModel(double tdb) const; // Size methods diff --git a/src/celengine/frame.cpp b/src/celengine/frame.cpp index 93a4596c..b8c7e260 100644 --- a/src/celengine/frame.cpp +++ b/src/celengine/frame.cpp @@ -29,32 +29,10 @@ static const double ANGULAR_VELOCITY_DIFF_DELTA = 1.0 / 1440.0; /*** ReferenceFrame ***/ ReferenceFrame::ReferenceFrame(Selection center) : - centerObject(center), - refCount(0) + centerObject(center) { } - -int -ReferenceFrame::addRef() const -{ - return ++refCount; -} - - -int -ReferenceFrame::release() const -{ - --refCount; - assert(refCount >= 0); - int refCountCopy = refCount; - if (refCount <= 0) - delete this; - - return refCountCopy; -} - - // High-precision rotation using 64.64 fixed point path. Rotate uc by // the rotation specified by unit quaternion q. static UniversalCoord rotate(const UniversalCoord& uc, const Quaterniond& q) @@ -691,8 +669,6 @@ FrameVector::FrameVector(const FrameVector& fv) : vec(fv.vec), frame(fv.frame) { - if (frame != nullptr) - frame->addRef(); } @@ -705,11 +681,7 @@ FrameVector::operator=(const FrameVector& fv) target = fv.target; vec = fv.vec; - if (frame != nullptr) - frame->release(); frame = fv.frame; - if (frame != nullptr) - frame->addRef(); return *this; } @@ -725,14 +697,6 @@ FrameVector::FrameVector(FrameVectorType t) : { } - -FrameVector::~FrameVector() -{ - if (frame != nullptr) - frame->release(); -} - - FrameVector FrameVector::createRelativePositionVector(const Selection& _observer, const Selection& _target) @@ -759,13 +723,11 @@ FrameVector::createRelativeVelocityVector(const Selection& _observer, FrameVector FrameVector::createConstantVector(const Vector3d& _vec, - const ReferenceFrame* _frame) + const ReferenceFrame::SharedConstPtr& _frame) { FrameVector fv(ConstantVector); fv.vec = _vec; fv.frame = _frame; - if (fv.frame != nullptr) - fv.frame->addRef(); return fv; } diff --git a/src/celengine/frame.h b/src/celengine/frame.h index ecfe0578..e2e5369a 100644 --- a/src/celengine/frame.h +++ b/src/celengine/frame.h @@ -11,6 +11,7 @@ #ifndef _CELENGINE_FRAME_H_ #define _CELENGINE_FRAME_H_ +#include #include #include #include @@ -26,12 +27,11 @@ class ReferenceFrame { public: + using SharedPtr = std::shared_ptr; + using SharedConstPtr = std::shared_ptr; ReferenceFrame(Selection center); virtual ~ReferenceFrame() {}; - int addRef() const; - int release() const; - UniversalCoord convertFromUniversal(const UniversalCoord& uc, double tjd) const; UniversalCoord convertToUniversal(const UniversalCoord& uc, double tjd) const; Eigen::Quaterniond convertFromUniversal(const Eigen::Quaterniond& q, double tjd) const; @@ -61,7 +61,6 @@ class ReferenceFrame private: Selection centerObject; - mutable int refCount; }; @@ -133,6 +132,8 @@ class J2000EquatorFrame : public ReferenceFrame class BodyFixedFrame : public ReferenceFrame { public: + using SharedPtr = std::shared_ptr; + using SharedConstPtr = std::shared_ptr; BodyFixedFrame(Selection center, Selection obj); virtual ~BodyFixedFrame() {}; Eigen::Quaterniond getOrientation(double tjd) const; @@ -150,6 +151,8 @@ class BodyFixedFrame : public ReferenceFrame class BodyMeanEquatorFrame : public ReferenceFrame { public: + using SharedPtr = std::shared_ptr; + using SharedConstPtr = std::shared_ptr; BodyMeanEquatorFrame(Selection center, Selection obj, double freeze); BodyMeanEquatorFrame(Selection center, Selection obj); virtual ~BodyMeanEquatorFrame() {}; @@ -175,7 +178,7 @@ class FrameVector EIGEN_MAKE_ALIGNED_OPERATOR_NEW FrameVector(const FrameVector& fv); - ~FrameVector(); + ~FrameVector() = default; FrameVector& operator=(const FrameVector&); Eigen::Vector3d direction(double tjd) const; @@ -199,7 +202,7 @@ class FrameVector static FrameVector createRelativeVelocityVector(const Selection& _observer, const Selection& _target); static FrameVector createConstantVector(const Eigen::Vector3d& _vec, - const ReferenceFrame* _frame); + const ReferenceFrame::SharedConstPtr& _frame); private: /*! Type-only constructor is private. Code outside the class should @@ -211,7 +214,7 @@ class FrameVector Selection observer; Selection target; Eigen::Vector3d vec; // constant vector - const ReferenceFrame* frame; // frame for constant vector + ReferenceFrame::SharedConstPtr frame; // frame for constant vector }; diff --git a/src/celengine/frametree.cpp b/src/celengine/frametree.cpp index 9c714c21..f13b0c34 100644 --- a/src/celengine/frametree.cpp +++ b/src/celengine/frametree.cpp @@ -41,6 +41,8 @@ * object will all cause the tree to be marked as changed. */ +using namespace std; + /*! Create a frame tree associated with a star. */ FrameTree::FrameTree(Star* star) : @@ -51,8 +53,7 @@ FrameTree::FrameTree(Star* star) : { // Default frame for a star is J2000 ecliptical, centered // on the star. - defaultFrame = new J2000EclipticFrame(Selection(star)); - defaultFrame->addRef(); + defaultFrame = make_shared(Selection(star)); } @@ -65,21 +66,19 @@ FrameTree::FrameTree(Body* body) : defaultFrame(nullptr) { // Default frame for a solar system body is the mean equatorial frame of the body. - defaultFrame = new BodyMeanEquatorFrame(Selection(body), Selection(body)); - defaultFrame->addRef(); + defaultFrame = make_shared(Selection(body), Selection(body)); } FrameTree::~FrameTree() { - defaultFrame->release(); } /*! Return the default reference frame for the object a frame tree is associated * with. */ -ReferenceFrame* +const ReferenceFrame::SharedConstPtr& FrameTree::getDefaultReferenceFrame() const { return defaultFrame; @@ -160,9 +159,8 @@ FrameTree::recomputeBoundingSphere() /*! Add a new phase to this tree. */ void -FrameTree::addChild(TimelinePhase* phase) +FrameTree::addChild(const TimelinePhase::SharedConstPtr &phase) { - phase->addRef(); children.push_back(phase); markChanged(); } @@ -172,12 +170,11 @@ FrameTree::addChild(TimelinePhase* phase) * phase doesn't exist in the tree. */ void -FrameTree::removeChild(TimelinePhase* phase) +FrameTree::removeChild(const TimelinePhase::SharedConstPtr &phase) { - vector::iterator iter = find(children.begin(), children.end(), phase); + auto iter = find(children.begin(), children.end(), phase); if (iter != children.end()) { - (*iter)->release(); children.erase(iter); markChanged(); } @@ -185,7 +182,7 @@ FrameTree::removeChild(TimelinePhase* phase) /*! Return the child at the specified index. */ -TimelinePhase* +const TimelinePhase::SharedConstPtr& FrameTree::getChild(unsigned int n) const { return children[n]; diff --git a/src/celengine/frametree.h b/src/celengine/frametree.h index f7bceb0b..d3513767 100644 --- a/src/celengine/frametree.h +++ b/src/celengine/frametree.h @@ -13,14 +13,14 @@ #ifndef _CELENGINE_FRAMETREE_H_ #define _CELENGINE_FRAMETREE_H_ +#include #include #include +#include "frame.h" +#include "timelinephase.h" class Star; class Body; -class ReferenceFrame; -class TimelinePhase; - class FrameTree { @@ -37,11 +37,11 @@ public: return starParent; } - ReferenceFrame* getDefaultReferenceFrame() const; + const ReferenceFrame::SharedConstPtr &getDefaultReferenceFrame() const; - void addChild(TimelinePhase* phase); - void removeChild(TimelinePhase* phase); - TimelinePhase* getChild(unsigned int n) const; + void addChild(const TimelinePhase::SharedConstPtr &phase); + void removeChild(const TimelinePhase::SharedConstPtr &phase); + const TimelinePhase::SharedConstPtr &getChild(unsigned int n) const; unsigned int childCount() const; void markChanged(); @@ -92,7 +92,7 @@ public: private: Star* starParent; Body* bodyParent; - std::vector children; + std::vector children; double m_boundingSphereRadius{ 0.0 }; double m_maxChildRadius{ 0.0 }; @@ -100,7 +100,7 @@ private: bool m_changed{ false }; int m_childClassMask{ 0 }; - ReferenceFrame* defaultFrame; + ReferenceFrame::SharedConstPtr defaultFrame; }; #endif // _CELENGINE_FRAMETREE_H_ diff --git a/src/celengine/observer.cpp b/src/celengine/observer.cpp index d0ccbd55..4b89aac9 100644 --- a/src/celengine/observer.cpp +++ b/src/celengine/observer.cpp @@ -55,9 +55,8 @@ static Vector3d slerp(double t, const Vector3d& v0, const Vector3d& v1) * updates due to an active goto operation. */ -Observer::Observer() +Observer::Observer() : frame(make_shared()) { - frame = new ObserverFrame(); updateUniversal(); } @@ -69,7 +68,6 @@ Observer::Observer(const Observer& o) : orientation(o.orientation), velocity(o.velocity), angularVelocity(o.angularVelocity), - frame(nullptr), realTime(o.realTime), targetSpeed(o.targetSpeed), targetVelocity(o.targetVelocity), @@ -83,15 +81,10 @@ Observer::Observer(const Observer& o) : locationFilter(o.locationFilter), displayedSurface(o.displayedSurface) { - frame = new ObserverFrame(*o.frame); + setFrame(o.frame); updateUniversal(); } -Observer::~Observer() -{ - delete frame; -} - Observer& Observer::operator=(const Observer& o) { simTime = o.simTime; @@ -113,7 +106,7 @@ Observer& Observer::operator=(const Observer& o) locationFilter = o.locationFilter; displayedSurface = o.displayedSurface; - setFrame(*o.frame); + setFrame(o.frame); updateUniversal(); return *this; @@ -775,7 +768,7 @@ void Observer::setMode(Observer::ObserverMode mode) // Private method to convert coordinates when a new observer frame is set. // Universal coordinates remain the same. All frame coordinates get updated, including // the goto parameters. -void Observer::convertFrameCoordinates(const ObserverFrame* newFrame) +void Observer::convertFrameCoordinates(const ObserverFrame::SharedConstPtr &newFrame) { double now = getTime(); @@ -797,9 +790,8 @@ void Observer::convertFrameCoordinates(const ObserverFrame* newFrame) */ void Observer::setFrame(ObserverFrame::CoordinateSystem cs, const Selection& refObj, const Selection& targetObj) { - ObserverFrame* newFrame = new ObserverFrame(cs, refObj, targetObj); + auto newFrame = make_shared(cs, refObj, targetObj); convertFrameCoordinates(newFrame); - delete frame; frame = newFrame; } @@ -816,25 +808,22 @@ void Observer::setFrame(ObserverFrame::CoordinateSystem cs, const Selection& ref /*! Set the observer's reference frame. The position of the observer in * universal coordinates will not change. */ -void Observer::setFrame(const ObserverFrame& f) +void Observer::setFrame(const ObserverFrame::SharedConstPtr& f) { - if (frame != &f) + if (frame != f) { - auto* newFrame = new ObserverFrame(f); - - if (frame != nullptr) + if (frame) { - convertFrameCoordinates(newFrame); - delete frame; + convertFrameCoordinates(f); } - frame = newFrame; + frame = f; } } /*! Get the current reference frame for the observer. */ -const ObserverFrame* Observer::getFrame() const +const ObserverFrame::SharedConstPtr& Observer::getFrame() const { return frame; } @@ -1403,7 +1392,6 @@ ObserverFrame::ObserverFrame() : frame(nullptr) { frame = createFrame(Universal, Selection(), Selection()); - frame->addRef(); } @@ -1419,7 +1407,6 @@ ObserverFrame::ObserverFrame(CoordinateSystem _coordSys, targetObject(_targetObject) { frame = createFrame(_coordSys, _refObject, _targetObject); - frame->addRef(); } @@ -1430,7 +1417,6 @@ ObserverFrame::ObserverFrame(const ReferenceFrame &f) : coordSys(Unknown), frame(&f) { - frame->addRef(); } @@ -1440,7 +1426,6 @@ ObserverFrame::ObserverFrame(const ObserverFrame& f) : frame(f.frame), targetObject(f.targetObject) { - frame->addRef(); } @@ -1450,21 +1435,11 @@ ObserverFrame& ObserverFrame::operator=(const ObserverFrame& f) targetObject = f.targetObject; // In case frames are the same, make sure we addref before releasing - f.frame->addRef(); - frame->release(); frame = f.frame; return *this; } - -ObserverFrame::~ObserverFrame() -{ - if (frame != nullptr) - frame->release(); -} - - ObserverFrame::CoordinateSystem ObserverFrame::getCoordinateSystem() const { @@ -1486,7 +1461,7 @@ ObserverFrame::getTargetObject() const } -const ReferenceFrame* +const ReferenceFrame::SharedConstPtr& ObserverFrame::getFrame() const { return frame; @@ -1524,8 +1499,8 @@ ObserverFrame::convertToUniversal(const Quaterniond& q, double tjd) const /*! Convert a position from one frame to another. */ UniversalCoord -ObserverFrame::convert(const ObserverFrame* fromFrame, - const ObserverFrame* toFrame, +ObserverFrame::convert(const ObserverFrame::SharedConstPtr& fromFrame, + const ObserverFrame::SharedConstPtr& toFrame, const UniversalCoord& uc, double t) { @@ -1537,8 +1512,8 @@ ObserverFrame::convert(const ObserverFrame* fromFrame, /*! Convert an orientation from one frame to another. */ Quaterniond -ObserverFrame::convert(const ObserverFrame* fromFrame, - const ObserverFrame* toFrame, +ObserverFrame::convert(const ObserverFrame::SharedConstPtr& fromFrame, + const ObserverFrame::SharedConstPtr& toFrame, const Quaterniond& q, double t) { @@ -1548,7 +1523,7 @@ ObserverFrame::convert(const ObserverFrame* fromFrame, // Create the ReferenceFrame for the specified observer frame parameters. -ReferenceFrame* +ReferenceFrame::SharedConstPtr ObserverFrame::createFrame(CoordinateSystem _coordSys, const Selection& _refObject, const Selection& _targetObject) @@ -1556,27 +1531,27 @@ ObserverFrame::createFrame(CoordinateSystem _coordSys, switch (_coordSys) { case Universal: - return new J2000EclipticFrame(Selection()); + return make_shared(Selection()); case Ecliptical: - return new J2000EclipticFrame(_refObject); + return make_shared(_refObject); case Equatorial: - return new BodyMeanEquatorFrame(_refObject, _refObject); + return make_shared(_refObject, _refObject); case BodyFixed: - return new BodyFixedFrame(_refObject, _refObject); + return make_shared(_refObject, _refObject); case PhaseLock: { - return new TwoVectorFrame(_refObject, + return make_shared(_refObject, FrameVector::createRelativePositionVector(_refObject, _targetObject), 1, FrameVector::createRelativeVelocityVector(_refObject, _targetObject), 2); } case Chase: { - return new TwoVectorFrame(_refObject, + return make_shared(_refObject, FrameVector::createRelativeVelocityVector(_refObject, _refObject.parent()), 1, FrameVector::createRelativePositionVector(_refObject, _refObject.parent()), 2); } @@ -1584,8 +1559,8 @@ ObserverFrame::createFrame(CoordinateSystem _coordSys, case PhaseLock_Old: { FrameVector rotAxis(FrameVector::createConstantVector(Vector3d::UnitY(), - new BodyMeanEquatorFrame(_refObject, _refObject))); - return new TwoVectorFrame(_refObject, + make_shared(_refObject, _refObject))); + return make_shared(_refObject, FrameVector::createRelativePositionVector(_refObject, _targetObject), 3, rotAxis, 2); } @@ -1593,9 +1568,9 @@ ObserverFrame::createFrame(CoordinateSystem _coordSys, case Chase_Old: { FrameVector rotAxis(FrameVector::createConstantVector(Vector3d::UnitY(), - new BodyMeanEquatorFrame(_refObject, _refObject))); + make_shared(_refObject, _refObject))); - return new TwoVectorFrame(_refObject, + return make_shared(_refObject, FrameVector::createRelativeVelocityVector(_refObject.parent(), _refObject), 3, rotAxis, 2); } @@ -1603,10 +1578,10 @@ ObserverFrame::createFrame(CoordinateSystem _coordSys, case ObserverLocal: // TODO: This is only used for computing up vectors for orientation; it does // define a proper frame for the observer position orientation. - return new J2000EclipticFrame(Selection()); + return make_shared(Selection()); default: - return new J2000EclipticFrame(_refObject); + return make_shared(_refObject); } } diff --git a/src/celengine/observer.h b/src/celengine/observer.h index e301a036..557f19e3 100644 --- a/src/celengine/observer.h +++ b/src/celengine/observer.h @@ -18,6 +18,7 @@ #ifndef _CELENGINE_OBSERVER_H_ #define _CELENGINE_OBSERVER_H_ +#include #include #include #include @@ -27,6 +28,8 @@ class ObserverFrame { public: + using SharedPtr = std::shared_ptr; + using SharedConstPtr = std::shared_ptr; enum CoordinateSystem { Universal = 0, @@ -53,43 +56,43 @@ public: ObserverFrame(); ObserverFrame(CoordinateSystem cs, - const Selection& _refObject, - const Selection& _targetObj = Selection()); + const Selection &_refObject, + const Selection &_targetObj = Selection()); ObserverFrame(const ObserverFrame&); - ObserverFrame(const ReferenceFrame& f); + ObserverFrame(const ReferenceFrame &f); - ~ObserverFrame(); + ~ObserverFrame() = default; - ObserverFrame& operator=(const ObserverFrame& f); + ObserverFrame &operator=(const ObserverFrame &f); CoordinateSystem getCoordinateSystem() const; Selection getRefObject() const; Selection getTargetObject() const; - const ReferenceFrame* getFrame() const; + const ReferenceFrame::SharedConstPtr &getFrame() const; - UniversalCoord convertFromUniversal(const UniversalCoord& uc, double tjd) const; - UniversalCoord convertToUniversal(const UniversalCoord& uc, double tjd) const; - Eigen::Quaterniond convertFromUniversal(const Eigen::Quaterniond& q, double tjd) const; - Eigen::Quaterniond convertToUniversal(const Eigen::Quaterniond& q, double tjd) const; + UniversalCoord convertFromUniversal(const UniversalCoord &uc, double tjd) const; + UniversalCoord convertToUniversal(const UniversalCoord &uc, double tjd) const; + Eigen::Quaterniond convertFromUniversal(const Eigen::Quaterniond &q, double tjd) const; + Eigen::Quaterniond convertToUniversal(const Eigen::Quaterniond &q, double tjd) const; - static UniversalCoord convert(const ObserverFrame* fromFrame, - const ObserverFrame* toFrame, - const UniversalCoord& uc, + static UniversalCoord convert(const ObserverFrame::SharedConstPtr &fromFrame, + const ObserverFrame::SharedConstPtr &toFrame, + const UniversalCoord &uc, double t); - static Eigen::Quaterniond convert(const ObserverFrame* fromFrame, - const ObserverFrame* toFrame, - const Eigen::Quaterniond& q, + static Eigen::Quaterniond convert(const ObserverFrame::SharedConstPtr &fromFrame, + const ObserverFrame::SharedConstPtr &toFrame, + const Eigen::Quaterniond &q, double t); private: - ReferenceFrame* createFrame(CoordinateSystem _coordSys, - const Selection& _refObject, - const Selection& _targetObject); + ReferenceFrame::SharedConstPtr createFrame(CoordinateSystem _coordSys, + const Selection &_refObject, + const Selection &_targetObject); private: CoordinateSystem coordSys; - const ReferenceFrame* frame; + ReferenceFrame::SharedConstPtr frame; Selection targetObject; }; @@ -108,10 +111,10 @@ public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW Observer(); - Observer(const Observer& o); - ~Observer(); + Observer(const Observer &o); + ~Observer() = default; - Observer& operator=(const Observer& o); + Observer &operator=(const Observer &o); UniversalCoord getPosition() const; void setPosition(const UniversalCoord&); @@ -135,8 +138,8 @@ public: Eigen::Vector3f getPickRay(float x, float y) const; - void orbit(const Selection&, const Eigen::Quaternionf& q); - void rotate(const Eigen::Quaternionf& q); + void orbit(const Selection&, const Eigen::Quaternionf &q); + void rotate(const Eigen::Quaternionf &q); void changeOrbitDistance(const Selection&, float d); void setTargetSpeed(float s); float getTargetSpeed(); @@ -144,7 +147,7 @@ public: Selection getTrackedObject() const; void setTrackedObject(const Selection&); - const std::string& getDisplayedSurface() const; + const std::string &getDisplayedSurface() const; void setDisplayedSurface(const std::string&); uint64_t getLocationFilter() const; @@ -152,41 +155,41 @@ public: void gotoSelection(const Selection&, double gotoTime, - const Eigen::Vector3f& up, + const Eigen::Vector3f &up, ObserverFrame::CoordinateSystem upFrame); void gotoSelection(const Selection&, double gotoTime, double startInter, double endInter, - const Eigen::Vector3f& up, + const Eigen::Vector3f &up, ObserverFrame::CoordinateSystem upFrame); void gotoSelectionGC(const Selection&, double gotoTime, double startInter, double endInter, - const Eigen::Vector3f& up, + const Eigen::Vector3f &up, ObserverFrame::CoordinateSystem upFrame); void gotoSelection(const Selection&, double gotoTime, double distance, - const Eigen::Vector3f& up, + const Eigen::Vector3f &up, ObserverFrame::CoordinateSystem upFrame); void gotoSelectionLongLat(const Selection&, double gotoTime, double distance, float longitude, float latitude, - const Eigen::Vector3f& up); - void gotoLocation(const UniversalCoord& toPosition, - const Eigen::Quaterniond& toOrientation, + const Eigen::Vector3f &up); + void gotoLocation(const UniversalCoord &toPosition, + const Eigen::Quaterniond &toOrientation, double duration); void getSelectionLongLat(const Selection&, - double& distance, - double& longitude, - double& latitude); - void gotoSelectionGC(const Selection& selection, + double &distance, + double &longitude, + double &latitude); + void gotoSelectionGC(const Selection &selection, double gotoTime, double distance, - const Eigen::Vector3f& up, + const Eigen::Vector3f &up, ObserverFrame::CoordinateSystem upFrame); void gotoSurface(const Selection&, double duration); void centerSelection(const Selection&, double centerTime = 0.5); @@ -199,11 +202,11 @@ public: void reverseOrientation(); - void setFrame(ObserverFrame::CoordinateSystem cs, const Selection& refObj, const Selection& targetObj); - void setFrame(ObserverFrame::CoordinateSystem cs, const Selection& refObj); - void setFrame(const ObserverFrame& f); + void setFrame(ObserverFrame::CoordinateSystem cs, const Selection &refObj, const Selection &targetObj); + void setFrame(ObserverFrame::CoordinateSystem cs, const Selection &refObj); + void setFrame(const ObserverFrame::SharedConstPtr &f); - const ObserverFrame* getFrame() const; + const ObserverFrame::SharedConstPtr &getFrame() const; double getArrivalTime() const; @@ -251,34 +254,34 @@ public: // void setSimulation(Simulation* _sim) { sim = _sim; }; private: - void computeGotoParameters(const Selection& sel, - JourneyParams& jparams, + void computeGotoParameters(const Selection &sel, + JourneyParams &jparams, double gotoTime, double startInter, double endInter, - const Eigen::Vector3d& offset, + const Eigen::Vector3d &offset, ObserverFrame::CoordinateSystem offsetFrame, - const Eigen::Vector3f& up, + const Eigen::Vector3f &up, ObserverFrame::CoordinateSystem upFrame); - void computeGotoParametersGC(const Selection& sel, - JourneyParams& jparams, + void computeGotoParametersGC(const Selection &sel, + JourneyParams &jparams, double gotoTime, double startInter, double endInter, - const Eigen::Vector3d& offset, + const Eigen::Vector3d &offset, ObserverFrame::CoordinateSystem offsetFrame, - const Eigen::Vector3f& up, + const Eigen::Vector3f &up, ObserverFrame::CoordinateSystem upFrame, - const Selection& centerObj); - void computeCenterParameters(const Selection& sel, - JourneyParams& jparams, + const Selection ¢erObj); + void computeCenterParameters(const Selection &sel, + JourneyParams &jparams, double centerTime); - void computeCenterCOParameters(const Selection& sel, - JourneyParams& jparams, + void computeCenterCOParameters(const Selection &sel, + JourneyParams &jparams, double centerTime); void updateUniversal(); - void convertFrameCoordinates(const ObserverFrame* newFrame); + void convertFrameCoordinates(const ObserverFrame::SharedConstPtr &newFrame); private: double simTime{ 0.0 }; @@ -294,7 +297,7 @@ public: UniversalCoord positionUniv; Eigen::Quaterniond orientationUniv; - ObserverFrame* frame{ nullptr }; + ObserverFrame::SharedConstPtr frame; double realTime{ 0.0 }; diff --git a/src/celengine/parseobject.cpp b/src/celengine/parseobject.cpp index c0eed8a7..af578472 100644 --- a/src/celengine/parseobject.cpp +++ b/src/celengine/parseobject.cpp @@ -1307,7 +1307,7 @@ getFrameCenter(const Universe& universe, Hash* frameData, const Selection& defau } -static BodyFixedFrame* +static BodyFixedFrame::SharedConstPtr CreateBodyFixedFrame(const Universe& universe, Hash* frameData, const Selection& defaultCenter) @@ -1316,11 +1316,11 @@ CreateBodyFixedFrame(const Universe& universe, if (center.empty()) return nullptr; - return new BodyFixedFrame(center, center); + return make_shared(center, center); } -static BodyMeanEquatorFrame* +static BodyMeanEquatorFrame::SharedConstPtr CreateMeanEquatorFrame(const Universe& universe, Hash* frameData, const Selection& defaultCenter) @@ -1346,11 +1346,11 @@ CreateMeanEquatorFrame(const Universe& universe, double freezeEpoch = 0.0; if (ParseDate(frameData, "Freeze", freezeEpoch)) { - return new BodyMeanEquatorFrame(center, obj, freezeEpoch); + return make_shared(center, obj, freezeEpoch); } else { - return new BodyMeanEquatorFrame(center, obj); + return make_shared(center, obj); } } @@ -1542,7 +1542,7 @@ CreateFrameVector(const Universe& universe, // The frame for the vector is optional; a nullptr frame indicates // J2000 ecliptic. - ReferenceFrame* f = nullptr; + ReferenceFrame::SharedConstPtr f; Value* frameValue = constVecData->getValue("Frame"); if (frameValue != nullptr) { @@ -1561,7 +1561,7 @@ CreateFrameVector(const Universe& universe, } -static TwoVectorFrame* +static shared_ptr CreateTwoVectorFrame(const Universe& universe, Hash* frameData, const Selection& defaultCenter) @@ -1623,22 +1623,19 @@ CreateTwoVectorFrame(const Universe& universe, center, secondaryData); - TwoVectorFrame* frame = nullptr; + shared_ptr frame; if (primaryVector != nullptr && secondaryVector != nullptr) { - frame = new TwoVectorFrame(center, + frame = make_shared(center, *primaryVector, primaryAxis, *secondaryVector, secondaryAxis); } - delete primaryVector; - delete secondaryVector; - return frame; } -static J2000EclipticFrame* +static shared_ptr CreateJ2000EclipticFrame(const Universe& universe, Hash* frameData, const Selection& defaultCenter) @@ -1648,11 +1645,11 @@ CreateJ2000EclipticFrame(const Universe& universe, if (center.empty()) return nullptr; - return new J2000EclipticFrame(center); + return make_shared(center); } -static J2000EquatorFrame* +static shared_ptr CreateJ2000EquatorFrame(const Universe& universe, Hash* frameData, const Selection& defaultCenter) @@ -1662,7 +1659,7 @@ CreateJ2000EquatorFrame(const Universe& universe, if (center.empty()) return nullptr; - return new J2000EquatorFrame(center); + return make_shared(center); } @@ -1670,16 +1667,16 @@ CreateJ2000EquatorFrame(const Universe& universe, * Helper function for CreateTopocentricFrame(). * Creates a two-vector frame with the specified center, target, and observer. */ -TwoVectorFrame* +shared_ptr CreateTopocentricFrame(const Selection& center, const Selection& target, const Selection& observer) { - BodyMeanEquatorFrame* eqFrame = new BodyMeanEquatorFrame(target, target); + shared_ptr eqFrame = make_shared(target, target); FrameVector north = FrameVector::createConstantVector(Vector3d::UnitY(), eqFrame); FrameVector up = FrameVector::createRelativePositionVector(observer, target); - return new TwoVectorFrame(center, up, -2, north, -3); + return make_shared(center, up, -2, north, -3); } @@ -1723,7 +1720,7 @@ CreateTopocentricFrame(const Selection& center, * ... * } */ -static TwoVectorFrame* +static shared_ptr CreateTopocentricFrame(const Universe& universe, Hash* frameData, const Selection& defaultTarget, @@ -1805,7 +1802,7 @@ CreateTopocentricFrame(const Universe& universe, } -static ReferenceFrame* +static ReferenceFrame::SharedConstPtr CreateComplexFrame(const Universe& universe, Hash* frameData, const Selection& defaultCenter, Body* defaultObserver) { Value* value = frameData->getValue("BodyFixed"); @@ -1886,7 +1883,7 @@ CreateComplexFrame(const Universe& universe, Hash* frameData, const Selection& d } -ReferenceFrame* CreateReferenceFrame(const Universe& universe, +ReferenceFrame::SharedConstPtr CreateReferenceFrame(const Universe& universe, Value* frameValue, const Selection& defaultCenter, Body* defaultObserver) diff --git a/src/celengine/parseobject.h b/src/celengine/parseobject.h index 07182acc..74bb266b 100644 --- a/src/celengine/parseobject.h +++ b/src/celengine/parseobject.h @@ -14,14 +14,14 @@ #define _CELENGINE_PARSEOBJECT_H_ #include +#include #include #include +#include "frame.h" #include "parser.h" class Body; class Star; -class ReferenceFrame; -class TwoVectorFrame; class Universe; class Selection; @@ -46,12 +46,12 @@ RotationModel* CreateRotationModel(Hash* rotationData, RotationModel* CreateDefaultRotationModel(double syncRotationPeriod); -ReferenceFrame* CreateReferenceFrame(const Universe& universe, +ReferenceFrame::SharedConstPtr CreateReferenceFrame(const Universe& universe, Value* frameValue, const Selection& defaultCenter, Body* defaultObserver); -TwoVectorFrame* CreateTopocentricFrame(const Selection& center, +std::shared_ptr CreateTopocentricFrame(const Selection& center, const Selection& target, const Selection& observer); diff --git a/src/celengine/render.cpp b/src/celengine/render.cpp index 6093b279..c2f950fa 100644 --- a/src/celengine/render.cpp +++ b/src/celengine/render.cpp @@ -5906,7 +5906,7 @@ void Renderer::buildRenderLists(const Vector3d& astrocentricObserverPos, unsigned int nChildren = tree != nullptr ? tree->childCount() : 0; for (unsigned int i = 0; i < nChildren; i++) { - const TimelinePhase* phase = tree->getChild(i); + auto phase = tree->getChild(i); // No need to do anything if the phase isn't active now if (!phase->includes(now)) @@ -5919,7 +5919,7 @@ void Renderer::buildRenderLists(const Vector3d& astrocentricObserverPos, // Get the position of the body relative to the sun. Vector3d p = phase->orbit()->positionAtTime(now); - ReferenceFrame* frame = phase->orbitFrame(); + auto frame = phase->orbitFrame(); Vector3d pos_s = frameCenter + frame->getOrientation(now).conjugate() * p; // We now have the positions of the observer and the planet relative @@ -6126,7 +6126,7 @@ void Renderer::buildOrbitLists(const Vector3d& astrocentricObserverPos, unsigned int nChildren = tree != nullptr ? tree->childCount() : 0; for (unsigned int i = 0; i < nChildren; i++) { - const TimelinePhase* phase = tree->getChild(i); + auto phase = tree->getChild(i); // No need to do anything if the phase isn't active now if (!phase->includes(now)) @@ -6281,7 +6281,7 @@ void Renderer::buildLabelLists(const Frustum& viewFrustum, { bool isBehindPrimary = false; - const TimelinePhase* phase = body->getTimeline()->findPhase(now); + auto phase = body->getTimeline()->findPhase(now); Body* primary = phase->orbitFrame()->getCenter().body(); if (primary != nullptr && (primary->getClassification() & Body::Invisible) != 0) { @@ -7103,7 +7103,7 @@ void Renderer::renderSkyGrids(const Observer& observer) if ((renderFlags & ShowHorizonGrid) != 0) { double tdb = observer.getTime(); - const ObserverFrame* frame = observer.getFrame(); + auto frame = observer.getFrame(); Body* body = frame->getRefObject().body(); if (body != nullptr) diff --git a/src/celengine/simulation.cpp b/src/celengine/simulation.cpp index b8bc5d49..91c9a68f 100644 --- a/src/celengine/simulation.cpp +++ b/src/celengine/simulation.cpp @@ -233,7 +233,7 @@ void Simulation::setFrame(ObserverFrame::CoordinateSystem coordSys, activeObserver->setFrame(coordSys, refObject); } -const ObserverFrame* Simulation::getFrame() const +const ObserverFrame::SharedConstPtr& Simulation::getFrame() const { return activeObserver->getFrame(); } diff --git a/src/celengine/simulation.h b/src/celengine/simulation.h index a41acc7b..480100d8 100644 --- a/src/celengine/simulation.h +++ b/src/celengine/simulation.h @@ -10,6 +10,7 @@ #ifndef _CELENGINE_SIMULATION_H_ #define _CELENGINE_SIMULATION_H_ +#include #include #include #include @@ -113,7 +114,7 @@ class Simulation void setFrame(ObserverFrame::CoordinateSystem, const Selection& refObject, const Selection& targetObject); void setFrame(ObserverFrame::CoordinateSystem, const Selection& refObject); - const ObserverFrame* getFrame() const; + const ObserverFrame::SharedConstPtr& getFrame() const; private: SolarSystem* getSolarSystem(const Star* star); diff --git a/src/celengine/solarsys.cpp b/src/celengine/solarsys.cpp index 03cfb210..03013782 100644 --- a/src/celengine/solarsys.cpp +++ b/src/celengine/solarsys.cpp @@ -274,15 +274,15 @@ static Selection GetParentObject(PlanetarySystem* system) } -TimelinePhase* CreateTimelinePhase(Body* body, - Universe& universe, - Hash* phaseData, - const string& path, - ReferenceFrame* defaultOrbitFrame, - ReferenceFrame* defaultBodyFrame, - bool isFirstPhase, - bool isLastPhase, - double previousPhaseEnd) +TimelinePhase::SharedConstPtr CreateTimelinePhase(Body* body, + Universe& universe, + Hash* phaseData, + const string& path, + const ReferenceFrame::SharedConstPtr& defaultOrbitFrame, + const ReferenceFrame::SharedConstPtr& defaultBodyFrame, + bool isFirstPhase, + bool isLastPhase, + double previousPhaseEnd) { double beginning = previousPhaseEnd; double ending = numeric_limits::infinity(); @@ -306,7 +306,7 @@ TimelinePhase* CreateTimelinePhase(Body* body, } // Get the orbit reference frame. - ReferenceFrame* orbitFrame; + ReferenceFrame::SharedConstPtr orbitFrame; Value* frameValue = phaseData->getValue("OrbitFrame"); if (frameValue != nullptr) { @@ -321,17 +321,15 @@ TimelinePhase* CreateTimelinePhase(Body* body, // No orbit frame specified; use the default frame. orbitFrame = defaultOrbitFrame; } - orbitFrame->addRef(); // Get the body reference frame - ReferenceFrame* bodyFrame; + ReferenceFrame::SharedConstPtr bodyFrame; Value* bodyFrameValue = phaseData->getValue("BodyFrame"); if (bodyFrameValue != nullptr) { bodyFrame = CreateReferenceFrame(universe, bodyFrameValue, defaultBodyFrame->getCenter(), body); if (bodyFrame == nullptr) { - orbitFrame->release(); return nullptr; } } @@ -340,7 +338,6 @@ TimelinePhase* CreateTimelinePhase(Body* body, // No body frame specified; use the default frame. bodyFrame = defaultBodyFrame; } - bodyFrame->addRef(); // Use planet units (AU for semimajor axis) if the center of the orbit // reference frame is a star. @@ -351,8 +348,6 @@ TimelinePhase* CreateTimelinePhase(Body* body, if (!orbit) { clog << "Error: missing orbit in timeline phase.\n"; - bodyFrame->release(); - orbitFrame->release(); return nullptr; } @@ -368,17 +363,15 @@ TimelinePhase* CreateTimelinePhase(Body* body, rotationModel = new ConstantOrientation(Quaterniond::Identity()); } - TimelinePhase* phase = TimelinePhase::CreateTimelinePhase(universe, - body, - beginning, ending, - *orbitFrame, - *orbit, - *bodyFrame, - *rotationModel); + auto phase = TimelinePhase::CreateTimelinePhase(universe, + body, + beginning, ending, + orbitFrame, + *orbit, + bodyFrame, + *rotationModel); // Frame ownership transfered to phase; release local references - orbitFrame->release(); - bodyFrame->release(); return phase; } @@ -388,8 +381,8 @@ Timeline* CreateTimelineFromArray(Body* body, Universe& universe, ValueArray* timelineArray, const string& path, - ReferenceFrame* defaultOrbitFrame, - ReferenceFrame* defaultBodyFrame) + const ReferenceFrame::SharedConstPtr& defaultOrbitFrame, + const ReferenceFrame::SharedConstPtr& defaultBodyFrame) { auto* timeline = new Timeline(); double previousEnding = -numeric_limits::infinity(); @@ -407,11 +400,11 @@ Timeline* CreateTimelineFromArray(Body* body, bool isFirstPhase = iter == timelineArray->begin(); bool isLastPhase = *iter == timelineArray->back(); - TimelinePhase* phase = CreateTimelinePhase(body, universe, phaseData, - path, - defaultOrbitFrame, - defaultBodyFrame, - isFirstPhase, isLastPhase, previousEnding); + auto phase = CreateTimelinePhase(body, universe, phaseData, + path, + defaultOrbitFrame, + defaultBodyFrame, + isFirstPhase, isLastPhase, previousEnding); if (phase == nullptr) { clog << "Error in timeline of '" << body->getName() << "', phase " << iter - timelineArray->begin() + 1 << endl; @@ -457,14 +450,12 @@ static bool CreateTimeline(Body* body, return false; } - ReferenceFrame* defaultOrbitFrame = nullptr; - ReferenceFrame* defaultBodyFrame = nullptr; + ReferenceFrame::SharedConstPtr defaultOrbitFrame; + ReferenceFrame::SharedConstPtr defaultBodyFrame; if (bodyType == SurfaceObject) { - defaultOrbitFrame = new BodyFixedFrame(parentObject, parentObject); + defaultOrbitFrame = make_shared(parentObject, parentObject); defaultBodyFrame = CreateTopocentricFrame(parentObject, parentObject, Selection(body)); - defaultOrbitFrame->addRef(); - defaultBodyFrame->addRef(); } else { @@ -480,8 +471,6 @@ static bool CreateTimeline(Body* body, if (value->getType() != Value::ArrayType) { clog << "Error: Timeline must be an array\n"; - delete defaultBodyFrame; - delete defaultOrbitFrame; return false; } @@ -496,8 +485,8 @@ static bool CreateTimeline(Body* body, } // Information required for the object timeline. - ReferenceFrame* orbitFrame = nullptr; - ReferenceFrame* bodyFrame = nullptr; + ReferenceFrame::SharedConstPtr orbitFrame; + ReferenceFrame::SharedConstPtr bodyFrame; Orbit* orbit = nullptr; RotationModel* rotationModel = nullptr; double beginning = -numeric_limits::infinity(); @@ -518,7 +507,7 @@ static bool CreateTimeline(Body* body, const Timeline* timeline = body->getTimeline(); if (timeline->phaseCount() == 1) { - const TimelinePhase* phase = timeline->getPhase(0); + auto phase = timeline->getPhase(0).get(); orbitFrame = phase->orbitFrame(); bodyFrame = phase->bodyFrame(); orbit = phase->orbit(); @@ -533,7 +522,7 @@ static bool CreateTimeline(Body* body, Value* frameValue = planetData->getValue("OrbitFrame"); if (frameValue != nullptr) { - ReferenceFrame* frame = CreateReferenceFrame(universe, frameValue, parentObject, body); + auto frame = CreateReferenceFrame(universe, frameValue, parentObject, body); if (frame != nullptr) { orbitFrame = frame; @@ -547,7 +536,7 @@ static bool CreateTimeline(Body* body, Value* bodyFrameValue = planetData->getValue("BodyFrame"); if (bodyFrameValue != nullptr) { - ReferenceFrame* frame = CreateReferenceFrame(universe, bodyFrameValue, parentObject, body); + auto frame = CreateReferenceFrame(universe, bodyFrameValue, parentObject, body); if (frame != nullptr) { bodyFrame = frame; @@ -582,7 +571,6 @@ static bool CreateTimeline(Body* body, else { clog << "No valid orbit specified for object '" << body->getName() << "'. Skipping.\n"; - delete defaultOrbitFrame; return false; } } @@ -629,23 +617,19 @@ static bool CreateTimeline(Body* body, if (beginning >= ending) { clog << "Beginning time must be before Ending time.\n"; - delete defaultBodyFrame; - delete bodyFrame; - delete defaultOrbitFrame; - delete orbitFrame; delete rotationModel; return false; } // We finally have an orbit, rotation model, frames, and time range. Create // the object timeline. - TimelinePhase* phase = TimelinePhase::CreateTimelinePhase(universe, - body, - beginning, ending, - *orbitFrame, - *orbit, - *bodyFrame, - *rotationModel); + auto phase = TimelinePhase::CreateTimelinePhase(universe, + body, + beginning, ending, + orbitFrame, + *orbit, + bodyFrame, + *rotationModel); // We've already checked that beginning < ending; nothing else should go // wrong during the creation of a TimelinePhase. diff --git a/src/celengine/timeline.cpp b/src/celengine/timeline.cpp index d159e524..457a69a7 100644 --- a/src/celengine/timeline.cpp +++ b/src/celengine/timeline.cpp @@ -28,14 +28,12 @@ Timeline::~Timeline() { // Remove the phase from whatever phase tree contains it. phase->getFrameTree()->removeChild(phase); - - phase->release(); } } bool -Timeline::appendPhase(TimelinePhase* phase) +Timeline::appendPhase(TimelinePhase::SharedConstPtr &phase) { // Validate start and end times. If there are existing phases in the timeline, // startTime must be equal to endTime of the previous phases so that there are @@ -46,14 +44,13 @@ Timeline::appendPhase(TimelinePhase* phase) return false; } - phase->addRef(); phases.push_back(phase); return true; } -const TimelinePhase* +const TimelinePhase::SharedConstPtr& Timeline::findPhase(double t) const { // Find the phase containing time t. The overwhelming common case is @@ -65,7 +62,7 @@ Timeline::findPhase(double t) const } else { - for (const auto phase : phases) + for (const auto& phase : phases) { if (t < phase->endTime()) return phase; @@ -79,7 +76,7 @@ Timeline::findPhase(double t) const /*! Get the phase at the specified index. */ -const TimelinePhase* +const TimelinePhase::SharedConstPtr& Timeline::getPhase(unsigned int n) const { return phases.at(n); diff --git a/src/celengine/timeline.h b/src/celengine/timeline.h index 2fc069c8..e535ce1a 100644 --- a/src/celengine/timeline.h +++ b/src/celengine/timeline.h @@ -13,12 +13,13 @@ #ifndef _CELENGINE_TIMELINE_H_ #define _CELENGINE_TIMELINE_H_ +#include #include +#include "timelinephase.h" class ReferenceFrame; class Orbit; class RotationModel; -class TimelinePhase; class Timeline { @@ -26,9 +27,9 @@ public: Timeline() = default; ~Timeline(); - const TimelinePhase* findPhase(double t) const; - bool appendPhase(TimelinePhase*); - const TimelinePhase* getPhase(unsigned int n) const; + const TimelinePhase::SharedConstPtr& findPhase(double t) const; + bool appendPhase(TimelinePhase::SharedConstPtr&); + const TimelinePhase::SharedConstPtr& getPhase(unsigned int n) const; unsigned int phaseCount() const; double startTime() const; @@ -38,7 +39,7 @@ public: void markChanged(); private: - std::vector phases; + std::vector phases; }; #endif // _CELENGINE_TIMELINE_H_ diff --git a/src/celengine/timelinephase.cpp b/src/celengine/timelinephase.cpp index f2cd02f8..64d0264d 100644 --- a/src/celengine/timelinephase.cpp +++ b/src/celengine/timelinephase.cpp @@ -22,9 +22,9 @@ TimelinePhase::TimelinePhase(Body* _body, double _startTime, double _endTime, - ReferenceFrame* _orbitFrame, + const ReferenceFrame::SharedConstPtr& _orbitFrame, Orbit* _orbit, - ReferenceFrame* _bodyFrame, + const ReferenceFrame::SharedConstPtr& _bodyFrame, RotationModel* _rotationModel, FrameTree* _owner) : m_body(_body), @@ -34,67 +34,21 @@ TimelinePhase::TimelinePhase(Body* _body, m_orbit(_orbit), m_bodyFrame(_bodyFrame), m_rotationModel(_rotationModel), - m_owner(_owner), - refCount(0) + m_owner(_owner) { // assert(owner == orbitFrame->getCenter()->getFrameTree()); - m_orbitFrame->addRef(); - m_bodyFrame->addRef(); } - -TimelinePhase::~TimelinePhase() -{ - m_orbitFrame->release(); - m_bodyFrame->release(); -} - - -// Declared private--should never be used -TimelinePhase::TimelinePhase(const TimelinePhase&) -{ - assert(0); -} - - -// Declared private--should never be used -TimelinePhase& TimelinePhase::operator=(const TimelinePhase&) -{ - assert(0); - return *this; -} - - -int TimelinePhase::addRef() const -{ - return ++refCount; -} - - -int TimelinePhase::release() const -{ - --refCount; - assert(refCount >= 0); - if (refCount <= 0) - { - delete this; - return 0; - } - - return refCount; -} - - /*! Create a new timeline phase in the specified universe. */ -TimelinePhase* +TimelinePhase::SharedConstPtr TimelinePhase::CreateTimelinePhase(Universe& universe, Body* body, double startTime, double endTime, - ReferenceFrame& orbitFrame, + const ReferenceFrame::SharedConstPtr& orbitFrame, Orbit& orbit, - ReferenceFrame& bodyFrame, + const ReferenceFrame::SharedConstPtr& bodyFrame, RotationModel& rotationModel) { // Validate the time range. @@ -104,7 +58,7 @@ TimelinePhase::CreateTimelinePhase(Universe& universe, // Get the frame tree to add the new phase to. Verify that the reference frame // center is either a star or solar system body. FrameTree* frameTree = nullptr; - Selection center = orbitFrame.getCenter(); + Selection center = orbitFrame->getCenter(); if (center.body() != nullptr) { frameTree = center.body()->getOrCreateFrameTree(); @@ -126,14 +80,14 @@ TimelinePhase::CreateTimelinePhase(Universe& universe, return nullptr; } - TimelinePhase* phase = new TimelinePhase(body, - startTime, - endTime, - &orbitFrame, - &orbit, - &bodyFrame, - &rotationModel, - frameTree); + auto phase = make_shared(body, + startTime, + endTime, + orbitFrame, + &orbit, + bodyFrame, + &rotationModel, + frameTree); frameTree->addChild(phase); diff --git a/src/celengine/timelinephase.h b/src/celengine/timelinephase.h index bc24765f..cacc3745 100644 --- a/src/celengine/timelinephase.h +++ b/src/celengine/timelinephase.h @@ -13,7 +13,8 @@ #ifndef _CELENGINE_TIMELINEPHASE_H_ #define _CELENGINE_TIMELINEPHASE_H_ -class ReferenceFrame; +#include +#include "frame.h" class Orbit; class RotationModel; class FrameTree; @@ -24,9 +25,8 @@ class Body; class TimelinePhase { public: - int addRef() const; - int release() const; - + using SharedPtr = std::shared_ptr; + using SharedConstPtr = std::shared_ptr; Body* body() const { return m_body; @@ -42,7 +42,7 @@ public: return m_endTime; } - ReferenceFrame* orbitFrame() const + const ReferenceFrame::SharedConstPtr& orbitFrame() const { return m_orbitFrame; } @@ -52,7 +52,7 @@ public: return m_orbit; } - ReferenceFrame* bodyFrame() const + const ReferenceFrame::SharedConstPtr& bodyFrame() const { return m_bodyFrame; } @@ -78,33 +78,28 @@ public: return m_startTime <= t && t < m_endTime; } - static TimelinePhase* CreateTimelinePhase(Universe& universe, - Body* body, - double startTime, - double endTime, - ReferenceFrame& orbitFrame, - Orbit& orbit, - ReferenceFrame& bodyFrame, - RotationModel& rotationModel); + static TimelinePhase::SharedConstPtr CreateTimelinePhase(Universe& universe, + Body* body, + double startTime, + double endTime, + const ReferenceFrame::SharedConstPtr& orbitFrame, + Orbit& orbit, + const ReferenceFrame::SharedConstPtr& bodyFrame, + RotationModel& rotationModel); + + ~TimelinePhase() = default; -private: - // Private constructor; phases can only created with the - // createTimelinePhase factory method. TimelinePhase(Body* _body, double _startTime, double _endTime, - ReferenceFrame* _orbitFrame, + const ReferenceFrame::SharedConstPtr& _orbitFrame, Orbit* _orbit, - ReferenceFrame* _bodyFrame, + const ReferenceFrame::SharedConstPtr& _bodyFrame, RotationModel* _rotationModel, FrameTree* _owner); - // Private copy constructor and assignment operator; should never be used. - TimelinePhase(const TimelinePhase& phase); - TimelinePhase& operator=(const TimelinePhase& phase); - - // TimelinePhases are refCounted; use release() instead. - ~TimelinePhase(); + TimelinePhase(const TimelinePhase& phase) = delete; + TimelinePhase& operator=(const TimelinePhase& phase) = delete; private: Body* m_body; @@ -112,14 +107,12 @@ private: double m_startTime; double m_endTime; - ReferenceFrame* m_orbitFrame; + ReferenceFrame::SharedConstPtr m_orbitFrame; Orbit* m_orbit; - ReferenceFrame* m_bodyFrame; + ReferenceFrame::SharedConstPtr m_bodyFrame; RotationModel* m_rotationModel; FrameTree* m_owner; - - mutable int refCount; }; #endif // _CELENGINE_TIMELINEPHASE_H_ diff --git a/src/celengine/universe.cpp b/src/celengine/universe.cpp index a16c4efa..bbfae8fd 100644 --- a/src/celengine/universe.cpp +++ b/src/celengine/universe.cpp @@ -424,7 +424,7 @@ static bool traverseFrameTree(FrameTree* frameTree, { for (unsigned int i = 0; i < frameTree->childCount(); i++) { - TimelinePhase* phase = frameTree->getChild(i); + auto phase = frameTree->getChild(i); if (phase->includes(tdb)) { Body* body = phase->body(); diff --git a/src/celestia/celx.cpp b/src/celestia/celx.cpp index fd0e44f0..c0ac782a 100644 --- a/src/celestia/celx.cpp +++ b/src/celestia/celx.cpp @@ -1851,7 +1851,7 @@ void CelxLua::newFrame(const ObserverFrame& f) frame_new(m_lua, f); } -void CelxLua::newPhase(const TimelinePhase& phase) +void CelxLua::newPhase(const shared_ptr& phase) { phase_new(m_lua, phase); } diff --git a/src/celestia/celx_internal.h b/src/celestia/celx_internal.h index 3b06133e..a644d675 100644 --- a/src/celestia/celx_internal.h +++ b/src/celestia/celx_internal.h @@ -13,16 +13,17 @@ #ifndef _CELX_INTERNAL_H_ #define _CELX_INTERNAL_H_ +#include #include #include #include #include #include #include +#include #include "celx.h" class CelestiaCore; -class TimelinePhase; enum { @@ -260,7 +261,7 @@ public: void newRotation(const Eigen::Quaterniond& q); void newPosition(const UniversalCoord& uc); void newObject(const Selection& sel); - void newPhase(const TimelinePhase& phase); + void newPhase(const TimelinePhase::SharedConstPtr& phase); Eigen::Vector3d* toVector(int n); Eigen::Quaterniond* toRotation(int n); diff --git a/src/celestia/celx_object.cpp b/src/celestia/celx_object.cpp index b04e50b4..e7071434 100644 --- a/src/celestia/celx_object.cpp +++ b/src/celestia/celx_object.cpp @@ -1121,7 +1121,7 @@ static int object_orbitframe(lua_State* l) } else { - const ReferenceFrame* f = sel->body()->getOrbitFrame(t); + auto f = sel->body()->getOrbitFrame(t); celx.newFrame(ObserverFrame(*f)); } @@ -1162,7 +1162,7 @@ static int object_bodyframe(lua_State* l) } else { - const ReferenceFrame* f = sel->body()->getBodyFrame(t); + auto f = sel->body()->getBodyFrame(t); celx.newFrame(ObserverFrame(*f)); } @@ -1206,7 +1206,7 @@ static int object_getphase(lua_State* l) const Timeline* timeline = sel->body()->getTimeline(); if (timeline->includes(t)) { - celx.newPhase(*timeline->findPhase(t)); + celx.newPhase(timeline->findPhase(t)); } else { @@ -1245,8 +1245,8 @@ static int object_phases_iter(lua_State* l) lua_pushnumber(l, i + 1); lua_replace(l, lua_upvalueindex(2)); - const TimelinePhase* phase = timeline->getPhase(i); - celx.newPhase(*phase); + auto phase = timeline->getPhase(i); + celx.newPhase(phase); return 1; } diff --git a/src/celestia/celx_observer.cpp b/src/celestia/celx_observer.cpp index d5dfc193..ad00e070 100644 --- a/src/celestia/celx_observer.cpp +++ b/src/celestia/celx_observer.cpp @@ -9,6 +9,7 @@ // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. +#include #include "celx.h" #include "celx_internal.h" #include "celx_observer.h" @@ -17,6 +18,7 @@ #include "celestiacore.h" #include +using namespace std; using namespace Eigen; using namespace celmath; @@ -301,7 +303,7 @@ static int observer_gototable(lua_State* l) jparams.endInterpolation = min(1.0, max(0.0, jparams.endInterpolation)); // args are in universal coords, let setFrame handle conversion: - ObserverFrame tmp = *(o->getFrame()); + auto tmp = o->getFrame(); o->setFrame(ObserverFrame::Universal, Selection()); o->gotoJourney(jparams); o->setFrame(tmp); @@ -698,7 +700,7 @@ static int observer_getframe(lua_State* l) Observer* obs = this_observer(l); - const ObserverFrame* frame = obs->getFrame(); + auto frame = obs->getFrame(); celx.newFrame(*frame); return 1; } @@ -714,7 +716,7 @@ static int observer_setframe(lua_State* l) frame = celx.toFrame(2); if (frame != nullptr) { - obs->setFrame(*frame); + obs->setFrame(make_shared(*frame)); } else { diff --git a/src/celestia/celx_phase.cpp b/src/celestia/celx_phase.cpp index 3d09698f..1f431c23 100644 --- a/src/celestia/celx_phase.cpp +++ b/src/celestia/celx_phase.cpp @@ -9,6 +9,7 @@ // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. +#include #include "celx.h" #include "celx_internal.h" #include "celx_phase.h" @@ -16,38 +17,15 @@ #include #include +using namespace std; -// We want to avoid copying TimelinePhase objects, so we can't make them -// userdata. But, they can't be lightuserdata either because they need to -// be reference counted, and Lua doesn't garbage collect lightuserdata. The -// solution is the PhaseReference object, which just wraps a TimelinePhase -// pointer. -class PhaseReference -{ -public: - PhaseReference(const TimelinePhase& _phase) : - phase(&_phase) -{ - phase->addRef(); -} - -~PhaseReference() -{ - phase->release(); -} - -const TimelinePhase* phase; -}; - - - -int phase_new(lua_State* l, const TimelinePhase& phase) +int phase_new(lua_State* l, const TimelinePhase::SharedConstPtr& phase) { CelxLua celx(l); // Use placement new to put the new phase reference in the userdata block. - void* block = lua_newuserdata(l, sizeof(PhaseReference)); - new (block) PhaseReference(phase); + void* block = lua_newuserdata(l, sizeof(TimelinePhase::SharedConstPtr)); + new (block) TimelinePhase::SharedConstPtr(phase); celx.setClass(Celx_Phase); @@ -55,29 +33,28 @@ int phase_new(lua_State* l, const TimelinePhase& phase) } -static const TimelinePhase* to_phase(lua_State* l, int index) +static TimelinePhase::SharedConstPtr* to_phase(lua_State* l, int index) { CelxLua celx(l); - PhaseReference* ref = static_cast(celx.checkUserData(index, Celx_Phase)); - return ref == nullptr ? nullptr : ref->phase; + return celx.safeGetClass(index); } -static const TimelinePhase* this_phase(lua_State* l) +static const TimelinePhase::SharedConstPtr& this_phase(lua_State* l) { CelxLua celx(l); - const TimelinePhase* phase = to_phase(l, 1); + auto phase = to_phase(l, 1); + assert(phase != nullptr); if (phase == nullptr) { celx.doError("Bad phase object!"); } - return phase; + return *phase; } - /*! phase:timespan() * * Return the start and end times for this timeline phase. @@ -98,7 +75,7 @@ static int phase_timespan(lua_State* l) celx.checkArgs(1, 1, "No arguments allowed for to phase:timespan"); - const TimelinePhase* phase = this_phase(l); + auto phase = this_phase(l); celx.push(phase->startTime(), phase->endTime()); //lua_pushnumber(l, phase->startTime()); //lua_pushnumber(l, phase->endTime()); @@ -117,8 +94,8 @@ static int phase_orbitframe(lua_State* l) celx.checkArgs(1, 1, "No arguments allowed for to phase:orbitframe"); - const TimelinePhase* phase = this_phase(l); - const ReferenceFrame* f = phase->orbitFrame(); + auto phase = this_phase(l); + auto f = phase->orbitFrame(); celx.newFrame(ObserverFrame(*f)); return 1; @@ -135,8 +112,8 @@ static int phase_bodyframe(lua_State* l) celx.checkArgs(1, 1, "No arguments allowed for to phase:bodyframe"); - const TimelinePhase* phase = this_phase(l); - const ReferenceFrame* f = phase->bodyFrame(); + auto phase = this_phase(l); + auto f = phase->bodyFrame(); celx.newFrame(ObserverFrame(*f)); return 1; @@ -155,7 +132,7 @@ static int phase_getposition(lua_State* l) celx.checkArgs(2, 2, "One argument required for phase:getposition"); - const TimelinePhase* phase = this_phase(l); + auto phase = this_phase(l); double tdb = celx.safeGetNumber(2, WrongType, "Argument to phase:getposition() must be number", 0.0); if (tdb < phase->startTime()) @@ -180,7 +157,7 @@ static int phase_getorientation(lua_State* l) celx.checkArgs(2, 2, "One argument required for phase:getorientation"); - const TimelinePhase* phase = this_phase(l); + auto phase = this_phase(l); double tdb = celx.safeGetNumber(2, WrongType, "Argument to phase:getorientation() must be number", 0.0); if (tdb < phase->startTime()) @@ -211,15 +188,14 @@ static int phase_gc(lua_State* l) { CelxLua celx(l); - PhaseReference* ref = static_cast(celx.checkUserData(1, Celx_Phase)); - if (ref == nullptr) + auto ref = this_phase(l); + if (ref) { - celx.doError("Bad phase object during garbage collection!"); + ref.reset(); } else { - // Explicitly call the destructor since the object was created with placement new - ref->~PhaseReference(); + celx.doError("Bad phase object during garbage collection!"); } return 0; diff --git a/src/celestia/celx_phase.h b/src/celestia/celx_phase.h index 21a1682e..2fba00ca 100644 --- a/src/celestia/celx_phase.h +++ b/src/celestia/celx_phase.h @@ -12,10 +12,17 @@ #ifndef _CELX_PHASE_H_ #define _CELX_PHASE_H_ +#include + struct lua_State; class TimelinePhase; +inline int celxClassId(const TimelinePhase::SharedConstPtr&) +{ + return Celx_Phase; +} + extern void CreatePhaseMetaTable(lua_State* l); -extern int phase_new(lua_State* l, const TimelinePhase& phase); +extern int phase_new(lua_State* l, const TimelinePhase::SharedConstPtr& phase); #endif // _CELX_PHASE_H_ diff --git a/src/celestia/url.cpp b/src/celestia/url.cpp index 5a6f35fb..712e731b 100644 --- a/src/celestia/url.cpp +++ b/src/celestia/url.cpp @@ -47,7 +47,7 @@ CelestiaState::captureState(CelestiaCore* appCore) Simulation *sim = appCore->getSimulation(); Renderer *renderer = appCore->getRenderer(); - const ObserverFrame* frame = sim->getFrame(); + auto frame = sim->getFrame(); coordSys = frame->getCoordinateSystem(); if (coordSys != ObserverFrame::Universal)