Compare commits
10 commits
f7ecbd6d20
...
79ac12a4d7
Author | SHA1 | Date | |
---|---|---|---|
79ac12a4d7 | |||
|
42a15457ec | ||
|
fb6eb84c9e | ||
|
c3f1d7ffe7 | ||
|
c513d24565 | ||
42a20bcc41 | |||
87bfb71f2b | |||
c319ee20eb | |||
0e2e1bf8d0 | |||
cfb5f82948 |
18 changed files with 6495 additions and 52 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -18,3 +18,5 @@ cmake/CPM.cmake
|
||||||
cpm-package-lock.cmake
|
cpm-package-lock.cmake
|
||||||
include/openssl
|
include/openssl
|
||||||
include/tls.h
|
include/tls.h
|
||||||
|
libcserver_shared.so
|
||||||
|
libcserver_static.a
|
||||||
|
|
|
@ -7,6 +7,7 @@ set(CXX_EXTENSIONS NO)
|
||||||
set(Boost_USE_MULTITHREADED ON)
|
set(Boost_USE_MULTITHREADED ON)
|
||||||
set(BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED "url;program_options")
|
set(BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED "url;program_options")
|
||||||
set(BOOST_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED "asio;pfr")
|
set(BOOST_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED "asio;pfr")
|
||||||
|
set(UTEMPL_MODULE OFF)
|
||||||
set(TRY_BOOST_VERSION "1.85.0")
|
set(TRY_BOOST_VERSION "1.85.0")
|
||||||
set(BOOST_INCLUDE_LIBRARIES
|
set(BOOST_INCLUDE_LIBRARIES
|
||||||
"${BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED};${BOOST_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED}"
|
"${BOOST_NOT_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED};${BOOST_HEADER_ONLY_COMPONENTS_THAT_YOU_NEED}"
|
||||||
|
@ -14,6 +15,7 @@ set(BOOST_INCLUDE_LIBRARIES
|
||||||
|
|
||||||
option(CPM_USE_LOCAL_PACKAGES "Use local packages" ON)
|
option(CPM_USE_LOCAL_PACKAGES "Use local packages" ON)
|
||||||
option(CSERVER_USE_LIBRESSL "Use LibreSSL" OFF)
|
option(CSERVER_USE_LIBRESSL "Use LibreSSL" OFF)
|
||||||
|
option(UTEMPL_USE_LOCAL_PACKAGE "Use utempl local package" OFF)
|
||||||
|
|
||||||
file(
|
file(
|
||||||
DOWNLOAD
|
DOWNLOAD
|
||||||
|
@ -69,11 +71,16 @@ CPMAddPackage(
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(TMP ${CPM_USE_LOCAL_PACKAGES})
|
||||||
|
set(CPM_USE_LOCAL_PACKAGES ${UTEMPL_USE_LOCAL_PACKAGE})
|
||||||
|
|
||||||
CPMAddPackage(
|
CPMAddPackage(
|
||||||
NAME utempl
|
NAME utempl
|
||||||
URL "https://github.com/linuxnyasha/utempl/archive/refs/heads/main.zip"
|
URL "https://github.com/linuxnyasha/utempl/archive/refs/heads/main.zip"
|
||||||
|
EXCLUDE_FROM_ALL ON
|
||||||
OPTIONS "ENABLE_TESTS OFF" "ENABLE_EXAMPLES OFF"
|
OPTIONS "ENABLE_TESTS OFF" "ENABLE_EXAMPLES OFF"
|
||||||
)
|
)
|
||||||
|
set(CPM_USE_LOCAL_PACKAGES ${TMP})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
16
Makefile
16
Makefile
|
@ -1,5 +1,10 @@
|
||||||
|
VERSION = $(shell git describe --tags --always --long)
|
||||||
|
|
||||||
MAKEFILE_DIR = $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
MAKEFILE_DIR = $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
||||||
TESTS_BIN = $(MAKEFILE_DIR)/build/cserver_tests
|
BUILD_DIR = $(MAKEFILE_DIR)/build
|
||||||
|
TESTS_BIN = $(BUILD_DIR)/cserver_tests
|
||||||
|
|
||||||
|
DOXYGEN ?= doxygen
|
||||||
|
|
||||||
CC = clang
|
CC = clang
|
||||||
CXX = clang++
|
CXX = clang++
|
||||||
|
@ -75,6 +80,13 @@ tidy: build/.ran-cmake
|
||||||
$(shell find examples -name *.cpp) \
|
$(shell find examples -name *.cpp) \
|
||||||
$(shell find tests -name *.cpp)
|
$(shell find tests -name *.cpp)
|
||||||
|
|
||||||
|
docs:
|
||||||
|
@( \
|
||||||
|
cat docs/doxygen.conf; \
|
||||||
|
echo PROJECT_NUMBER=$(VERSION); \
|
||||||
|
echo OUTPUT_DIRECTORY=$(BUILD_DIR)/docs \
|
||||||
|
) | $(DOXYGEN) -
|
||||||
|
|
||||||
FORCE: ;
|
FORCE: ;
|
||||||
|
|
||||||
.PHONY: all cmake test format clean distclean
|
.PHONY: all cmake format test tidy docs clean distclean
|
|
@ -1,29 +0,0 @@
|
||||||
#include <tuple>
|
|
||||||
#include <utempl/loopholes/core.hpp>
|
|
||||||
#include <utempl/type_list.hpp>
|
|
||||||
|
|
||||||
struct SomeStruct {
|
|
||||||
constexpr SomeStruct(auto&& arg) {
|
|
||||||
arg.Method(42);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Injector {
|
|
||||||
template <typename T, auto _ = utempl::loopholes::Injector<0, utempl::TypeList<T>{}>{}>
|
|
||||||
auto Method(T&&) const -> void;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, auto... Args>
|
|
||||||
inline constexpr auto Use() {
|
|
||||||
std::ignore = T{Args...};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename...>
|
|
||||||
consteval auto Ignore() {};
|
|
||||||
|
|
||||||
|
|
||||||
auto main() -> int {
|
|
||||||
Ignore<decltype(Use<SomeStruct, Injector{}>())>();
|
|
||||||
static_assert(std::is_same_v<decltype(Magic(utempl::loopholes::Getter<0>{})), utempl::TypeList<int>>);
|
|
||||||
};
|
|
||||||
|
|
|
@ -2,9 +2,3 @@
|
||||||
|
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
||||||
check_required_components("@PROJECT_NAME@")
|
check_required_components("@PROJECT_NAME@")
|
||||||
|
|
||||||
try_compile(loopholes_body_inject
|
|
||||||
SOURCES "${CMAKE_CURRENT_LIST_DIR}/check.cpp")
|
|
||||||
if(NOT loopholes_body_inject)
|
|
||||||
message(FATAL_ERROR "The Compiler Doesn't Support Retrieval Of Information Via Loopholes. If You Are Using gcc, Enable Optimizations.")
|
|
||||||
endif()
|
|
||||||
|
|
157
docs/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js
Normal file
157
docs/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
/**
|
||||||
|
|
||||||
|
Doxygen Awesome
|
||||||
|
https://github.com/jothepro/doxygen-awesome-css
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 - 2023 jothepro
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DoxygenAwesomeDarkModeToggle extends HTMLElement {
|
||||||
|
// SVG icons from https://fonts.google.com/icons
|
||||||
|
// Licensed under the Apache 2.0 license:
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
static lightModeIcon = `<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#FCBF00"><rect fill="none" height="24" width="24"/><circle cx="12" cy="12" opacity=".3" r="3"/><path d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"/></svg>`
|
||||||
|
static darkModeIcon = `<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#FE9700"><rect fill="none" height="24" width="24"/><path d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27 C17.45,17.19,14.93,19,12,19c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z" opacity=".3"/><path d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"/></svg>`
|
||||||
|
static title = "Toggle Light/Dark Mode"
|
||||||
|
|
||||||
|
static prefersLightModeInDarkModeKey = "prefers-light-mode-in-dark-mode"
|
||||||
|
static prefersDarkModeInLightModeKey = "prefers-dark-mode-in-light-mode"
|
||||||
|
|
||||||
|
static _staticConstructor = function() {
|
||||||
|
DoxygenAwesomeDarkModeToggle.enableDarkMode(DoxygenAwesomeDarkModeToggle.userPreference)
|
||||||
|
// Update the color scheme when the browsers preference changes
|
||||||
|
// without user interaction on the website.
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
|
||||||
|
DoxygenAwesomeDarkModeToggle.onSystemPreferenceChanged()
|
||||||
|
})
|
||||||
|
// Update the color scheme when the tab is made visible again.
|
||||||
|
// It is possible that the appearance was changed in another tab
|
||||||
|
// while this tab was in the background.
|
||||||
|
document.addEventListener("visibilitychange", visibilityState => {
|
||||||
|
if (document.visibilityState === 'visible') {
|
||||||
|
DoxygenAwesomeDarkModeToggle.onSystemPreferenceChanged()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}()
|
||||||
|
|
||||||
|
static init() {
|
||||||
|
$(function() {
|
||||||
|
$(document).ready(function() {
|
||||||
|
const toggleButton = document.createElement('doxygen-awesome-dark-mode-toggle')
|
||||||
|
toggleButton.title = DoxygenAwesomeDarkModeToggle.title
|
||||||
|
toggleButton.updateIcon()
|
||||||
|
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
|
||||||
|
toggleButton.updateIcon()
|
||||||
|
})
|
||||||
|
document.addEventListener("visibilitychange", visibilityState => {
|
||||||
|
if (document.visibilityState === 'visible') {
|
||||||
|
toggleButton.updateIcon()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).ready(function(){
|
||||||
|
document.getElementById("MSearchBox").parentNode.appendChild(toggleButton)
|
||||||
|
})
|
||||||
|
$(window).resize(function(){
|
||||||
|
document.getElementById("MSearchBox").parentNode.appendChild(toggleButton)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.onclick=this.toggleDarkMode
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns `true` for dark-mode, `false` for light-mode system preference
|
||||||
|
*/
|
||||||
|
static get systemPreference() {
|
||||||
|
return window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns `true` for dark-mode, `false` for light-mode user preference
|
||||||
|
*/
|
||||||
|
static get userPreference() {
|
||||||
|
return (!DoxygenAwesomeDarkModeToggle.systemPreference && localStorage.getItem(DoxygenAwesomeDarkModeToggle.prefersDarkModeInLightModeKey)) ||
|
||||||
|
(DoxygenAwesomeDarkModeToggle.systemPreference && !localStorage.getItem(DoxygenAwesomeDarkModeToggle.prefersLightModeInDarkModeKey))
|
||||||
|
}
|
||||||
|
|
||||||
|
static set userPreference(userPreference) {
|
||||||
|
DoxygenAwesomeDarkModeToggle.darkModeEnabled = userPreference
|
||||||
|
if(!userPreference) {
|
||||||
|
if(DoxygenAwesomeDarkModeToggle.systemPreference) {
|
||||||
|
localStorage.setItem(DoxygenAwesomeDarkModeToggle.prefersLightModeInDarkModeKey, true)
|
||||||
|
} else {
|
||||||
|
localStorage.removeItem(DoxygenAwesomeDarkModeToggle.prefersDarkModeInLightModeKey)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(!DoxygenAwesomeDarkModeToggle.systemPreference) {
|
||||||
|
localStorage.setItem(DoxygenAwesomeDarkModeToggle.prefersDarkModeInLightModeKey, true)
|
||||||
|
} else {
|
||||||
|
localStorage.removeItem(DoxygenAwesomeDarkModeToggle.prefersLightModeInDarkModeKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DoxygenAwesomeDarkModeToggle.onUserPreferenceChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
static enableDarkMode(enable) {
|
||||||
|
if(enable) {
|
||||||
|
DoxygenAwesomeDarkModeToggle.darkModeEnabled = true
|
||||||
|
document.documentElement.classList.add("dark-mode")
|
||||||
|
document.documentElement.classList.remove("light-mode")
|
||||||
|
} else {
|
||||||
|
DoxygenAwesomeDarkModeToggle.darkModeEnabled = false
|
||||||
|
document.documentElement.classList.remove("dark-mode")
|
||||||
|
document.documentElement.classList.add("light-mode")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static onSystemPreferenceChanged() {
|
||||||
|
DoxygenAwesomeDarkModeToggle.darkModeEnabled = DoxygenAwesomeDarkModeToggle.userPreference
|
||||||
|
DoxygenAwesomeDarkModeToggle.enableDarkMode(DoxygenAwesomeDarkModeToggle.darkModeEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
static onUserPreferenceChanged() {
|
||||||
|
DoxygenAwesomeDarkModeToggle.enableDarkMode(DoxygenAwesomeDarkModeToggle.darkModeEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleDarkMode() {
|
||||||
|
DoxygenAwesomeDarkModeToggle.userPreference = !DoxygenAwesomeDarkModeToggle.userPreference
|
||||||
|
this.updateIcon()
|
||||||
|
}
|
||||||
|
|
||||||
|
updateIcon() {
|
||||||
|
if(DoxygenAwesomeDarkModeToggle.darkModeEnabled) {
|
||||||
|
this.innerHTML = DoxygenAwesomeDarkModeToggle.darkModeIcon
|
||||||
|
} else {
|
||||||
|
this.innerHTML = DoxygenAwesomeDarkModeToggle.lightModeIcon
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define("doxygen-awesome-dark-mode-toggle", DoxygenAwesomeDarkModeToggle);
|
|
@ -0,0 +1,85 @@
|
||||||
|
/**
|
||||||
|
|
||||||
|
Doxygen Awesome
|
||||||
|
https://github.com/jothepro/doxygen-awesome-css
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 - 2023 jothepro
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DoxygenAwesomeFragmentCopyButton extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.onclick=this.copyContent
|
||||||
|
}
|
||||||
|
static title = "Copy to clipboard"
|
||||||
|
static copyIcon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>`
|
||||||
|
static successIcon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z"/></svg>`
|
||||||
|
static successDuration = 980
|
||||||
|
static init() {
|
||||||
|
$(function() {
|
||||||
|
$(document).ready(function() {
|
||||||
|
if(navigator.clipboard) {
|
||||||
|
const fragments = document.getElementsByClassName("fragment")
|
||||||
|
for(const fragment of fragments) {
|
||||||
|
const fragmentWrapper = document.createElement("div")
|
||||||
|
fragmentWrapper.className = "doxygen-awesome-fragment-wrapper"
|
||||||
|
const fragmentCopyButton = document.createElement("doxygen-awesome-fragment-copy-button")
|
||||||
|
fragmentCopyButton.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon
|
||||||
|
fragmentCopyButton.title = DoxygenAwesomeFragmentCopyButton.title
|
||||||
|
|
||||||
|
fragment.parentNode.replaceChild(fragmentWrapper, fragment)
|
||||||
|
fragmentWrapper.appendChild(fragment)
|
||||||
|
fragmentWrapper.appendChild(fragmentCopyButton)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
copyContent() {
|
||||||
|
const content = this.previousSibling.cloneNode(true)
|
||||||
|
// filter out line number from file listings
|
||||||
|
content.querySelectorAll(".lineno, .ttc").forEach((node) => {
|
||||||
|
node.remove()
|
||||||
|
})
|
||||||
|
let textContent = content.textContent
|
||||||
|
// remove trailing newlines that appear in file listings
|
||||||
|
let numberOfTrailingNewlines = 0
|
||||||
|
while(textContent.charAt(textContent.length - (numberOfTrailingNewlines + 1)) == '\n') {
|
||||||
|
numberOfTrailingNewlines++;
|
||||||
|
}
|
||||||
|
textContent = textContent.substring(0, textContent.length - numberOfTrailingNewlines)
|
||||||
|
navigator.clipboard.writeText(textContent);
|
||||||
|
this.classList.add("success")
|
||||||
|
this.innerHTML = DoxygenAwesomeFragmentCopyButton.successIcon
|
||||||
|
window.setTimeout(() => {
|
||||||
|
this.classList.remove("success")
|
||||||
|
this.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon
|
||||||
|
}, DoxygenAwesomeFragmentCopyButton.successDuration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define("doxygen-awesome-fragment-copy-button", DoxygenAwesomeFragmentCopyButton)
|
81
docs/doxygen-awesome-css/doxygen-awesome-interactive-toc.js
Normal file
81
docs/doxygen-awesome-css/doxygen-awesome-interactive-toc.js
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/**
|
||||||
|
|
||||||
|
Doxygen Awesome
|
||||||
|
https://github.com/jothepro/doxygen-awesome-css
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 - 2023 jothepro
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DoxygenAwesomeInteractiveToc {
|
||||||
|
static topOffset = 38
|
||||||
|
static hideMobileMenu = true
|
||||||
|
static headers = []
|
||||||
|
|
||||||
|
static init() {
|
||||||
|
window.addEventListener("load", () => {
|
||||||
|
let toc = document.querySelector(".contents > .toc")
|
||||||
|
if(toc) {
|
||||||
|
toc.classList.add("interactive")
|
||||||
|
if(!DoxygenAwesomeInteractiveToc.hideMobileMenu) {
|
||||||
|
toc.classList.add("open")
|
||||||
|
}
|
||||||
|
document.querySelector(".contents > .toc > h3")?.addEventListener("click", () => {
|
||||||
|
if(toc.classList.contains("open")) {
|
||||||
|
toc.classList.remove("open")
|
||||||
|
} else {
|
||||||
|
toc.classList.add("open")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
document.querySelectorAll(".contents > .toc > ul a").forEach((node) => {
|
||||||
|
let id = node.getAttribute("href").substring(1)
|
||||||
|
DoxygenAwesomeInteractiveToc.headers.push({
|
||||||
|
node: node,
|
||||||
|
headerNode: document.getElementById(id)
|
||||||
|
})
|
||||||
|
|
||||||
|
document.getElementById("doc-content")?.addEventListener("scroll", () => {
|
||||||
|
DoxygenAwesomeInteractiveToc.update()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
DoxygenAwesomeInteractiveToc.update()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static update() {
|
||||||
|
let active = DoxygenAwesomeInteractiveToc.headers[0]?.node
|
||||||
|
DoxygenAwesomeInteractiveToc.headers.forEach((header) => {
|
||||||
|
let position = header.headerNode.getBoundingClientRect().top
|
||||||
|
header.node.classList.remove("active")
|
||||||
|
header.node.classList.remove("aboveActive")
|
||||||
|
if(position < DoxygenAwesomeInteractiveToc.topOffset) {
|
||||||
|
active = header.node
|
||||||
|
active?.classList.add("aboveActive")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
active?.classList.add("active")
|
||||||
|
active?.classList.remove("aboveActive")
|
||||||
|
}
|
||||||
|
}
|
51
docs/doxygen-awesome-css/doxygen-awesome-paragraph-link.js
Normal file
51
docs/doxygen-awesome-css/doxygen-awesome-paragraph-link.js
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
|
||||||
|
Doxygen Awesome
|
||||||
|
https://github.com/jothepro/doxygen-awesome-css
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 - 2023 jothepro
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DoxygenAwesomeParagraphLink {
|
||||||
|
// Icon from https://fonts.google.com/icons
|
||||||
|
// Licensed under the Apache 2.0 license:
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
static icon = `<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M17 7h-4v2h4c1.65 0 3 1.35 3 3s-1.35 3-3 3h-4v2h4c2.76 0 5-2.24 5-5s-2.24-5-5-5zm-6 8H7c-1.65 0-3-1.35-3-3s1.35-3 3-3h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-2zm-3-4h8v2H8z"/></svg>`
|
||||||
|
static title = "Permanent Link"
|
||||||
|
static init() {
|
||||||
|
$(function() {
|
||||||
|
$(document).ready(function() {
|
||||||
|
document.querySelectorAll(".contents a.anchor[id], .contents .groupheader > a[id]").forEach((node) => {
|
||||||
|
let anchorlink = document.createElement("a")
|
||||||
|
anchorlink.setAttribute("href", `#${node.getAttribute("id")}`)
|
||||||
|
anchorlink.setAttribute("title", DoxygenAwesomeParagraphLink.title)
|
||||||
|
anchorlink.classList.add("anchorlink")
|
||||||
|
node.classList.add("anchor")
|
||||||
|
anchorlink.innerHTML = DoxygenAwesomeParagraphLink.icon
|
||||||
|
node.parentElement.appendChild(anchorlink)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
Doxygen Awesome
|
||||||
|
https://github.com/jothepro/doxygen-awesome-css
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 - 2023 jothepro
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
|
||||||
|
#MSearchBox {
|
||||||
|
width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - var(--searchbar-height) - 1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#MSearchField {
|
||||||
|
width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - 66px - var(--searchbar-height));
|
||||||
|
}
|
||||||
|
}
|
116
docs/doxygen-awesome-css/doxygen-awesome-sidebar-only.css
Normal file
116
docs/doxygen-awesome-css/doxygen-awesome-sidebar-only.css
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/**
|
||||||
|
|
||||||
|
Doxygen Awesome
|
||||||
|
https://github.com/jothepro/doxygen-awesome-css
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 - 2023 jothepro
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
html {
|
||||||
|
/* side nav width. MUST be = `TREEVIEW_WIDTH`.
|
||||||
|
* Make sure it is wide enough to contain the page title (logo + title + version)
|
||||||
|
*/
|
||||||
|
--side-nav-fixed-width: 335px;
|
||||||
|
--menu-display: none;
|
||||||
|
|
||||||
|
--top-height: 120px;
|
||||||
|
--toc-sticky-top: -25px;
|
||||||
|
--toc-max-height: calc(100vh - 2 * var(--spacing-medium) - 25px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#projectname {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
html {
|
||||||
|
--searchbar-background: var(--page-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#side-nav {
|
||||||
|
min-width: var(--side-nav-fixed-width);
|
||||||
|
max-width: var(--side-nav-fixed-width);
|
||||||
|
top: var(--top-height);
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-tree, #side-nav {
|
||||||
|
height: calc(100vh - var(--top-height)) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-tree {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#top {
|
||||||
|
display: block;
|
||||||
|
border-bottom: none;
|
||||||
|
height: var(--top-height);
|
||||||
|
margin-bottom: calc(0px - var(--top-height));
|
||||||
|
max-width: var(--side-nav-fixed-width);
|
||||||
|
overflow: hidden;
|
||||||
|
background: var(--side-nav-background);
|
||||||
|
}
|
||||||
|
#main-nav {
|
||||||
|
float: left;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-resizable-handle {
|
||||||
|
cursor: default;
|
||||||
|
width: 1px !important;
|
||||||
|
background: var(--separator-color);
|
||||||
|
box-shadow: 0 calc(-2 * var(--top-height)) 0 0 var(--separator-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-path {
|
||||||
|
position: fixed;
|
||||||
|
right: 0;
|
||||||
|
left: var(--side-nav-fixed-width);
|
||||||
|
bottom: 0;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#doc-content {
|
||||||
|
height: calc(100vh - 31px) !important;
|
||||||
|
padding-bottom: calc(3 * var(--spacing-large));
|
||||||
|
padding-top: calc(var(--top-height) - 80px);
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-left: var(--side-nav-fixed-width) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#MSearchBox {
|
||||||
|
width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#MSearchField {
|
||||||
|
width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - 65px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#MSearchResultsWindow {
|
||||||
|
left: var(--spacing-medium) !important;
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
|
}
|
90
docs/doxygen-awesome-css/doxygen-awesome-tabs.js
Normal file
90
docs/doxygen-awesome-css/doxygen-awesome-tabs.js
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/**
|
||||||
|
|
||||||
|
Doxygen Awesome
|
||||||
|
https://github.com/jothepro/doxygen-awesome-css
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 jothepro
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DoxygenAwesomeTabs {
|
||||||
|
|
||||||
|
static init() {
|
||||||
|
window.addEventListener("load", () => {
|
||||||
|
document.querySelectorAll(".tabbed:not(:empty)").forEach((tabbed, tabbedIndex) => {
|
||||||
|
let tabLinkList = []
|
||||||
|
tabbed.querySelectorAll(":scope > ul > li").forEach((tab, tabIndex) => {
|
||||||
|
tab.id = "tab_" + tabbedIndex + "_" + tabIndex
|
||||||
|
let header = tab.querySelector(".tab-title")
|
||||||
|
let tabLink = document.createElement("button")
|
||||||
|
tabLink.classList.add("tab-button")
|
||||||
|
tabLink.appendChild(header)
|
||||||
|
header.title = header.textContent
|
||||||
|
tabLink.addEventListener("click", () => {
|
||||||
|
tabbed.querySelectorAll(":scope > ul > li").forEach((tab) => {
|
||||||
|
tab.classList.remove("selected")
|
||||||
|
})
|
||||||
|
tabLinkList.forEach((tabLink) => {
|
||||||
|
tabLink.classList.remove("active")
|
||||||
|
})
|
||||||
|
tab.classList.add("selected")
|
||||||
|
tabLink.classList.add("active")
|
||||||
|
})
|
||||||
|
tabLinkList.push(tabLink)
|
||||||
|
if(tabIndex == 0) {
|
||||||
|
tab.classList.add("selected")
|
||||||
|
tabLink.classList.add("active")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let tabsOverview = document.createElement("div")
|
||||||
|
tabsOverview.classList.add("tabs-overview")
|
||||||
|
let tabsOverviewContainer = document.createElement("div")
|
||||||
|
tabsOverviewContainer.classList.add("tabs-overview-container")
|
||||||
|
tabLinkList.forEach((tabLink) => {
|
||||||
|
tabsOverview.appendChild(tabLink)
|
||||||
|
})
|
||||||
|
tabsOverviewContainer.appendChild(tabsOverview)
|
||||||
|
tabbed.before(tabsOverviewContainer)
|
||||||
|
|
||||||
|
function resize() {
|
||||||
|
let maxTabHeight = 0
|
||||||
|
tabbed.querySelectorAll(":scope > ul > li").forEach((tab, tabIndex) => {
|
||||||
|
let visibility = tab.style.display
|
||||||
|
tab.style.display = "block"
|
||||||
|
maxTabHeight = Math.max(tab.offsetHeight, maxTabHeight)
|
||||||
|
tab.style.display = visibility
|
||||||
|
})
|
||||||
|
tabbed.style.height = `${maxTabHeight + 10}px`
|
||||||
|
}
|
||||||
|
|
||||||
|
resize()
|
||||||
|
new ResizeObserver(resize).observe(tabbed)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static resize(tabbed) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
2677
docs/doxygen-awesome-css/doxygen-awesome.css
Normal file
2677
docs/doxygen-awesome-css/doxygen-awesome.css
Normal file
File diff suppressed because it is too large
Load diff
2865
docs/doxygen.conf
Normal file
2865
docs/doxygen.conf
Normal file
File diff suppressed because it is too large
Load diff
247
docs/layout.xml
Normal file
247
docs/layout.xml
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<doxygenlayout version="1.0">
|
||||||
|
<!-- Generated by doxygen 1.11.0 -->
|
||||||
|
<!-- Navigation index tabs for HTML output -->
|
||||||
|
<navindex>
|
||||||
|
<tab type="mainpage" visible="yes" title="Home"/>
|
||||||
|
<tab type="usergroup" title="Documentation">
|
||||||
|
<!-- Put here all custom documentation pages -->
|
||||||
|
</tab>
|
||||||
|
<tab type="usergroup" visible="yes" title="Reference">
|
||||||
|
<tab type="namespacelist" visible="yes" title="" intro=""/>
|
||||||
|
<tab type="namespacemembers" visible="yes" title="" intro=""/>
|
||||||
|
<tab type="classlist" visible="yes" title="" intro=""/>
|
||||||
|
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
|
||||||
|
<tab type="hierarchy" visible="yes" title="" intro=""/>
|
||||||
|
<tab type="classmembers" visible="yes" title="" intro=""/>
|
||||||
|
<tab type="filelist" visible="yes" title="" intro=""/>
|
||||||
|
<tab type="globals" visible="yes" title="" intro=""/>
|
||||||
|
<tab type="examples" visible="yes" title="" intro=""/>
|
||||||
|
<tab type="pages" visible="no" title="" intro=""/>
|
||||||
|
</tab>
|
||||||
|
</navindex>
|
||||||
|
|
||||||
|
<!-- Layout definition for a class page -->
|
||||||
|
<class>
|
||||||
|
<briefdescription visible="yes"/>
|
||||||
|
<includes visible="$SHOW_HEADERFILE"/>
|
||||||
|
<inheritancegraph visible="yes"/>
|
||||||
|
<collaborationgraph visible="yes"/>
|
||||||
|
<memberdecl>
|
||||||
|
<nestedclasses visible="yes" title=""/>
|
||||||
|
<publictypes title=""/>
|
||||||
|
<services title=""/>
|
||||||
|
<interfaces title=""/>
|
||||||
|
<publicslots title=""/>
|
||||||
|
<signals title=""/>
|
||||||
|
<publicmethods title=""/>
|
||||||
|
<publicstaticmethods title=""/>
|
||||||
|
<publicattributes title=""/>
|
||||||
|
<publicstaticattributes title=""/>
|
||||||
|
<protectedtypes title=""/>
|
||||||
|
<protectedslots title=""/>
|
||||||
|
<protectedmethods title=""/>
|
||||||
|
<protectedstaticmethods title=""/>
|
||||||
|
<protectedattributes title=""/>
|
||||||
|
<protectedstaticattributes title=""/>
|
||||||
|
<packagetypes title=""/>
|
||||||
|
<packagemethods title=""/>
|
||||||
|
<packagestaticmethods title=""/>
|
||||||
|
<packageattributes title=""/>
|
||||||
|
<packagestaticattributes title=""/>
|
||||||
|
<properties title=""/>
|
||||||
|
<events title=""/>
|
||||||
|
<privatetypes title=""/>
|
||||||
|
<privateslots title=""/>
|
||||||
|
<privatemethods title=""/>
|
||||||
|
<privatestaticmethods title=""/>
|
||||||
|
<privateattributes title=""/>
|
||||||
|
<privatestaticattributes title=""/>
|
||||||
|
<friends title=""/>
|
||||||
|
<related title="" subtitle=""/>
|
||||||
|
<membergroups visible="yes"/>
|
||||||
|
</memberdecl>
|
||||||
|
<detaileddescription title=""/>
|
||||||
|
<memberdef>
|
||||||
|
<inlineclasses title=""/>
|
||||||
|
<typedefs title=""/>
|
||||||
|
<enums title=""/>
|
||||||
|
<services title=""/>
|
||||||
|
<interfaces title=""/>
|
||||||
|
<constructors title=""/>
|
||||||
|
<functions title=""/>
|
||||||
|
<related title=""/>
|
||||||
|
<variables title=""/>
|
||||||
|
<properties title=""/>
|
||||||
|
<events title=""/>
|
||||||
|
</memberdef>
|
||||||
|
<allmemberslink visible="yes"/>
|
||||||
|
<usedfiles visible="$SHOW_USED_FILES"/>
|
||||||
|
<authorsection visible="yes"/>
|
||||||
|
</class>
|
||||||
|
|
||||||
|
<!-- Layout definition for a namespace page -->
|
||||||
|
<namespace>
|
||||||
|
<briefdescription visible="yes"/>
|
||||||
|
<memberdecl>
|
||||||
|
<nestednamespaces visible="yes" title=""/>
|
||||||
|
<constantgroups visible="yes" title=""/>
|
||||||
|
<interfaces visible="yes" title=""/>
|
||||||
|
<classes visible="yes" title=""/>
|
||||||
|
<concepts visible="yes" title=""/>
|
||||||
|
<structs visible="yes" title=""/>
|
||||||
|
<exceptions visible="yes" title=""/>
|
||||||
|
<typedefs title=""/>
|
||||||
|
<sequences title=""/>
|
||||||
|
<dictionaries title=""/>
|
||||||
|
<enums title=""/>
|
||||||
|
<functions title=""/>
|
||||||
|
<variables title=""/>
|
||||||
|
<properties title=""/>
|
||||||
|
<membergroups visible="yes"/>
|
||||||
|
</memberdecl>
|
||||||
|
<detaileddescription title=""/>
|
||||||
|
<memberdef>
|
||||||
|
<inlineclasses title=""/>
|
||||||
|
<typedefs title=""/>
|
||||||
|
<sequences title=""/>
|
||||||
|
<dictionaries title=""/>
|
||||||
|
<enums title=""/>
|
||||||
|
<functions title=""/>
|
||||||
|
<variables title=""/>
|
||||||
|
<properties title=""/>
|
||||||
|
</memberdef>
|
||||||
|
<authorsection visible="yes"/>
|
||||||
|
</namespace>
|
||||||
|
|
||||||
|
<!-- Layout definition for a concept page -->
|
||||||
|
<concept>
|
||||||
|
<briefdescription visible="yes"/>
|
||||||
|
<includes visible="$SHOW_HEADERFILE"/>
|
||||||
|
<definition visible="yes" title=""/>
|
||||||
|
<detaileddescription title=""/>
|
||||||
|
<authorsection visible="yes"/>
|
||||||
|
</concept>
|
||||||
|
|
||||||
|
<!-- Layout definition for a file page -->
|
||||||
|
<file>
|
||||||
|
<briefdescription visible="yes"/>
|
||||||
|
<includes visible="$SHOW_INCLUDE_FILES"/>
|
||||||
|
<includegraph visible="yes"/>
|
||||||
|
<includedbygraph visible="yes"/>
|
||||||
|
<sourcelink visible="yes"/>
|
||||||
|
<memberdecl>
|
||||||
|
<interfaces visible="yes" title=""/>
|
||||||
|
<classes visible="yes" title=""/>
|
||||||
|
<structs visible="yes" title=""/>
|
||||||
|
<exceptions visible="yes" title=""/>
|
||||||
|
<namespaces visible="yes" title=""/>
|
||||||
|
<concepts visible="yes" title=""/>
|
||||||
|
<constantgroups visible="yes" title=""/>
|
||||||
|
<defines title=""/>
|
||||||
|
<typedefs title=""/>
|
||||||
|
<sequences title=""/>
|
||||||
|
<dictionaries title=""/>
|
||||||
|
<enums title=""/>
|
||||||
|
<functions title=""/>
|
||||||
|
<variables title=""/>
|
||||||
|
<properties title=""/>
|
||||||
|
<membergroups visible="yes"/>
|
||||||
|
</memberdecl>
|
||||||
|
<detaileddescription title=""/>
|
||||||
|
<memberdef>
|
||||||
|
<inlineclasses title=""/>
|
||||||
|
<defines title=""/>
|
||||||
|
<typedefs title=""/>
|
||||||
|
<sequences title=""/>
|
||||||
|
<dictionaries title=""/>
|
||||||
|
<enums title=""/>
|
||||||
|
<functions title=""/>
|
||||||
|
<variables title=""/>
|
||||||
|
<properties title=""/>
|
||||||
|
</memberdef>
|
||||||
|
<authorsection/>
|
||||||
|
</file>
|
||||||
|
|
||||||
|
<!-- Layout definition for a group page -->
|
||||||
|
<group>
|
||||||
|
<briefdescription visible="yes"/>
|
||||||
|
<groupgraph visible="yes"/>
|
||||||
|
<memberdecl>
|
||||||
|
<nestedgroups visible="yes" title=""/>
|
||||||
|
<modules visible="yes" title=""/>
|
||||||
|
<dirs visible="yes" title=""/>
|
||||||
|
<files visible="yes" title=""/>
|
||||||
|
<namespaces visible="yes" title=""/>
|
||||||
|
<concepts visible="yes" title=""/>
|
||||||
|
<classes visible="yes" title=""/>
|
||||||
|
<defines title=""/>
|
||||||
|
<typedefs title=""/>
|
||||||
|
<sequences title=""/>
|
||||||
|
<dictionaries title=""/>
|
||||||
|
<enums title=""/>
|
||||||
|
<enumvalues title=""/>
|
||||||
|
<functions title=""/>
|
||||||
|
<variables title=""/>
|
||||||
|
<signals title=""/>
|
||||||
|
<publicslots title=""/>
|
||||||
|
<protectedslots title=""/>
|
||||||
|
<privateslots title=""/>
|
||||||
|
<events title=""/>
|
||||||
|
<properties title=""/>
|
||||||
|
<friends title=""/>
|
||||||
|
<membergroups visible="yes"/>
|
||||||
|
</memberdecl>
|
||||||
|
<detaileddescription title=""/>
|
||||||
|
<memberdef>
|
||||||
|
<pagedocs/>
|
||||||
|
<inlineclasses title=""/>
|
||||||
|
<defines title=""/>
|
||||||
|
<typedefs title=""/>
|
||||||
|
<sequences title=""/>
|
||||||
|
<dictionaries title=""/>
|
||||||
|
<enums title=""/>
|
||||||
|
<enumvalues title=""/>
|
||||||
|
<functions title=""/>
|
||||||
|
<variables title=""/>
|
||||||
|
<signals title=""/>
|
||||||
|
<publicslots title=""/>
|
||||||
|
<protectedslots title=""/>
|
||||||
|
<privateslots title=""/>
|
||||||
|
<events title=""/>
|
||||||
|
<properties title=""/>
|
||||||
|
<friends title=""/>
|
||||||
|
</memberdef>
|
||||||
|
<authorsection visible="yes"/>
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<!-- Layout definition for a C++20 module page -->
|
||||||
|
<module>
|
||||||
|
<briefdescription visible="yes"/>
|
||||||
|
<exportedmodules visible="yes"/>
|
||||||
|
<memberdecl>
|
||||||
|
<concepts visible="yes" title=""/>
|
||||||
|
<classes visible="yes" title=""/>
|
||||||
|
<enums title=""/>
|
||||||
|
<typedefs title=""/>
|
||||||
|
<functions title=""/>
|
||||||
|
<variables title=""/>
|
||||||
|
<membergroups title=""/>
|
||||||
|
</memberdecl>
|
||||||
|
<detaileddescription title=""/>
|
||||||
|
<memberdecl>
|
||||||
|
<files visible="yes"/>
|
||||||
|
</memberdecl>
|
||||||
|
</module>
|
||||||
|
|
||||||
|
<!-- Layout definition for a directory page -->
|
||||||
|
<directory>
|
||||||
|
<briefdescription visible="yes"/>
|
||||||
|
<directorygraph visible="yes"/>
|
||||||
|
<memberdecl>
|
||||||
|
<dirs visible="yes"/>
|
||||||
|
<files visible="yes"/>
|
||||||
|
</memberdecl>
|
||||||
|
<detaileddescription title=""/>
|
||||||
|
</directory>
|
||||||
|
</doxygenlayout>
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
struct SomeStruct {
|
struct SomeStruct {
|
||||||
static_assert(utempl::OpenStruct<SomeStruct>());
|
static_assert(utempl::OpenStruct<SomeStruct>());
|
||||||
utempl::FieldAttribute<std::string, cserver::cli::Name<"field,f">> field;
|
utempl::FieldAttribute<std::string, utempl::TypeList<cserver::cli::Name<"field,f">>> field;
|
||||||
static_assert(utempl::CloseStruct<SomeStruct>());
|
static_assert(utempl::CloseStruct<SomeStruct>());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -74,10 +74,11 @@ struct Manager {
|
||||||
constexpr std::string_view nname = nnname.substr(0, nnname.find(','));
|
constexpr std::string_view nname = nnname.substr(0, nnname.find(','));
|
||||||
utempl::ConstexprString<nname.size() + 1> name;
|
utempl::ConstexprString<nname.size() + 1> name;
|
||||||
std::ranges::copy_n(nname.begin(), nname.size(), name.begin());
|
std::ranges::copy_n(nname.begin(), nname.size(), name.begin());
|
||||||
|
name.data[nname.size()] = '\0';
|
||||||
if(this->variableMap.count(name.begin())) {
|
if(this->variableMap.count(name.begin())) {
|
||||||
return this->variableMap[name.begin()].template as<typename decltype(fieldConfig)::Type>();
|
return this->variableMap[name.begin()].template as<typename decltype(fieldConfig)::Type>();
|
||||||
};
|
};
|
||||||
throw std::runtime_error(fmt::format("Not found cli option {}", name));
|
throw std::runtime_error(fmt::format("Not found cli option {}", name.begin()));
|
||||||
}()...};
|
}()...};
|
||||||
} | utempl::kSeq<utempl::kTupleSize<decltype(fieldConfigs)>>;
|
} | utempl::kSeq<utempl::kTupleSize<decltype(fieldConfigs)>>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <cxxabi.h>
|
#include <cxxabi.h>
|
||||||
|
|
||||||
#include <boost/core/demangle.hpp>
|
#include <boost/core/demangle.hpp>
|
||||||
|
#include <cserver/components/logger.hpp>
|
||||||
#include <cserver/engine/basic/task_processor.hpp>
|
#include <cserver/engine/basic/task_processor.hpp>
|
||||||
#include <cserver/engine/coroutine.hpp>
|
#include <cserver/engine/coroutine.hpp>
|
||||||
#include <utempl/loopholes/counter.hpp>
|
#include <utempl/loopholes/counter.hpp>
|
||||||
|
@ -187,21 +188,46 @@ inline constexpr auto InitComponents(T& ccontext, int ac, const char** av) -> vo
|
||||||
static utempl::Tuple inited =
|
static utempl::Tuple inited =
|
||||||
TransformDependencyGraphToTupleWithDependenciesToInitedFlagChanges<AsyncConditionVariable, DependencyGraph>(ioContext);
|
TransformDependencyGraphToTupleWithDependenciesToInitedFlagChanges<AsyncConditionVariable, DependencyGraph>(ioContext);
|
||||||
auto work = make_work_guard(ioContext);
|
auto work = make_work_guard(ioContext);
|
||||||
[]<std::size_t... Is>(std::index_sequence<Is...>) {
|
[](auto... is) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
(boost::asio::co_spawn(ioContext, []() -> cserver::Task<> {
|
(boost::asio::co_spawn(ioContext, [](auto is) -> cserver::Task<> {
|
||||||
using Current = decltype(Get<Is>(decltype(T::kUtils)::kComponentConfigs));
|
using Current = decltype(Get<is>(decltype(T::kUtils)::kComponentConfigs));
|
||||||
auto& dependencies = Get<Is>(inited);
|
auto& dependencies = Get<is>(inited);
|
||||||
|
constexpr auto logLevel = T::kConfig.template Get<"logging">().template Get<"level">();
|
||||||
|
if constexpr(logLevel == LoggingLevel::kTrace) {
|
||||||
|
fmt::println("[TRACE] Started coroutine for initialisation component {} with flag address {}",
|
||||||
|
static_cast<std::string_view>(Current::kName),
|
||||||
|
static_cast<void*>(&GetInitFlagFor<AsyncConditionVariable, is>(ioContext)));
|
||||||
|
};
|
||||||
for(auto* flag : dependencies) {
|
for(auto* flag : dependencies) {
|
||||||
|
if constexpr(logLevel == LoggingLevel::kTrace) {
|
||||||
|
fmt::println("[TRACE] {} Component: Waiting flag on address {}",
|
||||||
|
static_cast<std::string_view>(Current::kName),
|
||||||
|
static_cast<void*>(flag));
|
||||||
|
};
|
||||||
co_await flag->AsyncWait();
|
co_await flag->AsyncWait();
|
||||||
|
if constexpr(logLevel == LoggingLevel::kTrace) {
|
||||||
|
fmt::println("[TRACE] {} Component: Waited flag on address {}",
|
||||||
|
static_cast<std::string_view>(Current::kName),
|
||||||
|
static_cast<void*>(flag));
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
if constexpr(Current::kName == cliArgs) {
|
if constexpr(Current::kName == cliArgs) {
|
||||||
ServiceContextForComponentWithCliArgs<Current, T> currentContext{context, argc, argv};
|
ServiceContextForComponentWithCliArgs<Current, T> currentContext{context, argc, argv};
|
||||||
Get<Is>(context.storage).emplace(currentContext);
|
if constexpr(logLevel == LoggingLevel::kTrace) {
|
||||||
|
fmt::println("[TRACE] {} Component: call constructor with cli args",
|
||||||
|
static_cast<std::string_view>(Current::kName));
|
||||||
|
};
|
||||||
|
Get<is>(context.storage).emplace(currentContext);
|
||||||
} else {
|
} else {
|
||||||
ServiceContextForComponent<Current, T> currentContext{context};
|
ServiceContextForComponent<Current, T> currentContext{context};
|
||||||
Get<Is>(context.storage).emplace(currentContext);
|
if constexpr(logLevel == LoggingLevel::kTrace) {
|
||||||
|
fmt::println("[TRACE] {} Component: call constructor",
|
||||||
|
static_cast<std::string_view>(Current::kName));
|
||||||
|
};
|
||||||
|
Get<is>(context.storage).emplace(currentContext);
|
||||||
};
|
};
|
||||||
} catch(std::exception& error) {
|
} catch(std::exception& error) {
|
||||||
auto typeName = boost::core::demangle(__cxxabiv1::__cxa_current_exception_type()->name());
|
auto typeName = boost::core::demangle(__cxxabiv1::__cxa_current_exception_type()->name());
|
||||||
|
@ -217,14 +243,18 @@ inline constexpr auto InitComponents(T& ccontext, int ac, const char** av) -> vo
|
||||||
typeName);
|
typeName);
|
||||||
ioContext.stop();
|
ioContext.stop();
|
||||||
};
|
};
|
||||||
auto& componentInitFlag = GetInitFlagFor<AsyncConditionVariable, Is>(ioContext);
|
auto& componentInitFlag = GetInitFlagFor<AsyncConditionVariable, is>(ioContext);
|
||||||
componentInitFlag.NotifyAll();
|
if constexpr(logLevel == LoggingLevel::kTrace) {
|
||||||
if constexpr(requires{Get<Is>(context.storage)->Run();}) {
|
fmt::println("[TRACE] {} Component: notify",
|
||||||
Get<Is>(context.storage)->Run();
|
static_cast<std::string_view>(Current::kName));
|
||||||
};
|
};
|
||||||
}(), boost::asio::detached), ...);
|
componentInitFlag.NotifyAll();
|
||||||
|
if constexpr(requires{Get<is>(context.storage)->Run();}) {
|
||||||
|
Get<is>(context.storage)->Run();
|
||||||
|
};
|
||||||
|
}(is), boost::asio::detached), ...);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}(std::make_index_sequence<utempl::kTupleSize<decltype(DependencyGraph)>>());
|
} | utempl::kSeq<utempl::kTupleSize<decltype(DependencyGraph)>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
@ -334,9 +364,26 @@ namespace impl {
|
||||||
template <typename Current, std::size_t I>
|
template <typename Current, std::size_t I>
|
||||||
struct DependencyInfoKey {};
|
struct DependencyInfoKey {};
|
||||||
|
|
||||||
|
template <auto F>
|
||||||
|
consteval auto IsConstantImpl(...) {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <auto F, auto = (F(), 1)>
|
||||||
|
consteval auto IsConstantImpl(bool) {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <auto F>
|
||||||
|
consteval auto IsConstant() -> bool {
|
||||||
|
return IsConstantImpl<F>(true); // NOLINT
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, auto... Args>
|
template <typename T, auto... Args>
|
||||||
inline constexpr auto Use() {
|
inline constexpr auto Use() {
|
||||||
std::ignore = T{Args...};
|
std::ignore = IsConstant<[] {
|
||||||
|
T{Args...};
|
||||||
|
}>();
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename...>
|
template <typename...>
|
||||||
|
|
Loading…
Reference in a new issue