// // Created by misaki on 2025/9/14. // #include "PetDao.h" #include #include 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& pet, const std::string& filename) { // 转换为JSON cJSON* json = petToJson(pet); if (!json) { return false; } // 转换为字符串 char* jsonStr = cJSON_PrintUnformatted(json); std::string fullPath = std::string(PET_DATA_DIR) + "/" + filename; // 保存到文件 bool success = fileManager->writeFileSync(fullPath.c_str(), jsonStr); // 清理资源 free(jsonStr); cJSON_Delete(json); return success; } std::shared_ptr PetDAO::loadPet(const std::string& filename) { std::string fullPath = std::string(PET_DATA_DIR) + "/" + filename; // 读取文件内容 std::string content = fileManager->readFileSync(fullPath.c_str()); if (content.empty()) { return nullptr; } // 解析JSON cJSON* json = cJSON_Parse(content.c_str()); if (!json) { return nullptr; } // 创建宠物对象 auto pet = petFromJson(json); // 清理资源 cJSON_Delete(json); return pet; } std::vector 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); } cJSON* PetDAO::petToJson(const std::shared_ptr& pet) { cJSON* json = cJSON_CreateObject(); if (!json) return nullptr; // 添加基本信息 cJSON_AddStringToObject(json, "name", pet->pet_info.pet_name.c_str()); cJSON_AddNumberToObject(json, "hp", pet->pet_info.pet_hp); cJSON_AddNumberToObject(json, "density", pet->pet_info.pet_density); cJSON_AddStringToObject(json, "identity", pet->pet_info.pet_identity.c_str()); // 添加阶段策略 cJSON* stageJson = stageStrategyToJson(pet->pet_stage_strategy); if (stageJson) { cJSON_AddItemToObject(json, "stage_strategy", stageJson); } // 添加动作策略 cJSON* actionJson = actionStrategyToJson(pet->pet_action_strategy); if (actionJson) { cJSON_AddItemToObject(json, "action_strategy", actionJson); } return json; } std::shared_ptr PetDAO::petFromJson(cJSON* json) { if (!json) return nullptr; // 创建宠物基本信息 PetBaseInfo info; cJSON* nameItem = cJSON_GetObjectItemCaseSensitive(json, "name"); if (cJSON_IsString(nameItem)) { info.pet_name = nameItem->valuestring; } cJSON* hpItem = cJSON_GetObjectItemCaseSensitive(json, "hp"); if (cJSON_IsNumber(hpItem)) { info.pet_hp = hpItem->valueint; } cJSON* densityItem = cJSON_GetObjectItemCaseSensitive(json, "density"); if (cJSON_IsNumber(densityItem)) { info.pet_density = densityItem->valueint; } cJSON* identityItem = cJSON_GetObjectItemCaseSensitive(json, "identity"); if (cJSON_IsString(identityItem)) { info.pet_identity = identityItem->valuestring; } // 创建阶段策略 cJSON* stageJson = cJSON_GetObjectItemCaseSensitive(json, "stage_strategy"); auto stageStrategy = stageStrategyFromJson(stageJson); // 创建动作策略 cJSON* actionJson = cJSON_GetObjectItemCaseSensitive(json, "action_strategy"); auto actionStrategy = actionStrategyFromJson(actionJson); // 创建宠物对象 return std::make_shared(info, stageStrategy, actionStrategy); } cJSON* PetDAO::stageStrategyToJson(const std::shared_ptr& strategy) { if (!strategy) return nullptr; cJSON* json = cJSON_CreateObject(); if (!json) return nullptr; // 添加当前阶段 cJSON_AddStringToObject(json, "current_stage", stageTypeToString(strategy->getCurrentStageType()).c_str()); // 添加阶段模型映射 cJSON* modelMap = cJSON_CreateObject(); for (const auto& pair : strategy->getStageModelMap()) { cJSON_AddStringToObject(modelMap, stageTypeToString(pair.first).c_str(), pair.second.c_str()); } cJSON_AddItemToObject(json, "stage_model_map", modelMap); // 添加阶段音频映射 cJSON* audioMap = cJSON_CreateObject(); for (const auto& pair : strategy->getStageAudioMap()) { cJSON_AddStringToObject(audioMap, stageTypeToString(pair.first).c_str(), pair.second.c_str()); } cJSON_AddItemToObject(json, "stage_audio_map", audioMap); return json; } std::shared_ptr PetDAO::stageStrategyFromJson(cJSON* json) { if (!json) return nullptr; auto strategy = std::make_shared(); // 获取当前阶段 cJSON* currentStageItem = cJSON_GetObjectItemCaseSensitive(json, "current_stage"); if (cJSON_IsString(currentStageItem)) { strategy->current_stage = stringToStageType(currentStageItem->valuestring); } // 获取阶段模型映射 cJSON* modelMapItem = cJSON_GetObjectItemCaseSensitive(json, "stage_model_map"); if (cJSON_IsObject(modelMapItem)) { cJSON* child = modelMapItem->child; while (child) { if (cJSON_IsString(child)) { PetStageType stage = stringToStageType(child->string); strategy->stage_model_map[stage] = child->valuestring; } child = child->next; } } // 获取阶段音频映射 cJSON* audioMapItem = cJSON_GetObjectItemCaseSensitive(json, "stage_audio_map"); if (cJSON_IsObject(audioMapItem)) { cJSON* child = audioMapItem->child; while (child) { if (cJSON_IsString(child)) { PetStageType stage = stringToStageType(child->string); strategy->stage_audio_map[stage] = child->valuestring; } child = child->next; } } return strategy; } cJSON* PetDAO::actionStrategyToJson(const std::shared_ptr& strategy) { if (!strategy) return nullptr; cJSON* json = cJSON_CreateObject(); if (!json) return nullptr; // 添加当前动作 cJSON_AddStringToObject(json, "current_action", actionTypeToString(strategy->getCurrentActionType()).c_str()); // 添加动作模型映射 cJSON* modelMap = cJSON_CreateObject(); for (const auto& pair : strategy->getActionModelMap()) { cJSON_AddStringToObject(modelMap, actionTypeToString(pair.first).c_str(), pair.second.c_str()); } cJSON_AddItemToObject(json, "action_model_map", modelMap); // 添加动作音频映射 cJSON* audioMap = cJSON_CreateObject(); for (const auto& pair : strategy->getActionAudioMap()) { cJSON_AddStringToObject(audioMap, actionTypeToString(pair.first).c_str(), pair.second.c_str()); } cJSON_AddItemToObject(json, "action_audio_map", audioMap); return json; } std::shared_ptr PetDAO::actionStrategyFromJson(cJSON* json) { if (!json) return nullptr; auto strategy = std::make_shared(); // 获取当前动作 cJSON* currentActionItem = cJSON_GetObjectItemCaseSensitive(json, "current_action"); if (cJSON_IsString(currentActionItem)) { strategy->current_action = stringToActionType(currentActionItem->valuestring); } // 获取动作模型映射 cJSON* modelMapItem = cJSON_GetObjectItemCaseSensitive(json, "action_model_map"); if (cJSON_IsObject(modelMapItem)) { cJSON* child = modelMapItem->child; while (child) { if (cJSON_IsString(child)) { PetActionType action = stringToActionType(child->string); strategy->action_model_map[action] = child->valuestring; } child = child->next; } } // 获取动作音频映射 cJSON* audioMapItem = cJSON_GetObjectItemCaseSensitive(json, "action_audio_map"); if (cJSON_IsObject(audioMapItem)) { cJSON* child = audioMapItem->child; while (child) { if (cJSON_IsString(child)) { PetActionType action = stringToActionType(child->string); strategy->action_audio_map[action] = child->valuestring; } child = child->next; } } return strategy; }