add ObjectPolicy

This commit is contained in:
Nomango 2020-07-26 00:22:32 +08:00
parent 3ab717be25
commit 088cfda0c5
26 changed files with 484 additions and 199 deletions

View File

@ -517,8 +517,6 @@ void Actor::SetRotation(float angle)
void Actor::AddChild(ActorPtr child, int zorder)
{
KGE_ASSERT(child && "Actor::AddChild failed, NULL pointer exception");
if (child)
{
KGE_ASSERT(!child->parent_ && "Actor::AddChild failed, the actor to be added already has a parent");
@ -545,6 +543,10 @@ void Actor::AddChild(ActorPtr child, int zorder)
child->Reorder();
child->UpdateOpacity();
}
else
{
Fail("Actor::AddChild failed, NULL pointer exception");
}
}
void Actor::AddChildren(const Vector<ActorPtr>& children)
@ -614,8 +616,6 @@ void Actor::RemoveFromParent()
void Actor::RemoveChild(ActorPtr child)
{
KGE_ASSERT(child && "Actor::RemoveChild failed, NULL pointer exception");
if (children_.IsEmpty())
return;
@ -626,6 +626,10 @@ void Actor::RemoveChild(ActorPtr child)
child->SetStage(nullptr);
children_.Remove(child);
}
else
{
Fail("Actor::RemoveChild failed, NULL pointer exception");
}
}
void Actor::RemoveChildren(const String& child_name)

View File

@ -25,9 +25,16 @@ namespace kiwano
{
Canvas::Canvas(const Size& size)
{
try
{
ResizeAndClear(size);
}
catch (Exception& e)
{
Fail(String("Canvas::ResizeAndClear failed: ") + e.what());
}
}
RenderContextPtr Canvas::GetContext2D() const
{
@ -47,8 +54,15 @@ void Canvas::ResizeAndClear(Size size)
texture_cached_ = MakePtr<Texture>();
render_ctx_ = RenderContext::Create(*texture_cached_, size);
if (render_ctx_)
{
SetSize(render_ctx_->GetSize());
}
else
{
Fail("Canvas::ResizeAndClear failed");
}
}
TexturePtr Canvas::ExportToTexture() const
{

View File

@ -81,6 +81,8 @@ bool GifSprite::Load(GifImagePtr gif)
frame_to_render_ = MakePtr<Texture>();
frame_rt_ = RenderContext::Create(*frame_to_render_, frame_size);
if (frame_rt_)
{
SetSize(frame_rt_->GetSize());
if (gif_->GetFramesCount() > 0)
@ -89,6 +91,14 @@ bool GifSprite::Load(GifImagePtr gif)
}
return true;
}
else
{
Fail("GifSprite::Load failed: RenderContext::Create returns null");
return false;
}
}
Fail("GifSprite::Load failed: GifImage is invalid");
return false;
}

View File

@ -58,11 +58,12 @@ Sprite::~Sprite() {}
bool Sprite::Load(const String& file_path, bool autoresize)
{
FramePtr frame = MakePtr<Frame>(file_path);
if (frame)
if (frame && frame->IsValid())
{
SetFrame(frame, autoresize);
return true;
}
Fail("Sprite::Load failed");
return false;
}
@ -74,6 +75,7 @@ bool Sprite::Load(const Resource& res, bool autoresize)
SetFrame(frame, autoresize);
return true;
}
Fail("Sprite::Load failed");
return false;
}

View File

