├── .gitignore ├── CMakeLists.txt ├── CppTimer.h ├── CppTimerCallback.h ├── CppTimerStdFuncCallback.h ├── Doxyfile ├── LICENSE ├── README.md ├── demo.cpp ├── demo_runnable.cpp ├── demo_stdfunccallback.cpp ├── docs ├── CppTimerCallback_8h_source.html ├── CppTimer_8h_source.html ├── annotated.html ├── bc_s.png ├── bdwn.png ├── classCppTimer-members.html ├── classCppTimer.html ├── classCppTimer.png ├── classCppTimerCallback-members.html ├── classCppTimerCallback.html ├── classCppTimerCallback.png ├── classCppTimerCallback_1_1Runnable-members.html ├── classCppTimerCallback_1_1Runnable.html ├── classes.html ├── closed.png ├── doc.png ├── doxygen.css ├── doxygen.png ├── dynsections.js ├── files.html ├── folderclosed.png ├── folderopen.png ├── functions.html ├── functions_func.html ├── hierarchy.html ├── index.html ├── jquery.js ├── md_README.html ├── menu.js ├── menudata.js ├── nav_f.png ├── nav_g.png ├── nav_h.png ├── open.png ├── pages.html ├── pdf │ └── refman.pdf ├── search │ ├── all_0.html │ ├── all_0.js │ ├── all_1.html │ ├── all_1.js │ ├── all_2.html │ ├── all_2.js │ ├── all_3.html │ ├── all_3.js │ ├── all_4.html │ ├── all_4.js │ ├── classes_0.html │ ├── classes_0.js │ ├── classes_1.html │ ├── classes_1.js │ ├── close.png │ ├── functions_0.html │ ├── functions_0.js │ ├── functions_1.html │ ├── functions_1.js │ ├── functions_2.html │ ├── functions_2.js │ ├── functions_3.html │ ├── functions_3.js │ ├── mag_sel.png │ ├── nomatches.html │ ├── pages_0.html │ ├── pages_0.js │ ├── search.css │ ├── search.js │ ├── search_l.png │ ├── search_m.png │ ├── search_r.png │ └── searchdata.js ├── splitbar.png ├── sync_off.png ├── sync_on.png ├── tab_a.png ├── tab_b.png ├── tab_h.png ├── tab_s.png └── tabs.css └── test ├── CMakeLists.txt ├── oneshot.cpp ├── startstop.cpp ├── startstop_ms.cpp ├── twotimers.cpp └── twotimers_ms.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | #CMakeFiles 35 | CMakeCache.txt 36 | CMakeFiles/ 37 | CTestTestfile.cmake 38 | Makefile 39 | Testing/ 40 | cmake_install.cmake 41 | demo 42 | demo_runnable 43 | test/CMakeFiles/ 44 | test/CTestTestfile.cmake 45 | test/Makefile 46 | test/cmake_install.cmake 47 | test/test_startstop 48 | test/test_twotimers 49 | test/test_startstop_seconds 50 | test/test_twotimers_seconds 51 | 52 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.6) 2 | 3 | project (CppTimer 4 | DESCRIPTION "Wrapper for Linux timers" 5 | LANGUAGES CXX) 6 | 7 | set (CMAKE_CXX_STANDARD 17) 8 | add_compile_options(-Wall -Wconversion -Wextra -pedantic) 9 | include(GNUInstallDirs) 10 | enable_testing() 11 | 12 | add_library(cpptimer INTERFACE) 13 | 14 | add_executable(demo demo.cpp) 15 | TARGET_LINK_LIBRARIES(demo cpptimer) 16 | 17 | add_executable(demo_runnable demo_runnable.cpp) 18 | TARGET_LINK_LIBRARIES(demo_runnable cpptimer) 19 | 20 | add_executable(demo_stdfunccallback demo_stdfunccallback.cpp) 21 | TARGET_LINK_LIBRARIES(demo_stdfunccallback cpptimer) 22 | 23 | 24 | add_subdirectory(test) 25 | 26 | set_target_properties(cpptimer PROPERTIES 27 | PUBLIC_HEADER CppTimer.h) 28 | 29 | install(TARGETS cpptimer 30 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 31 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 32 | ) 33 | -------------------------------------------------------------------------------- /CppTimer.h: -------------------------------------------------------------------------------- 1 | #ifndef __CPP_TIMER_H_ 2 | #define __CPP_TIMER_H_ 3 | 4 | /** 5 | * GNU GENERAL PUBLIC LICENSE 6 | * Version 3, 29 June 2007 7 | * 8 | * (C) 2020-2024, Bernd Porr 9 | * 10 | * This is inspired by the timer_create man page. 11 | **/ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | /** 21 | * Enumeration of CppTimer types 22 | **/ 23 | enum cppTimerType_t 24 | { 25 | PERIODIC, 26 | ONESHOT 27 | }; 28 | 29 | /** 30 | * Timer class which repeatedly fires. It's wrapper around the 31 | * POSIX per-process timer. 32 | **/ 33 | class CppTimer 34 | { 35 | 36 | public: 37 | /** 38 | * Starts the timer. The timer fires first after 39 | * the specified time in nanoseconds and then at 40 | * that interval in PERIODIC mode. In ONESHOT mode 41 | * the timer fires once after the specified time in 42 | * nanoseconds. 43 | * @param nanosecs Time in nanoseconds 44 | * @param type Either PERIODIC or ONESHOT 45 | **/ 46 | virtual void startns(long nanosecs, cppTimerType_t t = PERIODIC) { 47 | if (uthread.joinable()) uthread.join(); 48 | if (running) return; 49 | timerType = t; 50 | if (fd < 0) 51 | throw("Could not start timer"); 52 | switch (timerType) 53 | { 54 | case (PERIODIC): 55 | //starts after specified period of nanoseconds 56 | its.it_value.tv_sec = nanosecs / 1000000000; 57 | its.it_value.tv_nsec = nanosecs % 1000000000; 58 | its.it_interval.tv_sec = nanosecs / 1000000000; 59 | its.it_interval.tv_nsec = nanosecs % 1000000000; 60 | break; 61 | case (ONESHOT): 62 | //fires once after specified period of nanoseconds 63 | its.it_value.tv_sec = nanosecs / 1000000000; 64 | its.it_value.tv_nsec = nanosecs % 1000000000; 65 | its.it_interval.tv_sec = 0; 66 | its.it_interval.tv_nsec = 0; 67 | break; 68 | } 69 | if (timerfd_settime(fd, 0, &its, NULL) == -1) 70 | throw("Could not start timer"); 71 | uthread = std::thread(&CppTimer::worker,this); 72 | } 73 | 74 | /** 75 | * Starts the timer. The timer fires first after 76 | * the specified time in milliseconds and then at 77 | * that interval in PERIODIC mode. In ONESHOT mode 78 | * the timer fires once after the specified time in 79 | * milliseconds. 80 | * @param millisecs Time in milliseconds 81 | * @param type Either PERIODIC or ONESHOT 82 | **/ 83 | virtual void startms(long millisecs, cppTimerType_t t = PERIODIC) { 84 | if (uthread.joinable()) uthread.join(); 85 | if (running) return; 86 | timerType = t; 87 | if (fd < 0) 88 | throw("Could not start timer"); 89 | switch (timerType) 90 | { 91 | case (PERIODIC): 92 | //starts after specified period of milliseconds 93 | its.it_value.tv_sec = millisecs / 1000; 94 | its.it_value.tv_nsec = (millisecs % 1000) * 1000000; 95 | its.it_interval.tv_sec = millisecs / 1000; 96 | its.it_interval.tv_nsec = (millisecs % 1000) * 1000000; 97 | break; 98 | case (ONESHOT): 99 | //fires once after specified period of milliseconds 100 | its.it_value.tv_sec = millisecs / 1000; 101 | its.it_value.tv_nsec = (millisecs % 1000) * 1000000; 102 | its.it_interval.tv_sec = 0; 103 | its.it_interval.tv_nsec = 0; 104 | break; 105 | } 106 | if (timerfd_settime(fd, 0, &its, NULL) == -1) 107 | throw("Could not start timer"); 108 | uthread = std::thread(&CppTimer::worker,this); 109 | } 110 | 111 | /** 112 | * Stops the timer by disarming it. It can be re-started 113 | * with start(). 114 | **/ 115 | virtual void stop() { 116 | running = false; 117 | if (uthread.joinable()) uthread.join(); 118 | } 119 | 120 | /** 121 | * Destructor disarms the timer, deletes it and 122 | * disconnect the signal handler. 123 | **/ 124 | virtual ~CppTimer() { 125 | stop(); 126 | close(fd); 127 | } 128 | 129 | protected: 130 | /** 131 | * Abstract function which needs to be implemented by the children. 132 | * This is called every time the timer fires. 133 | **/ 134 | virtual void timerEvent() = 0; 135 | 136 | private: 137 | cppTimerType_t timerType; 138 | const int fd = timerfd_create(CLOCK_MONOTONIC, 0); 139 | struct itimerspec its; 140 | bool running = false; 141 | std::thread uthread; 142 | void worker() { 143 | running = true; 144 | while (running) { 145 | uint64_t exp; 146 | const long int s = read(fd, &exp, sizeof(uint64_t)); 147 | if (s != sizeof(uint64_t) ) { 148 | throw "Timer didn't work."; 149 | } 150 | timerEvent(); 151 | if (ONESHOT == timerType) running = false; 152 | } 153 | // disarm 154 | struct itimerspec itsnew; 155 | itsnew.it_value.tv_sec = 0; 156 | itsnew.it_value.tv_nsec = 0; 157 | itsnew.it_interval.tv_sec = 0; 158 | itsnew.it_interval.tv_nsec = 0; 159 | timerfd_settime(fd, 0, &itsnew, &its); 160 | } 161 | }; 162 | 163 | #endif 164 | -------------------------------------------------------------------------------- /CppTimerCallback.h: -------------------------------------------------------------------------------- 1 | #ifndef __CPP_TIMER_CALLBACK 2 | #define __CPP_TIMER_CALLBACK 3 | #include 4 | #include "CppTimer.h" 5 | #include 6 | #include 7 | 8 | // Demo which creates a callback interface as the abstract class "Runnable". 9 | // This then allows to register a callback. 10 | 11 | class CppTimerCallback : public CppTimer { 12 | 13 | public: 14 | class Runnable { 15 | public: 16 | virtual void run() = 0; 17 | }; 18 | 19 | void registerEventRunnable(Runnable &h) { 20 | cppTimerEventRunnables.push_back(&h); 21 | } 22 | 23 | void timerEvent() { 24 | for(auto & r : cppTimerEventRunnables) { 25 | r->run(); 26 | } 27 | } 28 | 29 | private: 30 | std::vector cppTimerEventRunnables; 31 | }; 32 | 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /CppTimerStdFuncCallback.h: -------------------------------------------------------------------------------- 1 | #ifndef __CPP_TIMER_STD_CALLBACK 2 | #define __CPP_TIMER_STD_CALLBACK 3 | #include 4 | #include "CppTimer.h" 5 | #include 6 | #include 7 | #include 8 | 9 | // This is a demo how to create a callback with std::function which allows 10 | // calling methods in other classes by registering a lambda function! 11 | 12 | class CppTimerCallback : public CppTimer { 13 | 14 | public: 15 | 16 | using CallbackFunction = std::function; 17 | 18 | void registerEventCallback(CallbackFunction cf) { 19 | callbackFunction = cf; 20 | } 21 | 22 | inline void timerEvent() { 23 | callbackFunction(); 24 | } 25 | 26 | private: 27 | CallbackFunction callbackFunction; 28 | }; 29 | 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CppTimer 2 | Generic C++ Timer for Linux 3 | 4 | It's a wrapper around the Linux timers. The timer used is timerfd 5 | which is a file descriptor which blocks till a certain time has 6 | elapsed. This means it puts a thread to sleep till it unblocks 7 | which is the general approach for Linux events. 8 | There are three ways of using 9 | the timer: 10 | 1. by overloading the `timerEvent()` method in the `CppTimer` class itself (fastest) 11 | 2. by registering a callback class called `Runnable` with an overloaded `run()` method. 12 | 3. by registering a lambda function 13 | 14 | ## Installation 15 | ``` 16 | cmake . 17 | make 18 | sudo make install 19 | ``` 20 | 21 | ## Usage (overloading the timer event) 22 | The doxygen generated online docs are here: https://berndporr.github.io/cppTimer/ 23 | 24 | Include `CppTimer.h` in your program. That's it. 25 | ``` 26 | TARGET_LINK_LIBRARIES(your_project_title cpptimer rt) 27 | ``` 28 | 29 | ### Create the Timer class 30 | ``` 31 | class MyTimer : public CppTimer { 32 | 33 | void timerEvent() { 34 | // your timer event code here 35 | } 36 | }; 37 | ``` 38 | where you override `timerEvent` with your function. 39 | 40 | ### Run the Timer class 41 | The timer is programmed in nanoseconds: 42 | ``` 43 | MyTimer myTimer; 44 | // every 500000ns 45 | myTimer.startns(500000); 46 | ``` 47 | or milliseconds: 48 | ``` 49 | // every 200ms 50 | myTimer.startms(200); 51 | ``` 52 | As soon as start returns the timer fires instantly and 53 | then at the specified interval. 54 | 55 | ### Demo program 56 | 57 | To run `demo.cpp` just do `cmake .`, `make` and then `./demo`. 58 | 59 | ## Callback interface version 60 | 61 | Instead of overloading the `run()` method in the timer class you can 62 | overload the `run()` method in the `Runnable` class and then register 63 | this class with the timer class. Check out `demo_runnable` which 64 | demonstrates how to use this method. 65 | 66 | ## Callback via lambda function 67 | 68 | Here, the callback is established with the help of a lambda function 69 | instead of a callback interface. This allows direct registering 70 | of a method of the receiving class but one needs to get used to the 71 | lambda function syntax. It also allows more flexibility in doing 72 | some work inside of the lambda function and it's entirely pointer-free. 73 | 74 | ## Unit tests 75 | 76 | Run: 77 | 78 | ``` 79 | ctest 80 | ``` 81 | 82 | 83 | That's it. Enjoy! 84 | -------------------------------------------------------------------------------- /demo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "CppTimer.h" 3 | #include 4 | #include 5 | #include 6 | 7 | class DemoTimer1 : public CppTimer { 8 | 9 | void timerEvent() { 10 | fprintf(stdout,"Buh! "); 11 | fflush(stdout); 12 | } 13 | }; 14 | 15 | 16 | class DemoTimer2 : public CppTimer { 17 | 18 | void timerEvent() { 19 | fprintf(stdout,"Bah!!!!!!\n"); 20 | } 21 | }; 22 | 23 | 24 | 25 | class DemoTimer3 : public CppTimer { 26 | 27 | void timerEvent() { 28 | fprintf(stdout,"Booom!!!!!!\n"); 29 | } 30 | }; 31 | 32 | 33 | 34 | int main( int, const char**) { 35 | DemoTimer1 demoTimer1; 36 | demoTimer1.startms(250); 37 | DemoTimer2 demoTimer2; 38 | demoTimer2.startms(1000); 39 | DemoTimer3 demoTimer3; 40 | demoTimer3.startms(1000,ONESHOT); 41 | 42 | std::this_thread::sleep_for(std::chrono::seconds(2)); 43 | 44 | demoTimer1.stop(); 45 | demoTimer2.stop(); 46 | 47 | std::this_thread::sleep_for(std::chrono::seconds(1)); 48 | 49 | demoTimer1.startns(25000000); 50 | demoTimer2.startns(100000000); 51 | 52 | std::this_thread::sleep_for(std::chrono::seconds(1)); 53 | 54 | demoTimer1.stop(); 55 | demoTimer2.stop(); 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /demo_runnable.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "CppTimerCallback.h" 3 | #include 4 | #include 5 | 6 | class Callback1 : public CppTimerCallback::Runnable { 7 | void run() { 8 | fprintf(stdout,"Bah! "); 9 | fflush(stdout); 10 | } 11 | }; 12 | 13 | 14 | class Callback2 : public CppTimerCallback::Runnable { 15 | void run() { 16 | fprintf(stdout,"Buh! \n"); 17 | fflush(stdout); 18 | } 19 | }; 20 | 21 | 22 | int main( int, const char**) { 23 | CppTimerCallback demoTimer1; 24 | Callback1 callback1; 25 | demoTimer1.registerEventRunnable(callback1); 26 | demoTimer1.startns(250000000); 27 | CppTimerCallback demoTimer2; 28 | Callback2 callback2; 29 | demoTimer2.registerEventRunnable(callback2); 30 | demoTimer2.startms(1000); 31 | 32 | // do nothing and keep sleeping for 2 secs 33 | std::this_thread::sleep_for(std::chrono::seconds(2)); 34 | 35 | demoTimer1.stop(); 36 | demoTimer2.stop(); 37 | 38 | printf("\n"); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /demo_stdfunccallback.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "CppTimerStdFuncCallback.h" 3 | #include 4 | #include 5 | 6 | // Demo which shows how to register a callback via a lambda function. 7 | // The method run() in the receiving classes below is called from the class CppTimerCallback. 8 | 9 | class ReceiverClass1 { 10 | public: 11 | void run() { 12 | fprintf(stdout,"Bah! "); 13 | fflush(stdout); 14 | } 15 | }; 16 | 17 | 18 | class ReceiverClass2 { 19 | public: 20 | void run() { 21 | fprintf(stdout,"BUH! \n"); 22 | fflush(stdout); 23 | } 24 | }; 25 | 26 | 27 | int main( int, const char**) { 28 | CppTimerCallback demoTimer1; 29 | ReceiverClass1 receiverClass1; 30 | demoTimer1.registerEventCallback([&receiverClass1](){receiverClass1.run();}); 31 | demoTimer1.startns(77000000); 32 | 33 | CppTimerCallback demoTimer2; 34 | ReceiverClass2 receiverClass2; 35 | demoTimer2.registerEventCallback([&receiverClass2](){receiverClass2.run();}); 36 | demoTimer2.startns(250000000); 37 | 38 | // do nothing and keep sleeping for 2 secs 39 | std::this_thread::sleep_for(std::chrono::seconds(2)); 40 | 41 | demoTimer1.stop(); 42 | demoTimer2.stop(); 43 | 44 | printf("\n"); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /docs/CppTimerCallback_8h_source.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: CppTimerCallback.h Source File 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 |
49 | 50 |
54 |
55 | 56 | 57 |
58 | 61 |
62 | 63 |
64 |
65 |
CppTimerCallback.h
66 |
67 |
68 |
1 #ifndef __CPP_TIMER_CALLBACK
69 |
2 #define __CPP_TIMER_CALLBACK
70 |
3 #include <stdio.h>
71 |
4 #include "CppTimer.h"
72 |
5 #include <unistd.h>
73 |
6 
74 |
7 
75 |
8 class CppTimerCallback : public CppTimer {
76 |
9 
77 |
10 public:
78 |
11  class Runnable {
79 |
12  public:
80 |
13  virtual void run() = 0;
81 |
14  };
82 |
15 
83 |
16  void registerEventRunnable(Runnable &h) {
84 |
17  cppTimerEventRunnable = &h;
85 |
18  }
86 |
19 
87 |
20  void unregisterEventRunnable() {
88 |
21  cppTimerEventRunnable = NULL;
89 |
22  }
90 |
23 
91 |
24  void timerEvent() {
92 |
25  if (cppTimerEventRunnable) {
93 |
26  cppTimerEventRunnable->run();
94 |
27  }
95 |
28  }
96 |
29 
97 |
30 private:
98 |
31  Runnable* cppTimerEventRunnable = NULL;
99 |
32 
100 |
33 };
101 |
34 
102 |
35 
103 |
36 #endif
104 |
Definition: CppTimerCallback.h:11
105 |
Definition: CppTimerCallback.h:8
106 |
void timerEvent()
Definition: CppTimerCallback.h:24
107 |
Definition: CppTimer.h:34
108 |
109 | 110 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /docs/CppTimer_8h_source.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: CppTimer.h Source File 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 |
49 | 50 |
54 |
55 | 56 | 57 |
58 | 61 |
62 | 63 |
64 |
65 |
CppTimer.h
66 |
67 |
68 |
1 #ifndef __CPP_TIMER_H_
69 |
2 #define __CPP_TIMER_H_
70 |
3 
71 |
13 #include <stdlib.h>
72 |
14 #include <unistd.h>
73 |
15 #include <stdio.h>
74 |
16 #include <time.h>
75 |
17 #include <thread>
76 |
18 #include <sys/timerfd.h>
77 |
19 
78 |
23 enum cppTimerType_t
79 |
24 {
80 |
25  PERIODIC,
81 |
26  ONESHOT
82 |
27 };
83 |
28 
84 |
33 class CppTimer
85 |
34 {
86 |
35 
87 |
36 public:
88 |
46  virtual void startns(long nanosecs, cppTimerType_t type = PERIODIC) {
89 |
47  if (running) return;
90 |
48  fd = timerfd_create(CLOCK_MONOTONIC, 0);
91 |
49  if (fd < 0)
92 |
50  throw("Could not start timer");
93 |
51  switch (type)
94 |
52  {
95 |
53  case (PERIODIC):
96 |
54  //starts after specified period of nanoseconds
97 |
55  its.it_value.tv_sec = nanosecs / 1000000000;
98 |
56  its.it_value.tv_nsec = nanosecs % 1000000000;
99 |
57  its.it_interval.tv_sec = nanosecs / 1000000000;
100 |
58  its.it_interval.tv_nsec = nanosecs % 1000000000;
101 |
59  break;
102 |
60  case (ONESHOT):
103 |
61  //fires once after specified period of nanoseconds
104 |
62  its.it_value.tv_sec = nanosecs / 1000000000;
105 |
63  its.it_value.tv_nsec = nanosecs % 1000000000;
106 |
64  its.it_interval.tv_sec = 0;
107 |
65  its.it_interval.tv_nsec = 0;
108 |
66  break;
109 |
67  }
110 |
68  if (timerfd_settime(fd, 0, &its, NULL) == -1)
111 |
69  throw("Could not start timer");
112 |
70  uthread = std::thread(&CppTimer::worker,this);
113 |
71  }
114 |
72 
115 |
82  virtual void startms(long millisecs, cppTimerType_t type = PERIODIC) {
116 |
83  if (running) return;
117 |
84  fd = timerfd_create(CLOCK_MONOTONIC, 0);
118 |
85  if (fd < 0)
119 |
86  throw("Could not start timer");
120 |
87  switch (type)
121 |
88  {
122 |
89  case (PERIODIC):
123 |
90  //starts after specified period of milliseconds
124 |
91  its.it_value.tv_sec = millisecs / 1000;
125 |
92  its.it_value.tv_nsec = (millisecs % 1000) * 1000000;
126 |
93  its.it_interval.tv_sec = millisecs / 1000;
127 |
94  its.it_interval.tv_nsec = (millisecs % 1000) * 1000000;
128 |
95  break;
129 |
96  case (ONESHOT):
130 |
97  //fires once after specified period of milliseconds
131 |
98  its.it_value.tv_sec = millisecs / 1000;
132 |
99  its.it_value.tv_nsec = (millisecs % 1000) * 1000000;
133 |
100  its.it_interval.tv_sec = 0;
134 |
101  its.it_interval.tv_nsec = 0;
135 |
102  break;
136 |
103  }
137 |
104  if (timerfd_settime(fd, 0, &its, NULL) == -1)
138 |
105  throw("Could not start timer");
139 |
106  uthread = std::thread(&CppTimer::worker,this);
140 |
107  }
141 |
108 
142 |
113  virtual void stop() {
143 |
114  if (!running) return;
144 |
115  running = false;
145 |
116  uthread.join();
146 |
117  }
147 |
118 
148 |
123  virtual ~CppTimer() {
149 |
124  stop();
150 |
125  }
151 |
126 
152 |
127 protected:
153 |
132  virtual void timerEvent() = 0;
154 |
133 
155 |
134 private:
156 |
135  int fd = 0;
157 |
136  struct itimerspec its;
158 |
137  bool running = false;
159 |
138  std::thread uthread;
160 |
139  void worker() {
161 |
140  running = true;
162 |
141  while (running) {
163 |
142  uint64_t exp;
164 |
143  const long int s = read(fd, &exp, sizeof(uint64_t));
165 |
144  if (s != sizeof(uint64_t) ) {
166 |
145  running = false;
167 |
146  return;
168 |
147  }
169 |
148  timerEvent();
170 |
149  }
171 |
150  // disarm
172 |
151  struct itimerspec itsnew;
173 |
152  itsnew.it_value.tv_sec = 0;
174 |
153  itsnew.it_value.tv_nsec = 0;
175 |
154  itsnew.it_interval.tv_sec = 0;
176 |
155  itsnew.it_interval.tv_nsec = 0;
177 |
156  timerfd_settime(fd, 0, &itsnew, &its);
178 |
157  close(fd);
179 |
158  fd = -1;
180 |
159  }
181 |
160 };
182 |
161 
183 |
162 #endif
184 |
Definition: CppTimer.h:34
185 |
virtual ~CppTimer()
Definition: CppTimer.h:123
186 |
virtual void startns(long nanosecs, cppTimerType_t type=PERIODIC)
Definition: CppTimer.h:46
187 |
virtual void startms(long millisecs, cppTimerType_t type=PERIODIC)
Definition: CppTimer.h:82
188 |
virtual void stop()
Definition: CppTimer.h:113
189 |
virtual void timerEvent()=0
190 |
191 | 192 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /docs/annotated.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: Class List 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 |
49 | 50 |
54 |
55 | 56 | 57 |
58 | 61 |
62 | 63 |
64 |
65 |
Class List
66 |
67 |
68 |
Here are the classes, structs, unions and interfaces with brief descriptions:
69 |
[detail level 12]
70 | 71 | 72 | 73 |
 CCppTimer
 CCppTimerCallback
 CRunnable
