Skip to content

Commit

Permalink
Merge pull request #1 from connectivecpp/develop
Browse files Browse the repository at this point in the history
Merge develop to main
  • Loading branch information
cliffg-softwarelibre committed May 21, 2024
2 parents a685b0e + 2f7bc6d commit fcd60d5
Show file tree
Hide file tree
Showing 12 changed files with 3,449 additions and 2 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/build_run_unit_test_cmake.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Build, run unit tests
name: CMake build and run unit test matrix

on:
push:
branches:
- main
- develop
env:
BUILD_TYPE: Release
jobs:
build_matrix:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-14]
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash
steps:
- name: checkout
uses: actions/checkout@v4
- name: create-build-dir
run: mkdir build
- name: configure-cmake
run: cd build && cmake -D PERIODIC_TIMER_BUILD_TESTS:BOOL=ON ..
- name: build
run: cd build && cmake --build . --config $BUILD_TYPE
- name: run-unit-test
run: cd build && ctest -C $BUILD_TYPE
28 changes: 28 additions & 0 deletions .github/workflows/gen_docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Build, run unit tests
name: Generate documentation

on:
push:
branches:
- main
jobs:
build_matrix:
strategy:
matrix:
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash
steps:
- name: checkout
uses: actions/checkout@v4
- name: run-doxygen
uses: mattnotmitt/[email protected]
with:
working-directory: doc
- name: deploy-pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./doc/doc_output/html
57 changes: 57 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright (c) 2024 by Cliff Green
#
# https://github.com/connectivecpp/periodic-timer
#
# I'm still learning CMake, so improvement suggestions are always welcome.
#
# The Asio CMake code is taken from CPM.cmake examples/asio-standalone.
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

cmake_minimum_required ( VERSION 3.14 FATAL_ERROR )

project ( periodic_timer
LANGUAGES CXX
DESCRIPTION "An asynchronous periodic timer based on Asio"
HOMEPAGE_URL "https://github.com/connectivecpp/periodic-timer/" )

option ( PERIODIC_TIMER_BUILD_TESTS "Build unit tests" OFF )
option ( PERIODIC_TIMER_BUILD_EXAMPLES "Build examples" OFF )
option ( PERIODIC_TIMER_INSTALL "Install header only library" OFF )

# add library targets

add_library ( periodic_timer INTERFACE )
add_library ( chops::periodic_timer ALIAS periodic_timer )

# thread support specified in Asio download

include ( cmake/download_asio_cpm.cmake )

# configure library target

target_include_directories ( periodic_timer INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>
$<INSTALL_INTERFACE:include/> )
target_compile_features ( periodic_timer INTERFACE cxx_std_20 )

# check to build unit tests
if ( ${PERIODIC_TIMER_BUILD_TESTS} )
enable_testing()
add_subdirectory ( test )
endif ()

# check to build example code
if ( ${PERIODIC_TIMER_BUILD_EXAMPLES} )
add_subdirectory ( example )
endif ()

# check to install
if ( ${PERIODIC_TIMER_INSTALL} )
set ( CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt )
include ( CPack )
endif ()

# end of file

64 changes: 62 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,62 @@
# periodic-timer
An asynchronous periodic timer simplifying Asio timers, with function object timer callbacks
# Periodic Timer, a Header-Only C++ 20 Asynchronous Periodic Timer

#### Unit Test and Documentation Generation Workflow Status

![GH Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/connectivecpp/periodic-timer/build_run_unit_test_cmake.yml?branch=main&label=GH%20Actions%20build,%20unit%20tests%20on%20main)

![GH Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/connectivecpp/periodic-timer/build_run_unit_test_cmake.yml?branch=develop&label=GH%20Actions%20build,%20unit%20tests%20on%20develop)

![GH Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/connectivecpp/periodic-timer/gen_docs.yml?branch=main&label=GH%20Actions%20generate%20docs)

## Overview

`periodic_timer` is an asynchronous periodic timer that wraps and simplifies Asio timers when periodic callbacks are needed. The periodicity can be based on either a simple duration or on timepoints based on a duration.

Timepoint calculations are performed by this class template so that timepoint durations don't "drift". In other words, if the processing during a callback takes 15 milliseconds, the next callback invocation is adjusted accordingly.

Asynchronous timers from Asio are relatively easy to use. However, there are no timers that are periodic. This class simplifies the usage, using application supplied function object callbacks. When the timer is started, the application specifies whether each callback is invoked based on a duration (e.g. one second after the last callback), or on timepoints (e.g. a callback will be invoked each second according to the clock).

## Generated Documentation

