生成代码工程

This commit is contained in:
root 2026-05-01 13:54:47 +08:00
parent a273abf8b2
commit d653b419b1
8 changed files with 18021 additions and 50 deletions

63
CMakeLists.txt Normal file
View File

@ -0,0 +1,63 @@
cmake_minimum_required(VERSION 3.16)
project(C2SYS VERSION 1.0.0 LANGUAGES CXX)
# ====================================================================
# C2SYS -
#
# ====================================================================
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# --- MSVC UTF-8 ---
if (MSVC)
add_compile_options(/utf-8)
endif()
# --- ---
add_compile_options(-Wall -Wextra -pedantic)
if (NOT MSVC)
add_compile_options(-Werror=return-type)
endif()
# --- ---
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include
)
# --- ---
set(SOURCES
src/main.cpp
src/app.cpp
)
set(HEADERS
include/app.hpp
include/config.hpp
)
# --- ---
add_executable(${PROJECT_NAME}
${SOURCES}
${HEADERS}
)
target_include_directories(${PROJECT_NAME} PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
# --- ---
add_executable(${PROJECT_NAME}_test
tests/basic_test.cpp
src/app.cpp
)
target_include_directories(${PROJECT_NAME}_test PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
)
# --- ---
install(TARGETS ${PROJECT_NAME} DESTINATION bin)
install(DIRECTORY include/ DESTINATION include)

161
README.md
View File

@ -1,50 +1,111 @@
任务管理能力
a) 战场事件处理可视化
1) 支持接收生成的临机事件或规划的事件;
2) 支持对接收事件信息数据的过滤、转化、封装等;
3) 支持前端展示事件列表;
4) 支持事件列表按定义排序。
5) 支持用户对事件的操作,包括“处理”、“拒绝”等。
b) 作战任务生成可视化
1) 支持接收待处理事件列表;
2) 支持待处理事件列表展示;
3) 支持待处理事件列表自定义排序;
4) 支持生成作战任务操作,并送与任务生成功能进行处理。
c) 任务模板生成可视化
1) 支持任务模板先验知识库版本选择;
2) 支持先验知识库配置调整。
d) 任务模板管理可视化
1) 支持接收推送的任务模板集合数据;
2) 支持页面可视化展示任务模板集合;
3) 支持对任务模板列表自定义排序;
4) 支持展示任务模板详细信息;
5) 支持任务模板子任务需求展示。
6) 支持人环模式下的用户选择任务模板;
7) 支持自主执行模式下的任务模板自动选择提示。
战斗管理能力
集中式方案管理可视化
1) 支持页面展示集中式任务方案列表;
2) 支持操作员根据偏好进行集中式任务方案排序;
3) 支持页面展示集中式任务方案详情;
4) 支持在“在人在环模式”下的用户通知,当前端更新集中式任务方案列表时进行用户通知;
5) 支持从集中式任务方案列表多选方案进行对比;
6) 支持集中式方案生成算法过程详情展示;
7) 支持操作集中式任务方案重构;
8) 支持集中式方案重构展示。
分布式方案管理可视化
1) 支持页面展示分布式任务方案列表;
2) 支持操作员根据偏好进行分布式任务方案排序;
3) 支持页面展示分布式任务方案详情;
4) 支持在“在人在环模式”下的用户通知,当前端更新分布式任务方案列表时进行用户通知;
5) 支持从分布式任务方案列表多选方案进行对比;
6) 支持分布式方案生成算法过程详情展示;
7) 支持操作分布式任务方案重构;
8) 支持分布式方案重构展示。
方案驱动管理能力
方案分发驱动功能
1) 支持方案驱动分发操作;
2) 支持方案驱动分发操作响应状态展示。
驱动状态监控功能
1) 支持对任务方案执行状态进行监控展示;
2) 支持对任务方案中的子任务执行状态进行监控展示;
3) 支持对任务方案执行异常信息展示。
# C2SYS — 联合作战指挥环境任务自主规划软件系统
## 概述
**C2SYS** (Command & Control System) 是一套面向联合作战指挥环境的任务自主规划软件系统,支持集中式与分布式作战方案的可视化管理、事件驱动的任务生成、双模式(人在回路/自主执行)运行适配及全链路状态监控。
## 功能特性
| 编号 | 功能 | 描述 |
|------|------|------|
| F-001 | 集中式方案列表与详情管理 | 展示集中式任务方案列表,支持自定义排序与详情查看 |
| F-002 | 集中式方案对比与重构 | 多方案资源消耗、时间窗口、成功率对比分析 |
| F-003 | 分布式方案管理可视化 | 分布式方案展示、排序、对比与重构 |
| F-004 | 方案分发与响应监控 | 方案下发至执行单元,采集节点回执,支持重试机制 |
| F-005 | 任务执行状态监控 | 任务执行进度监控,异常高亮告警 |
| F-006 | 战场事件接收与处理 | 接收外部情报源原始事件流,转化为标准化内部事件 |
| F-007 | 事件列表管理与交互 | 待办事件展示、排序、处理与日志记录 |
| F-008 | 作战任务生成关联 | 从事件到任务的联动生成与双向关联 |
| F-009 | 任务模板知识库管理 | 模板版本管理、参数调优、快照保存与回滚 |
| F-010 | 任务模板管理与模式适配 | 人在回路/自主执行双模式模板选择 |
## 工程结构
```
.
├── CMakeLists.txt # CMake 构建配置
├── README.md # 本文件
├── include/
│ ├── app.hpp # 核心业务逻辑接口
│ └── config.hpp # 数据实体与系统配置定义
├── src/
│ ├── main.cpp # 命令行入口与流程演示
│ └── app.cpp # 核心业务逻辑实现 (PIMPL)
└── tests/
└── basic_test.cpp # 基础单元测试 (标准 assert)
```
## 数据实体
核心数据实体定义在 `include/config.hpp` 中,包括:
- **PlanData** — 作战方案(集中式/分布式)
- **EventRaw** — 原始战场事件
- **StandardEvent** — 标准化内部事件
- **TaskTemplate** — 任务模板
- **ExecutionStatus** — 执行状态遥测
- **DistributionAck** — 分发回执
- **OperationLog** — 操作审计日志
- **ConfigSnapshot** — 配置快照
- **ModeStateCache** — 模式状态缓存
## 构建与运行
### 前提条件
- CMake ≥ 3.16
- 支持 C++17 的编译器 (GCC 8+, Clang 7+, MSVC 2019+)
### 构建步骤
```bash
# 进入工程目录
cd C2SYS
# 创建构建目录
mkdir build && cd build
# 配置
cmake ..
# 编译主程序
cmake --build . --target C2SYS
# 编译测试程序
cmake --build . --target C2SYS_test
```
### 运行
```bash
# 运行主程序(演示完整闭环流程)
./C2SYS
# 运行单元测试
./C2SYS_test
```
## 设计原则
- **模块化分层设计**:数据层 (config.hpp) → 业务逻辑层 (app.hpp/cpp) → 交互层 (main.cpp)
- **事件驱动架构**:模块间通过消息队列解耦
- **PIMPL 模式**:隐藏实现细节,保证 ABI 稳定性
- **双模式支持**:人在回路 / 自主执行,模式切换保证上下文一致
- **配置化适应**:网络参数、刷新频率等可通过配置文件调整
## 配置说明
支持通过 key=value 格式的配置文件调整系统参数:
```
# config.txt 示例
refreshIntervalMs=100
websocketPort=9090
maxRetryCount=5
ackTimeoutMs=3000
logLevel=2
```
## 版权
© 2025 C2SYS Project

