Files
Bionic_sphere/Bionic_Core/PetBaseClass/PetDao.cpp
T
Misaki ba5e47bc77 这是一次长久的提交:
1. 应用界面增加了返回主页的按钮
2. 修复了gif渲染内存泄漏的严重bug
3. 将PetDao当中的cJSON API替换为cpp_json,完美通过测试
4. 整合已经实现的各种上层建筑,实现了一个宠物对话基本业务应用,用于样品测试展示用
5. 重构了音频播放类,使其更modern,更加便于移植和拓展
2025-10-16 11:36:45 +08:00

274 lines
8.3 KiB
C++

//
// Created by misaki on 2025/9/14.
//
#include "PetDao.h"
#include <iostream>
#include <sstream>
using namespace PetEnumConverter;
// PetEnumConverter 实现
std::string PetEnumConverter::stageTypeToString(PetStageType stage) {
switch (stage) {
#define X(name, desc) case PetStageType::name: return #name;
PET_STAGE_TYPES
#undef X
default: return "UNKNOWN";
}
}
PetStageType PetEnumConverter::stringToStageType(const std::string& str) {
#define X(name, desc) if (str == #name) return PetStageType::name;
PET_STAGE_TYPES
#undef X
return PetStageType::PET_STAGE_YOUNG; // 默认值
}
std::string PetEnumConverter::actionTypeToString(PetActionType action) {
switch (action) {
#define X(name, desc) case PetActionType::name: return #name;
PET_ACTION_TYPES
#undef X
default: return "UNKNOWN";
}
}
PetActionType PetEnumConverter::stringToActionType(const std::string& str) {
#define X(name, desc) if (str == #name) return PetActionType::name;
PET_ACTION_TYPES
#undef X
return PetActionType::PET_ACTION_SLEEP; // 默认值
}
// PetDAO 实现
PetDAO::PetDAO(SDFileManager* fileManager) : fileManager(fileManager) {
// 确保宠物数据目录存在
fileManager->mkdirCommand( PET_DATA_DIR);
}
bool PetDAO::savePet(const std::shared_ptr<PetBase>& pet, const std::string& filename) {
try {
// 转换为JSON
cppjson::Json json = petToJson(pet);
// 序列化为字符串
std::string jsonStr = json.dump();
std::string fullPath = std::string(PET_DATA_DIR) + "/" + filename;
// 保存到文件
const bool success = fileManager->writeFileSync(fullPath.c_str(), jsonStr.c_str(), jsonStr.size(), "w");
return success;
} catch (const std::exception& e) {
std::cerr << "Save pet failed: " << e.what() << std::endl;
return false;
}
}
std::shared_ptr<PetBase> PetDAO::loadPet(const std::string& filename) {
try {
std::string fullPath = std::string(PET_DATA_DIR) + "/" + filename;
// 读取文件内容
std::string content = fileManager->readFileSync(fullPath.c_str());
if (content.empty()) {
return nullptr;
}
// 解析JSON
cppjson::Json json = cppjson::Json::parse(content);
// 创建宠物对象
return petFromJson(json);
} catch (const std::exception& e) {
std::cerr << "Load pet failed: " << e.what() << std::endl;
return nullptr;
}
}
std::vector<std::string> PetDAO::listPetFiles() {
return fileManager->listFilesSync(PET_DATA_DIR, ".json");
}
bool PetDAO::deletePetFile(const std::string& filename) {
std::string fullPath = std::string(PET_DATA_DIR) + "/" + filename;
return fileManager->rmCommand(fullPath.c_str(), false);
}
cppjson::Json PetDAO::petToJson(const std::shared_ptr<PetBase>& pet) {
auto json = cppjson::Json::object();
// 添加基本信息
json.set("name", cppjson::Json(pet->pet_info.pet_name))
.set("hp", cppjson::Json(pet->pet_info.pet_hp))
.set("density", cppjson::Json(pet->pet_info.pet_density))
.set("identity", cppjson::Json(pet->pet_info.pet_identity));
// 添加阶段策略
auto stageJson = stageStrategyToJson(pet->pet_stage_strategy);
if (!stageJson.isNull()) {
json.set("stage_strategy", stageJson);
}
// 添加动作策略
auto actionJson = actionStrategyToJson(pet->pet_action_strategy);
if (!actionJson.isNull()) {
json.set("action_strategy", actionJson);
}
return json;
}
std::shared_ptr<PetBase> PetDAO::petFromJson(const cppjson::Json& json) {
if (json.isNull()) return nullptr;
// 创建宠物基本信息
PetBaseInfo info;
if (json["name"].isString()) {
info.pet_name = json["name"].asString();
}
if (json["hp"].isNumber()) {
info.pet_hp = json["hp"].asInt();
}
if (json["density"].isNumber()) {
info.pet_density = json["density"].asInt();
}
if (json["identity"].isString()) {
info.pet_identity = json["identity"].asString();
}
// 创建阶段策略
auto stageStrategy = stageStrategyFromJson(json["stage_strategy"]);
// 创建动作策略
auto actionStrategy = actionStrategyFromJson(json["action_strategy"]);
// 创建宠物对象
return std::make_shared<PetBase>(info, stageStrategy, actionStrategy);
}
cppjson::Json PetDAO::stageStrategyToJson(const std::shared_ptr<PetStageStrategy>& strategy) {
if (!strategy) return {};
auto json = cppjson::Json::object();
// 添加当前阶段
json.set("current_stage", cppjson::Json(stageTypeToString(strategy->getCurrentStageType())));
// 添加阶段模型映射
auto modelMap = cppjson::Json::object();
for (const auto& pair : strategy->getStageModelMap()) {
modelMap.set(stageTypeToString(pair.first), cppjson::Json(pair.second));
}
json.set("stage_model_map", modelMap);
// 添加阶段音频映射
auto audioMap = cppjson::Json::object();
for (const auto& pair : strategy->getStageAudioMap()) {
audioMap.set(stageTypeToString(pair.first), cppjson::Json(pair.second));
}
json.set("stage_audio_map", audioMap);
return json;
}
std::shared_ptr<PetStageStrategy> PetDAO::stageStrategyFromJson(const cppjson::Json& json) {
if (json.isNull()) return nullptr;
auto strategy = std::make_shared<PetStageStrategy>();
// 获取当前阶段
if (json["current_stage"].isString()) {
strategy->current_stage = stringToStageType(json["current_stage"].asString());
}
// 获取阶段模型映射
auto modelMapJson = json["stage_model_map"];
if (modelMapJson.isObject()) {
for (const auto& item : modelMapJson.items()) {
if (item.second.isString()) {
PetStageType stage = stringToStageType(item.first);
strategy->stage_model_map[stage] = item.second.asString();
}
}
}
// 获取阶段音频映射
auto audioMapJson = json["stage_audio_map"];
if (audioMapJson.isObject()) {
for (const auto& item : audioMapJson.items()) {
if (item.second.isString()) {
PetStageType stage = stringToStageType(item.first);
strategy->stage_audio_map[stage] = item.second.asString();
}
}
}
return strategy;
}
cppjson::Json PetDAO::actionStrategyToJson(const std::shared_ptr<PetActionStrategy>& strategy) {
if (!strategy) return {};
auto json = cppjson::Json::object();
// 添加当前动作
json.set("current_action", cppjson::Json(actionTypeToString(strategy->getCurrentActionType())));
// 添加动作模型映射
auto modelMap = cppjson::Json::object();
for (const auto& pair : strategy->getActionModelMap()) {
modelMap.set(actionTypeToString(pair.first), cppjson::Json(pair.second));
}
json.set("action_model_map", modelMap);
// 添加动作音频映射
auto audioMap = cppjson::Json::object();
for (const auto& pair : strategy->getActionAudioMap()) {
audioMap.set(actionTypeToString(pair.first), cppjson::Json(pair.second));
}
json.set("action_audio_map", audioMap);
return json;
}
std::shared_ptr<PetActionStrategy> PetDAO::actionStrategyFromJson(const cppjson::Json& json) {
if (json.isNull()) return nullptr;
auto strategy = std::make_shared<PetActionStrategy>();
// 获取当前动作
if (json["current_action"].isString()) {
strategy->current_action = stringToActionType(json["current_action"].asString());
}
// 获取动作模型映射
auto modelMapJson = json["action_model_map"];
if (modelMapJson.isObject()) {
for (const auto& item : modelMapJson.items()) {
if (item.second.isString()) {
PetActionType action = stringToActionType(item.first);
strategy->action_model_map[action] = item.second.asString();
}
}
}
// 获取动作音频映射
auto audioMapJson = json["action_audio_map"];
if (audioMapJson.isObject()) {
for (const auto& item : audioMapJson.items()) {
if (item.second.isString()) {
PetActionType action = stringToActionType(item.first);
strategy->action_audio_map[action] = item.second.asString();
}
}
}
return strategy;
}