Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
name: tests

on:
push:
branches: [master]
pull_request:
branches: [master]
on: [push]

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
Expand Down
26 changes: 23 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,43 @@ project(tyndall)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(C_CXX_EXTRA_FLAGS "-O2 -Wall -Wconversion -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -fconcepts-diagnostics-depth=4")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(C_CXX_EXTRA_FLAGS "-O2 -Wall -Wconversion -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -fconcepts-diagnostics-depth=4")
else()
set(C_CXX_EXTRA_FLAGS "-O2 -Wall -Wconversion -Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
endif()

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${C_CXX_EXTRA_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_EXTRA_FLAGS}")

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wno-gnu-string-literal-operator-template)
endif()

add_definitions(-DDEBUG)

include_directories(${CMAKE_SOURCE_DIR})
set(LD_FLAGS "-lpthread -lzmq -lprotobuf -lfmt -lrt -latomic")
set(LD_FLAGS "-lpthread")

if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(LD_FLAGS "${LD_FLAGS} -lrt -latomic")
endif()

link_directories(${ZeroMQ_LIBRARY_DIRS})

find_package(ament_cmake)
find_package(rclcpp)
find_package(std_msgs)
find_package(std_srvs)
find_package(builtin_interfaces)
find_package(Boost COMPONENTS program_options filesystem REQUIRED)
find_package(Protobuf REQUIRED)
find_package(fmt REQUIRED)

find_package(PkgConfig REQUIRED)
pkg_check_modules(ZeroMQ REQUIRED libzmq)

if("${rclcpp_FOUND}")
message(STATUS "ROS2 found")
Expand All @@ -33,7 +53,7 @@ endif()

file(GLOB CFILES "tyndall/*.c*" "tyndall/*/*.c*")
add_library(tyndall SHARED ${CFILES})
target_link_libraries(tyndall ${LD_FLAGS})
target_link_libraries(tyndall ${ZeroMQ_LIBRARIES} ${Protobuf_LIBRARIES} fmt::fmt ${LD_FLAGS})
install(TARGETS tyndall DESTINATION lib)