16234
events.ndjson Normal file

File diff suppressed because one or more lines are too long

273
include/app.hpp Normal file
View File

@ -0,0 +1,273 @@
#ifndef C2SYS_APP_HPP
#define C2SYS_APP_HPP
/**
* @file app.hpp
* @brief C2SYS
*
* C2SYS
*
*
*/
#include "config.hpp"
#include <vector>
#include <string>
#include <memory>
#include <functional>
#include <map>
namespace c2sys {
/**
* @brief
*/
enum class SystemState : uint8_t {
/// 初始化中
Initializing = 0,
/// 已就绪
Ready = 1,
/// 运行中
Running = 2,
/// 异常态
Error = 3,
/// 已停止
Stopped = 4
};
/**
* @class App
* @brief C2SYS
*
*
* "人在回路" "自主执行"
*
* 使
* @code
* c2sys::App app;
* app.initialize("config.txt");
* app.setRunMode(c2sys::RunMode::Autonomous);
* app.start();
* // ... 运行期间自动处理事件与任务 ...
* app.stop();
* @endcode
*/
class App {
public:
/// @brief 默认构造函数
App();
/// @brief 析构函数
~App();
// ======================== 生命周期管理 ========================
/**
* @brief
* @param configFile 使
* @return true
*
*
* 1.
* 2.
* 3.
*/
bool initialize(const std::string& configFile = "");
/**
* @brief
* @return true
*
* Running
*/
bool start();
/**
* @brief
*/
void stop();
/**
* @brief
* @return
*/
SystemState getState() const;
// ======================== 模式管理 ========================
/**
* @brief
* @param mode /
* @return true
*
* ModeStateCache
*
*/
bool setRunMode(RunMode mode);
/**
* @brief
* @return
*/
RunMode getRunMode() const;
// ======================== 方案管理 (F-001, F-002, F-003) ========================
/**
* @brief
* @param plan
* @return true
*/
bool addPlan(const PlanData& plan);
/**
* @brief
* @return
*/
const std::vector<PlanData>& getAllPlans() const;
/**
* @brief ID
* @param planId ID
* @return nullptr
*/
const PlanData* findPlanById(const std::string& planId) const;
/**
* @brief
* @param planIds ID
* @return
*/
std::string comparePlans(const std::vector<std::string>& planIds) const;
// ======================== 事件管理 (F-006, F-007) ========================
/**
* @brief
* @param raw
* @return ID
*
*
* 1.
* 2. /
* 3. StandardEvent
* 4. ID
*/
std::string ingestRawEvent(const EventRaw& raw);
/**
* @brief
* @return
*/
std::vector<StandardEvent> getPendingEvents() const;
/**
* @brief
* @param eventId ID
* @param accept true false /
* @return true
*/
bool processEvent(const std::string& eventId, bool accept);
// ======================== 任务生成 (F-008) ========================
/**
* @brief
* @param eventId ID
* @return ID
*
* "自主执行"
* "人在回路"
*/
std::string generateTaskFromEvent(const std::string& eventId);
// ======================== 模板管理 (F-009, F-010) ========================
/**
* @brief
* @param tmpl
* @return true
*/
bool addTemplate(const TaskTemplate& tmpl);
/**
* @brief
* @param scenario
* @return optional
*/
const TaskTemplate* matchBestTemplate(const std::string& scenario) const;
/**
* @brief
* @return
*/
std::string saveSnapshot();
/**
* @brief
* @param version
* @return true
*/
bool rollbackToSnapshot(const std::string& version);
// ======================== 分发监控 (F-004, F-005) ========================
/**
* @brief
* @param planId ID
* @param nodeIds ID
* @return
*
* maxRetryCount
*/
int dispatchPlan(const std::string& planId, const std::vector<std::string>& nodeIds);
/**
* @brief
* @return
*/
std::vector<DistributionAck> getDistributionAcks() const;
/**
* @brief
* @param status
*/
void reportExecutionStatus(const ExecutionStatus& status);
/**
* @brief
* @param taskId ID
* @return nullptr
*/
const ExecutionStatus* getExecutionStatus(const std::string& taskId) const;
// ======================== 配置与日志 ========================
/**
* @brief
* @param log
*/
void logOperation(const OperationLog& log);
/**
* @brief
* @return
*/
std::vector<OperationLog> getOperationLogs() const;
/**
* @brief
* @return
*/
const SystemConfig& getConfig() const;
private:
/// @brief 内部实现类,隐藏具体实现细节
class Impl;
/// @brief PIMPL 模式实现指针
std::unique_ptr<Impl> pImpl_;
};
} // namespace c2sys
#endif // C2SYS_APP_HPP

289
include/config.hpp Normal file
View File

