diff --git a/Modules/IGT/IGTFilters/mitkTimeStamp.cpp b/Modules/IGT/IGTFilters/mitkTimeStamp.cpp index a6619b558d..f47ff0000d 100644 --- a/Modules/IGT/IGTFilters/mitkTimeStamp.cpp +++ b/Modules/IGT/IGTFilters/mitkTimeStamp.cpp @@ -1,245 +1,158 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkTimeStamp.h" #include #include "mitkRealTimeClock.h" mitk::TimeStamp::Pointer mitk::TimeStamp::s_Instance = NULL; mitk::TimeStamp::TimeStamp() : itk::Object() , m_Time(-1.0), m_ReferenceTime(0.0) { } mitk::TimeStamp::~TimeStamp() { } - -/** -* \brief creates a new instance of mitkTimeStamp -* -* if no instance if mitkTimeStamp exisits, a new one is created and returned, else -* simply the existing one is returned -* If a new instance could not be created, 1 is thrown and NULL is returned. -*/ mitk::TimeStamp* mitk::TimeStamp::CreateInstance() { - if ( s_Instance.IsNotNull() ) - { - return s_Instance; - } - else - { - try - { - mitk::TimeStamp::Pointer ts = new mitk::TimeStamp; - s_Instance = ts; - } - catch(...) - { - s_Instance = NULL; - throw 1; - } - return s_Instance; - } - +return mitk::TimeStamp::GetInstance(); } -/** -* \brief returns a pointer to the current instance of mitkTimeStamp -* -* This method returns a pointer to the currently existing TimeStamp. -* If there is no exisiting instance, a new one is created and returned automatically -*/ mitk::TimeStamp* mitk::TimeStamp::GetInstance() { if (TimeStamp::s_Instance.IsNull()) { mitk::TimeStamp::Pointer ts = new mitk::TimeStamp; s_Instance = ts; return s_Instance; } else return s_Instance; } -/** -* \brief this method starts the time-acquiring -* -* This method first checks if a RealTimeClock has been set. If not, initialize() is called -* After this, a map is searched if any device has already "started tracking". Starting twice does not -* make sense and is not allowed. -* An internal variable saves the current time as a reference-time. All returned times are relative to this -* starting-time. -* Then the calling device is added to the map of itk::Objects. -*/ void mitk::TimeStamp::Start(itk::Object::Pointer device) { if (m_RealTimeClock.IsNull()) { Initialize(); } if ( s_Instance.IsNotNull() ) { if (m_DeviceMap.empty()) { m_ReferenceTime = GetCurrentStamp(); m_Time = 0.0; } m_DeviceMap.insert( std::pair(device, this->GetElapsed()) ); } else { itkGenericOutputMacro("Trying to use mitk::TimeStamp::Start() " << "without an available singleton instance. Either no instance has " << "been created (use TimeStamp::CreateInstance) or it has already " << "been destroyed."); } } -/** -* \brief this method ends the time-acquisition for a device -* -* When this method is called, the device that called will be erased from the map -* of devices. When the map is empty, the reference-time and the current timestamp -* are reset to 0. -*/ void mitk::TimeStamp::Stop(itk::Object::Pointer device) { if ( s_Instance.IsNotNull() ) { m_MapIterator = m_DeviceMap.find(device); if ( m_MapIterator != m_DeviceMap.end() ) { m_DeviceMap.erase( m_MapIterator ); } if (m_DeviceMap.empty()) { m_ReferenceTime = NULL; m_Time = -1; } } else { itkGenericOutputMacro("Trying to use mitk::TimeStamp::Stop() " << "without an available singleton instance. Either no instance has " << "been created (use TimeStamp::CreateInstance) or it has already " << "been destroyed."); } } double mitk::TimeStamp::GetElapsed() { if (m_Time > -1) { m_Time = GetCurrentStamp(); m_Time = m_Time - m_ReferenceTime; } return (double) m_Time; } double mitk::TimeStamp::GetElapsed(itk::Object::Pointer device) { double offset = this->GetOffset( device ); if ( offset > -1 ) { double time = this->GetElapsed(); return (double) time - this->GetOffset(device); } else { return (double) -1; } } - -/** -* \brief returns the current time acquired from the defined RealTimeClock -* -* only used internally -*/ double mitk::TimeStamp::GetCurrentStamp() { if (m_RealTimeClock.IsNotNull()) { return m_RealTimeClock->GetCurrentStamp(); } else return 0.0; } -/** -* \brief setter for the internally used RealTimeClock -* -* If you want to use a "third-party" RealTimeClock, e.g PocoRealTimeClock, BoostRealTimeClock -* or ITKRealTimeClock, you can set it using this method: -* mitk::RealTimeClock::Pointer RealTimeClock = mitk::RealTimeClock::New(); -* mitk::TimeStamp::GetInstance()->SetRealTimeClock(RealTimeClock); -* -* Notice: The mitk-implementation of an os-dependant RealTimeClock is used -* by default. -*/ void mitk::TimeStamp::SetRealTimeClock(mitk::RealTimeClock::Pointer Clock) { m_RealTimeClock = Clock; } -/** -* -* -* This method returns the time acquired when Start was called. -* This is the offset, that each device will have in relation to the device that -* started the time acqusition, that means, called Start first. -* Thus absolute time-values can be calculated for each device by subtracting the offset -* of all timeStamps. -* -* If this device has not been or is no longer saved in the map of devices, -* -1 will be returned. -* -*/ double mitk::TimeStamp::GetOffset(itk::Object::Pointer Device) { m_MapIterator = m_DeviceMap.find(Device); if ( m_MapIterator != m_DeviceMap.end() ) { return m_MapIterator->second; } else { return -1.0; } } -/** -* \brief creates a new RealTimeClock -* -* Instanciates a new RealTimeClock, that will be specific for the Operating System. -* This will only be called internally when no other RealTimeClock has been set -* by the user. -* -*/ void mitk::TimeStamp::Initialize() { if ( m_RealTimeClock.IsNull() ) m_RealTimeClock = mitk::RealTimeClock::New(); } diff --git a/Modules/IGT/IGTFilters/mitkTimeStamp.h b/Modules/IGT/IGTFilters/mitkTimeStamp.h index 1f2d34971f..b5fb0ab061 100644 --- a/Modules/IGT/IGTFilters/mitkTimeStamp.h +++ b/Modules/IGT/IGTFilters/mitkTimeStamp.h @@ -1,186 +1,191 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKTIMESTAMP_H_HEADER_INCLUDED_ #define MITKTIMESTAMP_H_HEADER_INCLUDED_ #include #include #include #include "mitkRealTimeClock.h" namespace mitk { /** * \brief Time stamp in milliseconds * * This class provides a timestamp in milliseconds. * It is a Singleton class, that internally uses a mitkRealTimeClock() for * time-acquisition. * * First you have to call Start() in order to set the reference-time to the current time. * If the user has not created and set his own "RealTimeClock", initialize() will be called and a * default mitkRealTimeClock() is created. * In addition the TimeStamp() saves a pointer to the device calling and the respective offset-time. * The first device will have an offset of 0, the following's offset will be the time elapsed since the * starting of the first device. This offset can be prompted by calling GetOffset(); * * You can always get the time elapsed since calling Start() with GetElapsed(). It returns the * time spent in milliseconds as a double. * * When the TimeStamp is no longer used, you can call Stop(). This erases the pointer to the device * and the offset. When all devices have "stopped tracking" the reference-time and the current-time are reset to 0. * * \ingroup IGT */ class MitkIGT_EXPORT TimeStamp : public itk::Object { public: mitkClassMacro(TimeStamp, itk::Object); - /** - * \brief creates and returns a new instance of mitkTimeStamp if necessary + /** + * \brief creates a new instance of mitkTimeStamp + * + * This method returns a pointer to the currently existing TimeStamp. + * If there is no exisiting instance, a new one is created and returned automatically + * + * DECREPATED: Use GetInstance instead */ static TimeStamp* CreateInstance(); - /** - * \brief returns the current instance of mitkTimeStamp if one exists. + /** + * \brief returns a pointer to the current instance of mitkTimeStamp * - * If no instance exists, a new one is created. + * This method returns a pointer to the currently existing TimeStamp. + * If there is no exisiting instance, a new one is created and returned automatically */ static TimeStamp* GetInstance(); /** * \brief starts the time-acquisition * * Each device is to call this method when it starts tracking. * The current time is saved as a reference-value (m_Time = 0). * Internally the device (pointer) and its offset are saved in a map, so that * no device can call this method twice. * If the user has not set its own RealTimeClock, a default one is created dependant on the OS * in use. * */ void Start( itk::Object::Pointer device ); /** * \brief stops the time-acqusition * * Each device has to call Stop() when it has finished and its * pointer will be erased from the map. When the last device has "stopped" * the reference-time and the current-time will be reset to 0. * */ void Stop( itk::Object::Pointer device ); /** * \brief returns the time elapsed since calling Start() for the first time in milliseconds * * GetElapsed() returns the time elapsed since Start() has been called first, no matter * which itk::Object did the call. * This method-call can be used if you want to need to have several processes you want to * monitor and need timestamps in the same space of time, e.g. when using two tracking-devices * on the same experiment. */ double GetElapsed(); /** * \brief returns the time elapsed since 'device' called Start() in milliseconds * * GetElapsed(itk::Object device) returns the time elapsed since the given itk::Object called * Start(). * This overloaded method should be used when you only have one independent process to keep * track of, e.g. when you want to measure how long it takes to execute a piece of code. */ double GetElapsed(itk::Object::Pointer device); /** * \brief returns the offset of this device's starting-time to the * reference-time in ms * * Device 'A' is the first device to call Start(). Device 'B' calls Start() * some time later. This time-difference is the offset, that each device has realtive to the * device that started the time-acquisition. * Each device's offset is stored in a map with a pointer to the device. * * If this device has not been or is no longer saved in the map of devices, * -1 will be returned. * * * only used internally */ double GetOffset(itk::Object::Pointer Device); /** * \brief setter for the internally used RealTimeClock() * * If you want to use a "third-party" RealTimeClock, e.g PocoRealTimeClock, BoostRealTimeClock * or ITKRealTimeClock, you can set it using this method: * mitk::RealTimeClock::Pointer RealTimeClock = mitk::RealTimeClock::New(); * mitk::TimeStamp::GetInstance()->SetRealTimeClock(RealTimeClock); * * Right now, none of these RealTimeClocks have been implemented!! * * Notice: The mitk-implementation of an os-dependant RealTimeClock is used * by default. */ void SetRealTimeClock(mitk::RealTimeClock::Pointer Clock); + /** + * \brief creates a new RealTimeClock + * + * Instanciates a new RealTimeClock, that will be specific for the Operating System. + * This will only be called internally when no other RealTimeClock has been set + * by the user. + * + */ void Initialize(); protected: + TimeStamp(); virtual ~TimeStamp(); double GetCurrentStamp(); - /* - the current timestamp when GetCurrentStamp() is called. - */ + /* the current timestamp when GetCurrentStamp() is called. */ double m_Time; - /* - the timestamp in ms acquired when Start() was called. - */ + /* the timestamp in ms acquired when Start() was called. */ double m_ReferenceTime; - /* - pointer to the RealTimeClock used internally - */ + /* pointer to the RealTimeClock used internally */ mitk::RealTimeClock::Pointer m_RealTimeClock; - /* - pointer to the current instance - */ + /* pointer to the current instance */ static mitk::TimeStamp::Pointer s_Instance; - /* - map, in which pointer to all devices calling Start(), are saved - */ + /* map, in which pointer to all devices calling Start(), are saved */ std::map m_DeviceMap; std::map::iterator m_MapIterator; }; } // namespace mitk #endif /* MITKTIMESTAMP_H_HEADER_INCLUDED_ */ diff --git a/Modules/IGT/Testing/mitkTimeStampTest.cpp b/Modules/IGT/Testing/mitkTimeStampTest.cpp index 182c3aabbb..c1ac8b8baf 100644 --- a/Modules/IGT/Testing/mitkTimeStampTest.cpp +++ b/Modules/IGT/Testing/mitkTimeStampTest.cpp @@ -1,104 +1,103 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-02-25 18:43:22 +0100 (Mi, 25 Feb 2009) $ Version: $Revision: 16010 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkTimeStamp.h" #include "mitkRealTimeClock.h" #include "mitkTestingMacros.h" #include "itkObject.h" //#include /** * test for the class "mitkTimeStamp" */ int mitkTimeStampTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("TimeStamp") // let's create an object of our class - // first test: did this work? // using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since // it makes no sense to continue without an object. MITK_TEST_CONDITION_REQUIRED(mitk::TimeStamp::GetInstance() != (0), "Testing GetInstance() of Singleton" ); itk::Object::Pointer tester = itk::Object::New(); itk::Object::Pointer tester2 = itk::Object::New(); //start-tracking sets the reference-time, timestamps are relative to this time mitk::TimeStamp::GetInstance()->Start(tester); std::cout << "first device has started tracking\n"; //sleeps for 20 ms #if defined (WIN32) || defined (_WIN32) Sleep(20); #else usleep(20000); #endif std::cout << "supposed to have waited 20ms \n"; double time_elapsed, relative_time_elapsed; //gets time elapsed since start time_elapsed = mitk::TimeStamp::GetInstance()->GetElapsed(); std::cout << "have actually waited : " << time_elapsed << "ms \n"; //elapsed time is not allowed to be too far from 20 ms (+-10ms)-> debugging "destroys" the correct value of course MITK_TEST_CONDITION_REQUIRED((time_elapsed-20) > -10 , "Testing if elapsed time is correct (-10)"); //MITK_TEST_CONDITION_REQUIRED((time_elapsed-20) < 10 , "Testing if elapsed time is correct (+10)"); //second "device" starts tracking mitk::TimeStamp::GetInstance()->Start(tester2); std::cout << "second device has started\n"; //first device stops mitk::TimeStamp::GetInstance()->Stop(tester); std::cout << "first device has stopped tracking\n"; time_elapsed = mitk::TimeStamp::GetInstance()->GetElapsed(); relative_time_elapsed = mitk::TimeStamp::GetInstance()->GetElapsed(tester2); std::cout << "time elapsed supposed to be greater than 20 ms\n"; std::cout << time_elapsed << " actually elapsed\n"; std::cout << "relative time elapsed supposed to be smaller than absolute time elapsed : \n"; std::cout << relative_time_elapsed << " actually elapsed\n"; //relative timespan must be smaller than absolute timespan MITK_TEST_CONDITION_REQUIRED( time_elapsed > relative_time_elapsed , " testing if relative timespan is shorter than absolute timespan"); //timestamp still has to be valid (tester2 still tracking), and has to be larger than 20ms //MITK_TEST_CONDITION_REQUIRED( time_elapsed > 15 , "testing if second device is still keeping the TimeStamp \"alive\""); mitk::TimeStamp::GetInstance()->Stop(tester2); std::cout << " second device has stopped tracking\n"; time_elapsed = mitk::TimeStamp::GetInstance()->GetElapsed(); //when all devices have stopped, -1 has to be returned MITK_TEST_CONDITION_REQUIRED( time_elapsed == -1 , "testing if -1 is returned after all devices have stopped"); // always end with this! MITK_TEST_END(); }