First commit

This commit is contained in:
wcjbr
2026-08-15 19:11:54 +08:00
commit 5f51a52ca6
18 changed files with 982 additions and 0 deletions
+229
View File
@@ -0,0 +1,229 @@
# ConsoleLib
> 一个用 C++ 编写的跨平台控制台操作库。
ConsoleLib 提供 Windows / Linux 下的控制台初始化、原始键盘输入、后台按键轮询、ANSI 真彩色输出、清屏和毫秒级休眠等功能,并同时产出静态库和动态库。
## 特性
- 控制台原始模式 / 原生模式初始化与恢复
- 后台键盘输入线程,轮询并记录按键
- 24 位 ANSI 真彩色输出
- 清屏
- 毫秒级跨平台休眠 `sleep_ms`
- 安全的 `quit` 退出
- 同时生成静态库和动态库
## 平台产物
| 平台 | 静态库 | 动态库 |
| --- | --- | --- |
| Linux | `libConsoleLib.a` | `libConsoleLib.so` |
| Windows | `ConsoleLib.lib` | `ConsoleLib.dll` |
## 环境要求
- CMake 3.10+(使用 `CMakePresets.json` 时建议 3.28+
- 支持 C++17 的编译器(Clang / GCC / MSVC
- 使用默认 preset 时需要 [Ninja](https://ninja-build.org/)
## 目录结构
```text
ConsoleLib/
├── CMakeLists.txt
├── CMakePresets.json
├── ConsoleLib.cpp
├── include/
│ └── ConsoleLib.h
├── example/
│ ├── CMakeLists.txt
│ ├── CMakePresets.json
│ ├── build.sh
│ ├── build.bat
│ ├── helloworld/
│ │ ├── CMakeLists.txt
│ │ └── main.cpp
│ └── keyinput/
│ ├── CMakeLists.txt
│ └── main.cpp
└── docs/
└── image.png
```
## 快速开始
### 方式一:使用 CMake Presets(推荐)
```bash
# 项目根目录
./build.sh
```
等价命令:
```bash
cmake --preset Clang
cmake --build --preset Clang -j
```
构建产物默认在 `build/`
Windows 下可运行:
```bat
build.bat
```
### 方式二:手动构建
```bash
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug
cmake --build build -j
```
### 单独构建示例
```bash
cd example
./build.sh
```
或:
```bash
cd example
cmake --preset Clang
cmake --build --preset Clang -j
./build/helloworld/helloworld
./build/keyinput/keyinput
```
## 示例
### HelloWorld
`example/helloworld/main.cpp`
```cpp
#include <ConsoleLib.h>
using namespace ConsoleLib;
signed main() {
initConsole();
clearConsole();
printToConsole("HelloWorld!\r\n");
printToConsole("Red", 0xff0000);
printToConsole("Green", 0x00ff00);
printToConsole("Blue", 0x0000ff);
quit(0);
}
```
输出效果见 `docs/image.png`
### 按键输入(含方向键)
`example/keyinput/main.cpp` 展示了 `getConsoleKeyInput()` 与方向键、`Home``End``F1` ~ `F4` 以及普通可打印字符的检测:
```cpp
#include <ConsoleLib.h>
using namespace ConsoleLib;
signed main() {
initConsole();
clearConsole();
printToConsole("Press arrow keys, q or ESC to quit.\r\n");
while (true) {
auto &keys = getConsoleKeyInput();
if (keys[KEY_UP]) {
printToConsole("UP\r\n");
}
if (keys[KEY_DOWN]) {
printToConsole("DOWN\r\n");
}
if (keys[KEY_LEFT]) {
printToConsole("LEFT\r\n");
}
if (keys[KEY_RIGHT]) {
printToConsole("RIGHT\r\n");
}
if (keys[KEY_q] || keys[KEY_ESCAPE]) {
break;
}
sleep_ms(16);
}
quit(0);
}
```
## 集成到你的项目
### 静态库
```cmake
add_subdirectory(ConsoleLib)
target_link_libraries(your_target PRIVATE ConsoleLib)
```
### 动态库
```cmake
add_subdirectory(ConsoleLib)
target_link_libraries(your_target PRIVATE ConsoleLib_shared)
```
`ConsoleLib` 目标已通过 `target_include_directories(... PUBLIC ...)` 暴露 `include/` 目录,因此直接包含即可:
```cpp
#include <ConsoleLib.h>
```
## API 参考
| 函数 | 说明 |
| --- | --- |
| `void initConsole()` | 初始化控制台并启动后台输入线程 |
| `void stopInputThread()` | 停止后台输入线程 |
| `void restoreConsoleMode()` | 恢复终端原始模式 / Windows 控制台模式 |
| `void RawPrint(std::string_view text)` | 直接输出文本,不做颜色处理 |
| `void printToConsole(std::string_view data)` | 打印文本 |
| `void printToConsole(std::string_view data, Color color)` | 打印指定颜色的文本 |
| `void clearConsole()` | 清屏并将光标移动到左上角 |
| `char getinput()` | 读取一个输入字符 |
| `std::array<bool, KEYCODE_COUNT> &getConsoleKeyInput()` | 返回并清空按键状态表,下标为 `Keycode` |
| `bool isKeyPressed(Keycode key)` | 查询某个按键当前是否被按下 |
| `void sleep_ms(unsigned int ms)` | 休眠指定毫秒数 |
| `void setInputFrequency(std::uint8_t frequency)` | 设置输入轮询频率(Hz |
| `std::uint8_t getInputFrequency()` | 获取当前输入轮询频率 |
| `void quit(int exitCode)` | 停止线程、恢复终端并退出进程 |
`Color``uint32_t`,格式为 `0xRRGGBB`
## 按键码
`Keycode` 为 SDL 风格的按键码:
- ASCII 字符直接使用其 ASCII 值,例如 `KEY_a``KEY_0``KEY_SPACE`
- 特殊键从 `128` 开始,例如 `KEY_UP``KEY_DOWN``KEY_LEFT``KEY_RIGHT``KEY_HOME``KEY_END``KEY_F1` ~ `KEY_F4`
| 常量 | 含义 |
| --- | --- |
| `ASCII_TABLE_SIZE` | ASCII 范围大小,固定为 `128` |
| `KEYCODE_COUNT` | 按键状态表大小 |
| `DEFAULT_CONSOLE_INPUT_FREQUENCY` | 默认输入轮询频率(50 Hz) |
`getConsoleKeyInput()` 返回长度为 `KEYCODE_COUNT``std::array<bool, KEYCODE_COUNT>`,下标即 `Keycode`;调用后内部按键记录会被清空。`isKeyPressed(Keycode)` 仅查询、不会清空记录。
## 说明
- `initConsole()` 会将终端切换到非回显的原始模式;程序结束前请调用 `quit()``restoreConsoleMode()`,否则终端状态可能无法恢复。
- `quit()` 已包含 `stopInputThread()``restoreConsoleMode()`
- `getinput()` 仅返回单个 ASCII 字符;方向键、功能键等特殊键请使用 `getConsoleKeyInput()``isKeyPressed()`