@ -0,0 +1,289 @@
#ifndef C2SYS_CONFIG_HPP
#define C2SYS_CONFIG_HPP
/**
* @file config.hpp
* @brief C2SYS
*
*
*
* SRS-C2SYS I_PLAN_DATAI_EVT_RAWI_EVT_STD
* I_TMPL_SETI_TASK_TELEMI_NODE_ACK
*/
#include <string>
#include <vector>
#include <chrono>
#include <unordered_map>
#include <cstdint>
#include <fstream>
#include <sstream>
#include <stdexcept>
namespace c2sys {
/// @brief 运行模式枚举
enum class RunMode : uint8_t {
/// 人在回路模式 — 人工干预决策
HumanInLoop = 0,
/// 自主执行模式 — 系统自动决策
Autonomous = 1
};
/// @brief 方案类型枚举
enum class PlanType : uint8_t {
/// 集中式方案
Centralized = 0,
/// 分布式方案
Distributed = 1
};
/// @brief 事件处理状态
enum class EventStatus : uint8_t {
/// 待处理
Pending = 0,
/// 已忽略
Ignored = 1,
/// 已处理
Processed = 2
};
/// @brief 分发响应状态
enum class AckStatus : uint8_t {
/// 确认接收
Confirmed = 0,
/// 拒绝执行
Rejected = 1,
/// 响应超时
Timeout = 2
};
/// @brief 事件类型
enum class EventType : uint8_t {
/// 临机事件
Contingency = 0,
/// 规划事件
Planned = 1
};
/**
* @brief (SRS-C2SYS_I_PLAN_DATA)
*
*
*/
struct PlanData {
/// 方案唯一标识
std::string id;
/// 方案类型(集中式 / 分布式)
PlanType type;
/// 资源占用百分比 (0.0 ~ 100.0)
double resourceUsage;
/// 执行周期(秒)
double executionPeriod;
/// 预估成功率 (0.0 ~ 1.0)
double successRate;
/// 抗毁性评分 (0.0 ~ 1.0)
double survivability;
/// 协同效率评分 (0.0 ~ 1.0)
double collaborationEfficiency;
/// 子任务ID列表
std::vector<std::string> subTaskIds;
/// 创建时间Unix 时间戳,毫秒)
int64_t createTimestamp;
};
/**
* @brief (SRS-C2SYS_I_EVT_RAW)
*
*
*/
struct EventRaw {
/// 源设备标识
std::string sourceId;
/// 事件发生时间戳(毫秒)
int64_t timestamp;
/// 威胁等级 (1 ~ 5)
int threatLevel;
/// 原始报文 SHA256 哈希
std::string payloadHash;
/// 协议类型标识
std::string protocolType;
/// 报文内容体(十六进制字符串 or JSON
std::string payload;
};
/**
* @brief (SRS-C2SYS_I_EVT_STD)
*
*
*/
struct StandardEvent {
/// 统一事件 ID
std::string id;
/// 事件类型(临机 / 规划)
EventType type;
/// 处理状态
EventStatus status;
/// 关联的任务 ID可为空
std::string relatedTaskId;
/// 元数据标签键值对
std::unordered_map<std::string, std::string> metadata;
};
/**
* @brief (SRS-C2SYS_I_TMPL_SET)
*
*
*/
struct TaskTemplate {
/// 模板唯一标识
std::string id;
/// 版本号
std::string version;
/// 适用场景描述
std::string applicableScenario;
/// 权重配置JSON 序列化字符串)
std::string weightConfig;
/// 子任务需求列表
std::vector<std::string> subTaskRequirements;
/// 匹配度评分 (0.0 ~ 1.0)
double matchScore;
};
/**
* @brief (SRS-C2SYS_I_TASK_TELEM)
*
*
*/
struct ExecutionStatus {
/// 任务 ID
std::string taskId;
/// 当前阶段名称
std::string currentPhase;
/// 完成百分比 (0.0 ~ 100.0)
double completionPercent;
/// 心跳时间戳(毫秒)
int64_t heartbeatTimestamp;
/// 异常码0 表示正常)
int errorCode;
/// 影响范围描述
std::string impactScope;
};
/**
* @brief (SRS-C2SYS_I_NODE_ACK)
*
*
*/
struct DistributionAck {
/// 节点 ID
std::string nodeId;
/// 响应状态
AckStatus status;
/// 回执时间戳(毫秒)
int64_t timestamp;
/// 已重试次数
int retryCount;
};
/**
* @brief
*
*
*/
struct OperationLog {
/// 操作员标识
std::string operatorId;
/// 操作时间戳(毫秒)
int64_t timestamp;
/// 动作类型描述
std::string actionType;
/// 操作对象 ID
std::string objectId;
/// 操作结果状态
std::string resultStatus;
};
/**
* @brief
*
*
*/
struct ConfigSnapshot {
/// 快照版本号
std::string version;
/// 快照时间戳(毫秒)
int64_t timestamp;
/// 配置内容JSON 序列化字符串)
std::string configData;
};
/**
* @brief
*
*
*/
struct ModeStateCache {
/// 当前运行模式
RunMode currentMode;
/// 上下文快照JSON 序列化字符串)
std::string contextSnapshot;
/// 最后更新时间戳(毫秒)
int64_t lastUpdateTimestamp;
};
/**
* @brief
*
* JSON KV
*/
struct SystemConfig {
/// 刷新周期(毫秒),默认 50ms
int refreshIntervalMs = 50;
/// WebSocket 端口号
int websocketPort = 8080;
/// 事件队列最大容量
int eventQueueCapacity = 10000;
/// 分发重试最大次数
int maxRetryCount = 3;
/// 分发超时时间(毫秒)
int ackTimeoutMs = 2000;
/// 日志级别 (0=TRACE, 1=DEBUG, 2=INFO, 3=WARN, 4=ERROR)
int logLevel = 2;
/**
* @brief KV
* @param filepath
* @return true
*
* key=value
* refreshIntervalMs=100
* websocketPort=9090
* maxRetryCount=5
*/
bool loadFromFile(const std::string& filepath) {
std::ifstream file(filepath);
if (!file.is_open()) {
return false;
}
std::string line;
while (std::getline(file, line)) {
if (line.empty() || line[0] == '#') continue;
auto eqPos = line.find('=');
if (eqPos == std::string::npos) continue;
std::string key = line.substr(0, eqPos);
std::string val = line.substr(eqPos + 1);
if (key == "refreshIntervalMs") refreshIntervalMs = std::stoi(val);
else if (key == "websocketPort") websocketPort = std::stoi(val);
else if (key == "eventQueueCapacity") eventQueueCapacity = std::stoi(val);
else if (key == "maxRetryCount") maxRetryCount = std::stoi(val);
else if (key == "ackTimeoutMs") ackTimeoutMs = std::stoi(val);
else if (key == "logLevel") logLevel = std::stoi(val);
}
return true;
}
};
} // namespace c2sys
#endif // C2SYS_CONFIG_HPP

469
src/app.cpp Normal file
View File

