这是一次长久的提交:
1. 应用界面增加了返回主页的按钮 2. 修复了gif渲染内存泄漏的严重bug 3. 将PetDao当中的cJSON API替换为cpp_json,完美通过测试 4. 整合已经实现的各种上层建筑,实现了一个宠物对话基本业务应用,用于样品测试展示用 5. 重构了音频播放类,使其更modern,更加便于移植和拓展
This commit is contained in:
@@ -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_); }
|
||||
|
||||
Reference in New Issue
Block a user