diff --git a/src/kiwano/base/ObjectBase.cpp b/src/kiwano/base/ObjectBase.cpp index b83c23d1..90fc2032 100644 --- a/src/kiwano/base/ObjectBase.cpp +++ b/src/kiwano/base/ObjectBase.cpp @@ -32,7 +32,7 @@ namespace bool tracing_leaks = false; Vector tracing_objects; std::atomic last_object_id = 0; -ObjectPolicyFunc object_policy_ = ObjectPolicy::ErrorLog(); +ObjectPolicyFunc object_policy_ = ObjectPolicy::Exception(); } // namespace @@ -49,33 +49,33 @@ char const* ObjectFailException::what() const return status_.msg.empty() ? "Object operation failed" : status_.msg.c_str(); } -ObjectPolicyFunc ObjectPolicy::WarnLog() +ObjectPolicyFunc ObjectPolicy::WarnLog(int threshold) { - return [](ObjectBase* obj, const ObjectStatus& status) + return [=](ObjectBase* obj, const ObjectStatus& status) { - if (!obj->IsValid()) + if (!obj->IsValid() || status.code <= threshold) { KGE_WARNF("Object operation failed: obj(%p), code(%d), msg(%s)", obj, status.code, status.msg.c_str()); } }; } -ObjectPolicyFunc ObjectPolicy::ErrorLog() +ObjectPolicyFunc ObjectPolicy::ErrorLog(int threshold) { - return [](ObjectBase* obj, const ObjectStatus& status) + return [=](ObjectBase* obj, const ObjectStatus& status) { - if (!obj->IsValid()) + if (!obj->IsValid() || status.code <= threshold) { KGE_ERRORF("Object operation failed: obj(%p), code(%d), msg(%s)", obj, status.code, status.msg.c_str()); } }; } -ObjectPolicyFunc ObjectPolicy::Exception() +ObjectPolicyFunc ObjectPolicy::Exception(int threshold) { - return [](ObjectBase* obj, const ObjectStatus& status) + return [=](ObjectBase* obj, const ObjectStatus& status) { - if (!obj->IsValid()) + if (!obj->IsValid() || status.code <= threshold) { throw ObjectFailException(obj, status); } @@ -86,6 +86,7 @@ ObjectBase::ObjectBase() : tracing_leak_(false) , name_(nullptr) , user_data_(nullptr) + , status_(nullptr) , id_(++last_object_id) { #ifdef KGE_DEBUG @@ -101,6 +102,8 @@ ObjectBase::~ObjectBase() name_ = nullptr; } + ClearStatus(); + #ifdef KGE_DEBUG ObjectBase::RemoveObjectFromTracingList(this); #endif @@ -151,24 +154,29 @@ void ObjectBase::DoDeserialize(Deserializer* deserializer) bool ObjectBase::IsValid() const { - return status_.Success(); + return status_ ? status_->Success() : true; } -ObjectStatus ObjectBase::GetStatus() const +ObjectStatus* ObjectBase::GetStatus() const { return status_; } void ObjectBase::SetStatus(const ObjectStatus& status) { - status_.msg = status.msg; - if (status_.code != status.code) + if (!status_) { - status_.code = status.code; + status_ = new ObjectStatus; + } + + status_->msg = status.msg; + if (status_->code != status.code) + { + status_->code = status.code; if (object_policy_) { - object_policy_(this, status_); + object_policy_(this, *status_); } } } @@ -180,7 +188,11 @@ void ObjectBase::Fail(const String& msg, int code) void ObjectBase::ClearStatus() { - status_ = ObjectStatus{}; + if (status_) + { + delete status_; + status_ = nullptr; + } } void ObjectBase::SetObjectPolicy(const ObjectPolicyFunc& policy) diff --git a/src/kiwano/base/ObjectBase.h b/src/kiwano/base/ObjectBase.h index dc3361d7..c73f1205 100644 --- a/src/kiwano/base/ObjectBase.h +++ b/src/kiwano/base/ObjectBase.h @@ -102,15 +102,21 @@ struct ObjectPolicy /// \~chinese /// @brief 在对象状态变为失败时打印警告日志 - static ObjectPolicyFunc WarnLog(); + /// @param threshold 触发阈值 + /// @return 对象处理策略方法 + static ObjectPolicyFunc WarnLog(int threshold = ObjectStatus::fail); /// \~chinese - /// @brief 在对象状态变为失败时打印错误日志(默认策略) - static ObjectPolicyFunc ErrorLog(); + /// @brief 在对象状态变为失败时打印错误日志 + /// @param threshold 触发阈值 + /// @return 对象处理策略方法 + static ObjectPolicyFunc ErrorLog(int threshold = ObjectStatus::fail); /// \~chinese - /// @brief 在对象状态变为失败时抛出 ObjectFailException - static ObjectPolicyFunc Exception(); + /// @brief 在对象状态变为失败时抛出 ObjectFailException(默认策略) + /// @param threshold 触发阈值 + /// @return 对象处理策略方法 + static ObjectPolicyFunc Exception(int threshold = ObjectStatus::fail); }; /** @@ -167,7 +173,7 @@ public: /// \~chinese /// @brief 获取对象状态 - ObjectStatus GetStatus() const; + ObjectStatus* GetStatus() const; /// \~chinese /// @brief 设置对象状态 @@ -218,7 +224,7 @@ private: String* name_; void* user_data_; - ObjectStatus status_; + ObjectStatus* status_; }; inline String ObjectBase::GetName() const