Skip to content

Commit

Permalink
Utilize ImplPtr for Timer (#299)
Browse files Browse the repository at this point in the history
* Use ImplPtr in Timer
* Add unittests for Timer

Signed-off-by: Michael Carroll <michael@openrobotics.org>
  • Loading branch information
mjcarroll authored Feb 8, 2022
1 parent fdcb378 commit e79b31f
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 27 deletions.
17 changes: 3 additions & 14 deletions include/ignition/common/Timer.hh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#define IGNITION_COMMON_TIMER_HH_

#include <ignition/common/Export.hh>
#include <ignition/utils/SuppressWarning.hh>
#include <ignition/utils/ImplPtr.hh>

#include <chrono>
#include <iostream>
Expand All @@ -34,9 +34,6 @@ namespace ignition
/// \brief Constructor
public: Timer();

/// \brief Destructor
public: virtual ~Timer();

/// \brief Start the timer
public: virtual void Start();

Expand All @@ -59,16 +56,8 @@ namespace ignition
return out;
}

IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING
/// \brief The time of the last call to Start
private: std::chrono::steady_clock::time_point start;

/// \brief The time when Stop was called.
private: std::chrono::steady_clock::time_point stop;
IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING

/// \brief True if the timer is running.
private: bool running;
/// \brief Private data pointer
IGN_UTILS_IMPL_PTR(dataPtr)
};
}
}
Expand Down
35 changes: 22 additions & 13 deletions src/Timer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,50 +20,59 @@
using namespace ignition;
using namespace common;

//////////////////////////////////////////////////
Timer::Timer()
: running(false)
/// \brief Private data for the Timer class
class ignition::common::Timer::Implementation
{
}
/// \brief The time of the last call to Start
public: std::chrono::steady_clock::time_point start;

/// \brief The time when Stop was called.
public: std::chrono::steady_clock::time_point stop;

/// \brief True if the timer is running.
public: bool running {false};
};

//////////////////////////////////////////////////
Timer::~Timer()
Timer::Timer()
: dataPtr(ignition::utils::MakeImpl<Implementation>())
{
}

//////////////////////////////////////////////////
void Timer::Start()
{
this->start = std::chrono::steady_clock::now();
this->running = true;
this->dataPtr->start = std::chrono::steady_clock::now();
this->dataPtr->running = true;
}

//////////////////////////////////////////////////
void Timer::Stop()
{
this->stop = std::chrono::steady_clock::now();
this->running = false;
this->dataPtr->stop = std::chrono::steady_clock::now();
this->dataPtr->running = false;
}

//////////////////////////////////////////////////
bool Timer::Running() const
{
return this->running;
return this->dataPtr->running;
}

//////////////////////////////////////////////////
std::chrono::duration<double> Timer::ElapsedTime() const
{
if (this->running)
if (this->dataPtr->running)
{
std::chrono::steady_clock::time_point currentTime;
currentTime = std::chrono::steady_clock::now();
std::chrono::duration<double> diff = currentTime - this->start;
std::chrono::duration<double> diff = currentTime - this->dataPtr->start;
return diff;
}
else
{
std::chrono::duration<double> diff = this->stop - this->start;
std::chrono::duration<double> diff =
this->dataPtr->stop - this->dataPtr->start;
return diff;
}
}
85 changes: 85 additions & 0 deletions src/Timer_TEST.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright (C) 2022 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#include <gtest/gtest.h>

#include <thread>

#include <ignition/common/Console.hh>
#include <ignition/common/Timer.hh>

/////////////////////////////////////////////////
TEST(Timer_TEST, Sequence)
{
ignition::common::Timer t;
EXPECT_FALSE(t.Running());
EXPECT_DOUBLE_EQ(0.0, t.ElapsedTime().count());

// Call stop on a timer that hasn't been started
t.Stop();
EXPECT_FALSE(t.Running());

// Start the timer
t.Start();
EXPECT_TRUE(t.Running());
EXPECT_LT(0.0, t.ElapsedTime().count());

t.Stop();
EXPECT_FALSE(t.Running());
EXPECT_LT(0.0, t.ElapsedTime().count());
}

/////////////////////////////////////////////////
TEST(Timer_TEST, Elapsed)
{
ignition::common::Timer t;
t.Start();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
t.Stop();

// Loose margin just to make sure it is close without being flaky
EXPECT_LT(0.0, t.ElapsedTime().count());
igndbg << "Actual Elapsed: " << t.ElapsedTime().count() << std::endl;
}

/////////////////////////////////////////////////
TEST(Timer_TEST, Copy)
{
ignition::common::Timer t1;
t1.Start();
EXPECT_TRUE(t1.Running());

ignition::common::Timer t2 = t1;
EXPECT_TRUE(t2.Running());

// Stop the original
t1.Stop();
EXPECT_FALSE(t1.Running());
EXPECT_TRUE(t2.Running());

// Stop the copy
t2.Stop();
EXPECT_FALSE(t1.Running());
EXPECT_FALSE(t2.Running());
}

/////////////////////////////////////////////////
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

0 comments on commit e79b31f

Please sign in to comment.