这是一次长久的提交:

1. 应用界面增加了返回主页的按钮
2. 修复了gif渲染内存泄漏的严重bug
3. 将PetDao当中的cJSON API替换为cpp_json,完美通过测试
4. 整合已经实现的各种上层建筑,实现了一个宠物对话基本业务应用,用于样品测试展示用
5. 重构了音频播放类,使其更modern,更加便于移植和拓展
This commit is contained in:
Misaki
2025-10-16 11:36:45 +08:00
parent 801138631e
commit ba5e47bc77
38 changed files with 2487 additions and 2008 deletions
+152 -17
View File
@@ -32,14 +32,15 @@
std::cout << "\n";\n
*/
// cpp_json.hpp
// cpp_json.h
#pragma once
#include <cJSON.h>
#include <memory>
#include <string>
#include <vector>
#include <map>
#include <memory>
#include <stdexcept>
#include <utility>
namespace cppjson {
@@ -152,42 +153,176 @@ public:
cJSON_AddItemToArray(ptr_, cJSON_Duplicate(v.ptr_, 1));
return *this;
}
// 便捷的 append 方法重载
Json& append(int value) {
return append(Json(value));
}
Json& append(double value) {
return append(Json(value));
}
Json& append(bool value) {
return append(Json(value));
}
Json& append(const char* value) {
return append(Json(value));
}
Json& append(const std::string& value) {
return append(Json(value));
}
Json& set(const std::string& key, const Json& v) {
if (!isObject()) throw std::runtime_error("not object");
cJSON_AddItemToObject(ptr_, key.c_str(), cJSON_Duplicate(v.ptr_, 1));
return *this;
}
// 便捷的 set 方法重载
Json& set(const std::string& key, int value) {
return set(key, Json(value));
}
Json& set(const std::string& key, double value) {
return set(key, Json(value));
}
Json& set(const std::string& key, bool value) {
return set(key, Json(value));
}
Json& set(const std::string& key, const char* value) {
return set(key, Json(value));
}
Json& set(const std::string& key, const std::string& value) {
return set(key, Json(value));
}
// 迭代器(只读)
// 获取对象的所有键
[[nodiscard]] std::vector<std::string> keys() const {
if (!isObject()) throw std::runtime_error("not object");
std::vector<std::string> result;
cJSON* child = ptr_->child;
while (child) {
if (child->string) {
result.emplace_back(child->string);
}
child = child->next;
}
return result;
}
// 数组迭代器(只读)
template <bool IsConst>
struct iterator_impl {
struct array_iterator_impl {
using iterator_category = std::forward_iterator_tag;
using value_type = Json;
using difference_type = std::ptrdiff_t;
using pointer = typename std::conditional<IsConst, const Json, Json>::type*;
using reference = typename std::conditional<IsConst, const Json, Json>::type&;
iterator_impl(cJSON* h, cJSON* c) : head_(h), cur_(c) {}
array_iterator_impl(cJSON* head, cJSON* c) : head_(head), cur_(c) {}
reference operator*() {
tmp = std::make_unique<Json>(cur_, false);
return *tmp;
}
pointer operator->() { return &(operator*()); }
iterator_impl& operator++() { cur_ = cur_ ? cur_->next : nullptr; return *this; }
friend bool operator==(const iterator_impl& a, const iterator_impl& b) { return a.cur_ == b.cur_; }
friend bool operator!=(const iterator_impl& a, const iterator_impl& b) { return !(a == b); }
array_iterator_impl& operator++() { cur_ = cur_ ? cur_->next : nullptr; return *this; }
friend bool operator==(const array_iterator_impl& a, const array_iterator_impl& b) { return a.cur_ == b.cur_; }
friend bool operator!=(const array_iterator_impl& a, const array_iterator_impl& b) { return !(a == b); }
private:
cJSON *head_, *cur_;
std::unique_ptr<Json> tmp; // 改为智能指针
std::unique_ptr<Json> tmp;
};
using iterator = iterator_impl<false>;
using const_iterator = iterator_impl<true>;
iterator begin() { return iterator(ptr_, ptr_ ? ptr_->child : nullptr); }
iterator end() { return iterator(ptr_, nullptr); }
[[nodiscard]] const_iterator begin() const { return cbegin(); }
[[nodiscard]] const_iterator end() const { return cend(); }
[[nodiscard]] const_iterator cbegin() const { return const_iterator(ptr_, ptr_ ? ptr_->child : nullptr); }
[[nodiscard]] const_iterator cend() const { return const_iterator(ptr_, nullptr); }
using array_iterator = array_iterator_impl<false>;
using const_array_iterator = array_iterator_impl<true>;
// 对象键值对迭代器
template <bool IsConst>
struct object_iterator_impl {
using iterator_category = std::forward_iterator_tag;
using value_type = std::pair<std::string, Json>;
using difference_type = std::ptrdiff_t;
using pointer = typename std::conditional<IsConst, const value_type, value_type>::type*;
using reference = typename std::conditional<IsConst, const value_type, value_type>::type&;
object_iterator_impl(cJSON* c) : cur_(c) {
if (cur_ && cur_->string) {
updateValue();
}
}
reference operator*() {
tmp = std::make_unique<value_type>(cur_->string ? cur_->string : "", Json(cur_, false));
return *tmp;
}
pointer operator->() { return &(operator*()); }
object_iterator_impl& operator++() {
cur_ = cur_ ? cur_->next : nullptr;
if (cur_) {
updateValue();
}
return *this;
}
friend bool operator==(const object_iterator_impl& a, const object_iterator_impl& b) { return a.cur_ == b.cur_; }
friend bool operator!=(const object_iterator_impl& a, const object_iterator_impl& b) { return !(a == b); }
private:
void updateValue() {
if (cur_ && cur_->string) {
current_key = cur_->string;
}
}
cJSON* cur_ = nullptr;
std::string current_key;
std::unique_ptr<value_type> tmp;
};
using object_iterator = object_iterator_impl<false>;
using const_object_iterator = object_iterator_impl<true>;
// 统一的迭代器接口(用于数组)
array_iterator begin() {
if (!isArray()) throw std::runtime_error("not array");
return {ptr_, ptr_ ? ptr_->child : nullptr};
}
array_iterator end() {
if (!isArray()) throw std::runtime_error("not array");
return {ptr_, nullptr};
}
[[nodiscard]] const_array_iterator begin() const { return cbegin(); }
[[nodiscard]] const_array_iterator end() const { return cend(); }
[[nodiscard]] const_array_iterator cbegin() const {
if (!isArray()) throw std::runtime_error("not array");
return {ptr_, ptr_ ? ptr_->child : nullptr};
}
[[nodiscard]] const_array_iterator cend() const {
if (!isArray()) throw std::runtime_error("not array");
return {ptr_, nullptr};
}
// 对象项迭代器
object_iterator begin_object() {
if (!isObject()) throw std::runtime_error("not object");
return {ptr_ ? ptr_->child : nullptr};
}
object_iterator end_object() {
if (!isObject()) throw std::runtime_error("not object");
return {nullptr};
}
[[nodiscard]] const_object_iterator begin_object() const { return cbegin_object(); }
[[nodiscard]] const_object_iterator end_object() const { return cend_object(); }
[[nodiscard]] const_object_iterator cbegin_object() const {
if (!isObject()) throw std::runtime_error("not object");
return {ptr_ ? ptr_->child : nullptr};
}
[[nodiscard]] const_object_iterator cend_object() const {
if (!isObject()) throw std::runtime_error("not object");
return {nullptr};
}
// 便利的 items() 方法,用于结构化绑定
class ItemsProxy {
public:
explicit ItemsProxy(Json* json) : json_(json) {}
object_iterator begin() { return json_->begin_object(); }
object_iterator end() { return json_->end_object(); }
[[nodiscard]] const_object_iterator begin() const { return json_->cbegin_object(); }
[[nodiscard]] const_object_iterator end() const { return json_->cend_object(); }
private:
Json* json_;
};
ItemsProxy items() { return ItemsProxy(this); }
[[nodiscard]] ItemsProxy items() const { return ItemsProxy(const_cast<Json*>(this)); }
/*-------- 工具 ------------------------------------------------*/
void swap(Json& rhs) noexcept { std::swap(ptr_, rhs.ptr_); std::swap(owner_, rhs.owner_); }