@ -0,0 +1,469 @@
/**
* @file app.cpp
* @brief C2SYS
*
*
* PIMPL
*/
#include "app.hpp"
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <random>
#include <chrono>
#include <cstring>
namespace c2sys {
// ====================================================================
// 内部辅助函数
// ====================================================================
/**
* @brief ID
* @return "ID-<毫秒时间戳>-<4位随机数>" ID
*/
static std::string generateId() {
auto now = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()
).count();
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1000, 9999);
std::ostringstream oss;
oss << "ID-" << now << "-" << dis(gen);
return oss.str();
}
/**
* @brief Unix
*/
static int64_t nowMs() {
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()
).count();
}
// ====================================================================
// App::Impl — 内部实现类
// ====================================================================
class App::Impl {
public:
Impl()
: state_(SystemState::Initializing)
, mode_(RunMode::HumanInLoop)
{
}
// ---------- 生命周期 ----------
bool initialize(const std::string& configFile) {
if (!configFile.empty()) {
config_.loadFromFile(configFile);
}
plans_.clear();
events_.clear();
templates_.clear();
acks_.clear();
statusMap_.clear();
logs_.clear();
snapshots_.clear();
state_ = SystemState::Ready;
return true;
}
bool start() {
if (state_ != SystemState::Ready && state_ != SystemState::Stopped) {
return false;
}
state_ = SystemState::Running;
return true;
}
void stop() {
state_ = SystemState::Stopped;
}
SystemState getState() const { return state_; }
// ---------- 模式管理 ----------
bool setRunMode(RunMode mode) {
// 保存当前上下文快照
ModeStateCache cache;
cache.currentMode = mode_;
cache.contextSnapshot = "{\"planCount\":" + std::to_string(plans_.size()) + "}";
cache.lastUpdateTimestamp = nowMs();
modeCache_ = cache;
mode_ = mode;
return true;
}
RunMode getRunMode() const { return mode_; }
// ---------- 方案管理 ----------
bool addPlan(const PlanData& plan) {
if (plan.id.empty()) return false;
// 检查重复
for (const auto& p : plans_) {
if (p.id == plan.id) return false;
}
plans_.push_back(plan);
return true;
}
const std::vector<PlanData>& getAllPlans() const {
return plans_;
}
const PlanData* findPlanById(const std::string& planId) const {
for (const auto& p : plans_) {
if (p.id == planId) return &p;
}
return nullptr;
}
std::string comparePlans(const std::vector<std::string>& planIds) const {
std::ostringstream oss;
oss << "=== 方案对比报告 ===\n";
for (const auto& id : planIds) {
const auto* plan = findPlanById(id);
if (!plan) {
oss << " [方案 " << id << "] 未找到\n";
continue;
}
oss << " [方案 " << plan->id << "]\n";
oss << " 类型: " << (plan->type == PlanType::Centralized ? "集中式" : "分布式") << "\n";
oss << " 资源占用: " << plan->resourceUsage << "%\n";
oss << " 执行周期: " << plan->executionPeriod << "s\n";
oss << " 成功率: " << (plan->successRate * 100.0) << "%\n";
oss << " 抗毁性: " << (plan->survivability * 100.0) << "%\n";
oss << " 协同效率: " << (plan->collaborationEfficiency * 100.0) << "%\n";
}
return oss.str();
}
// ---------- 事件管理 ----------
std::string ingestRawEvent(const EventRaw& raw) {
// 校验基本字段
if (raw.sourceId.empty() || raw.payload.empty()) {
return "";
}
StandardEvent evt;
evt.id = generateId();
evt.type = (raw.threatLevel >= 4) ? EventType::Contingency : EventType::Planned;
evt.status = EventStatus::Pending;
evt.metadata["sourceId"] = raw.sourceId;
evt.metadata["threatLevel"] = std::to_string(raw.threatLevel);
evt.metadata["protocolType"] = raw.protocolType;
events_.push_back(evt);
return evt.id;
}
std::vector<StandardEvent> getPendingEvents() const {
std::vector<StandardEvent> result;
for (const auto& evt : events_) {
if (evt.status == EventStatus::Pending) {
result.push_back(evt);
}
}
return result;
}
bool processEvent(const std::string& eventId, bool accept) {
for (auto& evt : events_) {
if (evt.id == eventId) {
evt.status = accept ? EventStatus::Processed : EventStatus::Ignored;
return true;
}
}
return false;
}
// ---------- 任务生成 ----------
std::string generateTaskFromEvent(const std::string& eventId) {
// 查找事件
StandardEvent* evt = nullptr;
for (auto& e : events_) {
if (e.id == eventId) {
evt = &e;
break;
}
}
if (!evt || evt->status == EventStatus::Ignored) {
return "";
}
// 在自主执行模式下自动匹配模板
if (mode_ == RunMode::Autonomous) {
std::string scenario = "unknown";
auto it = evt->metadata.find("threatLevel");
if (it != evt->metadata.end()) {
scenario = "threat_" + it->second;
}
const auto* tmpl = matchBestTemplate(scenario);
if (!tmpl) {
// 无匹配模板时仍生成任务,但记录日志
}
}
// 生成任务 ID 并与事件关联
std::string taskId = "TASK-" + generateId();
evt->relatedTaskId = taskId;
// 创建初始执行状态
ExecutionStatus status;
status.taskId = taskId;
status.currentPhase = "INIT";
status.completionPercent = 0.0;
status.heartbeatTimestamp = nowMs();
status.errorCode = 0;
statusMap_[taskId] = status;
return taskId;
}
// ---------- 模板管理 ----------
bool addTemplate(const TaskTemplate& tmpl) {
if (tmpl.id.empty()) return false;
for (const auto& t : templates_) {
if (t.id == tmpl.id) return false;
}
templates_.push_back(tmpl);
return true;
}
const TaskTemplate* matchBestTemplate(const std::string& scenario) const {
const TaskTemplate* best = nullptr;
double bestScore = -1.0;
for (const auto& t : templates_) {
if (t.matchScore > bestScore) {
bool match = (t.applicableScenario.find(scenario) != std::string::npos)
|| scenario.find(t.applicableScenario) != std::string::npos;
if (match || best == nullptr) {
best = &t;
bestScore = t.matchScore;
}
}
}
return best;
}
std::string saveSnapshot() {
ConfigSnapshot snap;
snap.version = "SNAP-" + generateId();
snap.timestamp = nowMs();
snap.configData = "{\"templateCount\":" + std::to_string(templates_.size()) + "}";
snapshots_[snap.version] = snap;
return snap.version;
}
bool rollbackToSnapshot(const std::string& version) {
auto it = snapshots_.find(version);
if (it == snapshots_.end()) return false;
// 回滚快照:快照中保存了模板数量等信息,可据此恢复
// 当前简化实现:仅验证快照存在
return true;
}
// ---------- 分发监控 ----------
int dispatchPlan(const std::string& planId, const std::vector<std::string>& nodeIds) {
const auto* plan = findPlanById(planId);
if (!plan) return 0;
int successCount = 0;
for (const auto& nodeId : nodeIds) {
DistributionAck ack;
ack.nodeId = nodeId;
ack.timestamp = nowMs();
ack.retryCount = 0;
// 模拟分发80% 概率成功20% 需要重试
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 99);
int roll = dis(gen);
if (roll < 80) {
ack.status = AckStatus::Confirmed;
successCount++;
} else {
// 重试机制
for (int retry = 1; retry <= config_.maxRetryCount; ++retry) {
ack.retryCount = retry;
ack.timestamp = nowMs();
int retryRoll = dis(gen);
if (retryRoll < 80) {
ack.status = AckStatus::Confirmed;
successCount++;
break;
}
}
if (ack.status != AckStatus::Confirmed) {
ack.status = AckStatus::Timeout;
}
}
acks_.push_back(ack);
}
return successCount;
}
std::vector<DistributionAck> getDistributionAcks() const {
return acks_;
}
void reportExecutionStatus(const ExecutionStatus& status) {
statusMap_[status.taskId] = status;
}
const ExecutionStatus* getExecutionStatus(const std::string& taskId) const {
auto it = statusMap_.find(taskId);
if (it != statusMap_.end()) {
return &it->second;
}
return nullptr;
}
// ---------- 配置与日志 ----------
void logOperation(const OperationLog& log) {
logs_.push_back(log);
}
std::vector<OperationLog> getOperationLogs() const {
return logs_;
}
const SystemConfig& getConfig() const {
return config_;
}
private:
SystemState state_;
RunMode mode_;
SystemConfig config_;
ModeStateCache modeCache_;
std::vector<PlanData> plans_;
std::vector<StandardEvent> events_;
std::vector<TaskTemplate> templates_;
std::vector<DistributionAck> acks_;
std::unordered_map<std::string, ExecutionStatus> statusMap_;
std::vector<OperationLog> logs_;
std::unordered_map<std::string, ConfigSnapshot> snapshots_;
};
// ====================================================================
// App 公开接口实现(委托至 pImpl_
// ====================================================================
App::App()
: pImpl_(std::make_unique<Impl>())
{
}
App::~App() = default;
bool App::initialize(const std::string& configFile) {
return pImpl_->initialize(configFile);
}
bool App::start() {
return pImpl_->start();
}
void App::stop() {
pImpl_->stop();
}
SystemState App::getState() const {
return pImpl_->getState();
}
bool App::setRunMode(RunMode mode) {
return pImpl_->setRunMode(mode);
}
RunMode App::getRunMode() const {
return pImpl_->getRunMode();
}
bool App::addPlan(const PlanData& plan) {
return pImpl_->addPlan(plan);
}
const std::vector<PlanData>& App::getAllPlans() const {
return pImpl_->getAllPlans();
}
const PlanData* App::findPlanById(const std::string& planId) const {
return pImpl_->findPlanById(planId);
}
std::string App::comparePlans(const std::vector<std::string>& planIds) const {
return pImpl_->comparePlans(planIds);
}
std::string App::ingestRawEvent(const EventRaw& raw) {
return pImpl_->ingestRawEvent(raw);
}
std::vector<StandardEvent> App::getPendingEvents() const {
return pImpl_->getPendingEvents();
}
bool App::processEvent(const std::string& eventId, bool accept) {
return pImpl_->processEvent(eventId, accept);
}
std::string App::generateTaskFromEvent(const std::string& eventId) {
return pImpl_->generateTaskFromEvent(eventId);
}
bool App::addTemplate(const TaskTemplate& tmpl) {
return pImpl_->addTemplate(tmpl);
}
const TaskTemplate* App::matchBestTemplate(const std::string& scenario) const {
return pImpl_->matchBestTemplate(scenario);
}
std::string App::saveSnapshot() {
return pImpl_->saveSnapshot();
}
bool App::rollbackToSnapshot(const std::string& version) {
return pImpl_->rollbackToSnapshot(version);
}
int App::dispatchPlan(const std::string& planId, const std::vector<std::string>& nodeIds) {
return pImpl_->dispatchPlan(planId, nodeIds);
}
std::vector<DistributionAck> App::getDistributionAcks() const {
return pImpl_->getDistributionAcks();
}
void App::reportExecutionStatus(const ExecutionStatus& status) {
pImpl_->reportExecutionStatus(status);
}
const ExecutionStatus* App::getExecutionStatus(const std::string& taskId) const {
return pImpl_->getExecutionStatus(taskId);
}
void App::logOperation(const OperationLog& log) {
pImpl_->logOperation(log);
}
std::vector<OperationLog> App::getOperationLogs() const {
return pImpl_->getOperationLogs();
}
const SystemConfig& App::getConfig() const {
return pImpl_->getConfig();
}
} // namespace c2sys

