Compare commits
No commits in common. "d65e0b9ad9910fe0c363492e4970b8602318ad58" and "992c55b7852439c356a20f87b1009ff8ec51368d" have entirely different histories.
d65e0b9ad9
...
992c55b785
@ -9,6 +9,7 @@ steps:
|
|||||||
commands:
|
commands:
|
||||||
- mkdir -p build
|
- mkdir -p build
|
||||||
- cd build
|
- cd build
|
||||||
|
- conan install .. --build=missing
|
||||||
- cmake .. -G "Ninja" -DCMAKE_BUILD_TYPE=Release -DWITH_TESTS=ON
|
- cmake .. -G "Ninja" -DCMAKE_BUILD_TYPE=Release -DWITH_TESTS=ON
|
||||||
- ninja
|
- ninja
|
||||||
- ctest . --output-on-failure
|
- ctest . --output-on-failure
|
||||||
|
|||||||
@ -1,19 +1,22 @@
|
|||||||
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
|
||||||
|
|
||||||
set(SKULLC_VERSION 0.1.0)
|
set(version 0.1.0)
|
||||||
|
|
||||||
project(skullc
|
project(skullc
|
||||||
VERSION ${SKULLC_VERSION}
|
VERSION ${version}
|
||||||
LANGUAGES
|
LANGUAGES
|
||||||
C
|
C
|
||||||
CXX
|
CXX
|
||||||
)
|
)
|
||||||
|
|
||||||
#list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
|
||||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/)
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/)
|
||||||
|
|
||||||
option(SKULLC_WITH_TESTS "Enable unit testing." OFF)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
option(SKULLC_WITH_HAL "Enable the compiling and deployment of the HAL dependent sections." OFF)
|
list(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra")
|
||||||
|
|
||||||
|
option(WITH_TESTS "Enable unit testing." OFF)
|
||||||
|
option(WITH_HAL "Enable the compiling and deployment of the HAL dependent sections." OFF)
|
||||||
|
|
||||||
include(skullc-install)
|
include(skullc-install)
|
||||||
|
|
||||||
@ -21,7 +24,7 @@ add_subdirectory(Peripherals)
|
|||||||
add_subdirectory(Utility)
|
add_subdirectory(Utility)
|
||||||
add_subdirectory(Messaging)
|
add_subdirectory(Messaging)
|
||||||
|
|
||||||
if(SKULLC_WITH_TESTS)
|
if(WITH_TESTS)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
add_subdirectory(Tests)
|
add_subdirectory(Tests)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
50
Jenkinsfile
vendored
50
Jenkinsfile
vendored
@ -1,50 +0,0 @@
|
|||||||
pipeline {
|
|
||||||
agent {
|
|
||||||
label 'ubuntu'
|
|
||||||
}
|
|
||||||
|
|
||||||
stages {
|
|
||||||
stage("build && test") {
|
|
||||||
steps {
|
|
||||||
echo "Workspace: ${env.WORKSPACE}"
|
|
||||||
sh 'mkdir -p build'
|
|
||||||
|
|
||||||
dir("build") {
|
|
||||||
sh 'ls'
|
|
||||||
sh 'cmake .. -G "Ninja" -DCMAKE_BUILD_TYPE=Release -DSKULLC_WITH_TESTS=ON'
|
|
||||||
sh 'ninja'
|
|
||||||
sh 'ctest . -T test --output-on-failure --no-compress-output'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
post {
|
|
||||||
always {
|
|
||||||
archiveArtifacts (
|
|
||||||
artifacts: 'build/Testing/**/*.xml',
|
|
||||||
fingerprint: true
|
|
||||||
)
|
|
||||||
|
|
||||||
// Process the CTest xml output with the xUnit plugin
|
|
||||||
xunit (
|
|
||||||
testTimeMargin: '3000',
|
|
||||||
thresholdMode: 1,
|
|
||||||
thresholds: [
|
|
||||||
skipped(failureThreshold: '0'),
|
|
||||||
failed(failureThreshold: '0')
|
|
||||||
],
|
|
||||||
tools: [CTest(
|
|
||||||
pattern: 'build/Testing/**/*.xml',
|
|
||||||
deleteOutputFiles: true,
|
|
||||||
failIfNotNew: false,
|
|
||||||
skipNoTestFiles: true,
|
|
||||||
stopProcessingIfError: true
|
|
||||||
)]
|
|
||||||
)
|
|
||||||
|
|
||||||
// Clear the source and build dirs before next run
|
|
||||||
deleteDir()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -5,9 +5,9 @@ add_library(messaging INTERFACE)
|
|||||||
add_library(skullc::messaging ALIAS messaging)
|
add_library(skullc::messaging ALIAS messaging)
|
||||||
|
|
||||||
target_include_directories(messaging
|
target_include_directories(messaging
|
||||||
INTERFACE
|
INTERFACE
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Inc>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Inc>
|
||||||
$<INSTALL_INTERFACE:include>
|
$<INSTALL_INTERFACE:include>
|
||||||
)
|
)
|
||||||
|
|
||||||
skullc_install_packages(skullc messaging ${SKULLC_VERSION})
|
skullc_install_packages(skullc messaging ${version})
|
||||||
|
|||||||
@ -11,4 +11,4 @@ target_include_directories(peripherals
|
|||||||
)
|
)
|
||||||
|
|
||||||
## INSTALL
|
## INSTALL
|
||||||
skullc_install_packages(skullc peripherals ${SKULLC_VERSION})
|
skullc_install_packages(skullc peripherals ${version})
|
||||||
|
|||||||
@ -74,12 +74,11 @@ public:
|
|||||||
|
|
||||||
const std::uint8_t new_gyro_conf = (std::uint32_t(scale_gyro_) << 3);
|
const std::uint8_t new_gyro_conf = (std::uint32_t(scale_gyro_) << 3);
|
||||||
registers.writeRegister(Registers_::GYRO_CONFIG & Registers_::WRITE_MASK,
|
registers.writeRegister(Registers_::GYRO_CONFIG & Registers_::WRITE_MASK,
|
||||||
new_gyro_conf);
|
new_gyro_conf);
|
||||||
|
|
||||||
const std::uint8_t new_accel_config = (std::uint32_t(scale_accel_) << 3);
|
const std::uint8_t new_accel_config = (std::uint32_t(scale_accel_) << 3);
|
||||||
registers.writeRegister(Registers_::ACCEL_CONFIG & Registers_::WRITE_MASK,
|
registers.writeRegister(Registers_::ACCEL_CONFIG & Registers_::WRITE_MASK,
|
||||||
new_accel_config);
|
new_accel_config);
|
||||||
|
|
||||||
|
|
||||||
// ACCEL_FCHOICE_B = 0, A_DLPF_CFG = 3 filter=44.8/61.5 rate=1KHz
|
// ACCEL_FCHOICE_B = 0, A_DLPF_CFG = 3 filter=44.8/61.5 rate=1KHz
|
||||||
registers.writeRegister(Registers_::ACCEL_CONFIG2 & Registers_::WRITE_MASK,
|
registers.writeRegister(Registers_::ACCEL_CONFIG2 & Registers_::WRITE_MASK,
|
||||||
|
|||||||
@ -15,6 +15,10 @@
|
|||||||
namespace Peripherals
|
namespace Peripherals
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#define SKULLC_CONCAT_IMPL(x, y) x##y
|
||||||
|
#define SKULLC_CONCAT(x, y) SKULLC_CONCAT_IMPL(x, y)
|
||||||
|
#define SKULLC_TAG struct SKULLC_CONCAT(SkullCTag_, __COUNTER__)
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr const T& clamp(const T& v, const T& lo, const T& hi)
|
constexpr const T& clamp(const T& v, const T& lo, const T& hi)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,16 +1,10 @@
|
|||||||
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
|
||||||
|
|
||||||
option(SKULLC_TESTS_WITH_SANITIZERS "Enable sanitizers for tests." ON)
|
option(TESTS_WITH_SANITIZERS "Enable sanitizers for tests." ON)
|
||||||
|
|
||||||
include(FetchContent)
|
find_package(Catch2 REQUIRED)
|
||||||
|
|
||||||
FetchContent_Declare(Catch2
|
if(TESTS_WITH_SANITIZERS)
|
||||||
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
|
|
||||||
GIT_TAG v2.13.8
|
|
||||||
)
|
|
||||||
FetchContent_MakeAvailable(Catch2)
|
|
||||||
|
|
||||||
if(SKULLC_TESTS_WITH_SANITIZERS)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined -fno-sanitize-recover")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined -fno-sanitize-recover")
|
||||||
set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined -fno-sanitize-recover")
|
set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined -fno-sanitize-recover")
|
||||||
endif()
|
endif()
|
||||||
@ -24,12 +18,7 @@ add_executable(tests
|
|||||||
rand.cpp
|
rand.cpp
|
||||||
fixedpoint.cpp
|
fixedpoint.cpp
|
||||||
pixelbuffer.cpp
|
pixelbuffer.cpp
|
||||||
pixelbuffer_effects.cpp
|
pixelbuffer_effects.cpp function.cpp)
|
||||||
function.cpp
|
|
||||||
assert_ndebug.cpp
|
|
||||||
assert.cpp
|
|
||||||
enum_helpers.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(tests
|
target_link_libraries(tests
|
||||||
PUBLIC
|
PUBLIC
|
||||||
@ -39,12 +28,6 @@ target_link_libraries(tests
|
|||||||
Catch2::Catch2
|
Catch2::Catch2
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(tests
|
|
||||||
PROPERTIES
|
|
||||||
CXX_STANDARD 17
|
|
||||||
)
|
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/contrib)
|
|
||||||
include(CTest)
|
include(CTest)
|
||||||
include(Catch)
|
include(Catch)
|
||||||
catch_discover_tests(tests)
|
catch_discover_tests(tests)
|
||||||
@ -1,68 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by erki on 29.06.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <catch2/catch.hpp>
|
|
||||||
|
|
||||||
#ifdef NDEBUG
|
|
||||||
#undef NDEBUG
|
|
||||||
#define NDEBUG_WAS_SET
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "utility_assert.hpp"
|
|
||||||
|
|
||||||
#ifdef NDEBUG_WAS_SET
|
|
||||||
#define NDEBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
bool assert_flag = false;
|
|
||||||
|
|
||||||
void assertCallback(const char*, const char*, const int)
|
|
||||||
{
|
|
||||||
assert_flag = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}// namespace
|
|
||||||
|
|
||||||
TEST_CASE("Assert debug without NDEBUG gets triggered if check is false.", "[utility],[assert]")
|
|
||||||
{
|
|
||||||
assert_flag = false;
|
|
||||||
Utility::Assert::setHandler(assertCallback);
|
|
||||||
|
|
||||||
SKULLC_ASSERT_DEBUG(false);
|
|
||||||
|
|
||||||
CHECK(assert_flag == true);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Assert debug without NDEBUG doesn't get triggered if check is true.", "[utility],[assert]")
|
|
||||||
{
|
|
||||||
assert_flag = false;
|
|
||||||
Utility::Assert::setHandler(assertCallback);
|
|
||||||
|
|
||||||
SKULLC_ASSERT_DEBUG(true);
|
|
||||||
|
|
||||||
CHECK(assert_flag == false);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Assert safe without NDEBUG gets triggered if check is false.", "[utility],[assert]")
|
|
||||||
{
|
|
||||||
assert_flag = false;
|
|
||||||
Utility::Assert::setHandler(assertCallback);
|
|
||||||
|
|
||||||
SKULLC_ASSERT_SAFE(false);
|
|
||||||
|
|
||||||
CHECK(assert_flag == true);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Assert safe without NDEBUG doesn't get triggered if check is true.", "[utility],[assert]")
|
|
||||||
{
|
|
||||||
assert_flag = false;
|
|
||||||
Utility::Assert::setHandler(assertCallback);
|
|
||||||
|
|
||||||
SKULLC_ASSERT_SAFE(true);
|
|
||||||
|
|
||||||
CHECK(assert_flag == false);
|
|
||||||
}
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by erki on 29.06.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <catch2/catch.hpp>
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
#define NDEBUG
|
|
||||||
#define NDEBUG_WAS_NOT_DEFINED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "utility_assert.hpp"
|
|
||||||
|
|
||||||
#ifdef NDEBUG_WAS_NOT_DEFINED
|
|
||||||
#undef NDEBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
bool assert_flag = false;
|
|
||||||
|
|
||||||
void assertCallback(const char*, const char*, const int)
|
|
||||||
{
|
|
||||||
assert_flag = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}// namespace
|
|
||||||
|
|
||||||
TEST_CASE("Assert debug with NDEBUG is a null-opt.", "[utility],[assert]")
|
|
||||||
{
|
|
||||||
assert_flag = false;
|
|
||||||
Utility::Assert::setHandler(assertCallback);
|
|
||||||
|
|
||||||
int check_number = 0;
|
|
||||||
SKULLC_ASSERT_DEBUG(check_number++ == 0);
|
|
||||||
|
|
||||||
CHECK(check_number == 0);
|
|
||||||
CHECK(assert_flag == false);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Assert safe with NDEBUG gets triggered if check is false.", "[utility],[assert]")
|
|
||||||
{
|
|
||||||
assert_flag = false;
|
|
||||||
Utility::Assert::setHandler(assertCallback);
|
|
||||||
|
|
||||||
int check_number = 0;
|
|
||||||
SKULLC_ASSERT_SAFE(check_number++ == 1);
|
|
||||||
|
|
||||||
CHECK(check_number == 1);
|
|
||||||
CHECK(assert_flag == true);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Assert safe with NDEBUG doesn't get triggered if check is true.", "[utility],[assert]")
|
|
||||||
{
|
|
||||||
assert_flag = false;
|
|
||||||
Utility::Assert::setHandler(assertCallback);
|
|
||||||
|
|
||||||
SKULLC_ASSERT_SAFE(true);
|
|
||||||
|
|
||||||
CHECK(assert_flag == false);
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by erki on 15.07.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <catch2/catch.hpp>
|
|
||||||
|
|
||||||
#include "utility_enum_helpers.hpp"
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
enum class TestEnum : unsigned
|
|
||||||
{
|
|
||||||
FLAG_0 = 1,
|
|
||||||
FLAG_1 = 2,
|
|
||||||
FLAG_2 = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
SKULLC_ENUM_DECLARE_BITFLAG_OPERATORS(TestEnum)
|
|
||||||
|
|
||||||
}// namespace
|
|
||||||
|
|
||||||
TEST_CASE("OR operator works as expected.", "[utility],[enum_helpers]")
|
|
||||||
{
|
|
||||||
const TestEnum a = TestEnum::FLAG_0;
|
|
||||||
const TestEnum b = TestEnum::FLAG_1;
|
|
||||||
|
|
||||||
const TestEnum sum = a | b;
|
|
||||||
CHECK(unsigned(sum) == 3u);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("AND operator works as expected.", "[utility],[enum_helpers]")
|
|
||||||
{
|
|
||||||
const TestEnum a = TestEnum::FLAG_0 | TestEnum::FLAG_1;
|
|
||||||
|
|
||||||
const TestEnum masked_1 = a & TestEnum::FLAG_0;
|
|
||||||
CHECK(masked_1 == TestEnum::FLAG_0);
|
|
||||||
|
|
||||||
const TestEnum masked_2 = a & TestEnum::FLAG_2;
|
|
||||||
CHECK(masked_2 != TestEnum::FLAG_2);
|
|
||||||
}
|
|
||||||
@ -5,7 +5,6 @@
|
|||||||
#include <catch2/catch.hpp>
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
#include <utility_function.hpp>
|
#include <utility_function.hpp>
|
||||||
#include <utility_tag.hpp>
|
|
||||||
|
|
||||||
TEST_CASE("Function calls function appropriately.", "[utility],[function]")
|
TEST_CASE("Function calls function appropriately.", "[utility],[function]")
|
||||||
{
|
{
|
||||||
@ -39,26 +38,6 @@ TEST_CASE("Function passes arguments appropriately.", "[utility],[function]")
|
|||||||
REQUIRE(bool_to_set == true);
|
REQUIRE(bool_to_set == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Function works with toStaticFunction.", "[utility],[function]")
|
|
||||||
{
|
|
||||||
static int int_to_set = 0;
|
|
||||||
static bool bool_to_set = false;
|
|
||||||
|
|
||||||
auto func_to_call = [](const int i, const bool b) {
|
|
||||||
int_to_set = i;
|
|
||||||
bool_to_set = b;
|
|
||||||
};
|
|
||||||
|
|
||||||
Utility::Function<void(int, bool)> function(func_to_call);
|
|
||||||
using signature = void (*)(int, bool);
|
|
||||||
|
|
||||||
signature func_pointer = function.toStaticFunction<SKULLC_TAG>();
|
|
||||||
func_pointer(10, true);
|
|
||||||
|
|
||||||
REQUIRE(int_to_set == 10);
|
|
||||||
REQUIRE(bool_to_set == true);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("FunctionOwned calls function appropriately.", "[utility],[function]")
|
TEST_CASE("FunctionOwned calls function appropriately.", "[utility],[function]")
|
||||||
{
|
{
|
||||||
struct S
|
struct S
|
||||||
@ -103,29 +82,3 @@ TEST_CASE("FunctionOwned passes arguments appropriately.", "[utility],[function]
|
|||||||
REQUIRE(subject.int_to_set == 10);
|
REQUIRE(subject.int_to_set == 10);
|
||||||
REQUIRE(subject.bool_to_set == false);
|
REQUIRE(subject.bool_to_set == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("FunctionOwned works with toStaticFunction.", "[utility],[function]")
|
|
||||||
{
|
|
||||||
struct S
|
|
||||||
{
|
|
||||||
int int_to_set = 0;
|
|
||||||
bool bool_to_set = true;
|
|
||||||
|
|
||||||
void toCall(const int i, const bool b)
|
|
||||||
{
|
|
||||||
int_to_set = i;
|
|
||||||
bool_to_set = b;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
S subject;
|
|
||||||
|
|
||||||
Utility::FunctionOwned<S, void(int, bool)> function(subject, &S::toCall);
|
|
||||||
using signature = void (*)(int, bool);
|
|
||||||
|
|
||||||
signature func_pointer = function.toStaticFunction<SKULLC_TAG>();
|
|
||||||
func_pointer(10, true);
|
|
||||||
|
|
||||||
REQUIRE(subject.int_to_set == 10);
|
|
||||||
REQUIRE(subject.bool_to_set == true);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -15,15 +15,15 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#include <threads_actor_thread.hpp>
|
#include "threads_primitivethread.hpp"
|
||||||
#include <threads_iactor.hpp>
|
#include "threads_signal.hpp"
|
||||||
#include <threads_signal.hpp>
|
#include "threads_timer.hpp"
|
||||||
|
|
||||||
namespace Threads
|
namespace Threads
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename CRTP, typename... Ts>
|
template<typename CRTP, typename... Ts>
|
||||||
class Actor : public IActor
|
class Actor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using value_type = std::variant<Ts...>;
|
using value_type = std::variant<Ts...>;
|
||||||
@ -31,11 +31,14 @@ public:
|
|||||||
static_assert(std::is_default_constructible_v<value_type>, "Ts must be default constructible.");
|
static_assert(std::is_default_constructible_v<value_type>, "Ts must be default constructible.");
|
||||||
static_assert(std::is_trivially_copyable_v<value_type>, "Ts must be trivially copyable.");
|
static_assert(std::is_trivially_copyable_v<value_type>, "Ts must be trivially copyable.");
|
||||||
|
|
||||||
Actor() : IActor(sizeof(value_type)),
|
Actor(const std::uint32_t queue_size, const char* name, const osPriority_t priority, const std::uint32_t stack_size)
|
||||||
signal_(this)
|
: thread_(&Actor<CRTP, Ts...>::threadHandler_, this, name, priority, stack_size),
|
||||||
{}
|
msg_queue_(xQueueCreate(queue_size, sizeof(value_type))), signal_(this)
|
||||||
|
{
|
||||||
|
assert(msg_queue_);
|
||||||
|
}
|
||||||
|
|
||||||
~Actor() override {}
|
virtual ~Actor() {}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Signal : Signallable<T>
|
struct Signal : Signallable<T>
|
||||||
@ -56,13 +59,17 @@ public:
|
|||||||
void emit(const T& data) override
|
void emit(const T& data) override
|
||||||
{
|
{
|
||||||
parent::value_type to_send = data;
|
parent::value_type to_send = data;
|
||||||
q_->dispatchEvent(to_send);
|
xQueueSend(q_->msg_queue_, &to_send, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseType_t emitFromIsr(const T& data) override
|
BaseType_t emitFromIsr(const T& data) override
|
||||||
{
|
{
|
||||||
parent::value_type to_send = data;
|
parent::value_type to_send = data;
|
||||||
return q_->dispatchEventFromIsr(to_send);
|
BaseType_t was_awoken = pdFALSE;
|
||||||
|
|
||||||
|
xQueueSendFromISR(q_->msg_queue_, &to_send, &was_awoken);
|
||||||
|
|
||||||
|
return was_awoken;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -90,12 +97,13 @@ public:
|
|||||||
return &signal_;
|
return &signal_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispatchSignal(const char* data) final
|
protected:
|
||||||
{
|
virtual void init() = 0;
|
||||||
dispatchImpl_(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PrimitiveThread thread_;
|
||||||
|
QueueHandle_t msg_queue_;
|
||||||
|
|
||||||
struct Visitor_
|
struct Visitor_
|
||||||
{
|
{
|
||||||
using parent = Actor<CRTP, Ts...>;
|
using parent = Actor<CRTP, Ts...>;
|
||||||
@ -113,15 +121,113 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void dispatchImpl_(const char* data)
|
void operator()()
|
||||||
{
|
{
|
||||||
const value_type* signal_data = reinterpret_cast<const value_type*>(data);
|
init();
|
||||||
std::visit(Visitor_{this}, *signal_data);
|
|
||||||
|
value_type data{};
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const BaseType_t got = xQueueReceive(msg_queue_, &data, portMAX_DELAY);
|
||||||
|
|
||||||
|
if (got == pdTRUE)
|
||||||
|
{
|
||||||
|
std::visit(Visitor_{this}, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void threadHandler_(void* d)
|
||||||
|
{
|
||||||
|
auto* dd = static_cast<Actor<CRTP, Ts...>*>(d);
|
||||||
|
(*dd)();
|
||||||
}
|
}
|
||||||
|
|
||||||
Signal<value_type> signal_;
|
Signal<value_type> signal_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename CRTP>
|
||||||
|
class Actor<CRTP, void>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using value_type = void;
|
||||||
|
|
||||||
|
Actor(const std::uint32_t queue_size, const char* name, const osPriority_t priority, const std::uint32_t stack_size)
|
||||||
|
: thread_([](void* d) {
|
||||||
|
auto* dd = static_cast<Actor<CRTP, value_type>*>(d);
|
||||||
|
(*dd)();
|
||||||
|
},
|
||||||
|
this, name, priority, stack_size),
|
||||||
|
msg_queue_(xQueueCreate(queue_size, sizeof(int))), signal_(*this)
|
||||||
|
{
|
||||||
|
assert(msg_queue_);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~Actor() {}
|
||||||
|
|
||||||
|
Signallable<value_type>* getSignal()
|
||||||
|
{
|
||||||
|
return &signal_;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void init() = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
PrimitiveThread thread_;
|
||||||
|
QueueHandle_t msg_queue_;
|
||||||
|
|
||||||
|
void operator()()
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
|
||||||
|
int data;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const BaseType_t got = xQueueReceive(msg_queue_, &data, portMAX_DELAY);
|
||||||
|
|
||||||
|
if (got == pdTRUE)
|
||||||
|
{
|
||||||
|
auto* crtp = static_cast<CRTP*>(this);
|
||||||
|
crtp->onSignal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
friend struct Signal_;
|
||||||
|
|
||||||
|
struct Signal_ : Signallable<value_type>
|
||||||
|
{
|
||||||
|
using parent = Actor<CRTP, void>;
|
||||||
|
parent& q;
|
||||||
|
|
||||||
|
explicit Signal_(parent& q)
|
||||||
|
: q(q)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void emit() override
|
||||||
|
{
|
||||||
|
const int data = 0;
|
||||||
|
|
||||||
|
xQueueSend(q.msg_queue_, &data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseType_t emitFromIsr() override
|
||||||
|
{
|
||||||
|
const int data = 0;
|
||||||
|
|
||||||
|
BaseType_t was_awoken = pdFALSE;
|
||||||
|
xQueueSendFromISR(q.msg_queue_, &data, &was_awoken);
|
||||||
|
|
||||||
|
return was_awoken;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Signal_ signal_;
|
||||||
|
};
|
||||||
|
|
||||||
}// namespace Threads
|
}// namespace Threads
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* threads_actor_thread.hpp
|
|
||||||
*
|
|
||||||
* Created on: Nov 13, 2021
|
|
||||||
* Author: erki
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SKULLC_THREADS_ACTOR_THREAD_HPP_
|
|
||||||
#define SKULLC_THREADS_ACTOR_THREAD_HPP_
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include <freertos_os2.h>
|
|
||||||
#include <queue.h>
|
|
||||||
|
|
||||||
#include <threads_thread.hpp>
|
|
||||||
|
|
||||||
namespace Threads
|
|
||||||
{
|
|
||||||
|
|
||||||
class IActor;
|
|
||||||
|
|
||||||
class ActorThread : public Thread<ActorThread>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ActorThread(const std::size_t queue_length, const char* name, const osPriority_t priority, const std::uint32_t stack_size);
|
|
||||||
|
|
||||||
void operator()();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void init_();
|
|
||||||
void doMessageLoop_();
|
|
||||||
|
|
||||||
friend class IActor;
|
|
||||||
std::size_t acceptActor_(IActor* actor);
|
|
||||||
|
|
||||||
std::size_t queue_length_;
|
|
||||||
std::size_t queue_item_length_ = 0;
|
|
||||||
|
|
||||||
QueueHandle_t queue_ = nullptr;
|
|
||||||
char* rx_buffer_ = nullptr;
|
|
||||||
char* tx_buffer_ = nullptr;
|
|
||||||
std::array<IActor*, 32> actors_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}// namespace Threads
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* SKULLC_THREADS_ACTOR_THREAD_HPP_ */
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* threads_iactor.hpp
|
|
||||||
*
|
|
||||||
* Created on: Nov 14, 2021
|
|
||||||
* Author: erki
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SKULLC_THREADS_IACTOR_HPP_
|
|
||||||
#define SKULLC_THREADS_IACTOR_HPP_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include <freertos_os2.h>
|
|
||||||
|
|
||||||
namespace Threads
|
|
||||||
{
|
|
||||||
|
|
||||||
class ActorThread;
|
|
||||||
|
|
||||||
class IActor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IActor(const std::size_t signal_size)
|
|
||||||
: signal_size_(signal_size)
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual ~IActor() {}
|
|
||||||
|
|
||||||
virtual void init() = 0;
|
|
||||||
virtual void dispatchSignal(const char* data) = 0;
|
|
||||||
|
|
||||||
void moveToThread(ActorThread* thread);
|
|
||||||
|
|
||||||
std::size_t actorIndex() const
|
|
||||||
{
|
|
||||||
return actor_index_;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t signalSize() const
|
|
||||||
{
|
|
||||||
return signal_size_;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
template<typename T>
|
|
||||||
void dispatchEvent(const T& data)
|
|
||||||
{
|
|
||||||
dispatchEventImpl_(&data, sizeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
BaseType_t dispatchEventFromIsr(const T& data)
|
|
||||||
{
|
|
||||||
return dispatchEventFromIsrImpl_(&data, sizeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ActorThread* parent_thread_ = nullptr;
|
|
||||||
std::size_t actor_index_ = 0;
|
|
||||||
std::size_t signal_size_;
|
|
||||||
|
|
||||||
void dispatchEventImpl_(const void* data, const std::size_t data_size);
|
|
||||||
BaseType_t dispatchEventFromIsrImpl_(const void* data, const std::size_t data_size);
|
|
||||||
};
|
|
||||||
|
|
||||||
}// namespace Threads
|
|
||||||
|
|
||||||
#endif /* SKULLC_THREADS_IACTOR_HPP_ */
|
|
||||||
@ -1,110 +0,0 @@
|
|||||||
/*
|
|
||||||
* threads_actor_thread.cpp
|
|
||||||
*
|
|
||||||
* Created on: Nov 13, 2021
|
|
||||||
* Author: erki
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "threads_actor_thread.hpp"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include <threads_iactor.hpp>
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
struct SignalMessage
|
|
||||||
{
|
|
||||||
std::size_t actor_index;
|
|
||||||
const char* data;
|
|
||||||
|
|
||||||
static SignalMessage fromData(char* data)
|
|
||||||
{
|
|
||||||
SignalMessage message;
|
|
||||||
std::memcpy(&message.actor_index, data, sizeof(message.actor_index));
|
|
||||||
message.data = data + sizeof(message.actor_index);
|
|
||||||
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}// namespace
|
|
||||||
|
|
||||||
namespace Threads
|
|
||||||
{
|
|
||||||
|
|
||||||
ActorThread::ActorThread(const std::size_t queue_length, const char* name, const osPriority_t priority, const std::uint32_t stack_size)
|
|
||||||
: Thread<ActorThread>(name, priority, stack_size), queue_length_(queue_length), queue_(nullptr)
|
|
||||||
{
|
|
||||||
actors_.fill(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActorThread::operator()()
|
|
||||||
{
|
|
||||||
init_();
|
|
||||||
|
|
||||||
osThreadYield();
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
doMessageLoop_();
|
|
||||||
|
|
||||||
osThreadYield();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActorThread::init_()
|
|
||||||
{
|
|
||||||
for (IActor* actor : actors_)
|
|
||||||
{
|
|
||||||
if (actor != nullptr)
|
|
||||||
{
|
|
||||||
queue_item_length_ = std::max(queue_item_length_, actor->signalSize());
|
|
||||||
|
|
||||||
actor->init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
queue_ = xQueueCreate(queue_length_, queue_item_length_ + sizeof(std::size_t));
|
|
||||||
assert(queue_ != nullptr);
|
|
||||||
|
|
||||||
rx_buffer_ = new char[queue_item_length_ + sizeof(std::size_t)];
|
|
||||||
tx_buffer_ = new char[queue_item_length_ + sizeof(std::size_t)];
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActorThread::doMessageLoop_()
|
|
||||||
{
|
|
||||||
const BaseType_t has_data = xQueueReceive(queue_, rx_buffer_, portMAX_DELAY);
|
|
||||||
|
|
||||||
if (has_data == pdTRUE)
|
|
||||||
{
|
|
||||||
const SignalMessage message = SignalMessage::fromData(rx_buffer_);
|
|
||||||
assert(message.actor_index <= actors_.size());
|
|
||||||
|
|
||||||
IActor* actor = actors_[message.actor_index];
|
|
||||||
assert(actor != nullptr);
|
|
||||||
|
|
||||||
actor->dispatchSignal(message.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t ActorThread::acceptActor_(IActor* actor)
|
|
||||||
{
|
|
||||||
for (auto it = actors_.begin(); it != actors_.end(); ++it)
|
|
||||||
{
|
|
||||||
if (*it == nullptr)
|
|
||||||
{
|
|
||||||
*it = actor;
|
|
||||||
return std::distance(actors_.begin(), it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(false);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}// namespace Threads
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* threads_iactor.cpp
|
|
||||||
*
|
|
||||||
* Created on: Nov 14, 2021
|
|
||||||
* Author: erki
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "threads_iactor.hpp"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include <queue.h>
|
|
||||||
|
|
||||||
#include "threads_actor_thread.hpp"
|
|
||||||
|
|
||||||
namespace Threads
|
|
||||||
{
|
|
||||||
|
|
||||||
void IActor::moveToThread(ActorThread* thread)
|
|
||||||
{
|
|
||||||
actor_index_ = thread->acceptActor_(this);
|
|
||||||
parent_thread_ = thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IActor::dispatchEventImpl_(const void* data, const std::size_t data_size)
|
|
||||||
{
|
|
||||||
taskENTER_CRITICAL();
|
|
||||||
|
|
||||||
std::memcpy(parent_thread_->tx_buffer_, &actor_index_, sizeof(std::size_t));
|
|
||||||
char* data_dest = parent_thread_->tx_buffer_ + sizeof(std::size_t);
|
|
||||||
std::memcpy(data_dest, data, data_size);
|
|
||||||
|
|
||||||
xQueueSend(parent_thread_->queue_, parent_thread_->tx_buffer_, 0);
|
|
||||||
|
|
||||||
taskEXIT_CRITICAL();
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseType_t IActor::dispatchEventFromIsrImpl_(const void* data, const std::size_t data_size)
|
|
||||||
{
|
|
||||||
const auto isr_data = taskENTER_CRITICAL_FROM_ISR();
|
|
||||||
|
|
||||||
std::memcpy(parent_thread_->tx_buffer_, &actor_index_, sizeof(std::size_t));
|
|
||||||
char* data_dest = parent_thread_->tx_buffer_ + sizeof(std::size_t);
|
|
||||||
std::memcpy(data_dest, data, data_size);
|
|
||||||
|
|
||||||
BaseType_t task_awoken = pdFALSE;
|
|
||||||
xQueueSendFromISR(parent_thread_->queue_, parent_thread_->tx_buffer_, &task_awoken);
|
|
||||||
|
|
||||||
taskEXIT_CRITICAL_FROM_ISR(isr_data);
|
|
||||||
|
|
||||||
return task_awoken;
|
|
||||||
}
|
|
||||||
|
|
||||||
}// namespace Threads
|
|
||||||
@ -1,9 +1,13 @@
|
|||||||
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
|
||||||
|
|
||||||
|
#if(WITH_HAL)
|
||||||
|
# set(additional_sources
|
||||||
|
# )
|
||||||
|
#endif()
|
||||||
|
|
||||||
add_library(utility STATIC
|
add_library(utility STATIC
|
||||||
Src/utility_logging.cpp
|
Src/utility_logging.cpp
|
||||||
Src/utility_rand.cpp
|
Src/utility_rand.cpp
|
||||||
Src/utility_assert.cpp
|
|
||||||
${additional_sources}
|
${additional_sources}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,9 +18,5 @@ target_include_directories(utility
|
|||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Inc>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Inc>
|
||||||
$<INSTALL_INTERFACE:include>
|
$<INSTALL_INTERFACE:include>
|
||||||
)
|
)
|
||||||
set_target_properties(utility
|
|
||||||
PROPERTIES
|
|
||||||
CXX_STANDARD 17
|
|
||||||
)
|
|
||||||
|
|
||||||
skullc_install_packages(skullc utility ${SKULLC_VERSION})
|
skullc_install_packages(skullc utility ${version})
|
||||||
|
|||||||
@ -1,33 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by erki on 29.06.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef SKULLC_UTILITY_ASSERT_HPP_
|
|
||||||
#define SKULLC_UTILITY_ASSERT_HPP_
|
|
||||||
|
|
||||||
namespace Utility::Assert::Detail
|
|
||||||
{
|
|
||||||
|
|
||||||
void assertImpl(const char* expression, const char* file, const int line);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
#define SKULLC_ASSERT_DEBUG(e) (!(e) ? Utility::Assert::Detail::assertImpl(#e, __FILE__, __LINE__) : ((void) 0))
|
|
||||||
#else
|
|
||||||
#define SKULLC_ASSERT_DEBUG(e)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SKULLC_ASSERT_SAFE(e) (!(e) ? Utility::Assert::Detail::assertImpl(#e, __FILE__, __LINE__) : ((void) 0))
|
|
||||||
|
|
||||||
namespace Utility::Assert
|
|
||||||
{
|
|
||||||
|
|
||||||
using assert_cb = void (*)(const char* expression, const char* file, const int line);
|
|
||||||
|
|
||||||
void setHandler(assert_cb callback);
|
|
||||||
assert_cb getHandler();
|
|
||||||
|
|
||||||
}// namespace Utility::Assert
|
|
||||||
|
|
||||||
#endif// SKULLC_UTILITY_ASSERT_HPP_
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by erki on 15.07.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef SKULLC_UTILITY_ENUM_HELPERS_HPP_
|
|
||||||
#define SKULLC_UTILITY_ENUM_HELPERS_HPP_
|
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#define SKULLC_ENUM_DECLARE_BITFLAG_OPERATORS(E) \
|
|
||||||
inline E operator|(const E& lhs, const E& rhs) \
|
|
||||||
{ \
|
|
||||||
using T = std::underlying_type_t<E>; \
|
|
||||||
return static_cast<E>(static_cast<T>(lhs) | static_cast<T>(rhs)); \
|
|
||||||
} \
|
|
||||||
inline E operator&(const E& lhs, const E& rhs) \
|
|
||||||
{ \
|
|
||||||
using T = std::underlying_type_t<E>; \
|
|
||||||
return static_cast<E>(static_cast<T>(lhs) & static_cast<T>(rhs)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif//SKULLC_UTILITY_ENUM_HELPERS_HPP_
|
|
||||||
@ -8,8 +8,6 @@
|
|||||||
#ifndef SKULLC_UTILITY_FUNCTION_HPP_
|
#ifndef SKULLC_UTILITY_FUNCTION_HPP_
|
||||||
#define SKULLC_UTILITY_FUNCTION_HPP_
|
#define SKULLC_UTILITY_FUNCTION_HPP_
|
||||||
|
|
||||||
#include <utility_assert.hpp>
|
|
||||||
|
|
||||||
namespace Utility
|
namespace Utility
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -21,19 +19,11 @@ class IFunction<R(Args...)>
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using result_type = R;
|
using result_type = R;
|
||||||
using static_signature = R (*)(Args...);
|
|
||||||
|
|
||||||
virtual ~IFunction()
|
virtual ~IFunction()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual result_type operator()(Args... args) = 0;
|
virtual result_type operator()(Args... args) = 0;
|
||||||
|
|
||||||
template<typename Tag>
|
|
||||||
static_signature toStaticFunction()
|
|
||||||
{
|
|
||||||
static decltype(this) h = this;
|
|
||||||
return +[](Args... args) { (*h)(args...); };
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class>
|
template<class>
|
||||||
@ -51,7 +41,7 @@ public:
|
|||||||
explicit Function(signature callable)
|
explicit Function(signature callable)
|
||||||
: callable_(callable)
|
: callable_(callable)
|
||||||
{
|
{
|
||||||
SKULLC_ASSERT_DEBUG(callable_);
|
assert(callable_);
|
||||||
}
|
}
|
||||||
|
|
||||||
~Function() override
|
~Function() override
|
||||||
@ -83,7 +73,7 @@ public:
|
|||||||
explicit FunctionOwned(source& src, signature callable)
|
explicit FunctionOwned(source& src, signature callable)
|
||||||
: src_(&src), callable_(callable)
|
: src_(&src), callable_(callable)
|
||||||
{
|
{
|
||||||
SKULLC_ASSERT_DEBUG(callable_);
|
assert(callable_);
|
||||||
}
|
}
|
||||||
|
|
||||||
~FunctionOwned() override
|
~FunctionOwned() override
|
||||||
|
|||||||
@ -8,11 +8,8 @@
|
|||||||
#ifndef SKULLC_UTILITY_STATICPOINTER_HPP_
|
#ifndef SKULLC_UTILITY_STATICPOINTER_HPP_
|
||||||
#define SKULLC_UTILITY_STATICPOINTER_HPP_
|
#define SKULLC_UTILITY_STATICPOINTER_HPP_
|
||||||
|
|
||||||
#include <new>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <utility_assert.hpp>
|
|
||||||
|
|
||||||
namespace Utility
|
namespace Utility
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -60,18 +57,6 @@ struct StaticPointer
|
|||||||
return initialized_;
|
return initialized_;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type* get()
|
|
||||||
{
|
|
||||||
SKULLC_ASSERT_DEBUG(initialized_);
|
|
||||||
return reinterpret_cast<value_type*>(storage);
|
|
||||||
}
|
|
||||||
|
|
||||||
const value_type* get() const
|
|
||||||
{
|
|
||||||
SKULLC_ASSERT_DEBUG(initialized_);
|
|
||||||
return reinterpret_cast<const value_type*>(storage);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool initialized_ = false;
|
bool initialized_ = false;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by erki on 26.06.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef SKULLC_UTILITY_TAG_HPP_
|
|
||||||
#define SKULLC_UTILITY_TAG_HPP_
|
|
||||||
|
|
||||||
#define SKULLC_CONCAT_IMPL(x, y) x##y
|
|
||||||
#define SKULLC_CONCAT(x, y) SKULLC_CONCAT_IMPL(x, y)
|
|
||||||
#define SKULLC_TAG struct SKULLC_CONCAT(SkullCTag_, __COUNTER__)
|
|
||||||
|
|
||||||
#endif// SKULLC_UTILITY_TAG_HPP_
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by erki on 29.06.22.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "utility_assert.hpp"
|
|
||||||
|
|
||||||
#include <exception>
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
Utility::Assert::assert_cb INSTALLED_HANDLER = nullptr;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Utility::Assert
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace Detail
|
|
||||||
{
|
|
||||||
|
|
||||||
void assertImpl(const char* expression, const char* file, const int line)
|
|
||||||
{
|
|
||||||
if (INSTALLED_HANDLER)
|
|
||||||
INSTALLED_HANDLER(expression, file, line);
|
|
||||||
else
|
|
||||||
std::terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
}// namespace Detail
|
|
||||||
|
|
||||||
void setHandler(assert_cb callback)
|
|
||||||
{
|
|
||||||
INSTALLED_HANDLER = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_cb getHandler()
|
|
||||||
{
|
|
||||||
return INSTALLED_HANDLER;
|
|
||||||
}
|
|
||||||
|
|
||||||
}// namespace Utility::Assert
|
|
||||||
Loading…
x
Reference in New Issue
Block a user