5.5 KiB
seallib
A modular and tiny C++20 powered library collection of random stuff I've needed for other projects.
Installation & Integration
1. Requirements
- Compiler: A C++20 compliant compiler.
- Build System: CMake 4.1.0 or higher.
2. Integration via CMake
Option A: Using FetchContent (Recommended)
You can pull the library directly into your project from the git repository. Add this to your CMakeLists.txt:
include(FetchContent)
FetchContent_Declare(
seallib
GIT_REPOSITORY https://git.neru.rip/neru/seallib.git
GIT_TAG main # or a specific commit hash
)
# Enable the modules you want before making it available
set(SEALLIB_LOG ON)
set(SEALLIB_ASSERT OFF)
FetchContent_MakeAvailable(seallib)
target_link_libraries(your_project PRIVATE seallib)
Option B: Local Path
If you have the library downloaded locally:
# Enable the modules you want before adding it
set(SEALLIB_LOG ON)
set(SEALLIB_ASSERT OFF)
add_subdirectory(path/to/seallib)
target_link_libraries(your_project PRIVATE seallib)
Build Options
| Option | Description | Default |
|---|---|---|
| SEALLIB_ASSERT | Enable Assertion utility | OFF |
| SEALLIB_EVENTS | Enable Event Dispatcher | OFF |
| SEALLIB_LOG | Enable Logging Framework | OFF |
| SEALLIB_VFS | Enable Virtual File System | OFF |
| SEALLIB_TEST | Build the test project | OFF |
Module Instructions
1. Logging
The Log module uses a Sink architecture. You create a Logger, attach an ILogSink, and log messages using std::format syntax.
#include <seallib/log.h>
#include <iostream>
using namespace seallib;
class ConsoleSink : public ILogSink {
public:
void receiveLog(LogType type, std::string_view loggerName, std::string_view message) override {
std::cout << getLogTypeColor(type) << "[" << getLogTypeName(type) << "] "
<< "[" << loggerName << "] "
<< message << "\x1b[0m" << std::endl;
}
};
int main() {
Logger logger("MainApp");
logger.addSink(std::make_shared<ConsoleSink>());
logger.info("Application started with version {}", 1.0);
logger.error("Failed to load config: {}", "file_not_found.json");
return 0;
}
2. Assertion
(Documentation pending implementation)
3. Events
(Documentation pending implementation)
4. VFS
The VFS (Virtual File System) module provides a unified interface for file operations by mapping virtual paths to user defined providers.
Implementing a file provider
To create a new storage backend (e.g., a zip loader, encrypted volume, etc), you must inherit from IFileProvider.
#include <seallib/vfs.h>
using namespace seallib;
class MyCustomProvider : public IFileProvider {
public:
// checks if file exists
bool exists(const std::string& path) const override {
/*
implementation logic here
*/
return true;
}
// loads data from provider to outBuffer
VFSResult readFile(const std::string& path, FileBuffer& outBuffer) const override {
/*
1. locate the file in your system.
2. if not found, return VFSResult::FileNotFound.
3. allocate memory: outBuffer.data = std::make_unique<uint8_t[]>(size);
4. copy data into outBuffer.data and set outBuffer.size = size;
*/
return VFSResult::Success;
}
// write data from a buffer to your provider
VFSResult writeFile(const std::string& path, const FileBuffer& buffer) override {
/*
VFS ensures 'buffer' is valid (data != nullptr) before calling this.
return VFSResult::AccessDenied if your provider is read-only or if that path shouldn't be written to
*/
return VFSResult::Success;
}
// generic file management operations
VFSResult deleteFile(const std::string& path) override { return VFSResult::Success; }
VFSResult createDirectory(const std::string& path) override { return VFSResult::Success; }
// list all files and subdirectories within a given path
std::vector<std::string> listDirectory(const std::string& path) const override {
// note: directories should ideally end with a '/' for clarity
return { "file1", "file2", "file3" };
}
// optional: return a name for debugging/logging
std::string getProviderName() const override { return "MyCustomProvider"; }
};
Example usage
#include <seallib/vfs.h>
using namespace seallib;
int main() {
VirtualFileSystem vfs;
/*
mount a disk provider to the virtual "assets" folder
higher priority (10 in this case) means this mount is checked before others
*/
vfs.mount("/assets", std::make_unique<DiskFileProvider>("./data"), 10);
// reading a file (Paths are automatically normalized to remove '../' etc.)
FileBuffer buffer;
if (vfs.readFile("/assets/somefile.bin", buffer) == VFSResult::Success) {
std::string rawData = buffer.toString();
}
return 0;
}
Running Tests
Windows (PowerShell + Visual Studio)
A script is provided to automate generation and open the solution in Visual Studio:
./create-test.ps1
Cross-Platform (CLI)
To build and run manually from the terminal:
mkdir build && cd build cmake .. -DSEALLIB_TEST=ON cmake --build . ./seallib-test