74 |
75 |
76 | 77 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /docs/bc_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/bc_s.png -------------------------------------------------------------------------------- /docs/bdwn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/bdwn.png -------------------------------------------------------------------------------- /docs/classCppTimer-members.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: Member List 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 | 49 |
53 |
54 | 55 | 56 |
57 | 60 |
61 | 62 |
63 |
64 |
65 |
CppTimer Member List
66 |
67 |
68 | 69 |

This is the complete list of members for CppTimer, including all inherited members.

70 | 71 | 72 | 73 | 74 | 75 | 76 |
startms(long millisecs, cppTimerType_t type=PERIODIC)CppTimerinlinevirtual
startns(long nanosecs, cppTimerType_t type=PERIODIC)CppTimerinlinevirtual
stop()CppTimerinlinevirtual
timerEvent()=0CppTimerprotectedpure virtual
~CppTimer()CppTimerinlinevirtual
77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /docs/classCppTimer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: CppTimer Class Reference 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 | 49 |
53 |
54 | 55 | 56 |
57 | 60 |
61 | 62 |
63 |
64 | 68 |
69 |
CppTimer Class Referenceabstract
70 |
71 |
72 | 73 |

#include <CppTimer.h>

74 |
75 | Inheritance diagram for CppTimer:
76 |
77 |
78 | 79 | 80 | CppTimerCallback 81 | 82 |
83 | 84 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 |

