Replace refcounted objects with std::shared_ptr

pull/3/head
pirogronian 2019-08-05 19:31:02 +02:00 committed by Hleb Valoshka
parent 2090a883d4
commit c3567d820c
27 changed files with 302 additions and 449 deletions

View File

@ -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);
}

View File

@ -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<double, 3, Affine>(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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -11,6 +11,7 @@
#ifndef _CELENGINE_FRAME_H_
#define _CELENGINE_FRAME_H_
#include <memory>
#include <celengine/astro.h>
#include <celengine/selection.h>
#include <Eigen/Core>
@ -26,12 +27,11 @@
class ReferenceFrame
{
public:
using SharedPtr = std::shared_ptr<ReferenceFrame>;
using SharedConstPtr = std::shared_ptr<const ReferenceFrame>;
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<BodyFixedFrame>;
using SharedConstPtr = std::shared_ptr<const BodyFixedFrame>;
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<BodyMeanEquatorFrame>;
using SharedConstPtr = std::shared_ptr<const BodyMeanEquatorFrame>;
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
};

View File

@ -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<J2000EclipticFrame>(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<BodyMeanEquatorFrame>(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<TimelinePhase*>::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];

View File

@ -13,14 +13,14 @@
#ifndef _CELENGINE_FRAMETREE_H_
#define _CELENGINE_FRAMETREE_H_
#include <memory>
#include <vector>
#include <cstddef>
#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<TimelinePhase*> children;
std::vector<TimelinePhase::SharedConstPtr> 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_

View File

@ -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<ObserverFrame>())
{
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<ObserverFrame>(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<J2000EclipticFrame>(Selection());
case Ecliptical:
return new J2000EclipticFrame(_refObject);
return make_shared<J2000EclipticFrame>(_refObject);
case Equatorial:
return new BodyMeanEquatorFrame(_refObject, _refObject);
return make_shared<BodyMeanEquatorFrame>(_refObject, _refObject);
case BodyFixed:
return new BodyFixedFrame(_refObject, _refObject);
return make_shared<BodyFixedFrame>(_refObject, _refObject);
case PhaseLock:
{
return new TwoVectorFrame(_refObject,
return make_shared<TwoVectorFrame>(_refObject,
FrameVector::createRelativePositionVector(_refObject, _targetObject), 1,
FrameVector::createRelativeVelocityVector(_refObject, _targetObject), 2);
}
case Chase:
{
return new TwoVectorFrame(_refObject,
return make_shared<TwoVectorFrame>(_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<BodyMeanEquatorFrame>(_refObject, _refObject)));
return make_shared<TwoVectorFrame>(_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<BodyMeanEquatorFrame>(_refObject, _refObject)));
return new TwoVectorFrame(_refObject,
return make_shared<TwoVectorFrame>(_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<J2000EclipticFrame>(Selection());
default:
return new J2000EclipticFrame(_refObject);
return make_shared<J2000EclipticFrame>(_refObject);
}
}

View File

@ -18,6 +18,7 @@
#ifndef _CELENGINE_OBSERVER_H_
#define _CELENGINE_OBSERVER_H_
#include <memory>
#include <celmath/mathlib.h>
#include <celengine/frame.h>
#include <Eigen/Core>
@ -27,6 +28,8 @@
class ObserverFrame
{
public:
using SharedPtr = std::shared_ptr<ObserverFrame>;
using SharedConstPtr = std::shared_ptr<const ObserverFrame>;
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 &centerObj);
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 };

View File

@ -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<BodyFixedFrame>(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<BodyMeanEquatorFrame>(center, obj, freezeEpoch);
}
else
{
return new BodyMeanEquatorFrame(center, obj);
return make_shared<BodyMeanEquatorFrame>(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<const TwoVectorFrame>
CreateTwoVectorFrame(const Universe& universe,
Hash* frameData,
const Selection& defaultCenter)
@ -1623,22 +1623,19 @@ CreateTwoVectorFrame(const Universe& universe,
center,
secondaryData);
TwoVectorFrame* frame = nullptr;
shared_ptr<const TwoVectorFrame> frame;
if (primaryVector != nullptr && secondaryVector != nullptr)
{
frame = new TwoVectorFrame(center,
frame = make_shared<TwoVectorFrame>(center,
*primaryVector, primaryAxis,
*secondaryVector, secondaryAxis);
}
delete primaryVector;
delete secondaryVector;
return frame;
}
static J2000EclipticFrame*
static shared_ptr<const J2000EclipticFrame>
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<J2000EclipticFrame>(center);
}
static J2000EquatorFrame*
static shared_ptr<const J2000EquatorFrame>
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<J2000EquatorFrame>(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<const TwoVectorFrame>
CreateTopocentricFrame(const Selection& center,
const Selection& target,
const Selection& observer)
{
BodyMeanEquatorFrame* eqFrame = new BodyMeanEquatorFrame(target, target);
shared_ptr<const BodyMeanEquatorFrame> eqFrame = make_shared<BodyMeanEquatorFrame>(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<TwoVectorFrame>(center, up, -2, north, -3);
}
@ -1723,7 +1720,7 @@ CreateTopocentricFrame(const Selection& center,
* ...
* } </pre>
*/
static TwoVectorFrame*
static shared_ptr<const TwoVectorFrame>
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)

View File

@ -14,14 +14,14 @@
#define _CELENGINE_PARSEOBJECT_H_
#include <string>
#include <memory>
#include <celephem/orbit.h>
#include <celephem/rotation.h>
#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<const TwoVectorFrame> CreateTopocentricFrame(const Selection& center,
const Selection& target,
const Selection& observer);

View File

@ -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)

View File

@ -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();
}

View File

@ -10,6 +10,7 @@
#ifndef _CELENGINE_SIMULATION_H_
#define _CELENGINE_SIMULATION_H_
#include <memory>
#include <celengine/texture.h>
#include <celengine/universe.h>
#include <celengine/astro.h>
@ -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);

View File

@ -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<double>::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<double>::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<BodyFixedFrame>(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<double>::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.

View File

@ -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);

View File

@ -13,12 +13,13 @@
#ifndef _CELENGINE_TIMELINE_H_
#define _CELENGINE_TIMELINE_H_
#include <memory>
#include <vector>
#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<TimelinePhase*> phases;
std::vector<TimelinePhase::SharedConstPtr> phases;
};
#endif // _CELENGINE_TIMELINE_H_