if("${rclcpp_FOUND}")
Expand Down
2 changes: 1 addition & 1 deletion examples/meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ int main() {
printf("replace: %s\n", ("hei din sei"_strval).replace<'i', 'y'>().c_str());
printf("remove_leading: %s\n",
("///hei din sei"_strval).remove_leading<'/'>().c_str());
printf("to_strval: %s\n", to_strval<42>::c_str());
printf("to_strval: %s\n", to_strval<42>{}.c_str());

{
printf("typevals:\n");
Expand Down
4 changes: 4 additions & 0 deletions tests/ipc/ipc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ int main() {
{
my_struct entry = {};
int rc = ipc_read(entry, "/test/standard");
if (rc != 0) {
perror("ipc_read failed");
std::cerr << "ipc_read returned error code: " << rc << std::endl;
}
check(rc == 0);
check(entry == ref);
}
Expand Down
31 changes: 25 additions & 6 deletions tests/meta/strval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,18 @@
#include <tyndall/meta/typeinfo.h>
#include <type_traits>


int main() {
constexpr auto hei = "hei"_strval;
decltype(hei)::c_str();
static_assert(hei.get<0>() == 'h');
static_assert(hei.get<1>() == 'e');
static_assert(hei.get<2>() == 'i');
decltype(hei){}.c_str();
static_assert(hei.length() == 3);
static_assert(hei + "du"_strval == "heidu"_strval);
static_assert(("hei din sei"_strval).occurrences('i') == 3);
static_assert(("a_b_c"_strval).replace<'_', '-'>() == "a-b-c"_strval);
static_assert(("///hei"_strval).remove_leading<'/'>() == hei);
static_assert(to_strval<42>{} == "42"_strval);
static_assert(sizeof(hei) == 3);
static_assert(sizeof(""_strval) == 0);
static_assert(sizeof(hei) == 4);
static_assert(sizeof(""_strval) == 1);

{
char buf[100];
Expand All @@ -27,4 +25,25 @@ int main() {
*hei_p = {};
assert(strcmp(buf, hei.c_str()) == 0);
}

{
assert("abcdef"_strval.length() == 6);
assert("abcdef"_strval.occurrences('a') == 1);
assert("abcdef"_strval.occurrences('b') == 1);
assert("abcdef"_strval.occurrences('c') == 1);
assert("abcdef"_strval.occurrences('d') == 1);
assert("abcdef"_strval.occurrences('e') == 1);
assert("abcdef"_strval.occurrences('f') == 1);
assert("abcdef"_strval.occurrences('g') == 0);
}

{
assert("/test/standard"_strval.length() == 14);
assert("/test/standard"_strval.occurrences('/') == 2);
assert("/test/standard"_strval.occurrences('t') == 3);
assert("/test/standard"_strval.occurrences('e') == 1);
assert("/test/standard"_strval.occurrences('s') == 2);
assert("/test/standard"_strval.occurrences('a') == 2);

}
}
2 changes: 1 addition & 1 deletion tests/reflect/reflect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ int main() {
static_assert(!std::is_aggregate_v<decltype(msg)> &&
!std::is_scalar_v<decltype(msg)>);
static_assert(reflect<decltype(msg)>().get_format() == ""_strval);
static_assert(sizeof(reflect<decltype(msg)>().get_format()) == 0);
static_assert(sizeof(reflect<decltype(msg)>().get_format()) == 1);
static_assert(reflect<decltype(msg)>().size() == 0);
}
}
24 changes: 5 additions & 19 deletions tyndall/ipc/id.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,14 @@
#include <tyndall/meta/strval.h>

#ifndef IPC_SHMEM_PREFIX
// echo ipc | sha1sum # more unique shared memory
// names reduce the chance of name collisions
#define IPC_SHMEM_PREFIX \
"ipc" \
"1ef42bc4e0bbfeb0ac34bc3642732768cf6f77b7"
#define IPC_SHMEM_PREFIX "tyn"
#endif

// Shared memory files all go in /dev/shm, so they need to be unique, and they
// can't have folders. We take names that look like absolute paths, like
// "/my-process/my_topic". We start with a prepend a constant unique prefix
// (IPC_SHMEM_PREFIX), Then we add the id, without leading slashes, and with the
// remaining slashes replaced with underscores. And lastly, we append a hash of
// the the id without leading slashes, but with slashes. The last hash is to
// distinguish between eg. my/topic and my_topic.
// remaining slashes replaced with underscores.

// Note that "my-topic" gets the same id as "/my-topic" and "//my-topic" etc.

Expand All @@ -27,22 +21,15 @@ template <typename STRING>
using id_remove_leading_slashes =
decltype(STRING::template remove_leading<'/'>());

template <typename STRING>
using id_hash = decltype(to_strval<hash_fnv1a_32<STRING>()>{});

template <typename STRING>
using id_replace_slashes_with_underscores =
decltype(STRING::template replace<'/', '_'>());
decltype(STRING::template replace<'/', '%'>());

template <typename ID>
using id_prepare =
decltype(create_strval(IPC_SHMEM_PREFIX) + "_"_strval +
id_replace_slashes_with_underscores<
id_remove_leading_slashes<ID>>{}
// switch slashes with underscores
+ "_"_strval + id_hash<id_remove_leading_slashes<ID>>{}
// hash id to prevent name clash between f.ex. /my/topic and
// my_topic
);

// runtime id generation
Expand All @@ -52,13 +39,12 @@ static inline std::string id_rtid_prepare(const char *id) {
while (*id == '/')
++id;

std::string prepared_id = IPC_SHMEM_PREFIX "_" + std::string{id} + "_" +
std::to_string(hash_fnv1a_32(id, strlen(id)));
std::string prepared_id = IPC_SHMEM_PREFIX "_" + std::string{id};

// replace slash with underscore
for (char &c : prepared_id)
if (c == '/')
c = '_';
c = '%';

return prepared_id;
}
Loading
Loading