85 | Public Member Functions

virtual void startns (long nanosecs, cppTimerType_t type=PERIODIC)
 
virtual void startms (long millisecs, cppTimerType_t type=PERIODIC)
 
virtual void stop ()
 
virtual ~CppTimer ()
 
95 | 97 | 98 | 99 |

96 | Protected Member Functions

virtual void timerEvent ()=0
 
100 |

Detailed Description

101 |

Timer class which repeatedly fires. It's wrapper around the POSIX per-process timer.

102 |

Constructor & Destructor Documentation

103 | 104 |

◆ ~CppTimer()

105 | 106 |
107 |
108 | 109 | 110 | 120 | 122 | 123 |
111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 |
virtual CppTimer::~CppTimer ()
119 |
121 | inlinevirtual
124 |
125 |

Destructor disarms the timer, deletes it and disconnect the signal handler.

126 | 127 |
128 |
129 |

Member Function Documentation

130 | 131 |

◆ startms()

132 | 133 |
134 |
135 | 136 | 137 | 158 | 160 | 161 |
138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 |
virtual void CppTimer::startms (long millisecs,
cppTimerType_t type = PERIODIC 
)
157 |
159 | inlinevirtual
162 |
163 |

Starts the timer. The timer fires first after the specified time in milliseconds and then at that interval in PERIODIC mode. In ONESHOT mode the timer fires once after the specified time in milliseconds.

Parameters
164 | 165 | 166 | 167 |
millisecsTime in milliseconds
typeEither PERIODIC or ONESHOT
168 |
169 |
170 | 171 |
172 |
173 | 174 |

◆ startns()

175 | 176 |
177 |
178 | 179 | 180 | 201 | 203 | 204 |
181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 |
virtual void CppTimer::startns (long nanosecs,
cppTimerType_t type = PERIODIC 
)
200 |
202 | inlinevirtual
205 |
206 |

Starts the timer. The timer fires first after the specified time in nanoseconds and then at that interval in PERIODIC mode. In ONESHOT mode the timer fires once after the specified time in nanoseconds.

Parameters
207 | 208 | 209 | 210 |
nanosecsTime in nanoseconds
typeEither PERIODIC or ONESHOT
211 |
212 |
213 | 214 |
215 |
216 | 217 |

◆ stop()

