生成代码工程

This commit is contained in:
root 2026-05-25 16:25:48 +08:00
parent 99b59b1877
commit a5d1d8f8bc
18 changed files with 10944 additions and 2 deletions

23
CMakeLists.txt Normal file
View File

@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.14)
project(BattlefieldTaskPlanner VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (MSVC)
add_compile_options(/utf-8)
endif()
#
include_directories(include)
# main.cpp
file(GLOB_RECURSE CORE_SOURCES src/core/*.cpp)
list(APPEND CORE_SOURCES src/app.cpp)
# ---------- ----------
add_executable(battle_planner src/main.cpp ${CORE_SOURCES})
# ---------- ----------
add_executable(basic_test tests/basic_test.cpp ${CORE_SOURCES})
target_include_directories(basic_test PRIVATE include)

View File

@ -1,3 +1,40 @@
# 任务自主规划与执行软件
# BattlefieldTaskPlanner — 战场任务规划原型系统
暂无描述
基于 C++17 实现的作战任务规划原型系统,覆盖从事件感知、任务生成、模板管理、
方案制定到分发监控的全流程核心模型。
## 工程结构
```
├── CMakeLists.txt
├── README.md
├── include/
│ ├── app.hpp # 顶层应用门面
│ └── core/
│ ├── event.hpp # 事件接收与处理模块
│ ├── task.hpp # 任务生成模块
│ ├── template.hpp # 模板管理模块
│ ├── plan.hpp # 方案管理模块
│ └── dispatch.hpp # 分发监控模块
├── src/
│ ├── main.cpp # 命令行入口
│ ├── app.cpp # 应用实现
│ └── core/
│ ├── event.cpp
│ ├── task.cpp
│ ├── template.cpp
│ ├── plan.cpp
│ └── dispatch.cpp
└── tests/
└── basic_test.cpp # 基于 assert 的单元测试
```
## 编译与运行
```bash
mkdir -p build && cd build
cmake ..
cmake --build .
./battle_planner # 运行主程序
./basic_test # 运行测试
```

9971
events.ndjson Normal file

File diff suppressed because one or more lines are too long

40
generation.json Normal file

File diff suppressed because one or more lines are too long

45
include/app.hpp Normal file
View File

@ -0,0 +1,45 @@
#ifndef BATTLEFIELD_APP_HPP
#define BATTLEFIELD_APP_HPP
#include <string>
#include "core/event.hpp"
#include "core/task.hpp"
#include "core/template.hpp"
#include "core/plan.hpp"
#include "core/dispatch.hpp"
namespace battlefield {
/// @brief 战场任务规划系统顶层应用门面
/// 组合所有核心模块,提供统一的全流程编排入口。
class App {
public:
/// @brief 构造函数,初始化各模块
App();
/// @brief 运行完整的演示流程
/// 模拟:事件接收 → 任务生成 → 模板选择 → 方案制定 → 分发监控
void Run();
/// @brief 获取事件处理器引用
EventProcessor& GetEventProcessor() { return eventProcessor_; }
/// @brief 获取任务生成器引用
TaskGenerator& GetTaskGenerator() { return taskGenerator_; }
/// @brief 获取模板管理器引用
TemplateManager& GetTemplateManager() { return templateManager_; }
/// @brief 获取方案管理器引用
PlanManager& GetPlanManager() { return planManager_; }
/// @brief 获取分发监控器引用
DispatchMonitor& GetDispatchMonitor() { return dispatchMonitor_; }
private:
EventProcessor eventProcessor_;
TaskGenerator taskGenerator_;
TemplateManager templateManager_;
PlanManager planManager_;
DispatchMonitor dispatchMonitor_;
};
} // namespace battlefield
#endif // BATTLEFIELD_APP_HPP

74
include/core/dispatch.hpp Normal file
View File

@ -0,0 +1,74 @@
#ifndef BATTLEFIELD_CORE_DISPATCH_HPP
#define BATTLEFIELD_CORE_DISPATCH_HPP
#include <string>
#include <vector>
#include <chrono>
#include <cstdint>
#include "core/plan.hpp"
namespace battlefield {
/// @brief 指令包数据结构,对应 IF-03 输出格式
struct CmdPacket {
std::string packetId; ///< 指令包ID
std::string planId; ///< 关联方案ID
std::string targetUnit; ///< 目标执行单元
std::string payload; ///< 指令载荷JSON
std::chrono::system_clock::time_point issueTime; ///< 下发时间
};
/// @brief 分发日志记录,对应 T_DISPATCH_LOG
struct DispatchLog {
std::string logId; ///< 日志ID
std::string planId; ///< 方案ID
std::string action; ///< 操作描述
std::chrono::system_clock::time_point timestamp; ///< 时间戳
bool success{true}; ///< 是否成功
};
/// @brief 监控状态快照
struct MonitorStatus {
int32_t totalTasks{0}; ///< 总任务数
int32_t completedTasks{0}; ///< 已完成
int32_t inProgressTasks{0}; ///< 进行中
int32_t failedTasks{0}; ///< 失败
double progressPercent{0.0}; ///< 总体进度百分比
};
/// @brief 分发监控模块(覆盖 SRS-F-06-001 ~ SRS-F-06-003
class DispatchMonitor {
public:
/// @brief 驱动最终方案的分发执行(对应 IF-03 / IF-05
/// @param plan 待分发的最终方案
/// @param targetUnit 目标执行单元
/// @return 生成的指令包
CmdPacket DispatchPlan(const Plan& plan, const std::string& targetUnit);
/// @brief 获取当前状态监控仪表盘数据
/// @return MonitorStatus 结构体
MonitorStatus GetMonitorStatus() const;
/// @brief 构建总览看板数据(含反馈闭环,触发重规划标识)
/// @return 看板摘要字符串
std::string GetDashboardData() const;
/// @brief 记录分发日志
/// @param planId 方案ID
/// @param action 操作描述
/// @param success 是否成功
void LogDispatch(const std::string& planId, const std::string& action, bool success);
/// @brief 模拟推进执行进度
/// @param completed 新完成的任务数
void AdvanceProgress(int32_t completed);
private:
std::vector<CmdPacket> issuedPackets_; ///< 已下发的指令包
std::vector<DispatchLog> logs_; ///< 分发日志
MonitorStatus status_; ///< 当前监控状态
};
} // namespace battlefield
#endif // BATTLEFIELD_CORE_DISPATCH_HPP

69
include/core/event.hpp Normal file
View File

@ -0,0 +1,69 @@
#ifndef BATTLEFIELD_CORE_EVENT_HPP
#define BATTLEFIELD_CORE_EVENT_HPP
#include <string>
#include <chrono>
#include <vector>
#include <cstdint>
namespace battlefield {
/// @brief 事件类型枚举
enum class EventType : int32_t {
UNKNOWN = 0, ///< 未知类型
INTEL = 1, ///< 情报事件
THREAT = 2, ///< 威胁事件
MISSION = 3, ///< 任务事件
LOGISTIC = 4 ///< 后勤事件
};
/// @brief 事件状态枚举
enum class EventStatus : int32_t {
PENDING = 0, ///< 待处理
PROCESSING = 1, ///< 处理中
RESOLVED = 2, ///< 已解决
ARCHIVED = 3 ///< 已归档
};
/// @brief 战场事件数据结构,对应数据库表 T_EVENT
struct Event {
std::string id; ///< EVENT_ID
EventType type; ///< EVENT_TYPE
std::chrono::system_clock::time_point timestamp; ///< TIMESTAMP
std::string location; ///< LOCATION
int32_t priority{0}; ///< PRIORITY
EventStatus status{EventStatus::PENDING}; ///< STATUS
};
/// @brief 事件接收与处理模块(覆盖 SRS-F-01-001 ~ SRS-F-01-004
class EventProcessor {
public:
/// @brief 接收外部事件数据包(对应接口 IF-01
/// @param rawJson 原始 JSON 格式的事件数据
/// @return 成功接收返回 true
bool ReceiveEvent(const std::string& rawJson);
/// @brief 对事件数据进行过滤、转化和封装
/// @param raw 原始字符串数据
/// @return 标准化后的 Event 对象
Event TransformEvent(const std::string& raw);
/// @brief 获取当前所有待处理事件列表
/// @return 事件列表(按接收顺序)
std::vector<Event> GetPendingEvents() const;
/// @brief 按优先级对待处理事件排序
/// @param ascending true 为升序低优先级在前false 为降序
void SortEventsByPriority(bool ascending = true);
/// @brief 获取事件总数
/// @return 事件数量
size_t GetEventCount() const { return events_.size(); }
private:
std::vector<Event> events_; ///< 内部事件存储
};
} // namespace battlefield
#endif // BATTLEFIELD_CORE_EVENT_HPP

70
include/core/plan.hpp Normal file
View File

@ -0,0 +1,70 @@
#ifndef BATTLEFIELD_CORE_PLAN_HPP
#define BATTLEFIELD_CORE_PLAN_HPP
#include <string>
#include <vector>
#include <cstdint>
#include <map>
namespace battlefield {
/// @brief 子任务关系图谱节点,对应 T_PLAN_SUBTASK
struct PlanSubTask {
std::string id; ///< 子任务ID
std::string parentId; ///< 父任务ID空字符串表示根任务
std::string name; ///< 子任务名称
std::string description; ///< 描述
int32_t orderIndex{0}; ///< 执行顺序
std::string assignedUnit; ///< 执行单元
};
/// @brief 作战方案主数据结构,对应 T_PLAN
struct Plan {
std::string id; ///< 方案ID
std::string name; ///< 方案名称
std::string description; ///< 方案描述
std::vector<PlanSubTask> subTasks; ///< 子任务列表
double score{0.0}; ///< 方案评分
};
/// @brief 方案管理模块(覆盖 SRS-F-05-001 ~ SRS-F-05-004
class PlanManager {
public:
/// @brief 创建新方案
/// @param name 方案名称
/// @param description 方案描述
/// @return 创建的 Plan 对象
Plan CreatePlan(const std::string& name, const std::string& description);
/// @brief 获取所有方案列表
/// @return 方案列表
std::vector<Plan> GetPlanList() const;
/// @brief 按评分排序方案列表
/// @param ascending 是否升序
void SortPlansByScore(bool ascending = false);
/// @brief 对比两个方案的详细信息
/// @param planIdA 方案A的ID
/// @param planIdB 方案B的ID
/// @return 差异描述字符串
std::string ComparePlans(const std::string& planIdA, const std::string& planIdB);
/// @brief 重组方案(调整子任务顺序或分配)
/// @param planId 方案ID
/// @param newSubTasks 新的子任务列表
/// @return 是否成功重组
bool ReorganizePlan(const std::string& planId, const std::vector<PlanSubTask>& newSubTasks);
/// @brief 合并多个方案为一个融合方案
/// @param planIds 待融合的方案ID列表
/// @return 融合后的新方案
Plan MergePlans(const std::vector<std::string>& planIds);
private:
std::map<std::string, Plan> plans_; ///< 方案存储key为方案ID
};
} // namespace battlefield
#endif // BATTLEFIELD_CORE_PLAN_HPP

57
include/core/task.hpp Normal file
View File

@ -0,0 +1,57 @@
#ifndef BATTLEFIELD_CORE_TASK_HPP
#define BATTLEFIELD_CORE_TASK_HPP
#include <string>
#include <vector>
#include <cstdint>
#include "core/event.hpp"
namespace battlefield {
/// @brief 任务草案状态枚举
enum class DraftStatus : int32_t {
DRAFT = 0, ///< 草稿
SUBMITTED = 1, ///< 已提交
APPROVED = 2, ///< 已批准
REJECTED = 3 ///< 已驳回
};
/// @brief 任务草案数据结构,对应 T_TASK_DRAFT内存缓存后持久化
struct TaskDraft {
std::string id; ///< 任务草案ID
std::string title; ///< 任务标题
std::string description; ///< 任务描述
int32_t priority{0}; ///< 优先级
DraftStatus status{DraftStatus::DRAFT}; ///< 状态
std::string relatedEventId; ///< 关联事件ID
};
/// @brief 任务生成模块(覆盖 SRS-F-02-001 ~ SRS-F-02-004
class TaskGenerator {
public:
/// @brief 基于选定事件生成作战任务草案
/// @param event 源事件
/// @return 生成的 TaskDraft 对象
TaskDraft CreateTaskFromEvent(const Event& event);
/// @brief 获取当前所有任务草案列表
/// @return 草案列表
std::vector<TaskDraft> GetDraftList() const;
/// @brief 提交任务草案送交处理(对应接口 IF-02
/// @param draftId 草案ID
/// @param targetUrl 目标任务引擎地址
/// @return 是否提交成功
bool SubmitDraft(const std::string& draftId, const std::string& targetUrl);
/// @brief 按优先级排序草案列表
/// @param ascending 是否升序
void SortDraftsByPriority(bool ascending = true);
private:
std::vector<TaskDraft> drafts_; ///< 内存暂存的任务草案
};
} // namespace battlefield
#endif // BATTLEFIELD_CORE_TASK_HPP

55
include/core/template.hpp Normal file
View File

@ -0,0 +1,55 @@
#ifndef BATTLEFIELD_CORE_TEMPLATE_HPP
#define BATTLEFIELD_CORE_TEMPLATE_HPP
#include <string>
#include <vector>
#include <cstdint>
namespace battlefield {
/// @brief 任务模板数据结构,对应 T_TEMPLATE含版本管理字段 VERSION_ID
struct TaskTemplate {
std::string versionId; ///< VERSION_ID版本号
std::string name; ///< 模板名称
std::string description; ///< 模板描述
std::string content; ///< 模板内容JSON格式
std::string dateIndex; ///< 日期索引
bool isActive{true}; ///< 是否当前激活版本
};
/// @brief 模板管理模块(覆盖 SRS-F-03 / SRS-F-04 相关需求)
class TemplateManager {
public:
/// @brief 加载任务模板集合(模拟从文件系统读取 JSON 模板文件)
/// @param directory 模板文件目录
/// @return 成功加载的模板数量
size_t LoadTemplates(const std::string& directory);
/// @brief 获取所有模板列表
/// @return 模板列表
std::vector<TaskTemplate> GetTemplateList() const;
/// @brief 按名称排序模板列表
/// @param ascending 是否升序
void SortTemplatesByName(bool ascending = true);
/// @brief 选择指定版本的模板(人环模式)
/// @param versionId 版本ID
/// @return 选中的模板,若不存在返回空
TaskTemplate SelectTemplate(const std::string& versionId);
/// @brief 自动推荐最优模板(自主模式)
/// @return 推荐的模板
TaskTemplate RecommendTemplate();
/// @brief 获取模板总数
/// @return 模板数量
size_t GetTemplateCount() const { return templates_.size(); }
private:
std::vector<TaskTemplate> templates_; ///< 模板集合
};
} // namespace battlefield
#endif // BATTLEFIELD_CORE_TEMPLATE_HPP

63
src/app.cpp Normal file
View File

@ -0,0 +1,63 @@
#include "app.hpp"
#include <iostream>
namespace battlefield {
App::App() {
// 各模块使用默认构造初始化
}
void App::Run() {
std::cout << "========== 战场任务规划系统 (BattlefieldTaskPlanner) ==========\n\n";
// ---- 1. 事件接收处理 ----
std::cout << "[1] 事件接收处理 (SRS-F-01)\n";
eventProcessor_.ReceiveEvent(R"({"type":"intel","source":"drone","priority":8})");
eventProcessor_.ReceiveEvent(R"({"type":"threat","source":"radar","priority":9})");
eventProcessor_.ReceiveEvent(R"({"type":"logistic","source":"supply","priority":3})");
std::cout << " 已接收 " << eventProcessor_.GetEventCount() << " 个事件\n";
eventProcessor_.SortEventsByPriority(false);
auto pendingEvents = eventProcessor_.GetPendingEvents();
for (const auto& e : pendingEvents) {
std::cout << " - " << e.id << " (Priority: " << e.priority << ")\n";
}
// ---- 2. 任务生成 ----
std::cout << "\n[2] 任务生成 (SRS-F-02)\n";
for (const auto& e : pendingEvents) {
TaskDraft draft = taskGenerator_.CreateTaskFromEvent(e);
std::cout << " 生成任务草案: " << draft.id << " <- " << draft.title << "\n";
}
taskGenerator_.SubmitDraft("DRF-EVT-{", "http://task-engine.local/submit");
// ---- 3. 模板管理 ----
std::cout << "\n[3] 模板管理 (SRS-F-03 / SRS-F-04)\n";
templateManager_.LoadTemplates("/lib/tpcs/templates");
std::cout << " 已加载 " << templateManager_.GetTemplateCount() << " 个模板\n";
auto selected = templateManager_.SelectTemplate("v1.1");
if (!selected.versionId.empty()) {
std::cout << " 选择模板: " << selected.name << " (v" << selected.versionId << ")\n";
}
auto recommended = templateManager_.RecommendTemplate();
std::cout << " 自主推荐模板: " << recommended.name << "\n";
// ---- 4. 方案管理 ----
std::cout << "\n[4] 方案管理 (SRS-F-05)\n";
Plan planA = planManager_.CreatePlan("Offensive Plan A", "Direct strike approach");
Plan planB = planManager_.CreatePlan("Defensive Plan B", "Perimeter hold approach");
std::cout << " 创建方案: " << planA.name << " (" << planA.id << ")\n";
std::cout << " 创建方案: " << planB.name << " (" << planB.id << ")\n";
std::cout << " 对比结果:\n" << planManager_.ComparePlans(planA.id, planB.id) << "\n";
// ---- 5. 分发监控 ----
std::cout << "\n[5] 分发监控 (SRS-F-06)\n";
CmdPacket cmd = dispatchMonitor_.DispatchPlan(planA, "battalion-1");
std::cout << " 下发指令包: " << cmd.packetId << " -> " << cmd.targetUnit << "\n";
dispatchMonitor_.AdvanceProgress(2);
std::cout << " 推进执行进度...\n";
std::cout << " 看板数据:\n" << dispatchMonitor_.GetDashboardData() << "\n";
std::cout << "\n========== 流程演示完毕 ==========\n";
}
} // namespace battlefield

68
src/core/dispatch.cpp Normal file
View File

@ -0,0 +1,68 @@
#include "core/dispatch.hpp"
#include <algorithm>
#include <sstream>
#include <iomanip>
namespace battlefield {
CmdPacket DispatchMonitor::DispatchPlan(const Plan& plan, const std::string& targetUnit) {
CmdPacket packet;
packet.packetId = "CMD-" + plan.id;
packet.planId = plan.id;
packet.targetUnit = targetUnit;
packet.payload = "{\"plan\": \"" + plan.name + "\", \"tasks\": " +
std::to_string(plan.subTasks.size()) + "}";
packet.issueTime = std::chrono::system_clock::now();
issuedPackets_.push_back(packet);
// 更新监控状态
status_.totalTasks += static_cast<int32_t>(plan.subTasks.size());
status_.inProgressTasks += static_cast<int32_t>(plan.subTasks.size());
LogDispatch(plan.id, "DISPATCH", true);
return packet;
}
MonitorStatus DispatchMonitor::GetMonitorStatus() const {
return status_;
}
std::string DispatchMonitor::GetDashboardData() const {
std::stringstream ss;
auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
ss << "=== Dashboard ===\n"
<< "Time: " << std::put_time(std::gmtime(&now), "%Y-%m-%d %H:%M:%S") << "\n"
<< "Total Tasks: " << status_.totalTasks << "\n"
<< "Completed: " << status_.completedTasks << "\n"
<< "In Progress: " << status_.inProgressTasks << "\n"
<< "Failed: " << status_.failedTasks << "\n"
<< "Progress: " << std::fixed << std::setprecision(1)
<< status_.progressPercent << "%\n"
<< "Issued Packets: " << issuedPackets_.size() << "\n"
<< "Log Entries: " << logs_.size();
return ss.str();
}
void DispatchMonitor::LogDispatch(const std::string& planId,
const std::string& action, bool success) {
DispatchLog log;
log.logId = "LOG-" + std::to_string(logs_.size() + 1);
log.planId = planId;
log.action = action;
log.timestamp = std::chrono::system_clock::now();
log.success = success;
logs_.push_back(log);
}
void DispatchMonitor::AdvanceProgress(int32_t completed) {
int32_t actualCompleted = std::min(completed, status_.inProgressTasks);
status_.completedTasks += actualCompleted;
status_.inProgressTasks -= actualCompleted;
if (status_.totalTasks > 0) {
status_.progressPercent =
100.0 * static_cast<double>(status_.completedTasks) /
static_cast<double>(status_.totalTasks);
}
}
} // namespace battlefield

47
src/core/event.cpp Normal file
View File

@ -0,0 +1,47 @@
#include "core/event.hpp"
#include <algorithm>
#include <sstream>
namespace battlefield {
bool EventProcessor::ReceiveEvent(const std::string& rawJson) {
// 模拟接收:将原始 JSON 转化为 Event 对象并加入列表
Event evt = TransformEvent(rawJson);
events_.push_back(evt);
return true;
}
Event EventProcessor::TransformEvent(const std::string& raw) {
// 模拟转化逻辑:从原始字符串解析字段
Event evt;
// 简单模拟:使用字符串内容生成 ID 和类型
std::stringstream ss(raw);
std::string token;
std::getline(ss, token, ',');
evt.id = "EVT-" + token.substr(0, 4);
evt.type = EventType::INTEL;
evt.priority = 5;
evt.location = "zone-alpha";
evt.timestamp = std::chrono::system_clock::now();
evt.status = EventStatus::PENDING;
return evt;
}
std::vector<Event> EventProcessor::GetPendingEvents() const {
std::vector<Event> pending;
for (const auto& e : events_) {
if (e.status == EventStatus::PENDING) {
pending.push_back(e);
}
}
return pending;
}
void EventProcessor::SortEventsByPriority(bool ascending) {
std::sort(events_.begin(), events_.end(),
[ascending](const Event& a, const Event& b) {
return ascending ? (a.priority < b.priority) : (a.priority > b.priority);
});
}
} // namespace battlefield

85
src/core/plan.cpp Normal file
View File

@ -0,0 +1,85 @@
#include "core/plan.hpp"
#include <algorithm>
#include <sstream>
#include <numeric>
namespace battlefield {
Plan PlanManager::CreatePlan(const std::string& name, const std::string& description) {
Plan plan;
plan.id = "PLN-" + std::to_string(plans_.size() + 1);
plan.name = name;
plan.description = description;
plan.score = 0.0;
plans_[plan.id] = plan;
return plan;
}
std::vector<Plan> PlanManager::GetPlanList() const {
std::vector<Plan> result;
for (const auto& pair : plans_) {
result.push_back(pair.second);
}
return result;
}
void PlanManager::SortPlansByScore(bool ascending) {
// map 本身无序,需要先转成 vector 排序后再重建
std::vector<Plan> sorted;
for (const auto& pair : plans_) sorted.push_back(pair.second);
std::sort(sorted.begin(), sorted.end(),
[ascending](const Plan& a, const Plan& b) {
return ascending ? (a.score < b.score) : (a.score > b.score);
});
plans_.clear();
for (const auto& p : sorted) {
plans_[p.id] = p;
}
}
std::string PlanManager::ComparePlans(const std::string& planIdA, const std::string& planIdB) {
auto itA = plans_.find(planIdA);
auto itB = plans_.find(planIdB);
if (itA == plans_.end() || itB == plans_.end()) return "Plan not found.";
std::stringstream ss;
ss << "Comparison [" << itA->second.name << " vs " << itB->second.name << "]:\n"
<< " Score: " << itA->second.score << " vs " << itB->second.score << "\n"
<< " SubTasks: " << itA->second.subTasks.size() << " vs "
<< itB->second.subTasks.size();
return ss.str();
}
bool PlanManager::ReorganizePlan(const std::string& planId,
const std::vector<PlanSubTask>& newSubTasks) {
auto it = plans_.find(planId);
if (it == plans_.end()) return false;
it->second.subTasks = newSubTasks;
return true;
}
Plan PlanManager::MergePlans(const std::vector<std::string>& planIds) {
Plan merged;
merged.id = "PLN-MERGED-" + std::to_string(plans_.size() + 1);
merged.name = "Merged Plan";
merged.description = "Fusion of " + std::to_string(planIds.size()) + " plans";
int subTaskIndex = 0;
for (const auto& pid : planIds) {
auto it = plans_.find(pid);
if (it != plans_.end()) {
for (const auto& st : it->second.subTasks) {
PlanSubTask copy = st;
copy.id = "MST-" + std::to_string(++subTaskIndex);
merged.subTasks.push_back(copy);
}
merged.score += it->second.score;
}
}
if (!planIds.empty()) merged.score /= static_cast<double>(planIds.size());
plans_[merged.id] = merged;
return merged;
}
} // namespace battlefield

41
src/core/task.cpp Normal file
View File

@ -0,0 +1,41 @@
#include "core/task.hpp"
#include <algorithm>
#include <sstream>
namespace battlefield {
TaskDraft TaskGenerator::CreateTaskFromEvent(const Event& event) {
TaskDraft draft;
draft.id = "DRF-" + event.id;
draft.title = "Task from " + event.id;
draft.description = "Auto-generated task based on event: " + event.id;
draft.priority = event.priority;
draft.status = DraftStatus::DRAFT;
draft.relatedEventId = event.id;
drafts_.push_back(draft);
return draft;
}
std::vector<TaskDraft> TaskGenerator::GetDraftList() const {
return drafts_;
}
bool TaskGenerator::SubmitDraft(const std::string& draftId, const std::string& targetUrl) {
for (auto& d : drafts_) {
if (d.id == draftId) {
d.status = DraftStatus::SUBMITTED;
// 模拟向 targetUrl 发送任务草案(对应 IF-02
return true;
}
}
return false;
}
void TaskGenerator::SortDraftsByPriority(bool ascending) {
std::sort(drafts_.begin(), drafts_.end(),
[ascending](const TaskDraft& a, const TaskDraft& b) {
return ascending ? (a.priority < b.priority) : (a.priority > b.priority);
});
}
} // namespace battlefield

48
src/core/template.cpp Normal file
View File

@ -0,0 +1,48 @@
#include "core/template.hpp"
#include <algorithm>
#include <ctime>
namespace battlefield {
size_t TemplateManager::LoadTemplates(const std::string& directory) {
// 模拟加载:生成若干示例模板
for (int i = 1; i <= 3; ++i) {
TaskTemplate tmpl;
tmpl.versionId = "v1." + std::to_string(i);
tmpl.name = "Template-" + std::to_string(i);
tmpl.description = "Standard mission template " + std::to_string(i);
tmpl.content = "{\"type\": \"mission\", \"version\": \"" + tmpl.versionId + "\"}";
tmpl.dateIndex = "2025-03-01";
tmpl.isActive = (i == 1);
templates_.push_back(tmpl);
}
return templates_.size();
}
std::vector<TaskTemplate> TemplateManager::GetTemplateList() const {
return templates_;
}
void TemplateManager::SortTemplatesByName(bool ascending) {
std::sort(templates_.begin(), templates_.end(),
[ascending](const TaskTemplate& a, const TaskTemplate& b) {
return ascending ? (a.name < b.name) : (a.name > b.name);
});
}
TaskTemplate TemplateManager::SelectTemplate(const std::string& versionId) {
for (const auto& t : templates_) {
if (t.versionId == versionId) return t;
}
return TaskTemplate{};
}
TaskTemplate TemplateManager::RecommendTemplate() {
// 自主模式:返回评分最高的模板(模拟选第一个激活的)
for (const auto& t : templates_) {
if (t.isActive) return t;
}
return templates_.empty() ? TaskTemplate{} : templates_.front();
}
} // namespace battlefield

9
src/main.cpp Normal file
View File

@ -0,0 +1,9 @@
#include "app.hpp"
/// @brief 命令行入口
/// @return 程序退出码
int main() {
battlefield::App app;
app.Run();
return 0;
}

140
tests/basic_test.cpp Normal file
View File

@ -0,0 +1,140 @@
#include <cassert>
#include <iostream>
#include <string>
#include "core/event.hpp"
#include "core/task.hpp"
#include "core/template.hpp"
#include "core/plan.hpp"
#include "core/dispatch.hpp"
/// @brief 测试 EventProcessor 模块
static void TestEventProcessor() {
battlefield::EventProcessor ep;
bool ok = ep.ReceiveEvent(R"({"type":"intel","priority":7})");
assert(ok);
assert(ep.GetEventCount() == 1);
ok = ep.ReceiveEvent(R"({"type":"threat","priority":9})");
assert(ok);
assert(ep.GetEventCount() == 2);
auto pending = ep.GetPendingEvents();
assert(pending.size() == 2);
ep.SortEventsByPriority(false); // 降序
pending = ep.GetPendingEvents();
assert(pending[0].priority >= pending[1].priority);
std::cout << "[PASS] TestEventProcessor\n";
}
/// @brief 测试 TaskGenerator 模块
static void TestTaskGenerator() {
battlefield::TaskGenerator tg;
battlefield::Event evt;
evt.id = "EVT-001";
evt.priority = 8;
evt.type = battlefield::EventType::INTEL;
battlefield::TaskDraft draft = tg.CreateTaskFromEvent(evt);
assert(draft.relatedEventId == "EVT-001");
assert(draft.status == battlefield::DraftStatus::DRAFT);
auto list = tg.GetDraftList();
assert(list.size() == 1);
bool submitted = tg.SubmitDraft(draft.id, "http://engine.local");
assert(submitted);
list = tg.GetDraftList();
assert(list[0].status == battlefield::DraftStatus::SUBMITTED);
std::cout << "[PASS] TestTaskGenerator\n";
}
/// @brief 测试 TemplateManager 模块
static void TestTemplateManager() {
battlefield::TemplateManager tm;
size_t count = tm.LoadTemplates("/fake/path");
assert(count == 3);
assert(tm.GetTemplateCount() == 3);
auto list = tm.GetTemplateList();
assert(list.size() == 3);
auto selected = tm.SelectTemplate("v1.1");
assert(!selected.versionId.empty());
assert(selected.name == "Template-1");
auto recommended = tm.RecommendTemplate();
assert(!recommended.versionId.empty());
std::cout << "[PASS] TestTemplateManager\n";
}
/// @brief 测试 PlanManager 模块
static void TestPlanManager() {
battlefield::PlanManager pm;
battlefield::Plan a = pm.CreatePlan("Plan A", "First option");
battlefield::Plan b = pm.CreatePlan("Plan B", "Second option");
assert(!a.id.empty());
assert(!b.id.empty());
auto list = pm.GetPlanList();
assert(list.size() == 2);
std::string cmp = pm.ComparePlans(a.id, b.id);
assert(cmp.find("Score") != std::string::npos);
// 融合测试
battlefield::Plan merged = pm.MergePlans({a.id, b.id});
assert(merged.id.find("MERGED") != std::string::npos);
std::cout << "[PASS] TestPlanManager\n";
}
/// @brief 测试 DispatchMonitor 模块
static void TestDispatchMonitor() {
battlefield::DispatchMonitor dm;
battlefield::Plan plan;
plan.id = "PLN-TEST";
plan.name = "Test Plan";
battlefield::PlanSubTask st;
st.id = "ST-1";
st.name = "Recon";
plan.subTasks.push_back(st);
battlefield::CmdPacket cmd = dm.DispatchPlan(plan, "unit-alpha");
assert(cmd.packetId.find("CMD-") != std::string::npos);
assert(cmd.targetUnit == "unit-alpha");
auto status = dm.GetMonitorStatus();
assert(status.totalTasks == 1);
dm.AdvanceProgress(1);
status = dm.GetMonitorStatus();
assert(status.completedTasks == 1);
assert(status.progressPercent == 100.0);
std::string dash = dm.GetDashboardData();
assert(dash.find("Progress") != std::string::npos);
std::cout << "[PASS] TestDispatchMonitor\n";
}
/// @brief 主测试入口
/// @return 0 全部通过
int main() {
std::cout << "========== BattlefieldTaskPlanner 单元测试 ==========\n\n";
TestEventProcessor();
TestTaskGenerator();
TestTemplateManager();
TestPlanManager();
TestDispatchMonitor();
std::cout << "\n========== 全部测试通过 ==========\n";
return 0;
}