View File

@ -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<const TimelinePhase>(body,
startTime,
endTime,
orbitFrame,
&orbit,
bodyFrame,
&rotationModel,
frameTree);
frameTree->addChild(phase);

View File

@ -13,7 +13,8 @@
#ifndef _CELENGINE_TIMELINEPHASE_H_
#define _CELENGINE_TIMELINEPHASE_H_
class ReferenceFrame;
#include <memory>
#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<TimelinePhase>;
using SharedConstPtr = std::shared_ptr<const TimelinePhase>;
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_

View File

@ -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();

View File

@ -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<const TimelinePhase>& phase)
{
phase_new(m_lua, phase);
}

View File

@ -13,16 +13,17 @@
#ifndef _CELX_INTERNAL_H_
#define _CELX_INTERNAL_H_
#include <memory>
#include <map>
#include <string>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <celutil/color.h>
#include <celengine/parser.h>
#include <celengine/timelinephase.h>
#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);

View File

@ -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;
}

View File

@ -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 <memory>
#include "celx.h"
#include "celx_internal.h"
#include "celx_observer.h"
@ -17,6 +18,7 @@
#include "celestiacore.h"
#include <Eigen/Geometry>
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<ObserverFrame>(*frame));
}
else
{

View File

@ -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 <assert.h>
#include "celx.h"
#include "celx_internal.h"
#include "celx_phase.h"
@ -16,38 +17,15 @@
#include <celephem/orbit.h>
#include <celephem/rotation.h>
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<PhaseReference*>(celx.checkUserData(index, Celx_Phase));
return ref == nullptr ? nullptr : ref->phase;
return celx.safeGetClass<TimelinePhase::SharedConstPtr>(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<PhaseReference*>(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;

View File

@ -12,10 +12,17 @@
#ifndef _CELX_PHASE_H_
#define _CELX_PHASE_H_
#include <memory>
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_

View File

@ -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)