@ -60,8 +60,16 @@ void TextActor::SetText(const String& text)
{
layout_ = MakePtr<TextLayout>();
}
try
{
layout_->Reset(text, style_);
}
catch (SystemError& e)
{
Fail(String("TextActor::SetText failed: ") + e.what());
}
}
void TextActor::SetStyle(const TextStyle& style)
{

View File

@ -18,10 +18,11 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <typeinfo>
#include <atomic>
#include <kiwano/base/ObjectBase.h>
#include <kiwano/utils/Logger.h>
#include <kiwano/utils/Json.h>
#include <typeinfo>
namespace kiwano
{
@ -30,14 +31,61 @@ namespace
bool tracing_leaks = false;
Vector<ObjectBase*> tracing_objects;
uint32_t last_object_id = 0;
std::atomic<uint64_t> last_object_id = 0;
ObjectPolicyFunc object_policy_ = ObjectPolicy::ErrorLog();
} // namespace
ObjectFailException::ObjectFailException(ObjectBase* obj, const ObjectStatus& status)
: obj_(obj)
, status_(status)
{
}
char const* ObjectFailException::what() const
{
return status_.msg.empty() ? "Object operation failed" : status_.msg.c_str();
}
ObjectPolicyFunc ObjectPolicy::WarnLog()
{
return [](ObjectBase* obj, const ObjectStatus& status)
{
if (!obj->IsValid())
{
KGE_WARNF("Object operation failed: obj(%p), code(%d), msg(%s)", obj, status.code, status.msg.c_str());
}
};
}
ObjectPolicyFunc ObjectPolicy::ErrorLog()
{
return [](ObjectBase* obj, const ObjectStatus& status)
{
if (!obj->IsValid())
{
KGE_ERRORF("Object operation failed: obj(%p), code(%d), msg(%s)", obj, status.code, status.msg.c_str());
}
};
}
ObjectPolicyFunc ObjectPolicy::Exception()
{
return [](ObjectBase* obj, const ObjectStatus& status)
{
if (!obj->IsValid())
{
throw ObjectFailException(obj, status);
}
};
}
ObjectBase::ObjectBase()
: tracing_leak_(false)
, name_(nullptr)
, user_data_()
, user_data_(nullptr)
, id_(++last_object_id)
{
#ifdef KGE_DEBUG
@ -58,12 +106,12 @@ ObjectBase::~ObjectBase()
#endif
}
const Any& ObjectBase::GetUserData() const
void* ObjectBase::GetUserData() const
{
return user_data_;
}
void ObjectBase::SetUserData(const Any& data)
void ObjectBase::SetUserData(void* data)
{
user_data_ = data;
}
@ -101,6 +149,45 @@ void ObjectBase::DoDeserialize(Deserializer* deserializer)
SetName(name);
}
bool ObjectBase::IsValid() const
{
return status_.Success();
}
ObjectStatus ObjectBase::GetStatus() const
{
return status_;
}
void ObjectBase::SetStatus(const ObjectStatus& status)
{
status_.msg = status.msg;
if (status_.code != status.code)
{
status_.code = status.code;
if (object_policy_)
{
object_policy_(this, status_);
}
}
}
void ObjectBase::Fail(const String& msg, int code)
{
SetStatus(ObjectStatus{ code, msg });
}
void ObjectBase::ClearStatus()
{
status_ = ObjectStatus{};
}
void ObjectBase::SetObjectPolicy(const ObjectPolicyFunc& policy)
{
object_policy_ = policy;
}
bool ObjectBase::IsTracingLeaks()
{
return tracing_leaks;

View File

@ -21,6 +21,7 @@
#pragma once
#include <kiwano/macros.h>
#include <kiwano/core/Common.h>
#include <kiwano/core/Exception.h>
#include <kiwano/core/Serializable.h>
#include <kiwano/base/RefObject.h>
#include <kiwano/base/RefPtr.h>
@ -29,6 +30,89 @@ namespace kiwano
{
KGE_DECLARE_SMART_PTR(ObjectBase);
/**
* \~chinese
* @brief
*/
struct ObjectStatus
{
int code = 0; ///< 状态码,等于 0 时为成功状态,否则为失败状态
String msg; ///< 状态信息
/// \~chinese
/// @brief 对象状态是否成功
inline bool Success() const
{
return this->code == 0;
}
/// \~chinese
/// @brief 对象失败状态
static const int fail = -1;
};
/**
* \~chinese
* @brief
*/
class ObjectFailException : public Exception
{
public:
ObjectFailException(ObjectBase* obj, const ObjectStatus& status);
/// \~chinese
/// @brief 获取失败的对象指针
inline ObjectBase* GetObj() const
{
return obj_;
}
/// \~chinese
/// @brief 获取对象状态
inline ObjectStatus GetStatus() const
{
return status_;
}
virtual char const* what() const override;
private:
ObjectBase* obj_;
ObjectStatus status_;
};
/**
* \~chinese
* @brief
*/
typedef Function<void(ObjectBase*, const ObjectStatus&)> ObjectPolicyFunc;
/**
* \~chinese
* @brief
*/
struct ObjectPolicy
{
/// \~chinese
/// @brief 忽略对象失败状态
static inline ObjectPolicyFunc Ignore()
{
return nullptr;
}
/// \~chinese
/// @brief 在对象状态变为失败时打印警告日志
static ObjectPolicyFunc WarnLog();
/// \~chinese
/// @brief 在对象状态变为失败时打印错误日志(默认策略)
static ObjectPolicyFunc ErrorLog();
/// \~chinese
/// @brief 在对象状态变为失败时抛出 ObjectFailException
static ObjectPolicyFunc Exception();
};
/**
* \~chinese
* @brief
@ -59,15 +143,15 @@ public:
/// \~chinese
/// @brief 获取用户数据
const Any& GetUserData() const;
void* GetUserData() const;
/// \~chinese
/// @brief 设置用户数据
void SetUserData(const Any& data);
void SetUserData(void* data);
/// \~chinese
/// @brief 获取对象ID
uint32_t GetObjectID() const;
uint64_t GetObjectID() const;
/// \~chinese
/// @brief 序列化
@ -77,6 +161,30 @@ public:
/// @brief 反序列化
void DoDeserialize(Deserializer* deserializer) override;
/// \~chinese
/// @brief 判断对象是否有效
virtual bool IsValid() const;
/// \~chinese
/// @brief 获取对象状态
ObjectStatus GetStatus() const;
/// \~chinese
/// @brief 设置对象状态
void SetStatus(const ObjectStatus& status);
/// \~chinese
/// @brief 将对象标记为失败状态
void Fail(const String& msg, int code = ObjectStatus::fail);
/// \~chinese
/// @brief 清除对象状态
void ClearStatus();
/// \~chinese
/// @brief 设置对象处理策略
static void SetObjectPolicy(const ObjectPolicyFunc& policy);
public:
/// \~chinese
/// @brief 是否启用了内存泄漏追踪
@ -104,11 +212,13 @@ private:
static void RemoveObjectFromTracingList(ObjectBase*);
private:
const uint32_t id_;
const uint64_t id_;
bool tracing_leak_;
String* name_;
Any user_data_;
void* user_data_;
ObjectStatus status_;
};
inline String ObjectBase::GetName() const
@ -123,7 +233,7 @@ inline bool ObjectBase::IsName(const String& name) const
return name_ ? (*name_ == name) : name.empty();
}
inline uint32_t ObjectBase::GetObjectID() const
inline uint64_t ObjectBase::GetObjectID() const
{
return id_;
}

View File

@ -29,13 +29,13 @@ namespace kiwano
/// @brief 默认的智能指针引用计数策略
struct DefaultRefPtrPolicy
{
static inline void Retain(RefObject* ptr)
inline void Retain(RefObject* ptr)
{
if (ptr)
ptr->Retain();
}
static inline void Release(RefObject* ptr)
inline void Release(RefObject* ptr)
{
if (ptr)
ptr->Release();

View File

@ -20,26 +20,9 @@
#pragma once
#include <kiwano/core/Common.h>
#include <kiwano/utils/Logger.h>
#include <stdexcept>
#include <system_error>
#define KGE_THROW(MESSAGE) \
do \
{ \
KGE_ERRORF("An exception occurred: %s", MESSAGE); \
kiwano::StackTracer().Print(); \
throw kiwano::RuntimeError(MESSAGE); \
} while (0)
#define KGE_THROW_SYSTEM_ERROR(ERRCODE, MESSAGE) \
do \
{ \
KGE_ERRORF("An exception occurred (%#x): %s", ERRCODE, MESSAGE); \
kiwano::StackTracer().Print(); \
throw kiwano::SystemError(std::error_code(kiwano::error_enum(ERRCODE)), MESSAGE); \
} while (0)
namespace kiwano
{
@ -104,12 +87,6 @@ inline std::error_condition make_error_condition(kiwano::error_enum errc) noexce
return std::error_condition(static_cast<int>(errc), kiwano::com_category());
}
#define KGE_THROW_IF_FAILED(HR, MESSAGE) \
if (FAILED(HR)) \
{ \
KGE_THROW_SYSTEM_ERROR(HR, MESSAGE); \
}
} // namespace kiwano
#endif // KGE_PLATFORM_WINDOWS

View File

@ -18,13 +18,12 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <kiwano/core/Exception.h>
#include <kiwano/utils/Logger.h>
#include <kiwano/core/Time.h>
#include <regex>
#include <unordered_map>
#include <chrono>
#include <thread>
#include <kiwano/core/Time.h>
#include <kiwano/utils/Logger.h>
namespace kiwano
{

View File

@ -28,7 +28,7 @@
namespace kiwano
{
Runner::Runner(Settings settings)
Runner::Runner(const Settings& settings)
: settings_(settings)
{
}

View File

@ -67,7 +67,7 @@ public:
/// \~chinese
/// @brief 创建程序运行器
/// @param main_window 主窗口
Runner(Settings settings);
Runner(const Settings& settings);
virtual ~Runner();
@ -92,16 +92,12 @@ public:
/// @param dt 时间间隔
/// @details 重载该函数以控制程序主循环
/// @return 返回false退出主循环否则继续运行主循环
virtual bool MainLoop(Duration dt);
bool MainLoop(Duration dt);
/// \~chinese
/// @brief 获取窗口
WindowPtr GetWindow() const;
/// \~chinese
/// @brief ÉèÖô°¿Ú
void SetWindow(WindowPtr window);
/// \~chinese
/// @brief 获取设置
Settings GetSettings() const;
@ -119,6 +115,10 @@ protected:
/// @brief 修改设置
void SetSettings(Settings settings);
/// \~chinese
/// @brief ÉèÖô°¿Ú
void SetWindow(WindowPtr window);
private:
friend class Application;

View File

@ -28,13 +28,13 @@ namespace kiwano
{
struct ComPtrPolicy
{
static inline void Retain(IUnknown* ptr)
inline void Retain(IUnknown* ptr)
{
if (ptr)
ptr->AddRef();
}
static inline void Release(IUnknown* ptr)
inline void Release(IUnknown* ptr)
{
if (ptr)
ptr->Release();

View File

@ -25,7 +25,6 @@
#include <memory>
#include <array>
#include <kiwano/core/Keys.h>
#include <kiwano/core/Exception.h>
#include <kiwano/utils/Logger.h>
#include <kiwano/event/Events.h>
#include <kiwano/platform/Application.h>

View File

@ -18,7 +18,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <kiwano/core/Exception.h>
#include <kiwano/utils/Logger.h>
#include <kiwano/platform/win32/libraries.h>

View File

@ -70,6 +70,12 @@ public:
HRESULT CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout>& text_layout, _In_ LPCWSTR text, UINT32 length,
_In_ ComPtr<IDWriteTextFormat> text_format) override;
HRESULT CreateFontCollectionFromFiles(_Out_ ComPtr<IDWriteFontCollection>& font_collection,
const Vector<String>& file_paths) override;
HRESULT CreateFontCollectionFromResources(_Out_ ComPtr<IDWriteFontCollection>& font_collection,
const Vector<Resource>& resources) override;
HRESULT SetDpi(float dpi) override;
HRESULT SetLogicalSize(float width, float height) override;
@ -93,6 +99,10 @@ private:
float dpi_;
ComPtr<IDXGISwapChain> dxgi_swap_chain_;
ComPtr<IFontCollectionLoader> font_collection_loader_;
ComPtr<IResourceFontFileLoader> res_font_file_loader_;
ComPtr<IResourceFontCollectionLoader> res_font_collection_loader_;
};
@ -173,13 +183,34 @@ STDMETHODIMP D2DDeviceResources::QueryInterface(const IID& riid, void** object)
void D2DDeviceResources::DiscardResources()
{
factory_.Reset();
device_.Reset();
device_context_.Reset();
target_bitmap_.Reset();
if (dwrite_factory_)
{
if (font_collection_loader_)
{
dwrite_factory_->UnregisterFontCollectionLoader(font_collection_loader_.Get());
font_collection_loader_.Reset();
}
if (res_font_file_loader_)
{
dwrite_factory_->UnregisterFontFileLoader(res_font_file_loader_.Get());
res_font_file_loader_.Reset();
}
if (res_font_collection_loader_)
{
dwrite_factory_->UnregisterFontCollectionLoader(res_font_collection_loader_.Get());
res_font_collection_loader_.Reset();
}
}
target_bitmap_.Reset();
device_context_.Reset();
device_.Reset();
imaging_factory_.Reset();
dwrite_factory_.Reset();
imaging_factory_.Reset();
factory_.Reset();
}
HRESULT D2DDeviceResources::CreateDeviceIndependentResources()
@ -225,6 +256,38 @@ HRESULT D2DDeviceResources::CreateDeviceIndependentResources()
dwrite_factory_ = dwrite_factory;
}
}
// FontFileLoader and FontCollectionLoader
if (SUCCEEDED(hr))
{
hr = IFontCollectionLoader::Create(&font_collection_loader_);
if (SUCCEEDED(hr))
{
hr = dwrite_factory->RegisterFontCollectionLoader(font_collection_loader_.Get());
}
}
// ResourceFontFileLoader and ResourceFontCollectionLoader
if (SUCCEEDED(hr))
{
hr = IResourceFontFileLoader::Create(&res_font_file_loader_);
if (SUCCEEDED(hr))
{
hr = dwrite_factory->RegisterFontFileLoader(res_font_file_loader_.Get());
}
if (SUCCEEDED(hr))
{
hr = IResourceFontCollectionLoader::Create(&res_font_collection_loader_, res_font_file_loader_.Get());
if (SUCCEEDED(hr))
{
hr = dwrite_factory->RegisterFontCollectionLoader(res_font_collection_loader_.Get());
}
}
}
return hr;
}
@ -450,6 +513,43 @@ HRESULT D2DDeviceResources::CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout>& te
return hr;
}
HRESULT D2DDeviceResources::CreateFontCollectionFromFiles(ComPtr<IDWriteFontCollection>& font_collection,
const Vector<String>& file_paths)
{
if (!dwrite_factory_ || !font_collection_loader_)
return E_UNEXPECTED;
LPVOID key = nullptr;
uint32_t key_size = 0;
HRESULT hr = font_collection_loader_->AddFilePaths(file_paths, &key, &key_size);
if (SUCCEEDED(hr))
{
hr =
dwrite_factory_->CreateCustomFontCollection(font_collection_loader_.Get(), key, key_size, &font_collection);
}
return hr;
}
HRESULT D2DDeviceResources::CreateFontCollectionFromResources(ComPtr<IDWriteFontCollection>& font_collection,
const Vector<Resource>& resources)
{
if (!dwrite_factory_ || !res_font_collection_loader_)
return E_UNEXPECTED;
LPVOID key = nullptr;
uint32_t key_size = 0;
HRESULT hr = res_font_collection_loader_->AddResources(resources, &key, &key_size);
if (SUCCEEDED(hr))
{
hr = dwrite_factory_->CreateCustomFontCollection(res_font_collection_loader_.Get(), key, key_size, &font_collection);
}
return hr;
}
} // namespace directx
} // namespace graphics
} // namespace kiwano

View File

@ -20,9 +20,7 @@
#pragma once
#include <kiwano/render/DirectX/helper.h>
#include <d2d1.h>
#include <d2d1_1.h>
#include <dwrite.h>
#include <kiwano/render/DirectX/FontCollectionLoader.h>
namespace kiwano
{
@ -58,6 +56,12 @@ public:
virtual HRESULT CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout> & text_layout, _In_ LPCWSTR text, UINT32 length,
_In_ ComPtr<IDWriteTextFormat> text_format) = 0;
virtual HRESULT CreateFontCollectionFromFiles(_Out_ ComPtr<IDWriteFontCollection> & font_collection,
const Vector<String>& file_paths) = 0;
virtual HRESULT CreateFontCollectionFromResources(_Out_ ComPtr<IDWriteFontCollection> & font_collection,
const Vector<Resource>& resources) = 0;
virtual HRESULT SetDpi(float dpi) = 0;
virtual HRESULT SetLogicalSize(float width, float height) = 0;

View File

@ -20,7 +20,8 @@
#pragma once
#include <kiwano/core/Resource.h>
#include <kiwano/render/DirectX/D2DDeviceResources.h>
#include <kiwano/render/DirectX/helper.h>
#include <dwrite.h>
namespace kiwano
{

View File

@ -18,7 +18,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <kiwano/core/Exception.h>
#include <kiwano/utils/Logger.h>
#include <kiwano/event/WindowEvent.h>
#include <kiwano/platform/FileSystem.h>
@ -27,7 +26,11 @@
#include <kiwano/render/DirectX/RendererImpl.h>
#include <kiwano/render/DirectX/NativePtr.h>
#include <memory>
#define KGE_SET_STATUS_IF_FAILED(ERRCODE, OBJ, MESSAGE) \
if (FAILED(ERRCODE)) \
{ \
OBJ.Fail(strings::Format("An exception occurred (%#x): %s", ERRCODE, MESSAGE)); \
}
namespace kiwano
{
@ -93,7 +96,6 @@ void RendererImpl::MakeContextForWindow(WindowPtr window)
}
}
// Initialize other device resources
if (SUCCEEDED(hr))
{
@ -106,38 +108,6 @@ void RendererImpl::MakeContextForWindow(WindowPtr window)
}
}
// FontFileLoader and FontCollectionLoader
if (SUCCEEDED(hr))
{
hr = IFontCollectionLoader::Create(&font_collection_loader_);
if (SUCCEEDED(hr))
{
hr = d2d_res_->GetDWriteFactory()->RegisterFontCollectionLoader(font_collection_loader_.Get());
}
}
// ResourceFontFileLoader and ResourceFontCollectionLoader
if (SUCCEEDED(hr))
{
hr = IResourceFontFileLoader::Create(&res_font_file_loader_);
if (SUCCEEDED(hr))
{
hr = d2d_res_->GetDWriteFactory()->RegisterFontFileLoader(res_font_file_loader_.Get());
}
if (SUCCEEDED(hr))
{
hr = IResourceFontCollectionLoader::Create(&res_font_collection_loader_, res_font_file_loader_.Get());
if (SUCCEEDED(hr))
{
hr = d2d_res_->GetDWriteFactory()->RegisterFontCollectionLoader(res_font_collection_loader_.Get());
}
}
}
KGE_THROW_IF_FAILED(hr, "Create render resources failed");
}
@ -147,14 +117,9 @@ void RendererImpl::Destroy()
if (d2d_res_)
{
d2d_res_->GetDWriteFactory()->UnregisterFontFileLoader(res_font_file_loader_.Get());
res_font_file_loader_.Reset();
d2d_res_->GetDWriteFactory()->UnregisterFontCollectionLoader(res_font_collection_loader_.Get());
res_font_collection_loader_.Reset();
render_ctx_.Reset();
d2d_res_->DiscardResources();
d2d_res_.Reset();
}
if (d3d_res_)
@ -243,10 +208,7 @@ void RendererImpl::CreateTexture(Texture& texture, const String& file_path)
}
}
if (FAILED(hr))
{
KGE_THROW_IF_FAILED(hr, "Load texture failed");
}
KGE_SET_STATUS_IF_FAILED(hr, texture, "Load texture failed");
}
void RendererImpl::CreateTexture(Texture& texture, const Resource& resource)
@ -298,10 +260,7 @@ void RendererImpl::CreateTexture(Texture& texture, const Resource& resource)
}
}
if (FAILED(hr))
{
KGE_WARNF("Load texture failed with HRESULT of %08X!", hr);
}
KGE_SET_STATUS_IF_FAILED(hr, texture, "Load texture failed");
}
void RendererImpl::CreateGifImage(GifImage& gif, const String& file_path)
@ -331,10 +290,7 @@ void RendererImpl::CreateGifImage(GifImage& gif, const String& file_path)
}
}
if (FAILED(hr))
{
KGE_WARNF("Load GIF texture failed with HRESULT of %08X!", hr);
}
KGE_SET_STATUS_IF_FAILED(hr, gif, "Load GIF texture failed");
}
void RendererImpl::CreateGifImage(GifImage& gif, const Resource& resource)
@ -363,10 +319,7 @@ void RendererImpl::CreateGifImage(GifImage& gif, const Resource& resource)
}
}
if (FAILED(hr))
{
KGE_WARNF("Load GIF texture failed with HRESULT of %08X!", hr);
}
KGE_SET_STATUS_IF_FAILED(hr, gif, "Load GIF texture failed");
}
void RendererImpl::CreateGifImageFrame(GifImage::Frame& frame, const GifImage& gif, size_t frame_index)
@ -527,10 +480,7 @@ void RendererImpl::CreateGifImageFrame(GifImage::Frame& frame, const GifImage& g
}
}
if (FAILED(hr))
{
KGE_WARNF("Load GIF frame failed with HRESULT of %08X!", hr);
}
KGE_SET_STATUS_IF_FAILED(hr, const_cast<GifImage&>(gif), "Load GIF frame failed");
}
void RendererImpl::CreateFontCollection(Font& font, const String& file_path)
@ -552,26 +502,18 @@ void RendererImpl::CreateFontCollection(Font& font, const String& file_path)
if (SUCCEEDED(hr))
{
LPVOID key = nullptr;
uint32_t key_size = 0;
String full_path = FileSystem::GetInstance().GetFullPathForFile(file_path);
hr = font_collection_loader_->AddFilePaths({ full_path }, &key, &key_size);
if (SUCCEEDED(hr))
{
ComPtr<IDWriteFontCollection> font_collection;
hr = d2d_res_->GetDWriteFactory()->CreateCustomFontCollection(font_collection_loader_.Get(), key, key_size,
&font_collection);
hr = d2d_res_->CreateFontCollectionFromFiles(font_collection, { full_path });
if (SUCCEEDED(hr))
{
NativePtr::Set(font, font_collection);
}
}
}
KGE_THROW_IF_FAILED(hr, "Create font collection failed");
KGE_SET_STATUS_IF_FAILED(hr, font, "Create font collection failed");
}
void RendererImpl::CreateFontCollection(Font& font, const Resource& res)
@ -582,27 +524,18 @@ void RendererImpl::CreateFontCollection(Font& font, const Resource& res)
hr = E_UNEXPECTED;
}
if (SUCCEEDED(hr))
{
LPVOID key = nullptr;
uint32_t key_size = 0;
hr = res_font_collection_loader_->AddResources(Vector<Resource>{ res }, &key, &key_size);
if (SUCCEEDED(hr))
{
ComPtr<IDWriteFontCollection> font_collection;
hr = d2d_res_->GetDWriteFactory()->CreateCustomFontCollection(res_font_collection_loader_.Get(), key,
key_size, &font_collection);
hr = d2d_res_->CreateFontCollectionFromResources(font_collection, Vector<Resource>{ res });
if (SUCCEEDED(hr))
{
NativePtr::Set(font, font_collection);
}
}
}
KGE_THROW_IF_FAILED(hr, "Create font collection failed");
KGE_SET_STATUS_IF_FAILED(hr, font, "Create font collection failed");
}
void RendererImpl::CreateTextLayout(TextLayout& layout, const String& content, const TextStyle& style)
@ -646,7 +579,7 @@ void RendererImpl::CreateTextLayout(TextLayout& layout, const String& content, c
}
}
KGE_THROW_IF_FAILED(hr, "Create text layout failed");
KGE_SET_STATUS_IF_FAILED(hr, layout, "Create text layout failed");
}
void RendererImpl::CreateLineShape(Shape& shape, const Point& begin_pos, const Point& end_pos)
@ -682,7 +615,7 @@ void RendererImpl::CreateLineShape(Shape& shape, const Point& begin_pos, const P
}
}
KGE_THROW_IF_FAILED(hr, "Create ID2D1PathGeometry failed");
KGE_SET_STATUS_IF_FAILED(hr, shape, "Create ID2D1PathGeometry failed");
}
void RendererImpl::CreateRectShape(Shape& shape, const Rect& rect)
@ -704,7 +637,7 @@ void RendererImpl::CreateRectShape(Shape& shape, const Rect& rect)
NativePtr::Set(shape, output);
}
KGE_THROW_IF_FAILED(hr, "Create ID2D1RectangleGeometry failed");
KGE_SET_STATUS_IF_FAILED(hr, shape, "Create ID2D1RectangleGeometry failed");
}
void RendererImpl::CreateRoundedRectShape(Shape& shape, const Rect& rect, const Vec2& radius)
@ -727,7 +660,7 @@ void RendererImpl::CreateRoundedRectShape(Shape& shape, const Rect& rect, const
NativePtr::Set(shape, output);
}
KGE_THROW_IF_FAILED(hr, "Create ID2D1RoundedRectangleGeometry failed");
KGE_SET_STATUS_IF_FAILED(hr, shape, "Create ID2D1RoundedRectangleGeometry failed");
}
void RendererImpl::CreateEllipseShape(Shape& shape, const Point& center, const Vec2& radius)
@ -750,7 +683,7 @@ void RendererImpl::CreateEllipseShape(Shape& shape, const Point& center, const V
NativePtr::Set(shape, output);
}
KGE_THROW_IF_FAILED(hr, "Create ID2D1EllipseGeometry failed");
KGE_SET_STATUS_IF_FAILED(hr, shape, "Create ID2D1EllipseGeometry failed");
}
void RendererImpl::CreateShapeSink(ShapeMaker& maker)
@ -775,7 +708,7 @@ void RendererImpl::CreateShapeSink(ShapeMaker& maker)
maker.SetShape(shape);
}
}
KGE_THROW_IF_FAILED(hr, "Create ID2D1PathGeometry failed");
KGE_SET_STATUS_IF_FAILED(hr, maker, "Create ID2D1PathGeometry failed");
}
void RendererImpl::CreateBrush(Brush& brush, const Color& color)
@ -809,7 +742,7 @@ void RendererImpl::CreateBrush(Brush& brush, const Color& color)
}
}
KGE_THROW_IF_FAILED(hr, "Create ID2D1SolidBrush failed");
KGE_SET_STATUS_IF_FAILED(hr, brush, "Create ID2D1SolidBrush failed");
}
void RendererImpl::CreateBrush(Brush& brush, const LinearGradientStyle& style)
@ -841,7 +774,7 @@ void RendererImpl::CreateBrush(Brush& brush, const LinearGradientStyle& style)
}
}
KGE_THROW_IF_FAILED(hr, "Create ID2D1LinearGradientBrush failed");
KGE_SET_STATUS_IF_FAILED(hr, brush, "Create ID2D1LinearGradientBrush failed");
}
void RendererImpl::CreateBrush(Brush& brush, const RadialGradientStyle& style)
@ -874,7 +807,7 @@ void RendererImpl::CreateBrush(Brush& brush, const RadialGradientStyle& style)
}
}
KGE_THROW_IF_FAILED(hr, "Create ID2D1RadialGradientBrush failed");
KGE_SET_STATUS_IF_FAILED(hr, brush, "Create ID2D1RadialGradientBrush failed");
}
void RendererImpl::CreateBrush(Brush& brush, TexturePtr texture)
@ -901,7 +834,7 @@ void RendererImpl::CreateBrush(Brush& brush, TexturePtr texture)
}
}
KGE_THROW_IF_FAILED(hr, "Create ID2D1RadialGradientBrush failed");
KGE_SET_STATUS_IF_FAILED(hr, brush, "Create ID2D1RadialGradientBrush failed");
}
void RendererImpl::CreateStrokeStyle(StrokeStyle& stroke_style)
@ -940,7 +873,7 @@ void RendererImpl::CreateStrokeStyle(StrokeStyle& stroke_style)
}
}
KGE_THROW_IF_FAILED(hr, "Create ID2D1StrokeStyle failed");
KGE_SET_STATUS_IF_FAILED(hr, stroke_style, "Create ID2D1StrokeStyle failed");
}
RenderContextPtr RendererImpl::CreateTextureRenderContext(Texture& texture, const Size* desired_size)

View File

@ -21,10 +21,8 @@
#pragma once
#include <kiwano/render/Renderer.h>
#include <kiwano/render/DirectX/D3DDeviceResources.h>
#include <kiwano/render/DirectX/FontCollectionLoader.h>
#include <kiwano/render/DirectX/RenderContextImpl.h>
namespace kiwano
{
@ -94,9 +92,6 @@ private:
ComPtr<ID2DDeviceResources> d2d_res_;
ComPtr<ID3DDeviceResources> d3d_res_;
ComPtr<IFontCollectionLoader> font_collection_loader_;
ComPtr<IResourceFontFileLoader> res_font_file_loader_;
ComPtr<IResourceFontCollectionLoader> res_font_collection_loader_;
};

View File

@ -20,10 +20,11 @@
#pragma once
#include <kiwano/math/Math.h>
#include <kiwano/core/Exception.h>
#include <kiwano/utils/Logger.h>
#include <kiwano/render/Color.h>
#include <kiwano/platform/win32/ComPtr.hpp>
#include <d2d1.h>
#include <d2d1_1.h>
namespace kiwano
{

View File

@ -41,12 +41,14 @@ FrameSequence::~FrameSequence() {}
void FrameSequence::AddFrame(FramePtr frame)
{
KGE_ASSERT(frame && "FrameSequence::Add failed, NULL pointer exception");
if (frame)
{
frames_.push_back(frame);
}
else
{
Fail("FrameSequence::Add failed, NULL pointer exception");
}
}
void FrameSequence::AddFrames(const Vector<FramePtr>& frames)

View File

@ -53,6 +53,7 @@ bool GifImage::Load(const String& file_path)
// Clear data
ResetNativePointer();
Fail("GifImage::Load failed");
}
return false;
}
@ -68,6 +69,7 @@ bool GifImage::Load(const Resource& res)
// Clear data
ResetNativePointer();
Fail("GifImage::Load failed");
}
return false;
}

View File

@ -109,6 +109,8 @@ bool ConfigIni::Load(const String& file_path)
{
return Load(ifs);
}
Fail("ConfigIni::Load failed");
return false;
}
@ -121,13 +123,13 @@ bool ConfigIni::Load(std::istream& istream)
{
ParseLine(line, &section);
}
return true;
}
catch (Exception)
catch (RuntimeError& e)
{
Fail(String("ConfigIni::Load failed: ") + e.what());
return false;
}
return false;
return true;
}
bool ConfigIni::Save(const String& file_path)
@ -138,6 +140,7 @@ bool ConfigIni::Save(const String& file_path)
{
return Save(ofs);
}
Fail("ConfigIni::Save failed");
return false;
}
@ -165,7 +168,12 @@ bool ConfigIni::Save(std::ostream& os)
os << std::endl;
}
}
return !os.fail();
if (os.fail())
{
Fail("ConfigIni::Save failed");
return false;
}
return true;
}
ConfigIni::SectionMap ConfigIni::GetSectionMap() const
@ -367,7 +375,7 @@ void ConfigIni::ParseLine(StringView line, String* section)
{
auto name = parser.GetSectionName();
if (name.IsEmpty())
throw Exception("Empty section name");
throw RuntimeError("Empty section name");
*section = name;
return;
}
@ -375,7 +383,7 @@ void ConfigIni::ParseLine(StringView line, String* section)
StringView key, value;
if (!parser.GetKeyValue(&key, &value))
{
throw Exception("Parse key-value failed");
throw RuntimeError("Parse key-value failed");
}
SetString(*section, key, value);
}

View File

@ -19,12 +19,13 @@
// THE SOFTWARE.
#pragma once
#include <kiwano/core/Time.h>
#include <kiwano/base/ObjectBase.h>
#include <mutex>
#include <iomanip>
#include <streambuf>
#include <fstream>
#include <kiwano/core/Common.h>
#include <kiwano/core/Time.h>
#include <kiwano/base/ObjectBase.h>
#ifndef KGE_DEBUG_LOG
#ifdef KGE_DEBUG
@ -74,12 +75,42 @@
#define KGE_ERRORF(FORMAT, ...) ::kiwano::Logger::GetInstance().Logf(::kiwano::LogLevel::Error, FORMAT, __VA_ARGS__)
#endif
#ifndef KGE_THROW
#define KGE_THROW(MESSAGE) \
do \
{ \
KGE_ERRORF("An exception occurred: %s", MESSAGE); \
kiwano::StackTracer().Print(); \
throw kiwano::RuntimeError(MESSAGE); \
} while (0)
#endif
#ifndef KGE_THROW_SYSTEM_ERROR
#define KGE_THROW_SYSTEM_ERROR(ERRCODE, MESSAGE) \
do \
{ \
KGE_ERRORF("An exception occurred (%#x): %s", ERRCODE, MESSAGE); \
kiwano::StackTracer().Print(); \
throw kiwano::SystemError(std::error_code(kiwano::error_enum(ERRCODE)), MESSAGE); \
} while (0)
#endif
#ifdef KGE_PLATFORM_WINDOWS
#ifndef KGE_THROW_IF_FAILED
#define KGE_THROW_IF_FAILED(HR, MESSAGE) \
if (FAILED(HR)) \
{ \
KGE_THROW_SYSTEM_ERROR(HR, MESSAGE); \
}
#endif
#endif // KGE_PLATFORM_WINDOWS
namespace kiwano
{
KGE_DECLARE_SMART_PTR(LogFormater);
KGE_DECLARE_SMART_PTR(LogProvider);
KGE_DECLARE_SMART_PTR(Logger);
/**
* \~chinese
@ -144,7 +175,7 @@ private:
/**
* \~chinese
* @brief
* @brief
*/
class KGE_API LogProvider : public ObjectBase
{
@ -170,7 +201,7 @@ protected:
/**
* \~chinese
* @brief
* @brief
*/
class KGE_API ConsoleLogProvider : public LogProvider
{
@ -194,7 +225,7 @@ private:
/**
* \~chinese
* @brief
* @brief
*/
class KGE_API FileLogProvider : public LogProvider
{
@ -253,8 +284,8 @@ public:
void SetLevel(LogLevel level);
/// \~chinese
/// @brief 添加日志提供
/// @param provider 日志提供
/// @brief 添加日志生产
/// @param provider 日志生产
void AddProvider(LogProviderPtr provider);
/// \~chinese

View File

@ -19,9 +19,8 @@
// THE SOFTWARE.
#include <fstream>
#include <kiwano/utils/Logger.h>
#include <kiwano/core/Exception.h>
#include <kiwano/platform/FileSystem.h>
#include <kiwano/utils/Logger.h>
#include <kiwano/utils/ResourceCache.h>
namespace kiwano
@ -76,14 +75,14 @@ bool ResourceCache::LoadFromJsonFile(const String& file_path)
ifs >> json_data;
ifs.close();
}
catch (std::wifstream::failure& e)
catch (std::ios_base::failure& e)
{
KGE_ERRORF("%s failed: Cannot open file. (%s)", __FUNCTION__, e.what());
KGE_ERRORF("%s failed: cannot open file. (%s)", __FUNCTION__, e.what());
return false;
}
catch (Json::exception& e)
{
KGE_ERRORF("%s failed: Cannot parse to JSON. (%s)", __FUNCTION__, e.what());
KGE_ERRORF("%s failed: cannot parse JSON. (%s)", __FUNCTION__, e.what());
return false;
}
return LoadFromJson(json_data);