Skip to content
Merged
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
66 changes: 62 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,40 @@ name: ci

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

jobs:
build-and-test-linux:
runs-on: ubuntu-22.04
build-and-test:
name: build-and-test-${{ matrix.platform }} (${{ matrix.cxx_standard }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
cxx_standard: [11, 14, 17]
include:
- platform: linux
os: ubuntu-22.04
cxx_standard: 11
- platform: linux
os: ubuntu-22.04
cxx_standard: 14
- platform: linux
os: ubuntu-22.04
cxx_standard: 17
- platform: windows
os: windows-latest
cxx_standard: 11
- platform: windows
os: windows-latest
cxx_standard: 14
- platform: windows
os: windows-latest
cxx_standard: 17
- platform: macos
os: macos-latest
cxx_standard: 17

steps:
- name: Checkout repository
Expand All @@ -21,7 +45,7 @@ jobs:

- name: Configure
run: >
cmake -S . -B build
cmake -S . -B build -G Ninja
-DCONSOLIX_CXX_STANDARD=${{ matrix.cxx_standard }}
-DCONSOLIX_BUILD_EXAMPLES=ON
-DCONSOLIX_BUILD_TESTS=ON
Expand All @@ -31,3 +55,37 @@ jobs:

- name: Test
run: ctest --test-dir build --output-on-failure

build-and-test-event-hub:
name: build-and-test-event-hub-${{ matrix.platform }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- platform: linux
os: ubuntu-22.04
- platform: windows
os: windows-latest
- platform: macos
os: macos-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true

- name: Configure
run: >
cmake -S . -B build -G Ninja
-DCONSOLIX_CXX_STANDARD=17
-DCONSOLIX_USE_EVENT_HUB=ON
-DCONSOLIX_BUILD_EXAMPLES=ON
-DCONSOLIX_BUILD_TESTS=ON

- name: Build
run: cmake --build build --parallel

- name: Test
run: ctest --test-dir build --output-on-failure
21 changes: 13 additions & 8 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
[submodule "libs/log-it-cpp"]
path = libs/log-it-cpp
[submodule "external/log-it-cpp"]
path = external/log-it-cpp
url = https://github.com/NewYaroslav/log-it-cpp.git
[submodule "libs/time-shield-cpp"]
path = libs/time-shield-cpp
branch = main
[submodule "external/time-shield-cpp"]
path = external/time-shield-cpp
url = https://github.com/NewYaroslav/time-shield-cpp.git
branch = main
[submodule "libs/cxxopts"]
path = libs/cxxopts
[submodule "external/cxxopts"]
path = external/cxxopts
url = https://github.com/jarro2783/cxxopts.git
[submodule "libs/json"]
path = libs/json
[submodule "external/json"]
path = external/json
url = https://github.com/nlohmann/json.git
[submodule "external/event-hub-cpp"]
path = external/event-hub-cpp
url = https://github.com/NewYaroslav/event-hub-cpp.git
branch = main
[submodule ".github/doxygen-awesome-css"]
path = .github/doxygen-awesome-css
url = https://github.com/jothepro/doxygen-awesome-css.git
36 changes: 32 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ endif()
option(CONSOLIX_USE_LOGIT "Use LogIt++ logging library" ON)
option(CONSOLIX_USE_JSON "Use nlohmann/json" ON)
option(CONSOLIX_USE_CXXOPTS "Use cxxopts for argument parsing" ON)
option(CONSOLIX_USE_EVENT_HUB "Use optional event-hub-cpp integration" OFF)
option(CONSOLIX_BUILD_EXAMPLES "Build Consolix examples" ON)
option(CONSOLIX_BUILD_TESTS "Build Consolix tests" ON)

if(CONSOLIX_USE_EVENT_HUB AND CONSOLIX_CXX_STANDARD LESS 17)
message(FATAL_ERROR "CONSOLIX_USE_EVENT_HUB requires CONSOLIX_CXX_STANDARD=17")
endif()

set(CMAKE_CXX_STANDARD ${CONSOLIX_CXX_STANDARD})
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
Expand All @@ -34,29 +39,42 @@ target_compile_definitions(Consolix
CONSOLIX_USE_LOGIT=$<BOOL:${CONSOLIX_USE_LOGIT}>
CONSOLIX_USE_JSON=$<BOOL:${CONSOLIX_USE_JSON}>
CONSOLIX_USE_CXXOPTS=$<BOOL:${CONSOLIX_USE_CXXOPTS}>
CONSOLIX_USE_EVENT_HUB=$<BOOL:${CONSOLIX_USE_EVENT_HUB}>
CONSOLIX_BASE_PATH="${CMAKE_CURRENT_SOURCE_DIR}"
)

if(CONSOLIX_USE_LOGIT)
target_include_directories(Consolix
SYSTEM INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/libs/log-it-cpp/include/logit_cpp>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/libs/time-shield-cpp/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/external/log-it-cpp/include/logit_cpp>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/external/time-shield-cpp/include>
)
endif()

if(CONSOLIX_USE_JSON)
target_include_directories(Consolix
SYSTEM INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/libs/json/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/external/json/include>
)
endif()

if(CONSOLIX_USE_CXXOPTS)
target_include_directories(Consolix
SYSTEM INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/libs/cxxopts/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/external/cxxopts/include>
)
endif()

if(CONSOLIX_USE_EVENT_HUB)
set(EVENT_HUB_CPP_BUILD_EXAMPLES OFF CACHE BOOL "Build event-hub-cpp examples" FORCE)
set(EVENT_HUB_CPP_BUILD_TESTS OFF CACHE BOOL "Build event-hub-cpp tests" FORCE)
set(EVENT_HUB_CPP_USE_TIME_SHIELD OFF CACHE BOOL "Enable optional time-shield-cpp integration" FORCE)

add_subdirectory(
${CMAKE_CURRENT_SOURCE_DIR}/external/event-hub-cpp
${CMAKE_CURRENT_BINARY_DIR}/external/event-hub-cpp
)
target_link_libraries(Consolix INTERFACE event_hub::event_hub)
endif()

if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CONSOLIX_CXX_STANDARD LESS 17)
Expand Down Expand Up @@ -125,4 +143,14 @@ if(CONSOLIX_BUILD_TESTS)
target_compile_definitions(test_posix_signal_shutdown PRIVATE CONSOLIX_WAIT_ON_ERROR=0)
set_tests_properties(test_posix_signal_shutdown PROPERTIES TIMEOUT 15)
endif()

if(CONSOLIX_USE_EVENT_HUB AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_event_hub_component.cpp")
consolix_add_test(test_event_hub_component "tests/test_event_hub_component.cpp")
set_tests_properties(test_event_hub_component PROPERTIES TIMEOUT 15)
endif()

if(CONSOLIX_USE_EVENT_HUB AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_module_hub_component.cpp")
consolix_add_test(test_module_hub_component "tests/test_module_hub_component.cpp")
set_tests_properties(test_module_hub_component PROPERTIES TIMEOUT 15)
endif()
endif()
1 change: 1 addition & 0 deletions external/cxxopts
Submodule cxxopts added at a3a21b
1 change: 1 addition & 0 deletions external/event-hub-cpp
Submodule event-hub-cpp added at 9e8b1a
1 change: 1 addition & 0 deletions external/json
Submodule json added at e08b3c
1 change: 1 addition & 0 deletions external/log-it-cpp
Submodule log-it-cpp added at 3a8bd8
1 change: 1 addition & 0 deletions external/time-shield-cpp
Submodule time-shield-cpp added at d3c251
13 changes: 12 additions & 1 deletion include/consolix/components.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@
/// - **ConfigComponent**: Loads and manages configuration from JSON files.
/// - **BaseLoopComponent**: A base class for loop-based components.
/// - **LoopComponent**: A component with customizable execution loops.
/// - **EventHubComponent**: Optional bridge to event-hub-cpp EventBus and TaskManager.
/// - **ModuleHubComponent**: Optional bridge to event-hub-cpp ModuleHub.
///
/// ### Key Features:
/// - Easy integration of logging and logo rendering.
/// - Convenient handling of command-line arguments.
/// - Lightweight JSON configuration management, including support for comments.
/// - Support for custom execution loops using either a base class or the LoopComponent.
/// - Optional event-hub-cpp processing from the Consolix component loop.
/// - UTF-8 support for program titles on all platforms:
/// - Automatically converted to UTF-16 on Windows for proper Unicode rendering.
/// - Displayed via ANSI escape sequences on Linux/macOS.
Expand All @@ -54,6 +57,8 @@
/// - `components/ConfigComponent.hpp`
/// - `components/BaseLoopComponent.hpp`
/// - `components/LoopComponent.hpp`
/// - `components/EventHubComponent.hpp` when `CONSOLIX_USE_EVENT_HUB=1`
/// - `components/ModuleHubComponent.hpp` when `CONSOLIX_USE_EVENT_HUB=1`
///
/// ### Example Usage:
///
Expand Down Expand Up @@ -94,11 +99,17 @@
#include "core/service_utils.hpp" ///< Utility functions for working with services.

// Core components of the Consolix framework
#include "components/TitleComponent.hpp" ///< Component for managing the console window title across platforms.
#include "components/TitleComponent.hpp" ///< Component for managing the console window title across platforms.
#include "components/LoggerComponent.hpp" ///< Component for managing logging.
#include "components/LogoComponent.hpp" ///< Component for rendering logos in the console.
#include "components/BaseLoopComponent.hpp" ///< Base class for implementing loop-based components.
#include "components/LoopComponent.hpp" ///< Component with configurable initialization, loop, and shutdown callbacks.

#if CONSOLIX_USE_EVENT_HUB == 1
#include "components/EventHubComponent.hpp" ///< Optional event-hub-cpp EventBus/TaskManager integration component.
#include "components/ModuleHubComponent.hpp" ///< Optional event-hub-cpp ModuleHub integration component.
#endif

#include "components/CliComponent.hpp" ///< Component for handling command-line arguments.

// JSON configuration management
Expand Down
114 changes: 114 additions & 0 deletions include/consolix/components/EventHubComponent.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#pragma once
#ifndef _CONSOLIX_EVENT_HUB_COMPONENT_HPP_INCLUDED
#define _CONSOLIX_EVENT_HUB_COMPONENT_HPP_INCLUDED

/// \file EventHubComponent.hpp
/// \brief Defines optional event-hub-cpp processing component.
/// \ingroup Components

#if CONSOLIX_USE_EVENT_HUB == 1

#include <cstddef>

#include <event_hub.hpp>

namespace consolix {

/// \class EventHubComponent
/// \brief Processes event-hub-cpp sources from the Consolix component loop.
///
/// The component is intentionally passive. It does not own a thread and only
/// calls `EventBus::process()` and `TaskManager::process()` when Consolix
/// invokes the component's `process()` method.
class EventHubComponent :
public IAppComponent,
public IShutdownable {
public:
/// \brief Default maximum number of tasks processed per loop pass.
static constexpr std::size_t default_max_tasks_per_pass = 128;

/// \brief Constructs an empty component.
EventHubComponent() = default;

/// \brief Constructs component with optional non-owning sources.
/// \param event_bus Event bus to process, or nullptr.
/// \param task_manager Task manager to process, or nullptr.
/// \param max_tasks_per_pass Maximum ready tasks processed per pass.
EventHubComponent(
event_hub::EventBus* event_bus,
event_hub::TaskManager* task_manager = nullptr,
std::size_t max_tasks_per_pass = default_max_tasks_per_pass) :
m_event_bus(event_bus),
m_task_manager(task_manager),
m_max_tasks_per_pass(max_tasks_per_pass) {
}

/// \brief Sets event bus processed by this component.
/// \param event_bus Event bus to process, or nullptr.
void set_event_bus(event_hub::EventBus* event_bus) {
m_event_bus = event_bus;
}

/// \brief Sets task manager processed by this component.
/// \param task_manager Task manager to process, or nullptr.
void set_task_manager(event_hub::TaskManager* task_manager) {
m_task_manager = task_manager;
}

/// \brief Sets maximum ready tasks processed per loop pass.
/// \param max_tasks_per_pass Maximum ready tasks processed per pass.
void set_max_tasks_per_pass(std::size_t max_tasks_per_pass) {
m_max_tasks_per_pass = max_tasks_per_pass;
}

/// \brief Returns total work units processed by the last pass.
/// \return Number of processed events and tasks.
std::size_t last_work_count() const {
return m_last_work_count;
}

protected:
bool initialize() override {
m_is_init = true;
return true;
}

bool is_initialized() const override {
return m_is_init;
}

void process() override {
std::size_t work_count = 0;

if (m_event_bus) {
work_count += m_event_bus->process();
}
if (m_task_manager) {
work_count += m_task_manager->process(m_max_tasks_per_pass);
}

m_last_work_count = work_count;
}

void shutdown(int /*signal*/) override {
if (m_event_bus) {
m_event_bus->clear_pending();
}
if (m_task_manager) {
m_task_manager->clear_pending();
}
}

private:
event_hub::EventBus* m_event_bus{nullptr}; ///< Non-owning event bus pointer.
event_hub::TaskManager* m_task_manager{nullptr}; ///< Non-owning task manager pointer.
std::size_t m_max_tasks_per_pass{default_max_tasks_per_pass};
std::size_t m_last_work_count{0};
bool m_is_init{false};
};

} // namespace consolix

#endif // CONSOLIX_USE_EVENT_HUB == 1

#endif // _CONSOLIX_EVENT_HUB_COMPONENT_HPP_INCLUDED
2 changes: 1 addition & 1 deletion include/consolix/components/LoggerComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
#define CONSOLIX_SET_DEBUG_MODE(mode) \
LOGIT_SET_LOGGER_ENABLED(CONSOLIX_LOGIT_DEBUG_INDEX, mode)

#include <LogIt.hpp>
#include <logit.hpp>
#include "LoggerComponent/MultiStream.hpp"

namespace consolix {
Expand Down
Loading
Loading