The generated Doxygen documentation for `periodic_timer` is [here](https://connectivecpp.github.io/periodic-timer/).

## Dependencies

The `periodic_timer` header file has the stand-alone Asio library for a dependency. Specific version (or branch) specs for the Asio dependency is in `cmake/download_asio_cpm.cmake`.

## C++ Standard

`periodic_timer` is built under C++ 20, but (currently) does not use any specific C++ 20 features. In the future `concepts` / `requires` will be added.

## Supported Compilers

Continuous integration workflows build and unit test on g++ (through Ubuntu), MSVC (through Windows), and clang (through macOS).

## Unit Test Dependencies

The unit test code uses [Catch2](https://github.com/catchorg/Catch2). If the `PERIODIC_TIMER_BUILD_TESTS` flag is provided to Cmake (see commands below) the Cmake configure / generate will download the Catch2 library as appropriate using the [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake) dependency manager. If Catch2 (v3 or greater) is already installed using a different package manager (such as Conan or vcpkg), the `CPM_USE_LOCAL_PACKAGES` variable can be set which results in `find_package` being attempted. Note that v3 (or later) of Catch2 is required.

Specific version (or branch) specs for the Catch2 dependency is in `test/CMakeLists.txt`.

## Build and Run Unit Tests

To build and run the unit test program:

First clone the `periodic-timer` repository, then create a build directory in parallel to the `periodic-timer` directory (this is called "out of source" builds, which is recommended), then `cd` (change directory) into the build directory. The CMake commands:

```
cmake -D PERIODIC_TIMER_BUILD_TESTS:BOOL=ON ../periodic-timer
cmake --build .
ctest
```

For additional test output, run the unit test individually, for example:

```
test/periodic_timer_test -s
```

The example can be built by adding `-D PERIODIC_TIMER_BUILD_EXAMPLES:BOOL=ON` to the CMake configure / generate step.

64 changes: 64 additions & 0 deletions cmake/download_asio_cpm.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# This Asio CMake code is taken from CPM.cmake examples/asio-standalone.
#
# This code assumes it is run from a top-level CMakeLists.txt file,
# with a download_cpm.cmake file in a parallel cmake directory.
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

set ( CMAKE_THREAD_PREFER_PTHREAD TRUE )
set ( THREADS_PREFER_PTHREAD_FLAG TRUE )
find_package ( Threads REQUIRED )

include ( cmake/download_cpm.cmake )
CPMAddPackage ( "gh:chriskohlhoff/asio#[email protected]" )

# ASIO doesn't use CMake, we have to configure it manually. Extra notes for using on Windows:
#
# 1) If _WIN32_WINNT is not set, ASIO assumes _WIN32_WINNT=0x0501, i.e. Windows XP target, which is
# definitely not the platform which most users target.
#
# 2) WIN32_LEAN_AND_MEAN is defined to make Winsock2 work.

if(asio_ADDED)
add_library(asio INTERFACE)

target_include_directories(asio SYSTEM INTERFACE ${asio_SOURCE_DIR}/asio/include)

target_compile_definitions(asio INTERFACE ASIO_STANDALONE ASIO_NO_DEPRECATED)

target_link_libraries(asio INTERFACE Threads::Threads)

if(WIN32)
# macro see @ https://stackoverflow.com/a/40217291/1746503
macro(get_win32_winnt version)
if(CMAKE_SYSTEM_VERSION)
set(ver ${CMAKE_SYSTEM_VERSION})
string(REGEX MATCH "^([0-9]+).([0-9])" ver ${ver})
string(REGEX MATCH "^([0-9]+)" verMajor ${ver})
# Check for Windows 10, b/c we'll need to convert to hex 'A'.
if("${verMajor}" MATCHES "10")
set(verMajor "A")
string(REGEX REPLACE "^([0-9]+)" ${verMajor} ver ${ver})
endif("${verMajor}" MATCHES "10")
# Remove all remaining '.' characters.
string(REPLACE "." "" ver ${ver})
# Prepend each digit with a zero.
string(REGEX REPLACE "([0-9A-Z])" "0\\1" ver ${ver})
set(${version} "0x${ver}")
endif()
endmacro()

if(NOT DEFINED _WIN32_WINNT)
get_win32_winnt(ver)
set(_WIN32_WINNT ${ver})
endif()

message(STATUS "Set _WIN32_WINNET=${_WIN32_WINNT}")

target_compile_definitions(asio INTERFACE _WIN32_WINNT=${_WIN32_WINNT} WIN32_LEAN_AND_MEAN)
endif()
endif()

# end of file

10 changes: 10 additions & 0 deletions cmake/download_cpm.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

# copied from CPM.cmake GitHub site
# download CPM.cmake

file(
DOWNLOAD
https://github.com/cpm-cmake/CPM.cmake/releases/download/v0.39.0/CPM.cmake
${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake
)
include(${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake)
Loading

0 comments on commit fcd60d5

Please sign in to comment.