218 | 219 |
220 |
221 | 222 | 223 | 233 | 235 | 236 |
224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 |
virtual void CppTimer::stop ()
232 |
234 | inlinevirtual
237 |
238 |

Stops the timer by disarming it. It can be re-started with start().

239 | 240 |
241 |
242 | 243 |

◆ timerEvent()

244 | 245 |
246 |
247 | 248 | 249 | 259 | 261 | 262 |
250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 |
virtual void CppTimer::timerEvent ()
258 |
260 | protectedpure virtual
263 |
264 |

Abstract function which needs to be implemented by the children. This is called every time the timer fires.

265 | 266 |

Implemented in CppTimerCallback.

267 | 268 |
269 |
270 |
The documentation for this class was generated from the following file: 273 |
274 | 275 | 278 | 279 | 280 | -------------------------------------------------------------------------------- /docs/classCppTimer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/classCppTimer.png -------------------------------------------------------------------------------- /docs/classCppTimerCallback-members.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: Member List 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 | 49 |
53 |
54 | 55 | 56 |
57 | 60 |
61 | 62 |
63 |
64 |
65 |
CppTimerCallback Member List
66 |
67 |
68 | 69 |

This is the complete list of members for CppTimerCallback, including all inherited members.

70 | 71 | 72 | 73 | 74 | 75 | 76 |
startms(long millisecs, cppTimerType_t type=PERIODIC)CppTimerinlinevirtual
startns(long nanosecs, cppTimerType_t type=PERIODIC)CppTimerinlinevirtual
stop()CppTimerinlinevirtual
timerEvent()CppTimerCallbackinlinevirtual
~CppTimer()CppTimerinlinevirtual
77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /docs/classCppTimerCallback.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: CppTimerCallback Class Reference 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 | 49 |
53 |
54 | 55 | 56 |
57 | 60 |
61 | 62 |
63 |
64 | 68 |
69 |
CppTimerCallback Class Reference
70 |
71 |
72 |
73 | Inheritance diagram for CppTimerCallback:
74 |
75 |
76 | 77 | 78 | CppTimer 79 | 80 |
81 | 82 | 84 | 85 | 86 |

83 | Classes

class  Runnable
 
87 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 |

88 | Public Member Functions

void timerEvent ()
 
- Public Member Functions inherited from CppTimer
virtual void startns (long nanosecs, cppTimerType_t type=PERIODIC)
 
virtual void startms (long millisecs, cppTimerType_t type=PERIODIC)
 
virtual void stop ()
 
virtual ~CppTimer ()
 
101 | 103 |

102 | Additional Inherited Members

104 |

Member Function Documentation

105 | 106 |

◆ timerEvent()

107 | 108 |
109 |
110 | 111 | 112 | 122 | 124 | 125 |
113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 |
void CppTimerCallback::timerEvent ()
121 |
123 | inlinevirtual
126 |
127 |

Abstract function which needs to be implemented by the children. This is called every time the timer fires.

128 | 129 |

Implements CppTimer.

130 | 131 |
132 |
133 |
The documentation for this class was generated from the following file: 136 |
137 | 138 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /docs/classCppTimerCallback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/classCppTimerCallback.png -------------------------------------------------------------------------------- /docs/classCppTimerCallback_1_1Runnable-members.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: Member List 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 | 49 |
53 |
54 | 55 | 56 |
57 | 60 |
61 | 62 | 66 |
67 |
68 |
69 |
CppTimerCallback::Runnable Member List
70 |
71 |
72 | 73 |

This is the complete list of members for CppTimerCallback::Runnable, including all inherited members.