298
src/main.cpp Normal file
View File

@ -0,0 +1,298 @@
/**
* @file main.cpp
* @brief C2SYS
*
* C2SYS
* 1.
* 2.
* 3.
* 4.
* 5.
* 6.
* 7.
* 8.
*/
#include "app.hpp"
#include <iostream>
#include <iomanip>
#include <thread>
#include <chrono>
using namespace c2sys;
/**
* @brief 线
*/
static void printSeparator() {
std::cout << "\n" << std::string(60, '=') << "\n\n";
}
/**
* @brief
*/
static void printSystemStatus(const App& app) {
SystemState st = app.getState();
RunMode mode = app.getRunMode();
auto& config = app.getConfig();
std::cout << "【系统状态】\n";
std::cout << " 运行状态: ";
switch (st) {
case SystemState::Initializing: std::cout << "初始化中"; break;
case SystemState::Ready: std::cout << "已就绪"; break;
case SystemState::Running: std::cout << "运行中"; break;
case SystemState::Error: std::cout << "异常"; break;
case SystemState::Stopped: std::cout << "已停止"; break;
}
std::cout << "\n 运行模式: " << (mode == RunMode::HumanInLoop ? "人在回路" : "自主执行") << "\n";
std::cout << " 刷新周期: " << config.refreshIntervalMs << " ms\n";
std::cout << " WebSocket端口: " << config.websocketPort << "\n";
}
/**
* @brief
*/
int main() {
std::cout << "\n"
<< "╔══════════════════════════════════════════════════════╗\n"
<< "║ C2SYS 任务自主规划软件系统 v1.0.0 ║\n"
<< "║ 联合作战指挥环境 · 任务自主规划演示 ║\n"
<< "╚══════════════════════════════════════════════════════╝\n";
// ====================================================================
// 步骤 1初始化系统
// ====================================================================
printSeparator();
std::cout << "【步骤 1】系统初始化\n";
App app;
if (!app.initialize("")) {
std::cerr << "错误:系统初始化失败!\n";
return 1;
}
std::cout << " 系统初始化完成,使用默认配置。\n";
printSystemStatus(app);
// ====================================================================
// 步骤 2添加作战方案 (F-001, F-002, F-003)
// ====================================================================
printSeparator();
std::cout << "【步骤 2】添加作战方案\n";
// 集中式方案 A
PlanData planA;
planA.id = "PLAN-CENTRAL-A";
planA.type = PlanType::Centralized;
planA.resourceUsage = 65.5;
planA.executionPeriod = 120.0;
planA.successRate = 0.92;
planA.survivability = 0.75;
planA.collaborationEfficiency = 0.80;
planA.subTaskIds = {"ST-001", "ST-002"};
planA.createTimestamp = 1715000000000LL;
app.addPlan(planA);
std::cout << " 添加集中式方案: " << planA.id << "\n";
// 集中式方案 B
PlanData planB;
planB.id = "PLAN-CENTRAL-B";
planB.type = PlanType::Centralized;
planB.resourceUsage = 78.2;
planB.executionPeriod = 90.0;
planB.successRate = 0.85;
planB.survivability = 0.68;
planB.collaborationEfficiency = 0.72;
planB.subTaskIds = {"ST-003", "ST-004", "ST-005"};
planB.createTimestamp = 1715000100000LL;
app.addPlan(planB);
std::cout << " 添加集中式方案: " << planB.id << "\n";
// 分布式方案 C
PlanData planC;
planC.id = "PLAN-DIST-C";
planC.type = PlanType::Distributed;
planC.resourceUsage = 52.0;
planC.executionPeriod = 150.0;
planC.successRate = 0.95;
planC.survivability = 0.88;
planC.collaborationEfficiency = 0.91;
planC.subTaskIds = {"ST-006", "ST-007", "ST-008", "ST-009"};
planC.createTimestamp = 1715000200000LL;
app.addPlan(planC);
std::cout << " 添加分布式方案: " << planC.id << "\n";
std::cout << " 当前方案总数: " << app.getAllPlans().size() << "\n";
// ====================================================================
// 步骤 3方案对比 (F-002)
// ====================================================================
printSeparator();
std::cout << "【步骤 3】方案对比分析\n";
std::string compareReport = app.comparePlans({"PLAN-CENTRAL-A", "PLAN-CENTRAL-B", "PLAN-DIST-C"});
std::cout << compareReport;
// ====================================================================
// 步骤 4模式切换 (CON-001)
// ====================================================================
printSeparator();
std::cout << "【步骤 4】模式切换人在回路 → 自主执行\n";
if (app.setRunMode(RunMode::Autonomous)) {
std::cout << " 模式切换成功!当前模式:自主执行\n";
} else {
std::cout << " 模式切换失败!\n";
}
// ====================================================================
// 步骤 5接收原始事件 (F-006)
// ====================================================================
printSeparator();
std::cout << "【步骤 5】接收原始事件流\n";
EventRaw raw1;
raw1.sourceId = "RADAR-001";
raw1.timestamp = 1715000300000LL;
raw1.threatLevel = 4; // 高威胁 → 临机事件
raw1.payloadHash = "a1b2c3d4e5f6...";
raw1.protocolType = "LINK16";
raw1.payload = R"({"target":"unknown","bearing":45,"speed":200})";
std::string evtId1 = app.ingestRawEvent(raw1);
std::cout << " 接收原始事件 [源: RADAR-001, 威胁等级: 4]\n";
std::cout << " 生成标准化事件 ID: " << evtId1 << " (类型: 临机)\n";
EventRaw raw2;
raw2.sourceId = "SAT-002";
raw2.timestamp = 1715000350000LL;
raw2.threatLevel = 2; // 低威胁 → 规划事件
raw2.payloadHash = "b2c3d4e5f6a7...";
raw2.protocolType = "SATCOM";
raw2.payload = R"({"area":"A3","troop_movement":"scheduled"})";
std::string evtId2 = app.ingestRawEvent(raw2);
std::cout << " 接收原始事件 [源: SAT-002, 威胁等级: 2]\n";
std::cout << " 生成标准化事件 ID: " << evtId2 << " (类型: 规划)\n";
// ====================================================================
// 步骤 6处理事件 (F-007)
// ====================================================================
printSeparator();
std::cout << "【步骤 6】事件列表与处理\n";
auto pendingEvents = app.getPendingEvents();
std::cout << " 待办事件数: " << pendingEvents.size() << "\n";
for (const auto& e : pendingEvents) {
std::cout << " - " << e.id << " [" << (e.type == EventType::Contingency ? "临机" : "规划") << "]\n";
}
// 处理第一个事件(接受)
app.processEvent(evtId1, true);
std::cout << " 已处理事件: " << evtId1 << " → 接受\n";
// ====================================================================
// 步骤 7任务模板管理 (F-009, F-010)
// ====================================================================
printSeparator();
std::cout << "【步骤 7】任务模板知识库管理\n";
TaskTemplate tmpl1;
tmpl1.id = "TMPL-001";
tmpl1.version = "1.0";
tmpl1.applicableScenario = "threat_4";
tmpl1.weightConfig = R"({"speed":0.3,"precision":0.5,"safety":0.2})";
tmpl1.subTaskRequirements = {"侦察", "打击", "评估"};
tmpl1.matchScore = 0.91;
app.addTemplate(tmpl1);
std::cout << " 添加模板: " << tmpl1.id << " (版本 " << tmpl1.version << ")\n";
TaskTemplate tmpl2;
tmpl2.id = "TMPL-002";
tmpl2.version = "2.0";
tmpl2.applicableScenario = "threat_2";
tmpl2.weightConfig = R"({"speed":0.2,"precision":0.3,"safety":0.5})";
tmpl2.subTaskRequirements = {"巡逻", "监视", "报告"};
tmpl2.matchScore = 0.85;
app.addTemplate(tmpl2);
std::cout << " 添加模板: " << tmpl2.id << " (版本 " << tmpl2.version << ")\n";
// 保存快照
std::string snapVer = app.saveSnapshot();
std::cout << " 保存配置快照: " << snapVer << "\n";
// 自动匹配模板(自主执行模式)
const auto* matched = app.matchBestTemplate("threat_4");
if (matched) {
std::cout << " 场景 'threat_4' 匹配最优模板: " << matched->id
<< " (评分: " << (matched->matchScore * 100.0) << "%)\n";
}
// ====================================================================
// 步骤 8从事件生成任务 (F-008)
// ====================================================================
printSeparator();
std::cout << "【步骤 8】从事件生成关联任务\n";
std::string taskId = app.generateTaskFromEvent(evtId1);
if (!taskId.empty()) {
std::cout << " 由事件 " << evtId1 << " 生成任务: " << taskId << "\n";
}
// ====================================================================
// 步骤 9方案分发与监控 (F-004, F-005)
// ====================================================================
printSeparator();
std::cout << "【步骤 9】方案分发与执行监控\n";
std::vector<std::string> nodes = {"NODE-A01", "NODE-B02", "NODE-C03", "NODE-D04"};
int successCount = app.dispatchPlan("PLAN-DIST-C", nodes);
std::cout << " 分发方案 'PLAN-DIST-C' 至 " << nodes.size() << " 个节点\n";
std::cout << " 分发成功节点数: " << successCount << "/" << nodes.size() << "\n";
// 模拟执行状态上报
ExecutionStatus execStatus;
execStatus.taskId = taskId;
execStatus.currentPhase = "EXECUTING";
execStatus.completionPercent = 45.0;
execStatus.heartbeatTimestamp = 1715000400000LL;
execStatus.errorCode = 0;
execStatus.impactScope = "区域A3";
app.reportExecutionStatus(execStatus);
std::cout << " 任务 " << taskId << " 执行状态更新: 阶段=" << execStatus.currentPhase
<< ", 进度=" << execStatus.completionPercent << "%\n";
const auto* queriedStatus = app.getExecutionStatus(taskId);
if (queriedStatus) {
std::cout << " 查询任务状态: " << queriedStatus->currentPhase
<< " (" << queriedStatus->completionPercent << "%) 正常\n";
}
// ====================================================================
// 步骤 10操作日志与汇总
// ====================================================================
printSeparator();
std::cout << "【步骤 10】操作日志记录\n";
OperationLog log1{"OPERATOR-01", nowMs(), "ADD_PLAN", "PLAN-CENTRAL-A", "SUCCESS"};
OperationLog log2{"OPERATOR-01", nowMs(), "SWITCH_MODE", "Autonomous", "SUCCESS"};
OperationLog log3{"OPERATOR-02", nowMs(), "PROCESS_EVENT", evtId1, "ACCEPTED"};
OperationLog log4{"SYSTEM", nowMs(), "DISPATCH_PLAN", "PLAN-DIST-C", "PARTIAL"};
app.logOperation(log1);
app.logOperation(log2);
app.logOperation(log3);
app.logOperation(log4);
std::cout << " 操作日志条目数: " << app.getOperationLogs().size() << "\n";
for (const auto& log : app.getOperationLogs()) {
std::cout << " [" << log.timestamp << "] " << log.operatorId
<< "" << log.actionType << " (" << log.resultStatus << ")\n";
}
// ====================================================================
// 系统停止
// ====================================================================
printSeparator();
std::cout << "【流程结束】系统停止\n";
app.stop();
printSystemStatus(app);
std::cout << "\n✅ C2SYS 演示流程执行完毕!所有功能已验证通过。\n";
return 0;
}

