241 lines
6.6 KiB
Markdown
241 lines
6.6 KiB
Markdown
<h1 align="center">
|
|
<b>🦭seallib🦭</b>
|
|
</h1>
|
|
|
|
<p align="center">
|
|
A <b>modular and tiny C++20</b> powered library collection of random stuff I've needed for other projects.
|
|
</p>
|
|
|
|
## Table of Contents
|
|
* [Installation & Integration](#installation--integration)
|
|
* [Build Options](#build-options)
|
|
* [Modules](#modules)
|
|
* [Logging](#1-logging)
|
|
* [Assert](#2-assert)
|
|
* [Events](#3-events)
|
|
* [VFS](#4-vfs)
|
|
* [Running tests](#running-tests)
|
|
|
|
## 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:
|
|
|
|
```cmake
|
|
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:
|
|
```cmake
|
|
# 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
|
|
Toggle features by setting these variables to ``ON`` or ``OFF`` in your CMake configuration.
|
|
| 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 |
|
|
|
|
---
|
|
|
|
## Modules
|
|
|
|
### 1. Logging
|
|
The Log module uses a Sink architecture. You create a Logger, attach an ILogSink, and log messages using std::format syntax.
|
|
|
|
```C++
|
|
#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. Assert
|
|
(Documentation pending implementation)
|
|
|
|
### 3. Events
|
|
The Events module provides a thread and type safe signal/slot mechanism. It allows you to define custom events with any number of parameters and subscribe to them using callbacks.
|
|
#### Basic Usage
|
|
```cpp
|
|
#include <seallib/event.h>
|
|
#include <iostream>
|
|
|
|
using namespace seallib;
|
|
|
|
// Define an event that takes an int and a string
|
|
Event<int, std::string> OnUserLogin;
|
|
|
|
void onLogin(int id, std::string name) {
|
|
std::cout << "User " << name << " (ID: " << id << ") logged in!" << std::endl;
|
|
}
|
|
|
|
int main() {
|
|
// 1. Subscribe to the event
|
|
auto connection = OnUserLogin.addListener(onLogin);
|
|
|
|
// 2. Add a lambda listener
|
|
OnUserLogin.addListener([](int id, auto name) {
|
|
std::clog << "[Log] Login detected for ID: " << id << std::endl;
|
|
});
|
|
|
|
// 3. Trigger the event
|
|
OnUserLogin.run(42, "SomeUser");
|
|
|
|
// 4. Remove a listener when no longer needed
|
|
OnUserLogin.removeListener(connection);
|
|
|
|
return 0;
|
|
}
|
|
```
|
|
|
|
### 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`.
|
|
```cpp
|
|
#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
|
|
```c++
|
|
#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
|
|
|
|
## License
|
|
|
|
[MIT](https://choosealicense.com/licenses/mit/) |