fprime/Fw/Time/Time.cpp
M Starch 2dcd21902d
Testing with configured fixed-size types (#3409)
* Testing with configured fixed-size types

* Linux fixes

* Final settings

* Removing FwNativeIntType
2025-03-28 11:11:13 -07:00

268 lines
7.4 KiB
C++

#include <Fw/Time/Time.hpp>
#include <FpConfig.hpp>
namespace Fw {
const Time ZERO_TIME = Time();
Time::Time() : m_seconds(0), m_useconds(0), m_timeBase(TB_NONE), m_timeContext(0) {
}
Time::~Time() {
}
Time::Time(const Time& other) : Serializable() {
this->set(other.m_timeBase,other.m_timeContext,other.m_seconds,other.m_useconds);
}
Time::Time(U32 seconds, U32 useconds) {
this->set(TB_NONE,0,seconds,useconds);
}
Time::Time(TimeBase timeBase, U32 seconds, U32 useconds) {
this->set(timeBase,0,seconds,useconds);
}
void Time::set(U32 seconds, U32 useconds) {
this->set(this->m_timeBase,this->m_timeContext,seconds,useconds);
}
void Time::set(TimeBase timeBase, U32 seconds, U32 useconds) {
this->set(timeBase,this->m_timeContext,seconds,useconds);
}
Time::Time(TimeBase timeBase, FwTimeContextStoreType context, U32 seconds, U32 useconds) {
this->set(timeBase,context,seconds,useconds);
}
void Time::set(TimeBase timeBase, FwTimeContextStoreType context, U32 seconds, U32 useconds) {
this->m_timeBase = timeBase;
this->m_timeContext = context;
this->m_useconds = useconds;
this->m_seconds = seconds;
}
Time& Time::operator=(const Time& other) {
this->m_timeBase = other.m_timeBase;
this->m_timeContext = other.m_timeContext;
this->m_useconds = other.m_useconds;
this->m_seconds = other.m_seconds;
return *this;
}
bool Time::operator==(const Time& other) const {
return (Time::compare(*this,other) == EQ);
}
bool Time::operator!=(const Time& other) const {
return (Time::compare(*this,other) != EQ);
}
bool Time::operator>(const Time& other) const {
return (Time::compare(*this,other) == GT);
}
bool Time::operator<(const Time& other) const {
return (Time::compare(*this,other) == LT);
}
bool Time::operator>=(const Time& other) const {
Time::Comparison c = Time::compare(*this,other);
return ((GT == c) or (EQ == c));
}
bool Time::operator<=(const Time& other) const {
Time::Comparison c = Time::compare(*this,other);
return ((LT == c) or (EQ == c));
}
SerializeStatus Time::serialize(SerializeBufferBase& buffer) const {
// serialize members
SerializeStatus stat = Fw::FW_SERIALIZE_OK;
#if FW_USE_TIME_BASE
stat = buffer.serialize(static_cast<FwTimeBaseStoreType>(this->m_timeBase));
if (stat != FW_SERIALIZE_OK) {
return stat;
}
#endif
#if FW_USE_TIME_CONTEXT
stat = buffer.serialize(this->m_timeContext);
if (stat != FW_SERIALIZE_OK) {
return stat;
}
#endif
stat = buffer.serialize(this->m_seconds);
if (stat != FW_SERIALIZE_OK) {
return stat;
}
return buffer.serialize(this->m_useconds);
}
SerializeStatus Time::deserialize(SerializeBufferBase& buffer) {
SerializeStatus stat = Fw::FW_SERIALIZE_OK;
#if FW_USE_TIME_BASE
FwTimeBaseStoreType deSer;
stat = buffer.deserialize(deSer);
if (stat != FW_SERIALIZE_OK) {
return stat;
}
this->m_timeBase = static_cast<TimeBase>(deSer);
#else
this->m_timeBase = TB_NONE;
#endif
#if FW_USE_TIME_CONTEXT
stat = buffer.deserialize(this->m_timeContext);
if (stat != FW_SERIALIZE_OK) {
return stat;
}
#else
this->m_timeContext = 0;
#endif
stat = buffer.deserialize(this->m_seconds);
if (stat != FW_SERIALIZE_OK) {
return stat;
}
return buffer.deserialize(this->m_useconds);
}
U32 Time::getSeconds() const {
return this->m_seconds;
}
U32 Time::getUSeconds() const {
return this->m_useconds;
}
TimeBase Time::getTimeBase() const {
return this->m_timeBase;
}
FwTimeContextStoreType Time::getContext() const {
return this->m_timeContext;
}
Time Time ::
zero(TimeBase timeBase)
{
Time time(timeBase,0, 0, 0);
return time;
}
Time::Comparison Time ::
compare(
const Time &time1,
const Time &time2
)
{
#if FW_USE_TIME_BASE
if (time1.getTimeBase() != time2.getTimeBase()) {
return INCOMPARABLE;
}
#endif
#if FW_USE_TIME_CONTEXT
if (time1.getContext() != time2.getContext()) {
return INCOMPARABLE;
}
#endif
const U32 s1 = time1.getSeconds();
const U32 s2 = time2.getSeconds();
const U32 us1 = time1.getUSeconds();
const U32 us2 = time2.getUSeconds();
if (s1 < s2) {
return LT;
} else if (s1 > s2) {
return GT;
} else if (us1 < us2) {
return LT;
} else if (us1 > us2) {
return GT;
} else {
return EQ;
}
}
Time Time ::
add(
const Time& a,
const Time& b
)
{
#if FW_USE_TIME_BASE
FW_ASSERT(a.getTimeBase() == b.getTimeBase(), static_cast<FwAssertArgType>(a.getTimeBase()), static_cast<FwAssertArgType>(b.getTimeBase()) );
#endif
#if FW_USE_TIME_CONTEXT
FW_ASSERT(a.getContext() == b.getContext(), static_cast<FwAssertArgType>(a.getContext()), static_cast<FwAssertArgType>(b.getContext()) );
#endif
U32 seconds = a.getSeconds() + b.getSeconds();
U32 uSeconds = a.getUSeconds() + b.getUSeconds();
FW_ASSERT(uSeconds < 1999999);
if (uSeconds >= 1000000) {
++seconds;
uSeconds -= 1000000;
}
Time c(a.getTimeBase(),a.getContext(),seconds,uSeconds);
return c;
}
Time Time ::
sub(
const Time& minuend, //!< Time minuend
const Time& subtrahend //!< Time subtrahend
)
{
#if FW_USE_TIME_BASE
FW_ASSERT(minuend.getTimeBase() == subtrahend.getTimeBase(), static_cast<FwAssertArgType>(minuend.getTimeBase()), static_cast<FwAssertArgType>(subtrahend.getTimeBase()));
#endif
#if FW_USE_TIME_CONTEXT
FW_ASSERT(minuend.getContext() == subtrahend.getContext(), static_cast<FwAssertArgType>(minuend.getContext()), static_cast<FwAssertArgType>(subtrahend.getContext()));
#endif
// Assert minuend is greater than subtrahend
FW_ASSERT(minuend >= subtrahend);
U32 seconds = minuend.getSeconds() - subtrahend.getSeconds();
U32 uSeconds;
if (subtrahend.getUSeconds() > minuend.getUSeconds()) {
seconds--;
uSeconds = minuend.getUSeconds() + 1000000 - subtrahend.getUSeconds();
} else {
uSeconds = minuend.getUSeconds() - subtrahend.getUSeconds();
}
return Time(minuend.getTimeBase(), minuend.getContext(), seconds, static_cast<U32>(uSeconds));
}
void Time::add(U32 seconds, U32 useconds) {
this->m_seconds += seconds;
this->m_useconds += useconds;
FW_ASSERT(this->m_useconds < 1999999, static_cast<FwAssertArgType>(this->m_useconds));
if (this->m_useconds >= 1000000) {
++this->m_seconds;
this->m_useconds -= 1000000;
}
}
void Time::setTimeBase(TimeBase timeBase) {
this->m_timeBase = timeBase;
}
void Time::setTimeContext(FwTimeContextStoreType context) {
this->m_timeContext = context;
}
#ifdef BUILD_UT
std::ostream& operator<<(std::ostream& os, const Time& val) {
os << "(" << val.getTimeBase() << "," << val.getUSeconds() << "," << val.getSeconds() << ")";
return os;
}
#endif
}