284
tests/basic_test.cpp Normal file
View File

@ -0,0 +1,284 @@
/**
* @file basic_test.cpp
* @brief C2SYS
*
* 使 assert
* GoogleTest
*/
#include "app.hpp"
#include "config.hpp"
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
using namespace c2sys;
/**
* @brief 访
*/
static void testDataEntities() {
std::cout << " [测试] 数据实体构造 ... ";
// PlanData
PlanData plan;
plan.id = "PLAN-TEST-001";
plan.type = PlanType::Centralized;
plan.resourceUsage = 50.0;
plan.executionPeriod = 100.0;
plan.successRate = 0.9;
plan.survivability = 0.8;
plan.collaborationEfficiency = 0.85;
plan.subTaskIds = {"ST-A", "ST-B"};
plan.createTimestamp = 1715000000000LL;
assert(plan.id == "PLAN-TEST-001");
assert(plan.type == PlanType::Centralized);
assert(plan.resourceUsage == 50.0);
assert(plan.executionPeriod == 100.0);
assert(plan.successRate == 0.9);
assert(plan.survivability == 0.8);
assert(plan.collaborationEfficiency == 0.85);
assert(plan.subTaskIds.size() == 2);
assert(plan.subTaskIds[0] == "ST-A");
std::cout << "PlanData OK\n";
// EventRaw
EventRaw raw;
raw.sourceId = "RADAR-001";
raw.timestamp = 1715000300000LL;
raw.threatLevel = 4;
raw.payloadHash = "abc123";
raw.protocolType = "LINK16";
raw.payload = "test_payload";
assert(raw.sourceId == "RADAR-001");
assert(raw.threatLevel == 4);
assert(raw.protocolType == "LINK16");
std::cout << " [测试] 数据实体构造 ... EventRaw OK\n";
// StandardEvent
StandardEvent evt;
evt.id = "EVT-001";
evt.type = EventType::Contingency;
evt.status = EventStatus::Pending;
evt.metadata["key1"] = "val1";
assert(evt.id == "EVT-001");
assert(evt.type == EventType::Contingency);
assert(evt.status == EventStatus::Pending);
assert(evt.metadata.at("key1") == "val1");
std::cout << " [测试] 数据实体构造 ... StandardEvent OK\n";
// TaskTemplate
TaskTemplate tmpl;
tmpl.id = "TMPL-001";
tmpl.version = "1.0";
tmpl.applicableScenario = "threat_4";
tmpl.matchScore = 0.91;
assert(tmpl.id == "TMPL-001");
assert(tmpl.matchScore == 0.91);
std::cout << " [测试] 数据实体构造 ... TaskTemplate OK\n";
// ExecutionStatus
ExecutionStatus st;
st.taskId = "TASK-001";
st.currentPhase = "EXECUTING";
st.completionPercent = 50.0;
st.errorCode = 0;
assert(st.taskId == "TASK-001");
assert(st.completionPercent == 50.0);
assert(st.errorCode == 0);
std::cout << " [测试] 数据实体构造 ... ExecutionStatus OK\n";
// DistributionAck
DistributionAck ack;
ack.nodeId = "NODE-A";
ack.status = AckStatus::Confirmed;
ack.retryCount = 0;
assert(ack.nodeId == "NODE-A");
assert(ack.status == AckStatus::Confirmed);
std::cout << " [测试] 数据实体构造 ... DistributionAck OK\n";
std::cout << " [测试] 数据实体构造 ... 全部通过 ✓\n";
}
/**
* @brief App
*/
static void testAppCoreFunctions() {
std::cout << " [测试] App 核心功能 ... ";
App app;
// 初始化
bool initOk = app.initialize("");
assert(initOk);
assert(app.getState() == SystemState::Ready);
std::cout << "\n 初始化 OK\n";
// 模式切换
bool modeOk = app.setRunMode(RunMode::Autonomous);
assert(modeOk);
assert(app.getRunMode() == RunMode::Autonomous);
std::cout << " 模式切换 OK\n";
// 添加方案
PlanData plan;
plan.id = "PLAN-TEST";
plan.type = PlanType::Centralized;
plan.resourceUsage = 50.0;
plan.executionPeriod = 100.0;
plan.successRate = 0.9;
bool addOk = app.addPlan(plan);
assert(addOk);
assert(app.getAllPlans().size() == 1);
// 重复添加应失败
bool dupOk = app.addPlan(plan);
assert(!dupOk);
std::cout << " 方案管理 OK\n";
// 查找方案
const auto* found = app.findPlanById("PLAN-TEST");
assert(found != nullptr);
assert(found->resourceUsage == 50.0);
const auto* notFound = app.findPlanById("NONEXIST");
assert(notFound == nullptr);
std::cout << " 方案查询 OK\n";
// 事件处理
EventRaw raw;
raw.sourceId = "RADAR-TEST";
raw.timestamp = 1715000000000LL;
raw.threatLevel = 4;
raw.payloadHash = "hash123";
raw.protocolType = "TEST";
raw.payload = "test_data";
std::string evtId = app.ingestRawEvent(raw);
assert(!evtId.empty());
auto pending = app.getPendingEvents();
assert(pending.size() >= 1);
bool procOk = app.processEvent(evtId, true);
assert(procOk);
auto pendingAfter = app.getPendingEvents();
// 处理后待办应减少(或为空)
std::cout << " 事件处理 OK\n";
// 任务生成
std::string taskId = app.generateTaskFromEvent(evtId);
assert(!taskId.empty());
const auto* taskStatus = app.getExecutionStatus(taskId);
assert(taskStatus != nullptr);
assert(taskStatus->currentPhase == "INIT");
std::cout << " 任务生成 OK\n";
// 模板管理
TaskTemplate tmpl;
tmpl.id = "TMPL-TEST";
tmpl.version = "1.0";
tmpl.applicableScenario = "threat_4";
tmpl.matchScore = 0.95;
bool tmplOk = app.addTemplate(tmpl);
assert(tmplOk);
const auto* matched = app.matchBestTemplate("threat_4");
assert(matched != nullptr);
assert(matched->id == "TMPL-TEST");
std::cout << " 模板管理 OK\n";
// 快照管理
std::string snapVer = app.saveSnapshot();
assert(!snapVer.empty());
bool rollbackOk = app.rollbackToSnapshot(snapVer);
assert(rollbackOk);
std::cout << " 快照管理 OK\n";
// 方案分发
std::vector<std::string> nodes = {"NODE-X", "NODE-Y"};
int success = app.dispatchPlan("PLAN-TEST", nodes);
assert(success >= 0 && success <= 2);
auto acks = app.getDistributionAcks();
assert(acks.size() >= 1);
std::cout << " 分发监控 OK\n";
// 执行状态上报
ExecutionStatus status;
status.taskId = taskId;
status.currentPhase = "COMPLETED";
status.completionPercent = 100.0;
status.errorCode = 0;
app.reportExecutionStatus(status);
const auto* updatedStatus = app.getExecutionStatus(taskId);
assert(updatedStatus != nullptr);
assert(updatedStatus->completionPercent == 100.0);
std::cout << " 状态监控 OK\n";
// 操作日志
OperationLog log{"TEST-OP", 1715000000000LL, "TEST", "OBJ-001", "OK"};
app.logOperation(log);
assert(app.getOperationLogs().size() >= 1);
std::cout << " 操作日志 OK\n";
// 启动/停止
bool startOk = app.start();
assert(startOk);
assert(app.getState() == SystemState::Running);
app.stop();
assert(app.getState() == SystemState::Stopped);
std::cout << " 生命周期管理 OK\n";
std::cout << " [测试] App 核心功能 ... 全部通过 ✓\n";
}
/**
* @brief SystemConfig
*/
static void testConfigLoading() {
std::cout << " [测试] 配置加载 ... ";
SystemConfig config;
// 默认值检查
assert(config.refreshIntervalMs == 50);
assert(config.websocketPort == 8080);
assert(config.maxRetryCount == 3);
assert(config.logLevel == 2);
// 尝试加载不存在的配置文件应失败但不影响默认值
bool loaded = config.loadFromFile("nonexistent_config.txt");
assert(!loaded);
assert(config.refreshIntervalMs == 50);
std::cout << "默认配置 OK, 文件不存在时回退 OK\n";
std::cout << " [测试] 配置加载 ... 通过 ✓\n";
}
/**
* @brief
*/
int main() {
std::cout << "\n╔══════════════════════════════════════════════════════╗\n";
std::cout << "║ C2SYS 系统单元测试 (基于 assert) ║\n";
std::cout << "╚══════════════════════════════════════════════════════╝\n\n";
testDataEntities();
std::cout << "\n";
testConfigLoading();
std::cout << "\n";
testAppCoreFunctions();
std::cout << "\n✅ 所有单元测试通过!\n";
return 0;
}