update ObjectStatus & ObjectPolicy

This commit is contained in:
Nomango 2020-07-26 10:38:41 +08:00
parent 088cfda0c5
commit f6b1bca46a
2 changed files with 42 additions and 24 deletions

View File

@ -32,7 +32,7 @@ namespace
bool tracing_leaks = false; bool tracing_leaks = false;
Vector<ObjectBase*> tracing_objects; Vector<ObjectBase*> tracing_objects;
std::atomic<uint64_t> last_object_id = 0; std::atomic<uint64_t> last_object_id = 0;
ObjectPolicyFunc object_policy_ = ObjectPolicy::ErrorLog(); ObjectPolicyFunc object_policy_ = ObjectPolicy::Exception();
} // namespace } // namespace
@ -49,33 +49,33 @@ char const* ObjectFailException::what() const
return status_.msg.empty() ? "Object operation failed" : status_.msg.c_str(); 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()); 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()); 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); throw ObjectFailException(obj, status);
} }
@ -86,6 +86,7 @@ ObjectBase::ObjectBase()
: tracing_leak_(false) : tracing_leak_(false)
, name_(nullptr) , name_(nullptr)
, user_data_(nullptr) , user_data_(nullptr)
, status_(nullptr)
, id_(++last_object_id) , id_(++last_object_id)
{ {
#ifdef KGE_DEBUG #ifdef KGE_DEBUG
@ -101,6 +102,8 @@ ObjectBase::~ObjectBase()
name_ = nullptr; name_ = nullptr;
} }
ClearStatus();
#ifdef KGE_DEBUG #ifdef KGE_DEBUG
ObjectBase::RemoveObjectFromTracingList(this); ObjectBase::RemoveObjectFromTracingList(this);
#endif #endif
@ -151,24 +154,29 @@ void ObjectBase::DoDeserialize(Deserializer* deserializer)
bool ObjectBase::IsValid() const bool ObjectBase::IsValid() const
{ {
return status_.Success(); return status_ ? status_->Success() : true;
} }
ObjectStatus ObjectBase::GetStatus() const ObjectStatus* ObjectBase::GetStatus() const
{ {
return status_; return status_;
} }
void ObjectBase::SetStatus(const ObjectStatus& status) void ObjectBase::SetStatus(const ObjectStatus& status)
{ {
status_.msg = status.msg; if (!status_)
if (status_.code != status.code)
{ {
status_.code = status.code; status_ = new ObjectStatus;
}
status_->msg = status.msg;
if (status_->code != status.code)
{
status_->code = status.code;
if (object_policy_) 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() void ObjectBase::ClearStatus()
{ {
status_ = ObjectStatus{}; if (status_)
{
delete status_;
status_ = nullptr;
}
} }
void ObjectBase::SetObjectPolicy(const ObjectPolicyFunc& policy) void ObjectBase::SetObjectPolicy(const ObjectPolicyFunc& policy)

View File

@ -102,15 +102,21 @@ struct ObjectPolicy
/// \~chinese /// \~chinese
/// @brief 在对象状态变为失败时打印警告日志 /// @brief 在对象状态变为失败时打印警告日志
static ObjectPolicyFunc WarnLog(); /// @param threshold 触发阈值
/// @return 对象处理策略方法
static ObjectPolicyFunc WarnLog(int threshold = ObjectStatus::fail);
/// \~chinese /// \~chinese
/// @brief 在对象状态变为失败时打印错误日志(默认策略) /// @brief 在对象状态变为失败时打印错误日志
static ObjectPolicyFunc ErrorLog(); /// @param threshold 触发阈值
/// @return 对象处理策略方法
static ObjectPolicyFunc ErrorLog(int threshold = ObjectStatus::fail);
/// \~chinese /// \~chinese
/// @brief 在对象状态变为失败时抛出 ObjectFailException /// @brief 在对象状态变为失败时抛出 ObjectFailException默认策略
static ObjectPolicyFunc Exception(); /// @param threshold 触发阈值
/// @return 对象处理策略方法
static ObjectPolicyFunc Exception(int threshold = ObjectStatus::fail);
}; };
/** /**
@ -167,7 +173,7 @@ public:
/// \~chinese /// \~chinese
/// @brief 获取对象状态 /// @brief 获取对象状态
ObjectStatus GetStatus() const; ObjectStatus* GetStatus() const;
/// \~chinese /// \~chinese
/// @brief 设置对象状态 /// @brief 设置对象状态
@ -218,7 +224,7 @@ private:
String* name_; String* name_;
void* user_data_; void* user_data_;
ObjectStatus status_; ObjectStatus* status_;
}; };
inline String ObjectBase::GetName() const inline String ObjectBase::GetName() const