Consolix
Loading...
Searching...
No Matches
Usage Examples

Examples of using Consolix framework.

Usage Examples

This page demonstrates how to use various features of the Consolix framework. It covers key components and utilities with practical examples.

Basic Setup

Here's how to initialize and use Consolix in a simple console application:

#define CONSOLIX_USE_LOGIT 1
int main(int argc, char* argv[]) {
// Initialize logger
// Display the application logo
// Handle command-line arguments
consolix::add<consolix::CliComponent>("MyApp", "Program description", [](auto& options) {
options.add_options()("debug", "Enable debug mode");
}, argc, argv);
// Load configuration from a JSON file
// Execute the main loop
CONSOLIX_STREAM() << "Executing main loop...";
});
}
#define CONSOLIX_STREAM()
Fallback for general logging.
Single include header for Consolix framework.
std::shared_ptr< Component > add(Args &&... args)
Adds a new component to the application. Creates a new instance of the specified component type and a...
void run()
Runs the application. Processes all components in the application's main loop.

Using the ServiceLocator

The ServiceLocator provides global access to shared resources:

int main() {
// Register a service
return std::make_shared<std::string>("Hello, Consolix!");
});
// Check and access the service
std::cout << message << std::endl;
}
}
Entry point for including all core headers of the Consolix framework.
void register_service()
Registers a resource with default construction globally. Registers a resource or service using defaul...
T & get_service()
Retrieves a resource globally. Retrieves a reference to a globally registered resource from the Servi...
bool has_service()
Checks if a resource is registered globally.

JSON Configuration Management

Load and manage application configuration from a JSON file:

struct AppConfig {
std::string app_name;
int max_connections;
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(AppConfig, app_name, max_connections)
int main() {
// Load configuration from a JSON file
// Access the configuration
std::cout << "App Name: " << config.app_name << "\n";
std::cout << "Max Connections: " << config.max_connections << "\n";
}
Entry point for including all Consolix components.
Application configuration structure.

Custom Loop Example

Define and use a custom execution loop:

int main() {
[]() -> bool {
std::cout << "Initialization complete.\n";
return true;
},
[]() {
std::cout << "Executing loop iteration.\n";
std::this_thread::sleep_for(std::chrono::seconds(1));
},
[](int signal) {
std::cout << "Shutting down on signal: " << signal << "\n";
}
);
}

On POSIX systems, a termination signal only requests shutdown. The on_shutdown callback above still runs later in the normal application flow rather than inside the signal handler.

Resource Cleanup and Worker Shutdown

Use on_shutdown(int) for controlled shutdown logic such as stopping background threads, joining them, and then releasing owned resources:

class ShutdownAndResourcesDemo final : public consolix::BaseLoopComponent {
public:
bool on_once() override {
m_resource.reset(new WorkerResource("background-worker"));
m_worker = std::thread(&ShutdownAndResourcesDemo::worker_loop, this);
return true;
}
void on_loop() override {
if (++m_tick_count >= 5) {
}
}
void on_shutdown(int signal) override {
m_worker_stop.store(true);
if (m_worker.joinable()) {
m_worker.join();
}
m_resource.reset();
}
private:
std::thread m_worker;
std::unique_ptr<WorkerResource> m_resource;
std::atomic<bool> m_worker_stop{false};
std::atomic<unsigned> m_heartbeats{0};
std::atomic<int> m_tick_count{0};
};
Abstract base class for application components with looping functionality.
virtual void on_shutdown(int signal)=0
Called when the application shuts down.
virtual void on_loop()=0
Called repeatedly during the application's main loop.
virtual bool on_once()=0
Called once during component initialization.
void stop()
Stops the application. Stops the application's main loop and begins the shutdown process.

This is the recommended lifecycle pattern in Consolix:

  • do not perform cleanup in the signal handler itself
  • do not detach long-lived worker threads owned by a component
  • request stop first, then join(), then release owned resources
  • use consolix::stop() for cooperative shutdown from the normal execution path

See examples/example_shutdown_and_resources.cpp for the full runnable example.

Logging with LogIt

Use the integrated LoggerComponent to manage logging:

#define CONSOLIX_USE_LOGIT 1
int main() {
CONSOLIX_STREAM() << "This is an informational message.";
LOGIT_PRINT_ERROR("This is an error message.");
return 0;
}

Working with Path Utilities

Resolve paths relative to the executable directory:

int main() {
std::string relative_path = "config/settings.json";
std::string absolute_path = consolix::resolve_exec_path(relative_path);
std::cout << "Absolute Path: " << absolute_path << std::endl;
}
std::string resolve_exec_path(const std::string &relative_path)
Resolves a relative path to absolute, based on executable location.
Entry point for including utility headers for Consolix.