74 |
75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /docs/classCppTimerCallback_1_1Runnable.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: CppTimerCallback::Runnable Class Reference 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 | 49 |
53 |
54 | 55 | 56 |
57 | 60 |
61 | 62 | 66 |
67 |
68 | 70 |
71 |
CppTimerCallback::Runnable Class Referenceabstract
72 |
73 |
74 |
The documentation for this class was generated from the following file: 77 |
78 | 79 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /docs/classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: Class Index 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 |
49 | 50 |
54 |
55 | 56 | 57 |
58 | 61 |
62 | 63 |
64 |
65 |
Class Index
66 |
67 |
68 |
C | R
69 |
70 |
71 |
C
72 |
CppTimer
CppTimerCallback
73 |
74 |
R
75 |
CppTimerCallback::Runnable
76 |
77 |
78 | 79 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /docs/closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/closed.png -------------------------------------------------------------------------------- /docs/doc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/doc.png -------------------------------------------------------------------------------- /docs/doxygen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/doxygen.png -------------------------------------------------------------------------------- /docs/dynsections.js: -------------------------------------------------------------------------------- 1 | /* 2 | @licstart The following is the entire license notice for the JavaScript code in this file. 3 | 4 | The MIT License (MIT) 5 | 6 | Copyright (C) 1997-2020 by Dimitri van Heesch 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software 9 | and associated documentation files (the "Software"), to deal in the Software without restriction, 10 | including without limitation the rights to use, copy, modify, merge, publish, distribute, 11 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all copies or 15 | substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 18 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | @licend The above is the entire license notice for the JavaScript code in this file 24 | */ 25 | function toggleVisibility(linkObj) 26 | { 27 | var base = $(linkObj).attr('id'); 28 | var summary = $('#'+base+'-summary'); 29 | var content = $('#'+base+'-content'); 30 | var trigger = $('#'+base+'-trigger'); 31 | var src=$(trigger).attr('src'); 32 | if (content.is(':visible')===true) { 33 | content.hide(); 34 | summary.show(); 35 | $(linkObj).addClass('closed').removeClass('opened'); 36 | $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); 37 | } else { 38 | content.show(); 39 | summary.hide(); 40 | $(linkObj).removeClass('closed').addClass('opened'); 41 | $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); 42 | } 43 | return false; 44 | } 45 | 46 | function updateStripes() 47 | { 48 | $('table.directory tr'). 49 | removeClass('even').filter(':visible:even').addClass('even'); 50 | } 51 | 52 | function toggleLevel(level) 53 | { 54 | $('table.directory tr').each(function() { 55 | var l = this.id.split('_').length-1; 56 | var i = $('#img'+this.id.substring(3)); 57 | var a = $('#arr'+this.id.substring(3)); 58 | if (l 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: File List 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 |
49 | 50 |
54 |
55 | 56 | 57 |
58 | 61 |
62 | 63 |
64 |
65 |
File List
66 |
67 |
68 |
Here is a list of all documented files with brief descriptions:
69 | 70 | 71 | 72 |
 CppTimer.h
 CppTimerCallback.h
73 |
74 |
75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /docs/folderclosed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/folderclosed.png -------------------------------------------------------------------------------- /docs/folderopen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/folderopen.png -------------------------------------------------------------------------------- /docs/functions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: Class Members 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 |
49 | 50 |
54 |
55 | 56 | 57 |
58 | 61 |
62 | 63 |
64 |
Here is a list of all documented class members with links to the class documentation for each member:
82 |
83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /docs/functions_func.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: Class Members - Functions 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 |
49 | 50 |
54 |
55 | 56 | 57 |
58 | 61 |
62 | 63 |
64 |   82 |
83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /docs/hierarchy.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: Class Hierarchy 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 |
49 | 50 |
54 |
55 | 56 | 57 |
58 | 61 |
62 | 63 |
64 |
65 |
Class Hierarchy
66 |
67 |
68 |
This inheritance list is sorted roughly, but not completely, alphabetically:
69 |
[detail level 12]
70 | 71 | 72 | 73 |
 CCppTimer
 CCppTimerCallback
 CCppTimerCallback::Runnable
74 |
75 |
76 | 77 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: Main Page 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 |
49 | 50 |
54 |
55 | 56 | 57 |
58 | 61 |
62 | 63 |
64 |
65 |
CppTimer Documentation
66 |
67 |
68 |
69 | 70 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /docs/md_README.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: CppTimer 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 27 | 28 | 29 |
24 |
CppTimer 25 |
26 |
30 |
31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 | 49 |
53 |
54 | 55 | 56 |
57 | 60 |
61 | 62 |
63 |
64 |
65 |
66 |
67 |
68 |

Generic C++ Timer for Linux

69 |

It's a wrapper around the Linux timers. There are two ways of using the timer: by overloading the timerEvent() method in the CppTimer class itself (fastest) or by registering a callback class called Runnable with an overloaded run() method.

70 |

71 | Installation

72 |
cmake .
73 |
make
74 |
sudo make install
75 |

76 | Usage (overloading the timer event)

77 |

The doxygen generated online docs are here: https://berndporr.github.io/cppTimer/

78 |

Include CppTimer.h in your program. That's it.

TARGET_LINK_LIBRARIES(your_project_title cpptimer rt)
79 |

80 | Create the Timer class

81 |
class MyTimer : public CppTimer {
82 |
83 |
void timerEvent() {
84 |
// your timer event code here
85 |
}
86 |
};
87 |

where you override timerEvent with your function.

88 |

89 | Run the Timer class

90 |

The timer is programmed in nanoseconds:

MyTimer myTimer;
91 |
// every 500000ns
92 |
myTimer.startns(500000);
93 |

or milliseconds:

// every 200ms
94 |
myTimer.startms(200);
95 |

As soon as start returns the timer fires instantly and then at the specified interval.

96 |

97 | Demo program

98 |

To run demo.cpp just do cmake ., make and then ./demo.

99 |

100 | Callback version

101 |

Instead of overloading the run() method in the timer class you can overload the run() method in the Runnable class and then register this class with the timer class. Check out demo_runnable which demonstrates how to use this method.

102 |

103 | Unit tests

104 |

Run:

105 |
ctest
106 |

That's it. Enjoy!

107 |
108 |
109 | 110 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /docs/menu.js: -------------------------------------------------------------------------------- 1 | /* 2 | @licstart The following is the entire license notice for the JavaScript code in this file. 3 | 4 | The MIT License (MIT) 5 | 6 | Copyright (C) 1997-2020 by Dimitri van Heesch 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software 9 | and associated documentation files (the "Software"), to deal in the Software without restriction, 10 | including without limitation the rights to use, copy, modify, merge, publish, distribute, 11 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all copies or 15 | substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 18 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | @licend The above is the entire license notice for the JavaScript code in this file 24 | */ 25 | function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { 26 | function makeTree(data,relPath) { 27 | var result=''; 28 | if ('children' in data) { 29 | result+=''; 36 | } 37 | return result; 38 | } 39 | 40 | $('#main-nav').append(makeTree(menudata,relPath)); 41 | $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); 42 | if (searchEnabled) { 43 | if (serverSide) { 44 | $('#main-menu').append('
  • '); 45 | } else { 46 | $('#main-menu').append('
  • '); 47 | } 48 | } 49 | $('#main-menu').smartmenus(); 50 | } 51 | /* @license-end */ 52 | -------------------------------------------------------------------------------- /docs/menudata.js: -------------------------------------------------------------------------------- 1 | /* 2 | @licstart The following is the entire license notice for the JavaScript code in this file. 3 | 4 | The MIT License (MIT) 5 | 6 | Copyright (C) 1997-2020 by Dimitri van Heesch 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software 9 | and associated documentation files (the "Software"), to deal in the Software without restriction, 10 | including without limitation the rights to use, copy, modify, merge, publish, distribute, 11 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all copies or 15 | substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 18 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | @licend The above is the entire license notice for the JavaScript code in this file 24 | */ 25 | var menudata={children:[ 26 | {text:"Main Page",url:"index.html"}, 27 | {text:"Related Pages",url:"pages.html"}, 28 | {text:"Classes",url:"annotated.html",children:[ 29 | {text:"Class List",url:"annotated.html"}, 30 | {text:"Class Index",url:"classes.html"}, 31 | {text:"Class Hierarchy",url:"hierarchy.html"}, 32 | {text:"Class Members",url:"functions.html",children:[ 33 | {text:"All",url:"functions.html"}, 34 | {text:"Functions",url:"functions_func.html"}]}]}, 35 | {text:"Files",url:"files.html",children:[ 36 | {text:"File List",url:"files.html"}]}]} 37 | -------------------------------------------------------------------------------- /docs/nav_f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/nav_f.png -------------------------------------------------------------------------------- /docs/nav_g.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/nav_g.png -------------------------------------------------------------------------------- /docs/nav_h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/nav_h.png -------------------------------------------------------------------------------- /docs/open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/open.png -------------------------------------------------------------------------------- /docs/pages.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CppTimer: Related Pages 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
    19 |
    20 | 21 | 22 | 23 | 27 | 28 | 29 |
    24 |
    CppTimer 25 |
    26 |
    30 |
    31 | 32 | 33 | 38 | 39 | 40 | 47 | 48 |
    49 | 50 |
    54 |
    55 | 56 | 57 |
    58 | 61 |
    62 | 63 |
    64 |
    65 |
    Related Pages
    66 |
    67 |
    68 |
    Here is a list of all related documentation pages:
    69 | 70 | 71 |
     CppTimer
    72 |
    73 |
    74 | 75 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /docs/pdf/refman.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/pdf/refman.pdf -------------------------------------------------------------------------------- /docs/search/all_0.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 |
    Loading...
    13 |
    14 | 19 |
    Searching...
    20 |
    No Matches
    21 | 35 |
    36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/search/all_0.js: -------------------------------------------------------------------------------- 1 | var searchData= 2 | [ 3 | ['cpptimer_0',['CppTimer',['../classCppTimer.html',1,'CppTimer'],['../md_README.html',1,'(Global Namespace)']]], 4 | ['cpptimercallback_1',['CppTimerCallback',['../classCppTimerCallback.html',1,'']]] 5 | ]; 6 | -------------------------------------------------------------------------------- /docs/search/all_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 |
    Loading...
    13 |
    14 | 19 |
    Searching...
    20 |
    No Matches
    21 | 35 |
    36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/search/all_1.js: -------------------------------------------------------------------------------- 1 | var searchData= 2 | [ 3 | ['runnable_2',['Runnable',['../classCppTimerCallback_1_1Runnable.html',1,'CppTimerCallback']]] 4 | ]; 5 | -------------------------------------------------------------------------------- /docs/search/all_2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 |
    Loading...
    13 |
    14 | 19 |
    Searching...
    20 |
    No Matches
    21 | 35 |
    36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/search/all_2.js: -------------------------------------------------------------------------------- 1 | var searchData= 2 | [ 3 | ['startms_3',['startms',['../classCppTimer.html#a8054cc8cead2e360b06b6ff99cc964cf',1,'CppTimer']]], 4 | ['startns_4',['startns',['../classCppTimer.html#a7de6bd2c8c9b5daa70d5c3d9b97fa49b',1,'CppTimer']]], 5 | ['stop_5',['stop',['../classCppTimer.html#aafb86e2bb43311bf154867dd6da43e80',1,'CppTimer']]] 6 | ]; 7 | -------------------------------------------------------------------------------- /docs/search/all_3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 |
    Loading...
    13 |
    14 | 19 |
    Searching...
    20 |
    No Matches
    21 | 35 |
    36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/search/all_3.js: -------------------------------------------------------------------------------- 1 | var searchData= 2 | [ 3 | ['timerevent_6',['timerEvent',['../classCppTimer.html#ac2665403595b6aee5f581d0ebfeb886c',1,'CppTimer::timerEvent()'],['../classCppTimerCallback.html#af6b39f5eb8e98bfc1b301ac3f25276e9',1,'CppTimerCallback::timerEvent()']]] 4 | ]; 5 | -------------------------------------------------------------------------------- /docs/search/all_4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 |
    Loading...
    13 |
    14 | 19 |
    Searching...
    20 |
    No Matches
    21 | 35 |
    36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/search/all_4.js: -------------------------------------------------------------------------------- 1 | var searchData= 2 | [ 3 | ['_7ecpptimer_7',['~CppTimer',['../classCppTimer.html#a2942aab831713273a76218048fe61b16',1,'CppTimer']]] 4 | ]; 5 | -------------------------------------------------------------------------------- /docs/search/classes_0.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 |
    Loading...
    13 |
    14 | 19 |
    Searching...
    20 |
    No Matches
    21 | 35 |
    36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/search/classes_0.js: -------------------------------------------------------------------------------- 1 | var searchData= 2 | [ 3 | ['cpptimer_8',['CppTimer',['../classCppTimer.html',1,'']]], 4 | ['cpptimercallback_9',['CppTimerCallback',['../classCppTimerCallback.html',1,'']]] 5 | ]; 6 | -------------------------------------------------------------------------------- /docs/search/classes_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 |
    Loading...
    13 |
    14 | 19 |
    Searching...
    20 |
    No Matches
    21 | 35 |
    36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/search/classes_1.js: -------------------------------------------------------------------------------- 1 | var searchData= 2 | [ 3 | ['runnable_10',['Runnable',['../classCppTimerCallback_1_1Runnable.html',1,'CppTimerCallback']]] 4 | ]; 5 | -------------------------------------------------------------------------------- /docs/search/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/search/close.png -------------------------------------------------------------------------------- /docs/search/functions_0.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 |
    Loading...
    13 |
    14 | 19 |
    Searching...
    20 |
    No Matches
    21 | 35 |
    36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/search/functions_0.js: -------------------------------------------------------------------------------- 1 | var searchData= 2 | [ 3 | ['startms_11',['startms',['../classCppTimer.html#a8054cc8cead2e360b06b6ff99cc964cf',1,'CppTimer']]], 4 | ['startns_12',['startns',['../classCppTimer.html#a7de6bd2c8c9b5daa70d5c3d9b97fa49b',1,'CppTimer']]], 5 | ['stop_13',['stop',['../classCppTimer.html#aafb86e2bb43311bf154867dd6da43e80',1,'CppTimer']]] 6 | ]; 7 | -------------------------------------------------------------------------------- /docs/search/functions_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 |
    Loading...
    13 |
    14 | 19 |
    Searching...
    20 |
    No Matches
    21 | 35 |
    36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/search/functions_1.js: -------------------------------------------------------------------------------- 1 | var searchData= 2 | [ 3 | ['timerevent_14',['timerEvent',['../classCppTimer.html#ac2665403595b6aee5f581d0ebfeb886c',1,'CppTimer::timerEvent()'],['../classCppTimerCallback.html#af6b39f5eb8e98bfc1b301ac3f25276e9',1,'CppTimerCallback::timerEvent()']]] 4 | ]; 5 | -------------------------------------------------------------------------------- /docs/search/functions_2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 |
    Loading...
    13 |
    14 | 19 |
    Searching...
    20 |
    No Matches
    21 | 35 |
    36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/search/functions_2.js: -------------------------------------------------------------------------------- 1 | var searchData= 2 | [ 3 | ['_7ecpptimer_15',['~CppTimer',['../classCppTimer.html#a2942aab831713273a76218048fe61b16',1,'CppTimer']]] 4 | ]; 5 | -------------------------------------------------------------------------------- /docs/search/functions_3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
    11 |
    Loading...
    12 |
    13 | 16 |
    Searching...
    17 |
    No Matches
    18 | 24 |
    25 | 26 | 27 | -------------------------------------------------------------------------------- /docs/search/functions_3.js: -------------------------------------------------------------------------------- 1 | var searchData= 2 | [ 3 | ['_7ecpptimer',['~CppTimer',['../classCppTimer.html#a2942aab831713273a76218048fe61b16',1,'CppTimer']]] 4 | ]; 5 | -------------------------------------------------------------------------------- /docs/search/mag_sel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berndporr/cppTimer/3aad9dca154e67bc92624bc2f59feae4d7bb6f2c/docs/search/mag_sel.png -------------------------------------------------------------------------------- /docs/search/nomatches.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
    10 |
    No Matches
    11 |
    12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/search/pages_0.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 |
    Loading...
    13 |
    14 | 19 |
    Searching...
    20 |
    No Matches
    21 | 35 |
    36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/search/pages_0.js: -------------------------------------------------------------------------------- 1 | var searchData= 2 | [ 3 | ['cpptimer_16',['CppTimer',['../md_README.html',1,'']]] 4 | ]; 5 | -------------------------------------------------------------------------------- /docs/search/search.css: -------------------------------------------------------------------------------- 1 | /*---------------- Search Box */ 2 | 3 | #MSearchBox { 4 | white-space : nowrap; 5 | background: white; 6 | border-radius: 0.65em; 7 | box-shadow: inset 0.5px 0.5px 3px 0px #555; 8 | z-index: 102; 9 | } 10 | 11 | #MSearchBox .left { 12 | display: inline-block; 13 | vertical-align: middle; 14 | height: 1.4em; 15 | } 16 | 17 | #MSearchSelect { 18 | display: inline-block; 19 | vertical-align: middle; 20 | height: 1.4em; 21 | padding: 0 0 0 0.3em; 22 | margin: 0; 23 | } 24 | 25 | #MSearchField { 26 | display: inline-block; 27 | vertical-align: middle; 28 | width: 7.5em; 29 | height: 1.1em; 30 | margin: 0 0.15em; 31 | padding: 0; 32 | line-height: 1em; 33 | border:none; 34 | color: #909090; 35 | outline: none; 36 | font-family: Arial, Verdana, sans-serif; 37 | -webkit-border-radius: 0px; 38 | border-radius: 0px; 39 | background: none; 40 | } 41 | 42 | 43 | #MSearchBox .right { 44 | display: inline-block; 45 | vertical-align: middle; 46 | width: 1.4em; 47 | height: 1.4em; 48 | } 49 | 50 | #MSearchClose { 51 | display: none; 52 | font-size: inherit; 53 | background : none; 54 | border: none; 55 | margin: 0; 56 | padding: 0; 57 | outline: none; 58 | 59 | } 60 | 61 | #MSearchCloseImg { 62 | height: 1.4em; 63 | padding: 0.3em; 64 | margin: 0; 65 | } 66 | 67 | .MSearchBoxActive #MSearchField { 68 | color: #000000; 69 | } 70 | 71 | #main-menu > li:last-child { 72 | /* This
  • object is the parent of the search bar */ 73 | display: flex; 74 | justify-content: center; 75 | align-items: center; 76 | height: 36px; 77 | margin-right: 1em; 78 | } 79 | 80 | /*---------------- Search filter selection */ 81 | 82 | #MSearchSelectWindow { 83 | display: none; 84 | position: absolute; 85 | left: 0; top: 0; 86 | border: 1px solid #90A5CE; 87 | background-color: #F9FAFC; 88 | z-index: 10001; 89 | padding-top: 4px; 90 | padding-bottom: 4px; 91 | -moz-border-radius: 4px; 92 | -webkit-border-top-left-radius: 4px; 93 | -webkit-border-top-right-radius: 4px; 94 | -webkit-border-bottom-left-radius: 4px; 95 | -webkit-border-bottom-right-radius: 4px; 96 | -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); 97 | } 98 | 99 | .SelectItem { 100 | font: 8pt Arial, Verdana, sans-serif; 101 | padding-left: 2px; 102 | padding-right: 12px; 103 | border: 0px; 104 | } 105 | 106 | span.SelectionMark { 107 | margin-right: 4px; 108 | font-family: monospace; 109 | outline-style: none; 110 | text-decoration: none; 111 | } 112 | 113 | a.SelectItem { 114 | display: block; 115 | outline-style: none; 116 | color: #000000; 117 | text-decoration: none; 118 | padding-left: 6px; 119 | padding-right: 12px; 120 | } 121 | 122 | a.SelectItem:focus, 123 | a.SelectItem:active { 124 | color: #000000; 125 | outline-style: none; 126 | text-decoration: none; 127 | } 128 | 129 | a.SelectItem:hover { 130 | color: #FFFFFF; 131 | background-color: #3D578C; 132 | outline-style: none; 133 | text-decoration: none; 134 | cursor: pointer; 135 | display: block; 136 | } 137 | 138 | /*---------------- Search results window */ 139 | 140 | iframe#MSearchResults { 141 | width: 60ex; 142 | height: 15em; 143 | } 144 | 145 | #MSearchResultsWindow { 146 | display: none; 147 | position: absolute; 148 | left: 0; top: 0; 149 | border: 1px solid #000; 150 | background-color: #EEF1F7; 151 | z-index:10000; 152 | } 153 | 154 | /* ----------------------------------- */ 155 | 156 | 157 | #SRIndex { 158 | clear:both; 159 | padding-bottom: 15px; 160 | } 161 | 162 | .SREntry { 163 | font-size: 10pt; 164 | padding-left: 1ex; 165 | } 166 | 167 | .SRPage .SREntry { 168 | font-size: 8pt; 169 | padding: 1px 5px; 170 | } 171 | 172 | body.SRPage { 173 | margin: 5px 2px; 174 | } 175 | 176 | .SRChildren { 177 | padding-left: 3ex; padding-bottom: .5em 178 | } 179 | 180 | .SRPage .SRChildren { 181 | display: none; 182 | } 183 | 184 | .SRSymbol { 185 | font-weight: bold; 186 | color: #425E97; 187 | font-family: Arial, Verdana, sans-serif; 188 | text-decoration: none; 189 | outline: none; 190 | } 191 | 192 | a.SRScope { 193 | display: block; 194 | color: #425E97; 195 | font-family: Arial, Verdana, sans-serif; 196 | text-decoration: none; 197 | outline: none; 198 | } 199 | 200 | a.SRSymbol:focus, a.SRSymbol:active, 201 | a.SRScope:focus, a.SRScope:active { 202 | text-decoration: underline; 203 | } 204 | 205 | span.SRScope { 206 | padding-left: 4px; 207 | font-family: Arial, Verdana, sans-serif; 208 | } 209 | 210 | .SRPage .SRStatus { 211 | padding: 2px 5px; 212 | font-size: 8pt; 213 | font-style: italic; 214 | font-family: Arial, Verdana, sans-serif; 215 | } 216 | 217 | .SRResult { 218 | display: none; 219 | } 220 | 221 | div.searchresults { 222 | margin-left: 10px; 223 | margin-right: 10px; 224 | } 225 | 226 | /*---------------- External search page results */ 227 | 228 | .searchresult { 229 | background-color: #F0F3F8; 230 | } 231 | 232 | .pages b { 233 | color: white; 234 | padding: 5px 5px 3px 5px; 235 | background-image: url("../tab_a.png"); 236 | background-repeat: repeat-x; 237 | text-shadow: 0 1px 1px #000000; 238 | } 239 | 240 | .pages { 241 | line-height: 17px; 242 | margin-left: 4px; 243 | text-decoration: none; 244 | } 245 | 246 | .hl { 247 | font-weight: bold; 248 | } 249 | 250 | #searchresults { 251 | margin-bottom: 20px; 252 | } 253 | 254 | .searchpages { 255 | margin-top: 10px; 256 | } 257 | 258 | -------------------------------------------------------------------------------- /docs/search/search.js: -------------------------------------------------------------------------------- 1 | /* 2 | @licstart The following is the entire license notice for the JavaScript code in this file. 3 | 4 | The MIT License (MIT) 5 | 6 | Copyright (C) 1997-2020 by Dimitri van Heesch 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software 9 | and associated documentation files (the "Software"), to deal in the Software without restriction, 10 | including without limitation the rights to use, copy, modify, merge, publish, distribute, 11 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all copies or 15 | substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 18 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | @licend The above is the entire license notice for the JavaScript code in this file 24 | */ 25 | function convertToId(search) 26 | { 27 | var result = ''; 28 | for (i=0;i do a search 287 | { 288 | this.Search(); 289 | } 290 | } 291 | 292 | this.OnSearchSelectKey = function(evt) 293 | { 294 | var e = (evt) ? evt : window.event; // for IE 295 | if (e.keyCode==40 && this.searchIndex0) // Up 301 | { 302 | this.searchIndex--; 303 | this.OnSelectItem(this.searchIndex); 304 | } 305 | else if (e.keyCode==13 || e.keyCode==27) 306 | { 307 | this.OnSelectItem(this.searchIndex); 308 | this.CloseSelectionWindow(); 309 | this.DOMSearchField().focus(); 310 | } 311 | return false; 312 | } 313 | 314 | // --------- Actions 315 | 316 | // Closes the results window. 317 | this.CloseResultsWindow = function() 318 | { 319 | this.DOMPopupSearchResultsWindow().style.display = 'none'; 320 | this.DOMSearchClose().style.display = 'none'; 321 | this.Activate(false); 322 | } 323 | 324 | this.CloseSelectionWindow = function() 325 | { 326 | this.DOMSearchSelectWindow().style.display = 'none'; 327 | } 328 | 329 | // Performs a search. 330 | this.Search = function() 331 | { 332 | this.keyTimeout = 0; 333 | 334 | // strip leading whitespace 335 | var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); 336 | 337 | var code = searchValue.toLowerCase().charCodeAt(0); 338 | var idxChar = searchValue.substr(0, 1).toLowerCase(); 339 | if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair 340 | { 341 | idxChar = searchValue.substr(0, 2); 342 | } 343 | 344 | var resultsPage; 345 | var resultsPageWithSearch; 346 | var hasResultsPage; 347 | 348 | var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); 349 | if (idx!=-1) 350 | { 351 | var hexCode=idx.toString(16); 352 | resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + this.extension; 353 | resultsPageWithSearch = resultsPage+'?'+escape(searchValue); 354 | hasResultsPage = true; 355 | } 356 | else // nothing available for this search term 357 | { 358 | resultsPage = this.resultsPath + '/nomatches' + this.extension; 359 | resultsPageWithSearch = resultsPage; 360 | hasResultsPage = false; 361 | } 362 | 363 | window.frames.MSearchResults.location = resultsPageWithSearch; 364 | var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); 365 | 366 | if (domPopupSearchResultsWindow.style.display!='block') 367 | { 368 | var domSearchBox = this.DOMSearchBox(); 369 | this.DOMSearchClose().style.display = 'inline-block'; 370 | if (this.insideFrame) 371 | { 372 | var domPopupSearchResults = this.DOMPopupSearchResults(); 373 | domPopupSearchResultsWindow.style.position = 'relative'; 374 | domPopupSearchResultsWindow.style.display = 'block'; 375 | var width = document.body.clientWidth - 8; // the -8 is for IE :-( 376 | domPopupSearchResultsWindow.style.width = width + 'px'; 377 | domPopupSearchResults.style.width = width + 'px'; 378 | } 379 | else 380 | { 381 | var domPopupSearchResults = this.DOMPopupSearchResults(); 382 | var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; 383 | var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; 384 | domPopupSearchResultsWindow.style.display = 'block'; 385 | left -= domPopupSearchResults.offsetWidth; 386 | domPopupSearchResultsWindow.style.top = top + 'px'; 387 | domPopupSearchResultsWindow.style.left = left + 'px'; 388 | } 389 | } 390 | 391 | this.lastSearchValue = searchValue; 392 | this.lastResultsPage = resultsPage; 393 | } 394 | 395 | // -------- Activation Functions 396 | 397 | // Activates or deactivates the search panel, resetting things to 398 | // their default values if necessary. 399 | this.Activate = function(isActive) 400 | { 401 | if (isActive || // open it 402 | this.DOMPopupSearchResultsWindow().style.display == 'block' 403 | ) 404 | { 405 | this.DOMSearchBox().className = 'MSearchBoxActive'; 406 | 407 | var searchField = this.DOMSearchField(); 408 | 409 | if (searchField.value == this.searchLabel) // clear "Search" term upon entry 410 | { 411 | searchField.value = ''; 412 | this.searchActive = true; 413 | } 414 | } 415 | else if (!isActive) // directly remove the panel 416 | { 417 | this.DOMSearchBox().className = 'MSearchBoxInactive'; 418 | this.DOMSearchField().value = this.searchLabel; 419 | this.searchActive = false; 420 | this.lastSearchValue = '' 421 | this.lastResultsPage = ''; 422 | } 423 | } 424 | } 425 | 426 | // ----------------------------------------------------------------------- 427 | 428 | // The class that handles everything on the search results page. 429 | function SearchResults(name) 430 | { 431 | // The number of matches from the last run of . 432 | this.lastMatchCount = 0; 433 | this.lastKey = 0; 434 | this.repeatOn = false; 435 | 436 | // Toggles the visibility of the passed element ID. 437 | this.FindChildElement = function(id) 438 | { 439 | var parentElement = document.getElementById(id); 440 | var element = parentElement.firstChild; 441 | 442 | while (element && element!=parentElement) 443 | { 444 | if (element.nodeName.toLowerCase() == 'div' && element.className == 'SRChildren') 445 | { 446 | return element; 447 | } 448 | 449 | if (element.nodeName.toLowerCase() == 'div' && element.hasChildNodes()) 450 | { 451 | element = element.firstChild; 452 | } 453 | else if (element.nextSibling) 454 | { 455 | element = element.nextSibling; 456 | } 457 | else 458 | { 459 | do 460 | { 461 | element = element.parentNode; 462 | } 463 | while (element && element!=parentElement && !element.nextSibling); 464 | 465 | if (element && element!=parentElement) 466 | { 467 | element = element.nextSibling; 468 | } 469 | } 470 | } 471 | } 472 | 473 | this.Toggle = function(id) 474 | { 475 | var element = this.FindChildElement(id); 476 | if (element) 477 | { 478 | if (element.style.display == 'block') 479 | { 480 | element.style.display = 'none'; 481 | } 482 | else 483 | { 484 | element.style.display = 'block'; 485 | } 486 | } 487 | } 488 | 489 | // Searches for the passed string. If there is no parameter, 490 | // it takes it from the URL query. 491 | // 492 | // Always returns true, since other documents may try to call it 493 | // and that may or may not be possible. 494 | this.Search = function(search) 495 | { 496 | if (!search) // get search word from URL 497 | { 498 | search = window.location.search; 499 | search = search.substring(1); // Remove the leading '?' 500 | search = unescape(search); 501 | } 502 | 503 | search = search.replace(/^ +/, ""); // strip leading spaces 504 | search = search.replace(/ +$/, ""); // strip trailing spaces 505 | search = search.toLowerCase(); 506 | search = convertToId(search); 507 | 508 | var resultRows = document.getElementsByTagName("div"); 509 | var matches = 0; 510 | 511 | var i = 0; 512 | while (i < resultRows.length) 513 | { 514 | var row = resultRows.item(i); 515 | if (row.className == "SRResult") 516 | { 517 | var rowMatchName = row.id.toLowerCase(); 518 | rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' 519 | 520 | if (search.length<=rowMatchName.length && 521 | rowMatchName.substr(0, search.length)==search) 522 | { 523 | row.style.display = 'block'; 524 | matches++; 525 | } 526 | else 527 | { 528 | row.style.display = 'none'; 529 | } 530 | } 531 | i++; 532 | } 533 | document.getElementById("Searching").style.display='none'; 534 | if (matches == 0) // no results 535 | { 536 | document.getElementById("NoMatches").style.display='block'; 537 | } 538 | else // at least one result 539 | { 540 | document.getElementById("NoMatches").style.display='none'; 541 | } 542 | this.lastMatchCount = matches; 543 | return true; 544 | } 545 | 546 | // return the first item with index index or higher that is visible 547 | this.NavNext = function(index) 548 | { 549 | var focusItem; 550 | while (1) 551 | { 552 | var focusName = 'Item'+index; 553 | focusItem = document.getElementById(focusName); 554 | if (focusItem && focusItem.parentNode.parentNode.style.display=='block') 555 | { 556 | break; 557 | } 558 | else if (!focusItem) // last element 559 | { 560 | break; 561 | } 562 | focusItem=null; 563 | index++; 564 | } 565 | return focusItem; 566 | } 567 | 568 | this.NavPrev = function(index) 569 | { 570 | var focusItem; 571 | while (1) 572 | { 573 | var focusName = 'Item'+index; 574 | focusItem = document.getElementById(focusName); 575 | if (focusItem && focusItem.parentNode.parentNode.style.display=='block') 576 | { 577 | break; 578 | } 579 | else if (!focusItem) // last element 580 | { 581 | break; 582 | } 583 | focusItem=null; 584 | index--; 585 | } 586 | return focusItem; 587 | } 588 | 589 | this.ProcessKeys = function(e) 590 | { 591 | if (e.type == "keydown") 592 | { 593 | this.repeatOn = false; 594 | this.lastKey = e.keyCode; 595 | } 596 | else if (e.type == "keypress") 597 | { 598 | if (!this.repeatOn) 599 | { 600 | if (this.lastKey) this.repeatOn = true; 601 | return false; // ignore first keypress after keydown 602 | } 603 | } 604 | else if (e.type == "keyup") 605 | { 606 | this.lastKey = 0; 607 | this.repeatOn = false; 608 | } 609 | return this.lastKey!=0; 610 | } 611 | 612 | this.Nav = function(evt,itemIndex) 613 | { 614 | var e = (evt) ? evt : window.event; // for IE 615 | if (e.keyCode==13) return true; 616 | if (!this.ProcessKeys(e)) return false; 617 | 618 | if (this.lastKey==38) // Up 619 | { 620 | var newIndex = itemIndex-1; 621 | var focusItem = this.NavPrev(newIndex); 622 | if (focusItem) 623 | { 624 | var child = this.FindChildElement(focusItem.parentNode.parentNode.id); 625 | if (child && child.style.display == 'block') // children visible 626 | { 627 | var n=0; 628 | var tmpElem; 629 | while (1) // search for last child 630 | { 631 | tmpElem = document.getElementById('Item'+newIndex+'_c'+n); 632 | if (tmpElem) 633 | { 634 | focusItem = tmpElem; 635 | } 636 | else // found it! 637 | { 638 | break; 639 | } 640 | n++; 641 | } 642 | } 643 | } 644 | if (focusItem) 645 | { 646 | focusItem.focus(); 647 | } 648 | else // return focus to search field 649 | { 650 | parent.document.getElementById("MSearchField").focus(); 651 | } 652 | } 653 | else if (this.lastKey==40) // Down 654 | { 655 | var newIndex = itemIndex+1; 656 | var focusItem; 657 | var item = document.getElementById('Item'+itemIndex); 658 | var elem = this.FindChildElement(item.parentNode.parentNode.id); 659 | if (elem && elem.style.display == 'block') // children visible 660 | { 661 | focusItem = document.getElementById('Item'+itemIndex+'_c0'); 662 | } 663 | if (!focusItem) focusItem = this.NavNext(newIndex); 664 | if (focusItem) focusItem.focus(); 665 | } 666 | else if (this.lastKey==39) // Right 667 | { 668 | var item = document.getElementById('Item'+itemIndex); 669 | var elem = this.FindChildElement(item.parentNode.parentNode.id); 670 | if (elem) elem.style.display = 'block'; 671 | } 672 | else if (this.lastKey==37) // Left 673 | { 674 | var item = document.getElementById('Item'+itemIndex); 675 | var elem = this.FindChildElement(item.parentNode.parentNode.id); 676 | if (elem) elem.style.display = 'none'; 677 | } 678 | else if (this.lastKey==27) // Escape 679 | { 680 | parent.searchBox.CloseResultsWindow(); 681 | parent.document.getElementById("MSearchField").focus(); 682 | } 683 | else if (this.lastKey==13) // Enter 684 | { 685 | return true; 686 | } 687 | return false; 688 | } 689 | 690 | this.NavChild = function(evt,itemIndex,childIndex) 691 | { 692 | var e = (evt) ? evt : window.event; // for IE 693 | if (e.keyCode==13) return true; 694 | if (!this.ProcessKeys(e)) return false; 695 | 696 | if (this.lastKey==38) // Up 697 | { 698 | if (childIndex>0) 699 | { 700 | var newIndex = childIndex-1; 701 | document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); 702 | } 703 | else // already at first child, jump to parent 704 | { 705 | document.getElementById('Item'+itemIndex).focus(); 706 | } 707 | } 708 | else if (this.lastKey==40) // Down 709 | { 710 | var newIndex = childIndex+1; 711 | var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); 712 | if (!elem) // last child, jump to parent next parent 713 | { 714 | elem = this.NavNext(itemIndex+1); 715 | } 716 | if (elem) 717 | { 718 | elem.focus(); 719 | } 720 | } 721 | else if (this.lastKey==27) // Escape 722 | { 723 | parent.searchBox.CloseResultsWindow(); 724 | parent.document.getElementById("MSearchField").focus(); 725 | } 726 | else if (this.lastKey==13) // Enter 727 | { 728 | return true; 729 | } 730 | return false; 731 | } 732 | } 733 | 734 | function setKeyActions(elem,action) 735 | { 736 | elem.setAttribute('onkeydown',action); 737 | elem.setAttribute('onkeypress',action); 738 | elem.setAttribute('onkeyup',action); 739 | } 740 | 741 | function setClassAttr(elem,attr) 742 | { 743 | elem.setAttribute('class',attr); 744 | elem.setAttribute('className',attr); 745 | } 746 | 747 | function createResults() 748 | { 749 | var results = document.getElementById("SRResults"); 750 | for (var e=0; eli>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0px/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0px 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0px 1px 1px rgba(255,255,255,0.9);color:#283A5D;outline:none}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a.current{color:#D23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media (min-width: 768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283A5D transparent transparent transparent;background:transparent;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0px 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;border-radius:0 !important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a:hover span.sub-arrow{border-color:#fff transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;border-radius:5px !important;box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0 !important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent #fff}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #D23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#D23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} 2 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.6) 2 | enable_testing() 3 | include_directories( 4 | .. 5 | ) 6 | 7 | add_executable (test_startstop startstop.cpp) 8 | TARGET_LINK_LIBRARIES(test_startstop cpptimer) 9 | add_test(TestStartStop test_startstop) 10 | 11 | add_executable (test_twotimers twotimers.cpp) 12 | TARGET_LINK_LIBRARIES(test_twotimers cpptimer) 13 | add_test(TestTwotimers test_twotimers) 14 | 15 | add_executable (test_startstop_ms startstop_ms.cpp) 16 | TARGET_LINK_LIBRARIES(test_startstop_ms cpptimer) 17 | add_test(TestStartStop_ms test_startstop_ms) 18 | 19 | add_executable (test_twotimers_ms twotimers_ms.cpp) 20 | TARGET_LINK_LIBRARIES(test_twotimers_ms cpptimer) 21 | add_test(TestTwotimers_ms test_twotimers_ms) 22 | 23 | add_executable (test_oneshot oneshot.cpp) 24 | TARGET_LINK_LIBRARIES(test_oneshot cpptimer) 25 | add_test(TestOneShot test_oneshot) 26 | -------------------------------------------------------------------------------- /test/oneshot.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "CppTimer.h" 3 | #include 4 | #include 5 | #include 6 | 7 | class DemoTimer1 : public CppTimer { 8 | 9 | public: 10 | bool hasFired = false; 11 | void timerEvent() { 12 | fprintf(stdout,"."); 13 | fflush(stdout); 14 | hasFired = true; 15 | } 16 | }; 17 | 18 | 19 | int main( int, const char** ) { 20 | DemoTimer1 demoTimer1; 21 | demoTimer1.startns(0.5E9,ONESHOT); 22 | 23 | std::this_thread::sleep_for(std::chrono::seconds(1)); 24 | 25 | if (!demoTimer1.hasFired) { 26 | char tmp[] = "nanosec Timer has not fired"; 27 | printf("%s\n",tmp); 28 | fflush(stdout); 29 | throw tmp; 30 | } 31 | 32 | demoTimer1.hasFired = false; 33 | 34 | demoTimer1.startms(0.5E3,ONESHOT); 35 | 36 | std::this_thread::sleep_for(std::chrono::seconds(1)); 37 | 38 | if (!demoTimer1.hasFired) { 39 | char tmp[] = "ms timer has not fired"; 40 | printf("%s\n",tmp); 41 | fflush(stdout); 42 | throw tmp; 43 | } 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /test/startstop.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "CppTimer.h" 3 | #include 4 | #include 5 | #include 6 | 7 | class DemoTimer1 : public CppTimer { 8 | 9 | void timerEvent() { 10 | fprintf(stdout,"."); 11 | fflush(stdout); 12 | } 13 | }; 14 | 15 | 16 | int main( int, const char** ) { 17 | DemoTimer1 demoTimer1; 18 | demoTimer1.startns(250000000); 19 | 20 | std::this_thread::sleep_for(std::chrono::seconds(1)); 21 | 22 | demoTimer1.stop(); 23 | 24 | std::this_thread::sleep_for(std::chrono::seconds(1)); 25 | 26 | demoTimer1.startns(25000000); 27 | 28 | std::this_thread::sleep_for(std::chrono::seconds(1)); 29 | 30 | demoTimer1.stop(); 31 | 32 | fprintf(stdout,"\n"); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /test/startstop_ms.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "CppTimer.h" 3 | #include 4 | #include 5 | #include 6 | 7 | class DemoTimer1 : public CppTimer { 8 | 9 | void timerEvent() { 10 | fprintf(stdout,"."); 11 | fflush(stdout); 12 | } 13 | }; 14 | 15 | 16 | int main( int, const char** ) { 17 | DemoTimer1 demoTimer1; 18 | demoTimer1.startms(500); 19 | 20 | std::this_thread::sleep_for(std::chrono::seconds(1)); 21 | 22 | demoTimer1.stop(); 23 | 24 | std::this_thread::sleep_for(std::chrono::seconds(1)); 25 | 26 | demoTimer1.startms(1500); 27 | 28 | std::this_thread::sleep_for(std::chrono::seconds(2)); 29 | 30 | demoTimer1.stop(); 31 | 32 | fprintf(stdout,"\n"); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /test/twotimers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "CppTimer.h" 3 | #include 4 | #include 5 | #include 6 | 7 | class DemoTimer1 : public CppTimer { 8 | public: 9 | void timerEvent() { 10 | counter++; 11 | fprintf(stdout,"1"); 12 | fflush(stdout); 13 | } 14 | void startns(long nanosecs) { 15 | counter = 0; 16 | CppTimer::startns(nanosecs); 17 | } 18 | int getCounter() {return counter;} 19 | private: 20 | int counter = 0; 21 | }; 22 | 23 | 24 | class DemoTimer2 : public CppTimer { 25 | public: 26 | DemoTimer1* demoTimer1; 27 | DemoTimer2(DemoTimer1* dt1) : CppTimer() { 28 | demoTimer1 = dt1; 29 | } 30 | void timerEvent() { 31 | fprintf(stdout,"2\n"); 32 | if (0 == demoTimer1->getCounter()) { 33 | const char tmp[] = "BUG! Timer one hasn't fired.\n"; 34 | fprintf(stderr,tmp); 35 | throw tmp; 36 | } 37 | } 38 | }; 39 | 40 | 41 | 42 | int main( int, const char**) { 43 | DemoTimer1 demoTimer1; 44 | demoTimer1.startns(100000000); 45 | DemoTimer2 demoTimer2(&demoTimer1); 46 | demoTimer2.startns(200000000); 47 | 48 | std::this_thread::sleep_for(std::chrono::seconds(1)); 49 | 50 | demoTimer1.stop(); 51 | demoTimer2.stop(); 52 | 53 | demoTimer1.startns(25000000); 54 | demoTimer2.startns(100000000); 55 | 56 | std::this_thread::sleep_for(std::chrono::seconds(1)); 57 | 58 | demoTimer1.stop(); 59 | demoTimer2.stop(); 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /test/twotimers_ms.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "CppTimer.h" 3 | #include 4 | #include 5 | #include 6 | 7 | class DemoTimer1 : public CppTimer { 8 | public: 9 | void timerEvent() { 10 | counter++; 11 | fprintf(stdout,"1"); 12 | fflush(stdout); 13 | } 14 | void start(long millisecs) { 15 | counter = 0; 16 | CppTimer::startms(millisecs); 17 | } 18 | int getCounter() {return counter;} 19 | private: 20 | int counter = 0; 21 | }; 22 | 23 | 24 | class DemoTimer2 : public CppTimer { 25 | public: 26 | DemoTimer1* demoTimer1; 27 | DemoTimer2(DemoTimer1* dt1) : CppTimer() { 28 | demoTimer1 = dt1; 29 | } 30 | void timerEvent() { 31 | fprintf(stdout,"2\n"); 32 | if (0 == demoTimer1->getCounter()) { 33 | const char tmp[] = "BUG! Timer one hasn't fired.\n"; 34 | fprintf(stderr,tmp); 35 | throw tmp; 36 | } 37 | } 38 | }; 39 | 40 | 41 | 42 | int main( int, const char**) { 43 | DemoTimer1 demoTimer1; 44 | demoTimer1.startms(100); 45 | DemoTimer2 demoTimer2(&demoTimer1); 46 | demoTimer2.startms(200); 47 | 48 | std::this_thread::sleep_for(std::chrono::seconds(1)); 49 | 50 | demoTimer1.stop(); 51 | demoTimer2.stop(); 52 | 53 | demoTimer1.startms(25); 54 | demoTimer2.startms(100); 55 | 56 | std::this_thread::sleep_for(std::chrono::seconds(1)); 57 | 58 | demoTimer1.stop(); 59 | demoTimer2.stop(); 60 | 61 | return 0; 62 | } 63 | --------------------------------------------------------------------------------