From 832576d0aa41c13560949f436cb8eacf236755a9 Mon Sep 17 00:00:00 2001 From: Nomango Date: Thu, 6 Feb 2020 16:54:47 +0800 Subject: [PATCH] Add factory functions --- .../kiwano-physics/kiwano-physics.vcxproj | 2 - .../kiwano-physics.vcxproj.filters | 2 - projects/kiwano/kiwano.vcxproj | 13 +- projects/kiwano/kiwano.vcxproj.filters | 39 ++- src/kiwano-audio/Sound.cpp | 21 ++ src/kiwano-audio/Sound.h | 12 +- src/kiwano-audio/SoundPlayer.cpp | 7 + src/kiwano-audio/SoundPlayer.h | 4 + src/kiwano-imgui/ImGuiLayer.cpp | 17 ++ src/kiwano-imgui/ImGuiLayer.h | 10 + src/kiwano-network/HttpClient.cpp | 8 +- src/kiwano-network/HttpRequest.cpp | 40 ++++ src/kiwano-network/HttpRequest.h | 61 +++-- src/kiwano-physics/Body.cpp | 72 ++++-- src/kiwano-physics/Body.h | 61 +++-- src/kiwano-physics/Contact.cpp | 26 +- src/kiwano-physics/Contact.h | 14 +- src/kiwano-physics/ContactEdge.h | 15 +- src/kiwano-physics/Fixture.cpp | 149 +++++++++--- src/kiwano-physics/Fixture.h | 109 +++++++-- src/kiwano-physics/Joint.cpp | 121 ++++++++++ src/kiwano-physics/Joint.h | 66 ++++++ src/kiwano-physics/Shape.cpp | 222 ------------------ src/kiwano-physics/Shape.h | 157 ------------- src/kiwano-physics/World.cpp | 14 +- src/kiwano-physics/kiwano-physics.h | 1 - src/kiwano/2d/Actor.cpp | 8 + src/kiwano/2d/Actor.h | 7 +- src/kiwano/2d/Button.cpp | 87 ++++--- src/kiwano/2d/Button.h | 30 +-- src/kiwano/2d/Canvas.cpp | 7 + src/kiwano/2d/Canvas.h | 21 +- src/kiwano/2d/Frame.cpp | 33 +++ src/kiwano/2d/Frame.h | 22 ++ src/kiwano/2d/FrameSequence.cpp | 12 +- src/kiwano/2d/FrameSequence.h | 10 +- src/kiwano/2d/GifSprite.cpp | 33 +++ src/kiwano/2d/GifSprite.h | 15 ++ src/kiwano/2d/Layer.cpp | 7 + src/kiwano/2d/Layer.h | 4 + src/kiwano/2d/ShapeActor.cpp | 79 ++++++- src/kiwano/2d/ShapeActor.h | 75 ++++-- src/kiwano/2d/Sprite.cpp | 33 +++ src/kiwano/2d/Sprite.h | 15 ++ src/kiwano/2d/Stage.cpp | 7 + src/kiwano/2d/Stage.h | 4 + src/kiwano/2d/TextActor.cpp | 33 ++- src/kiwano/2d/TextActor.h | 18 +- src/kiwano/2d/Transform.h | 47 ---- src/kiwano/2d/Transition.cpp | 69 ++++-- src/kiwano/2d/Transition.h | 50 ++-- src/kiwano/2d/action/Action.h | 2 +- src/kiwano/core/AsyncTask.cpp | 17 +- src/kiwano/core/AsyncTask.h | 8 +- src/kiwano/core/EventDispatcher.cpp | 4 +- src/kiwano/core/EventListener.cpp | 37 ++- src/kiwano/core/EventListener.h | 68 +++--- src/kiwano/core/Timer.cpp | 39 +-- src/kiwano/core/Timer.h | 16 +- src/kiwano/core/TimerManager.cpp | 2 +- src/kiwano/core/event/Event.h | 2 +- src/kiwano/core/event/MouseEvent.h | 2 +- src/kiwano/kiwano.h | 13 +- src/kiwano/math/{constants.h => Constants.h} | 0 src/kiwano/math/{ease.h => EaseFunctions.h} | 2 +- src/kiwano/math/{math.h => Math.h} | 12 +- src/kiwano/math/Matrix.hpp | 82 +++---- src/kiwano/math/{rand.h => Random.h} | 0 src/kiwano/math/Rect.hpp | 50 ++-- src/kiwano/math/{scalar.h => Scalar.h} | 2 +- .../{2d/Transform.cpp => math/Transform.hpp} | 47 +++- src/kiwano/math/Vec2.hpp | 28 +-- src/kiwano/platform/Input.h | 2 +- src/kiwano/platform/Window.h | 2 +- src/kiwano/render/Brush.cpp | 36 ++- src/kiwano/render/Brush.h | 15 +- src/kiwano/render/DirectX/helper.h | 2 +- src/kiwano/render/Font.cpp | 39 ++- src/kiwano/render/Font.h | 16 +- src/kiwano/render/GifImage.cpp | 23 ++ src/kiwano/render/GifImage.h | 8 + src/kiwano/render/RenderContext.cpp | 88 +++++-- src/kiwano/render/RenderContext.h | 12 +- src/kiwano/render/Renderer.cpp | 44 ++-- src/kiwano/render/Renderer.h | 10 +- src/kiwano/render/Shape.h | 59 +++-- src/kiwano/render/ShapeSink.cpp | 13 +- src/kiwano/render/ShapeSink.h | 8 +- src/kiwano/render/StrokeStyle.cpp | 21 +- src/kiwano/render/StrokeStyle.h | 29 ++- src/kiwano/render/TextLayout.h | 6 +- src/kiwano/render/TextStyle.hpp | 24 +- src/kiwano/render/Texture.cpp | 23 ++ src/kiwano/render/Texture.h | 8 + src/kiwano/utils/LocalStorage.h | 7 +- src/kiwano/utils/ResourceCache.cpp | 10 +- 96 files changed, 1828 insertions(+), 1099 deletions(-) delete mode 100644 src/kiwano-physics/Shape.cpp delete mode 100644 src/kiwano-physics/Shape.h delete mode 100644 src/kiwano/2d/Transform.h rename src/kiwano/math/{constants.h => Constants.h} (100%) rename src/kiwano/math/{ease.h => EaseFunctions.h} (99%) rename src/kiwano/math/{math.h => Math.h} (88%) rename src/kiwano/math/{rand.h => Random.h} (100%) rename src/kiwano/math/{scalar.h => Scalar.h} (98%) rename src/kiwano/{2d/Transform.cpp => math/Transform.hpp} (58%) diff --git a/projects/kiwano-physics/kiwano-physics.vcxproj b/projects/kiwano-physics/kiwano-physics.vcxproj index 33cce9e7..8b9bb3d4 100644 --- a/projects/kiwano-physics/kiwano-physics.vcxproj +++ b/projects/kiwano-physics/kiwano-physics.vcxproj @@ -19,7 +19,6 @@ - @@ -29,7 +28,6 @@ - diff --git a/projects/kiwano-physics/kiwano-physics.vcxproj.filters b/projects/kiwano-physics/kiwano-physics.vcxproj.filters index e4f5fe7f..df3e5d6d 100644 --- a/projects/kiwano-physics/kiwano-physics.vcxproj.filters +++ b/projects/kiwano-physics/kiwano-physics.vcxproj.filters @@ -5,7 +5,6 @@ - @@ -16,7 +15,6 @@ - diff --git a/projects/kiwano/kiwano.vcxproj b/projects/kiwano/kiwano.vcxproj index 505cc43b..86570ca7 100644 --- a/projects/kiwano/kiwano.vcxproj +++ b/projects/kiwano/kiwano.vcxproj @@ -35,7 +35,6 @@ - @@ -48,13 +47,14 @@ - - - + + + - + - + + @@ -108,7 +108,6 @@ - diff --git a/projects/kiwano/kiwano.vcxproj.filters b/projects/kiwano/kiwano.vcxproj.filters index 6b3c7859..4500b9b2 100644 --- a/projects/kiwano/kiwano.vcxproj.filters +++ b/projects/kiwano/kiwano.vcxproj.filters @@ -60,9 +60,6 @@ math - - math - math @@ -138,24 +135,9 @@ core - - math - core - - 2d - - - math - - - math - - - math - utils @@ -285,6 +267,24 @@ render + + math + + + math + + + math + + + math + + + math + + + math + @@ -371,9 +371,6 @@ core - - 2d - core diff --git a/src/kiwano-audio/Sound.cpp b/src/kiwano-audio/Sound.cpp index 39158d6b..c8f20b5d 100644 --- a/src/kiwano-audio/Sound.cpp +++ b/src/kiwano-audio/Sound.cpp @@ -27,6 +27,27 @@ namespace kiwano { namespace audio { +SoundPtr Sound::Create(String const& file_path) +{ + SoundPtr ptr = new (std::nothrow) Sound; + if (ptr) + { + if (!ptr->Load(file_path)) + return nullptr; + } + return ptr; +} + +SoundPtr Sound::Create(Resource const& res) +{ + SoundPtr ptr = new (std::nothrow) Sound; + if (ptr) + { + if (!ptr->Load(res)) + return nullptr; + } + return ptr; +} Sound::Sound() : opened_(false) diff --git a/src/kiwano-audio/Sound.h b/src/kiwano-audio/Sound.h index 14987b15..50634eec 100644 --- a/src/kiwano-audio/Sound.h +++ b/src/kiwano-audio/Sound.h @@ -40,13 +40,23 @@ KGE_DECLARE_SMART_PTR(Sound); /** * \~chinese - * @brief 音频 + * @brief 音频对象 */ class KGE_API Sound : public virtual ObjectBase { friend class AudioEngine; public: + /// \~chinese + /// @brief 创建音频对象 + /// @param res 本地音频文件路径 + static SoundPtr Create(String const& file_path); + + /// \~chinese + /// @brief 创建音频对象 + /// @param res 音频资源 + static SoundPtr Create(Resource const& res); + Sound(); virtual ~Sound(); diff --git a/src/kiwano-audio/SoundPlayer.cpp b/src/kiwano-audio/SoundPlayer.cpp index 442a3e2a..f97ceb1f 100644 --- a/src/kiwano-audio/SoundPlayer.cpp +++ b/src/kiwano-audio/SoundPlayer.cpp @@ -24,6 +24,13 @@ namespace kiwano { namespace audio { + +SoundPlayerPtr SoundPlayer::Create() +{ + SoundPlayerPtr ptr = new (std::nothrow) SoundPlayer; + return ptr; +} + SoundPlayer::SoundPlayer() : volume_(1.f) { diff --git a/src/kiwano-audio/SoundPlayer.h b/src/kiwano-audio/SoundPlayer.h index df200860..e52a8a3c 100644 --- a/src/kiwano-audio/SoundPlayer.h +++ b/src/kiwano-audio/SoundPlayer.h @@ -40,6 +40,10 @@ KGE_DECLARE_SMART_PTR(SoundPlayer); class KGE_API SoundPlayer : public virtual ObjectBase { public: + /// \~chinese + /// @brief 创建音频播放器 + static SoundPlayerPtr Create(); + SoundPlayer(); ~SoundPlayer(); diff --git a/src/kiwano-imgui/ImGuiLayer.cpp b/src/kiwano-imgui/ImGuiLayer.cpp index 94054b4d..a47236ea 100644 --- a/src/kiwano-imgui/ImGuiLayer.cpp +++ b/src/kiwano-imgui/ImGuiLayer.cpp @@ -24,6 +24,23 @@ namespace kiwano { namespace imgui { + +ImGuiLayerPtr ImGuiLayer::Create() +{ + ImGuiLayerPtr ptr = new (std::nothrow) ImGuiLayer; + return ptr; +} + +ImGuiLayerPtr ImGuiLayer::Create(String const& name, ImGuiPipeline const& item) +{ + ImGuiLayerPtr ptr = new (std::nothrow) ImGuiLayer; + if (ptr) + { + ptr->AddItem(name, item); + } + return ptr; +} + ImGuiLayer::ImGuiLayer() { SetSwallowEvents(true); diff --git a/src/kiwano-imgui/ImGuiLayer.h b/src/kiwano-imgui/ImGuiLayer.h index a377805e..dfd3b8f0 100644 --- a/src/kiwano-imgui/ImGuiLayer.h +++ b/src/kiwano-imgui/ImGuiLayer.h @@ -38,6 +38,16 @@ using ImGuiPipeline = Function; class ImGuiLayer : public Layer { public: + /// \~chinese + /// @brief 创建ImGui图层 + static ImGuiLayerPtr Create(); + + /// \~chinese + /// @brief 创建ImGui图层 + /// @param name 元素名称 + /// @param item 管道 + static ImGuiLayerPtr Create(String const& name, ImGuiPipeline const& item); + ImGuiLayer(); virtual ~ImGuiLayer(); diff --git a/src/kiwano-network/HttpClient.cpp b/src/kiwano-network/HttpClient.cpp index cbee5f69..667d54c7 100644 --- a/src/kiwano-network/HttpClient.cpp +++ b/src/kiwano-network/HttpClient.cpp @@ -294,18 +294,18 @@ void HttpClient::Perform(HttpRequestPtr request, HttpResponsePtr response) switch (request->GetType()) { - case HttpRequest::Type::Get: + case HttpType::Get: ok = Curl::GetRequest(this, headers, url, &response_code, &response_data, &response_header, error_message); break; - case HttpRequest::Type::Post: + case HttpType::Post: ok = Curl::PostRequest(this, headers, url, data, &response_code, &response_data, &response_header, error_message); break; - case HttpRequest::Type::Put: + case HttpType::Put: ok = Curl::PutRequest(this, headers, url, data, &response_code, &response_data, &response_header, error_message); break; - case HttpRequest::Type::Delete: + case HttpType::Delete: ok = Curl::DeleteRequest(this, headers, url, &response_code, &response_data, &response_header, error_message); break; default: diff --git a/src/kiwano-network/HttpRequest.cpp b/src/kiwano-network/HttpRequest.cpp index 6aacca61..9880a4ac 100644 --- a/src/kiwano-network/HttpRequest.cpp +++ b/src/kiwano-network/HttpRequest.cpp @@ -25,10 +25,50 @@ namespace kiwano { namespace network { + +HttpRequestPtr HttpRequest::Create(String const& url, HttpType type, ResponseCallback const& callback) +{ + HttpRequestPtr ptr = new (std::nothrow) HttpRequest; + if (ptr) + { + ptr->SetUrl(url); + ptr->SetType(type); + ptr->SetResponseCallback(callback); + } + return ptr; +} + +HttpRequestPtr HttpRequest::Create(String const& url, HttpType type, String const& data, ResponseCallback const& callback) +{ + HttpRequestPtr ptr = new (std::nothrow) HttpRequest; + if (ptr) + { + ptr->SetUrl(url); + ptr->SetType(type); + ptr->SetData(data); + ptr->SetResponseCallback(callback); + } + return ptr; +} + +HttpRequestPtr HttpRequest::Create(String const& url, HttpType type, Json const& json, ResponseCallback const& callback) +{ + HttpRequestPtr ptr = new (std::nothrow) HttpRequest; + if (ptr) + { + ptr->SetUrl(url); + ptr->SetType(type); + ptr->SetJsonData(json); + ptr->SetResponseCallback(callback); + } + return ptr; +} + void HttpRequest::SetJsonData(Json const& json) { SetHeader(L"Content-Type", L"application/json;charset=UTF-8"); data_ = json.dump(); } + } // namespace network } // namespace kiwano diff --git a/src/kiwano-network/HttpRequest.h b/src/kiwano-network/HttpRequest.h index cc01a9cb..69efbbf0 100644 --- a/src/kiwano-network/HttpRequest.h +++ b/src/kiwano-network/HttpRequest.h @@ -36,6 +36,17 @@ KGE_DECLARE_SMART_PTR(HttpRequest); * @{ */ +/// \~chinese +/// @brief HTTP请求类型 +enum class HttpType +{ + Unknown, ///< 未知 + Get, ///< HTTP GET请求 + Post, ///< HTTP POST请求 + Put, ///< HTTP PUT请求 + Delete ///< HTTP DELETE请求 +}; + /** * \~chinese * @brief HTTP请求 @@ -48,19 +59,31 @@ public: using ResponseCallback = Function; /// \~chinese - /// @brief 请求类型 - enum class Type - { - Unknown, ///< 未知 - Get, ///< HTTP GET请求 - Post, ///< HTTP POST请求 - Put, ///< HTTP PUT请求 - Delete ///< HTTP DELETE请求 - }; + /// @brief 创建HTTP请求 + /// @param url 请求地址 + /// @param type 请求类型 + /// @param callback 响应回调函数 + static HttpRequestPtr Create(String const& url, HttpType type, ResponseCallback const& callback); + + /// \~chinese + /// @brief 创建HTTP请求 + /// @param url 请求地址 + /// @param type 请求类型 + /// @param data 请求数据 + /// @param callback 响应回调函数 + static HttpRequestPtr Create(String const& url, HttpType type, String const& data, ResponseCallback const& callback); + + /// \~chinese + /// @brief 创建HTTP请求 + /// @param url 请求地址 + /// @param type 请求类型 + /// @param json 请求的JSON数据 + /// @param callback 响应回调函数 + static HttpRequestPtr Create(String const& url, HttpType type, Json const& json, ResponseCallback const& callback); HttpRequest(); - HttpRequest(Type type); + HttpRequest(HttpType type); /// \~chinese /// @brief 设置请求地址 @@ -68,14 +91,14 @@ public: /// \~chinese /// @brief 设置请求类型 - void SetType(Type type); + void SetType(HttpType type); /// \~chinese - /// @brief 设置请求携带的数据 + /// @brief 设置请求数据 void SetData(String const& data); /// \~chinese - /// @brief 设置请求携带的JSON数据 + /// @brief 设置请求的JSON数据 void SetJsonData(Json const& json); /// \~chinese @@ -96,7 +119,7 @@ public: /// \~chinese /// @brief 获取请求类型 - Type GetType() const; + HttpType GetType() const; /// \~chinese /// @brief 获取请求数据 @@ -115,7 +138,7 @@ public: ResponseCallback const& GetResponseCallback() const; private: - Type type_; + HttpType type_; String url_; String data_; Map headers_; @@ -125,11 +148,11 @@ private: /** @} */ inline HttpRequest::HttpRequest() - : type_(Type::Unknown) + : type_(HttpType::Unknown) { } -inline HttpRequest::HttpRequest(Type type) +inline HttpRequest::HttpRequest(HttpType type) : type_(type) { } @@ -144,12 +167,12 @@ inline String const& HttpRequest::GetUrl() const return url_; } -inline void HttpRequest::SetType(Type type) +inline void HttpRequest::SetType(HttpType type) { type_ = type; } -inline HttpRequest::Type HttpRequest::GetType() const +inline HttpType HttpRequest::GetType() const { return type_; } diff --git a/src/kiwano-physics/Body.cpp b/src/kiwano-physics/Body.cpp index 7698824b..2d54a12d 100644 --- a/src/kiwano-physics/Body.cpp +++ b/src/kiwano-physics/Body.cpp @@ -26,6 +26,19 @@ namespace kiwano namespace physics { +BodyPtr Body::Create(World* world, Actor* actor, Type type) +{ + BodyPtr ptr = new (std::nothrow) Body; + if (ptr) + { + if (!ptr->InitBody(world, actor)) + return nullptr; + + ptr->SetType(type); + } + return ptr; +} + Body::Body() : body_(nullptr) , actor_(nullptr) @@ -61,42 +74,67 @@ bool Body::InitBody(World* world, Actor* actor) return false; } -Fixture Body::AddFixture(Shape* shape, const Fixture::Param& param) +void Body::AddFixture(FixturePtr fixture) { - KGE_ASSERT(body_ && world_); - return Fixture(this, shape, param); + fixtures_.push_back(fixture); } -Fixture Body::AddCircleShape(float radius, float density) +Fixture* Body::AddCircleShape(float radius, float density, float friction, float restitution, bool is_sensor) { - return AddFixture(&CircleShape(radius), Fixture::Param(density)); + Fixture::Param param(density, friction, restitution, is_sensor); + FixturePtr fixture = Fixture::CreateCircle(this, param, radius); + AddFixture(fixture); + return fixture.get(); } -Fixture Body::AddBoxShape(Vec2 const& size, float density) +Fixture* Body::AddRectShape(Vec2 const& size, float density, float friction, float restitution, bool is_sensor) { - return AddFixture(&BoxShape(size), Fixture::Param(density)); + Fixture::Param param(density, friction, restitution, is_sensor); + FixturePtr fixture = Fixture::CreateRect(this, param, size); + AddFixture(fixture); + return fixture.get(); } -Fixture Body::AddPolygonShape(Vector const& vertexs, float density) +Fixture* Body::AddPolygonShape(Vector const& vertexs, float density, float friction, float restitution, + bool is_sensor) { - return AddFixture(&PolygonShape(vertexs), Fixture::Param(density)); + Fixture::Param param(density, friction, restitution, is_sensor); + FixturePtr fixture = Fixture::CreatePolygon(this, param, vertexs); + AddFixture(fixture); + return fixture.get(); } -Fixture Body::AddEdgeShape(Point const& p1, Point const& p2, float density) +Fixture* Body::AddEdgeShape(Point const& p1, Point const& p2, float density, float friction, float restitution, + bool is_sensor) { - return AddFixture(&EdgeShape(p1, p2), Fixture::Param(density)); + Fixture::Param param(density, friction, restitution, is_sensor); + FixturePtr fixture = Fixture::CreateEdge(this, param, p1, p2); + AddFixture(fixture); + return fixture.get(); } -Fixture Body::AddChainShape(Vector const& vertexs, bool loop, float density) +Fixture* Body::AddChainShape(Vector const& vertexs, bool loop, float density, float friction, float restitution, + bool is_sensor) { - return AddFixture(&ChainShape(vertexs, loop), Fixture::Param(density)); + Fixture::Param param(density, friction, restitution, is_sensor); + FixturePtr fixture = Fixture::CreateChain(this, param, vertexs, loop); + AddFixture(fixture); + return fixture.get(); } -void Body::RemoveFixture(Fixture const& fixture) +void Body::RemoveFixture(FixturePtr fixture) { - if (fixture.GetB2Fixture()) + if (fixture) { - body_->DestroyFixture(fixture.GetB2Fixture()); + body_->DestroyFixture(fixture->GetB2Fixture()); + + for (auto iter = fixtures_.begin(); iter != fixtures_.end();) + { + if (*iter == fixture) + iter = fixtures_.erase(iter); + else + ++iter; + } } } @@ -248,6 +286,8 @@ void Body::SetB2Body(b2Body* body) void Body::Destroy() { + fixtures_.clear(); + if (world_) { world_->RemoveBody(this); diff --git a/src/kiwano-physics/Body.h b/src/kiwano-physics/Body.h index 25fd0c8e..cc570efd 100644 --- a/src/kiwano-physics/Body.h +++ b/src/kiwano-physics/Body.h @@ -21,7 +21,6 @@ #pragma once #include #include -#include #include namespace kiwano @@ -51,6 +50,20 @@ public: Dynamic, ///< 动态物体 }; + /// \~chinese + /// @brief 初始化 + /// @param[in] world 物理世界 + /// @param[in] actor 绑定的角色 + /// @param[in] type 物体类型 + static BodyPtr Create(World* world, ActorPtr actor, Type type); + + /// \~chinese + /// @brief 初始化 + /// @param[in] world 物理世界 + /// @param[in] actor 绑定的角色 + /// @param[in] type 物体类型 + static BodyPtr Create(World* world, Actor* actor, Type type); + Body(); virtual ~Body(); @@ -69,50 +82,54 @@ public: /// \~chinese /// @brief 添加夹具 - /// @param shape 物体形状 - /// @param density 物体密度 - Fixture AddFixture(Shape* shape, const Fixture::Param& param); + void AddFixture(FixturePtr fixture); /// \~chinese /// @brief 添加圆形夹具 /// @param radius 圆形半径 /// @param density 物体密度 - Fixture AddCircleShape(float radius, float density = 0.f); + /// @param + Fixture* AddCircleShape(float radius, float density, float friction = 0.2f, float restitution = 0.f, + bool is_sensor = false); /// \~chinese - /// @brief 添加盒形夹具 - /// @param size 盒大小 + /// @brief 添加矩形夹具 + /// @param size 矩形大小 /// @param density 物体密度 - Fixture AddBoxShape(Vec2 const& size, float density = 0.f); + Fixture* AddRectShape(Vec2 const& size, float density, float friction = 0.2f, float restitution = 0.f, + bool is_sensor = false); /// \~chinese /// @brief 添加多边形夹具 /// @param vertexs 多边形端点 /// @param density 物体密度 - Fixture AddPolygonShape(Vector const& vertexs, float density = 0.f); + Fixture* AddPolygonShape(Vector const& vertexs, float density, float friction = 0.2f, + float restitution = 0.f, bool is_sensor = false); /// \~chinese /// @brief 添加线段形夹具 /// @param p1 线段起点 /// @param p2 线段终点 /// @param density 物体密度 - Fixture AddEdgeShape(Point const& p1, Point const& p2, float density = 0.f); + Fixture* AddEdgeShape(Point const& p1, Point const& p2, float density, float friction = 0.2f, + float restitution = 0.f, bool is_sensor = false); /// \~chinese /// @brief 添加链条形夹具 /// @param vertexs 链条端点 /// @param loop 是否闭合 /// @param density 物体密度 - Fixture AddChainShape(Vector const& vertexs, bool loop, float density = 0.f); + Fixture* AddChainShape(Vector const& vertexs, bool loop, float density, float friction = 0.2f, + float restitution = 0.f, bool is_sensor = false); + + /// \~chinese + /// @brief 移除夹具 + void RemoveFixture(FixturePtr fixture); /// \~chinese /// @brief 获取夹具列表 FixtureList GetFixtureList() const; - /// \~chinese - /// @brief 移除夹具 - void RemoveFixture(Fixture const& fixture); - /// \~chinese /// @brief 获取接触边列表 ContactEdgeList GetContactList() const; @@ -318,10 +335,17 @@ private: uint16_t category_bits_; uint16_t mask_bits_; int16_t group_index_; + + Vector fixtures_; }; /** @} */ +inline BodyPtr Body::Create(World* world, ActorPtr actor, Type type) +{ + return Body::Create(world, actor.get(), type); +} + inline bool Body::InitBody(World* world, ActorPtr actor) { return InitBody(world, actor.get()); @@ -330,7 +354,12 @@ inline bool Body::InitBody(World* world, ActorPtr actor) inline FixtureList Body::GetFixtureList() const { KGE_ASSERT(body_); - return FixtureList(Fixture(body_->GetFixtureList())); + + if (!body_->GetFixtureList()) + return FixtureList(); + + Fixture* fixture = static_cast(body_->GetFixtureList()->GetUserData()); + return FixtureList(fixture); } inline ContactEdgeList Body::GetContactList() const diff --git a/src/kiwano-physics/Contact.cpp b/src/kiwano-physics/Contact.cpp index 4df8b5b5..072bb8c9 100644 --- a/src/kiwano-physics/Contact.cpp +++ b/src/kiwano-physics/Contact.cpp @@ -32,39 +32,37 @@ Contact::Contact() { } -Contact::Contact(b2Contact* contact) - : Contact() -{ - SetB2Contact(contact); -} - -Fixture Contact::GetFixtureA() const +Fixture* Contact::GetFixtureA() const { KGE_ASSERT(contact_); - return Fixture(contact_->GetFixtureA()); + + Fixture* fixture = static_cast(contact_->GetFixtureA()->GetUserData()); + return fixture; } -Fixture Contact::GetFixtureB() const +Fixture* Contact::GetFixtureB() const { KGE_ASSERT(contact_); - return Fixture(contact_->GetFixtureB()); + + Fixture* fixture = static_cast(contact_->GetFixtureB()->GetUserData()); + return fixture; } Body* Contact::GetBodyA() const { - return GetFixtureA().GetBody(); + return GetFixtureA()->GetBody(); } Body* Contact::GetBodyB() const { - return GetFixtureB().GetBody(); + return GetFixtureB()->GetBody(); } void Contact::SetTangentSpeed(float speed) { KGE_ASSERT(contact_); - Body* body = GetFixtureA().GetBody(); + Body* body = GetFixtureA()->GetBody(); KGE_ASSERT(body); World* world = body->GetWorld(); @@ -77,7 +75,7 @@ float Contact::GetTangentSpeed() const { KGE_ASSERT(contact_); - const Body* body = GetFixtureA().GetBody(); + const Body* body = GetFixtureA()->GetBody(); KGE_ASSERT(body); const World* world = body->GetWorld(); diff --git a/src/kiwano-physics/Contact.h b/src/kiwano-physics/Contact.h index 5e5a9a79..c5398878 100644 --- a/src/kiwano-physics/Contact.h +++ b/src/kiwano-physics/Contact.h @@ -39,7 +39,6 @@ class KGE_API Contact { public: Contact(); - Contact(b2Contact* contact); /// \~chinese /// @brief 是否有效 @@ -59,11 +58,11 @@ public: /// \~chinese /// @brief 获取物体A的夹具 - Fixture GetFixtureA() const; + Fixture* GetFixtureA() const; /// \~chinese /// @brief 获取物体B的夹具 - Fixture GetFixtureB() const; + Fixture* GetFixtureB() const; /// \~chinese /// @brief 获取物体A @@ -106,7 +105,8 @@ public: float GetTangentSpeed() const; b2Contact* GetB2Contact() const; - void SetB2Contact(b2Contact* contact); + + void SetB2Contact(b2Contact* contact); bool operator==(const Contact& rhs) const; bool operator!=(const Contact& rhs) const; @@ -117,7 +117,7 @@ private: /// \~chinese /// @brief 物理接触列表 -class ContactList : public List +class ContactList { template class IteratorImpl : public std::iterator @@ -206,7 +206,7 @@ public: inline iterator end() { - return iterator(nullptr); + return iterator(Contact()); } inline const_iterator end() const @@ -216,7 +216,7 @@ public: inline const_iterator cend() const { - return const_iterator(nullptr); + return const_iterator(Contact()); } private: diff --git a/src/kiwano-physics/ContactEdge.h b/src/kiwano-physics/ContactEdge.h index bf500f90..270e832c 100644 --- a/src/kiwano-physics/ContactEdge.h +++ b/src/kiwano-physics/ContactEdge.h @@ -36,6 +36,7 @@ class KGE_API ContactEdge { public: ContactEdge(); + ContactEdge(b2ContactEdge* edge); /// \~chinese @@ -51,7 +52,8 @@ public: Contact GetContact() const; b2ContactEdge* GetB2ContactEdge() const; - void SetB2ContactEdge(b2ContactEdge* edge); + + void SetB2ContactEdge(b2ContactEdge* edge); bool operator==(const ContactEdge& rhs) const; bool operator!=(const ContactEdge& rhs) const; @@ -174,28 +176,37 @@ inline bool ContactEdge::IsValid() const { return edge_ != nullptr; } + inline Body* ContactEdge::GetOtherBody() const { KGE_ASSERT(edge_); return static_cast(edge_->other->GetUserData()); } + inline Contact ContactEdge::GetContact() const { KGE_ASSERT(edge_); - return Contact(edge_->contact); + + Contact contact; + contact.SetB2Contact(edge_->contact); + return contact; } + inline b2ContactEdge* ContactEdge::GetB2ContactEdge() const { return edge_; } + inline void ContactEdge::SetB2ContactEdge(b2ContactEdge* edge) { edge_ = edge; } + inline bool ContactEdge::operator==(const ContactEdge& rhs) const { return edge_ == rhs.edge_; } + inline bool ContactEdge::operator!=(const ContactEdge& rhs) const { return edge_ != rhs.edge_; diff --git a/src/kiwano-physics/Fixture.cpp b/src/kiwano-physics/Fixture.cpp index 7cf316fc..10b7969a 100644 --- a/src/kiwano-physics/Fixture.cpp +++ b/src/kiwano-physics/Fixture.cpp @@ -27,49 +27,144 @@ namespace kiwano namespace physics { +namespace +{ + +FixturePtr CreateFixture(Body* body, b2Shape* shape, const Fixture::Param& param) +{ + KGE_ASSERT(body); + + b2Body* b2body = body->GetB2Body(); + KGE_ASSERT(b2body); + + b2FixtureDef fd; + fd.density = param.density; + fd.friction = param.friction; + fd.restitution = param.restitution; + fd.shape = shape; + + FixturePtr ptr = new (std::nothrow) Fixture; + if (ptr) + { + b2Fixture* fixture = b2body->CreateFixture(&fd); + if (fixture) + { + fixture->SetUserData(ptr.get()); + ptr->SetB2Fixture(fixture); + return ptr; + } + } + return nullptr; +} + +} // namespace + +FixturePtr Fixture::CreateCircle(Body* body, Param const& param, float radius, Point const& offset) +{ + KGE_ASSERT(body); + World* world = body->GetWorld(); + + b2CircleShape shape; + shape.m_radius = world->Stage2World(radius); + shape.m_p = world->Stage2World(offset); + + return CreateFixture(body, &shape, param); +} + +FixturePtr Fixture::CreateRect(Body* body, Param const& param, Size const& size, Point const& offset, float rotation) +{ + KGE_ASSERT(body); + World* world = body->GetWorld(); + + b2Vec2 b2size = world->Stage2World(size); + b2Vec2 b2offset = world->Stage2World(offset); + + b2PolygonShape shape; + shape.SetAsBox(b2size.x / 2, b2size.y / 2, b2offset, rotation); + + return CreateFixture(body, &shape, param); +} + +FixturePtr Fixture::CreatePolygon(Body* body, Param const& param, Vector const& vertexs) +{ + KGE_ASSERT(body); + World* world = body->GetWorld(); + + Vector b2vertexs; + b2vertexs.reserve(vertexs.size()); + for (const auto& v : vertexs) + { + b2vertexs.push_back(world->Stage2World(v)); + } + + b2PolygonShape shape; + shape.Set(&b2vertexs[0], static_cast(b2vertexs.size())); + + return CreateFixture(body, &shape, param); +} + +FixturePtr Fixture::CreateEdge(Body* body, Param const& param, Point const& p1, Point const& p2) +{ + KGE_ASSERT(body); + World* world = body->GetWorld(); + + b2Vec2 start = world->Stage2World(p1); + b2Vec2 end = world->Stage2World(p2); + + b2EdgeShape shape; + shape.Set(start, end); + + return CreateFixture(body, &shape, param); +} + +FixturePtr Fixture::CreateChain(Body* body, Param const& param, Vector const& vertexs, bool loop) +{ + KGE_ASSERT(body); + World* world = body->GetWorld(); + + Vector b2vertexs; + b2vertexs.reserve(vertexs.size()); + for (const auto& v : vertexs) + { + b2vertexs.push_back(world->Stage2World(v)); + } + + b2ChainShape shape; + if (loop) + { + shape.CreateLoop(&b2vertexs[0], static_cast(b2vertexs.size())); + } + else + { + shape.CreateChain(&b2vertexs[0], static_cast(b2vertexs.size())); + } + return CreateFixture(body, &shape, param); +} + Fixture::Fixture() : fixture_(nullptr) { } -Fixture::Fixture(b2Fixture* fixture) - : Fixture() +Fixture::~Fixture() { - SetB2Fixture(fixture); -} - -Fixture::Fixture(Body* body, Shape* shape, const Param& param) - : Fixture() -{ - KGE_ASSERT(body); - - if (shape) + if (fixture_) { - shape->FitWorld(body->GetWorld()); - - b2Body* b2body = body->GetB2Body(); - b2FixtureDef fd; - fd.density = param.density; - fd.friction = param.friction; - fd.restitution = param.restitution; - fd.shape = shape->GetB2Shape(); - auto fixture = b2body->CreateFixture(&fd); - SetB2Fixture(fixture); + b2Body* body = fixture_->GetBody(); + if (body) + { + body->DestroyFixture(fixture_); + } } } Body* Fixture::GetBody() const { + fixture_->GetShape(); KGE_ASSERT(fixture_); return static_cast(fixture_->GetBody()->GetUserData()); } -Shape Fixture::GetShape() const -{ - KGE_ASSERT(fixture_); - return Shape(fixture_->GetShape()); -} - void Fixture::GetMassData(float* mass, Point* center, float* inertia) const { KGE_ASSERT(fixture_); diff --git a/src/kiwano-physics/Fixture.h b/src/kiwano-physics/Fixture.h index e7f1d52b..5c827467 100644 --- a/src/kiwano-physics/Fixture.h +++ b/src/kiwano-physics/Fixture.h @@ -19,7 +19,6 @@ // THE SOFTWARE. #pragma once -#include #include namespace kiwano @@ -28,6 +27,8 @@ namespace physics { class Body; +KGE_DECLARE_SMART_PTR(Fixture); + /** * \addtogroup Physics * @{ @@ -35,16 +36,16 @@ class Body; /// \~chinese /// @brief 物理夹具 -class Fixture +class Fixture : public virtual ObjectBase { public: /// \~chinese /// @brief 夹具参数 struct Param { - float density = 0.f; ///< 密度 + float density = 0.0f; ///< 密度 float friction = 0.2f; ///< 摩擦力 - float restitution = 0.f; ///< 弹性恢复 + float restitution = 0.0f; ///< 弹性恢复 bool is_sensor = false; ///< 是否是接触传感器 Param() {} @@ -58,9 +59,50 @@ public: } }; + /// \~chinese + /// @brief 创建圆形夹具 + /// @param body 添加夹具的物体 + /// @param param 夹具参数 + /// @param radius 圆形半径 + /// @param offset 偏移量 + static FixturePtr CreateCircle(Body* body, Param const& param, float radius, Point const& offset = Point()); + + /// \~chinese + /// @brief 创建矩形夹具 + /// @param body 添加夹具的物体 + /// @param param 夹具参数 + /// @param size 矩形大小 + /// @param offset 偏移量 + /// @param rotation 旋转角度 + static FixturePtr CreateRect(Body* body, Param const& param, Size const& size, Point const& offset = Point(), + float rotation = 0.f); + + /// \~chinese + /// @brief 创建多边形夹具 + /// @param body 添加夹具的物体 + /// @param param 夹具参数 + /// @param vertexs 多边形顶点 + static FixturePtr CreatePolygon(Body* body, Param const& param, Vector const& vertexs); + + /// \~chinese + /// @brief 创建边夹具 + /// @param body 添加夹具的物体 + /// @param param 夹具参数 + /// @param p1 边的起点 + /// @param p2 边的终点 + static FixturePtr CreateEdge(Body* body, Param const& param, Point const& p1, Point const& p2); + + /// \~chinese + /// @brief 创建链条夹具 + /// @param body 添加夹具的物体 + /// @param param 夹具参数 + /// @param vertexs 链条顶点 + /// @param loop 是否连接链条的起点和终点 + static FixturePtr CreateChain(Body* body, Param const& param, Vector const& vertexs, bool loop = false); + Fixture(); - Fixture(b2Fixture* fixture); - Fixture(Body* body, Shape* shape, const Param& param); + + virtual ~Fixture(); /// \~chinese /// @brief 是否有效 @@ -70,10 +112,6 @@ public: /// @brief 获取夹具所在的物体 Body* GetBody() const; - /// \~chinese - /// @brief 形状 - Shape GetShape() const; - /// \~chinese /// @brief 是否是接触传感器 bool IsSensor() const; @@ -116,7 +154,8 @@ public: bool TestPoint(const Point& p) const; b2Fixture* GetB2Fixture() const; - void SetB2Fixture(b2Fixture* fixture); + + void SetB2Fixture(b2Fixture* fixture); bool operator==(const Fixture& rhs) const; bool operator!=(const Fixture& rhs) const; @@ -127,7 +166,7 @@ private: /// \~chinese /// @brief 物理夹具列表 -class FixtureList : public List +class FixtureList { template class IteratorImpl : public std::iterator @@ -135,31 +174,37 @@ class FixtureList : public List using herit = std::iterator; public: - IteratorImpl(const _Ty& elem) + using reference = typename herit::reference; + using pointer = typename herit::pointer; + + IteratorImpl(pointer elem) : elem_(elem) { } - inline typename herit::reference operator*() const + inline reference operator*() const { - return const_cast(elem_); + return const_cast(*elem_); } - inline typename herit::pointer operator->() const + inline pointer operator->() const { return std::pointer_traits::pointer_to(**this); } inline IteratorImpl& operator++() { - elem_ = elem_.GetB2Fixture()->GetNext(); + b2Fixture* next = elem_->GetB2Fixture()->GetNext(); + + elem_ = static_cast(next->GetUserData()); return *this; } inline IteratorImpl operator++(int) { IteratorImpl old = *this; - operator++(); + + operator++(); return old; } @@ -174,7 +219,7 @@ class FixtureList : public List } private: - _Ty elem_; + pointer elem_; }; public: @@ -182,21 +227,24 @@ public: using iterator = IteratorImpl; using const_iterator = IteratorImpl; - inline FixtureList() {} + inline FixtureList() + : first_(nullptr) + { + } - inline FixtureList(const value_type& first) + inline FixtureList(value_type* first) : first_(first) { } inline const value_type& front() const { - return first_; + return *first_; } inline value_type& front() { - return first_; + return *first_; } inline iterator begin() @@ -230,7 +278,7 @@ public: } private: - value_type first_; + value_type* first_; }; /** @} */ @@ -240,60 +288,73 @@ inline bool Fixture::IsSensor() const KGE_ASSERT(fixture_); return fixture_->IsSensor(); } + inline void Fixture::SetSensor(bool sensor) { KGE_ASSERT(fixture_); fixture_->SetSensor(sensor); } + inline float Fixture::GetDensity() const { KGE_ASSERT(fixture_); return fixture_->GetDensity(); } + inline void Fixture::SetDensity(float density) { KGE_ASSERT(fixture_); fixture_->SetDensity(density); } + inline float Fixture::GetFriction() const { KGE_ASSERT(fixture_); return fixture_->GetFriction(); } + inline void Fixture::SetFriction(float friction) { KGE_ASSERT(fixture_); fixture_->SetFriction(friction); } + inline float Fixture::GetRestitution() const { KGE_ASSERT(fixture_); return fixture_->GetRestitution(); } + inline void Fixture::SetRestitution(float restitution) { KGE_ASSERT(fixture_); fixture_->SetRestitution(restitution); } + inline bool Fixture::IsValid() const { return fixture_ != nullptr; } + inline b2Fixture* Fixture::GetB2Fixture() const { return fixture_; } + inline void Fixture::SetB2Fixture(b2Fixture* fixture) { fixture_ = fixture; } + inline bool Fixture::operator==(const Fixture& rhs) const { return fixture_ == rhs.fixture_; } + inline bool Fixture::operator!=(const Fixture& rhs) const { return fixture_ != rhs.fixture_; } + } // namespace physics } // namespace kiwano diff --git a/src/kiwano-physics/Joint.cpp b/src/kiwano-physics/Joint.cpp index ed52c955..08462be9 100644 --- a/src/kiwano-physics/Joint.cpp +++ b/src/kiwano-physics/Joint.cpp @@ -97,6 +97,17 @@ void Joint::Destroy() // DistanceJoint // +DistanceJointPtr DistanceJoint::Create(World* world, Param const& param) +{ + DistanceJointPtr ptr = new (std::nothrow) DistanceJoint; + if (ptr) + { + if (!ptr->InitJoint(world, param)) + return nullptr; + } + return ptr; +} + DistanceJoint::DistanceJoint() : Joint() , raw_joint_(nullptr) @@ -134,6 +145,17 @@ float DistanceJoint::GetLength() const // FrictionJoint // +FrictionJointPtr FrictionJoint::Create(World* world, Param const& param) +{ + FrictionJointPtr ptr = new (std::nothrow) FrictionJoint; + if (ptr) + { + if (!ptr->InitJoint(world, param)) + return nullptr; + } + return ptr; +} + FrictionJoint::FrictionJoint() : Joint() , raw_joint_(nullptr) @@ -182,6 +204,17 @@ float FrictionJoint::GetMaxTorque() const // GearJoint // +GearJointPtr GearJoint::Create(World* world, Param const& param) +{ + GearJointPtr ptr = new (std::nothrow) GearJoint; + if (ptr) + { + if (!ptr->InitJoint(world, param)) + return nullptr; + } + return ptr; +} + GearJoint::GearJoint() : Joint() , raw_joint_(nullptr) @@ -218,6 +251,17 @@ float GearJoint::GetRatio() const // MotorJoint // +MotorJointPtr MotorJoint::Create(World* world, Param const& param) +{ + MotorJointPtr ptr = new (std::nothrow) MotorJoint; + if (ptr) + { + if (!ptr->InitJoint(world, param)) + return nullptr; + } + return ptr; +} + MotorJoint::MotorJoint() : Joint() , raw_joint_(nullptr) @@ -267,6 +311,17 @@ float MotorJoint::GetMaxTorque() const // PrismaticJoint // +PrismaticJointPtr PrismaticJoint::Create(World* world, Param const& param) +{ + PrismaticJointPtr ptr = new (std::nothrow) PrismaticJoint; + if (ptr) + { + if (!ptr->InitJoint(world, param)) + return nullptr; + } + return ptr; +} + PrismaticJoint::PrismaticJoint() : Joint() , raw_joint_(nullptr) @@ -326,6 +381,17 @@ void PrismaticJoint::SetLimits(float lower, float upper) // PulleyJoint // +PulleyJointPtr PulleyJoint::Create(World* world, Param const& param) +{ + PulleyJointPtr ptr = new (std::nothrow) PulleyJoint; + if (ptr) + { + if (!ptr->InitJoint(world, param)) + return nullptr; + } + return ptr; +} + PulleyJoint::PulleyJoint() : Joint() , raw_joint_(nullptr) @@ -392,6 +458,17 @@ float PulleyJoint::GetCurrentLengthB() const // RevoluteJoint // +RevoluteJointPtr RevoluteJoint::Create(World* world, Param const& param) +{ + RevoluteJointPtr ptr = new (std::nothrow) RevoluteJoint; + if (ptr) + { + if (!ptr->InitJoint(world, param)) + return nullptr; + } + return ptr; +} + RevoluteJoint::RevoluteJoint() : Joint() , raw_joint_(nullptr) @@ -462,6 +539,17 @@ float RevoluteJoint::GetMaxMotorTorque() const // RopeJoint // +RopeJointPtr RopeJoint::Create(World* world, Param const& param) +{ + RopeJointPtr ptr = new (std::nothrow) RopeJoint; + if (ptr) + { + if (!ptr->InitJoint(world, param)) + return nullptr; + } + return ptr; +} + RopeJoint::RopeJoint() : Joint() , raw_joint_(nullptr) @@ -500,6 +588,17 @@ float RopeJoint::GetMaxLength() const // WeldJoint // +WeldJointPtr WeldJoint::Create(World* world, Param const& param) +{ + WeldJointPtr ptr = new (std::nothrow) WeldJoint; + if (ptr) + { + if (!ptr->InitJoint(world, param)) + return nullptr; + } + return ptr; +} + WeldJoint::WeldJoint() : Joint() , raw_joint_(nullptr) @@ -524,6 +623,17 @@ bool WeldJoint::InitJoint(World* world, WeldJoint::Param const& param) // WheelJoint // +WheelJointPtr WheelJoint::Create(World* world, Param const& param) +{ + WheelJointPtr ptr = new (std::nothrow) WheelJoint; + if (ptr) + { + if (!ptr->InitJoint(world, param)) + return nullptr; + } + return ptr; +} + WheelJoint::WheelJoint() : Joint() , raw_joint_(nullptr) @@ -576,6 +686,17 @@ float WheelJoint::GetMaxMotorTorque() const // MouseJoint // +MouseJointPtr MouseJoint::Create(World* world, Param const& param) +{ + MouseJointPtr ptr = new (std::nothrow) MouseJoint; + if (ptr) + { + if (!ptr->InitJoint(world, param)) + return nullptr; + } + return ptr; +} + MouseJoint::MouseJoint() : Joint() , raw_joint_(nullptr) diff --git a/src/kiwano-physics/Joint.h b/src/kiwano-physics/Joint.h index 995fc876..fde87cc2 100644 --- a/src/kiwano-physics/Joint.h +++ b/src/kiwano-physics/Joint.h @@ -151,6 +151,12 @@ public: } }; + /// \~chinese + /// @brief 创建固定距离关节 + /// @param world 物理世界 + /// @param param 关节参数 + static DistanceJointPtr Create(World* world, Param const& param); + DistanceJoint(); /// \~chinese @@ -210,6 +216,12 @@ public: } }; + /// \~chinese + /// @brief 创建摩擦关节 + /// @param world 物理世界 + /// @param param 关节参数 + static FrictionJointPtr Create(World* world, Param const& param); + FrictionJoint(); /// \~chinese @@ -263,6 +275,12 @@ public: } }; + /// \~chinese + /// @brief 创建齿轮关节 + /// @param world 物理世界 + /// @param param 关节参数 + static GearJointPtr Create(World* world, Param const& param); + GearJoint(); /// \~chinese @@ -310,6 +328,12 @@ public: } }; + /// \~chinese + /// @brief 创建马达关节 + /// @param world 物理世界 + /// @param param 关节参数 + static MotorJointPtr Create(World* world, Param const& param); + MotorJoint(); /// \~chinese @@ -378,6 +402,12 @@ public: } }; + /// \~chinese + /// @brief 创建平移关节 + /// @param world 物理世界 + /// @param param 关节参数 + static PrismaticJointPtr Create(World* world, Param const& param); + PrismaticJoint(); /// \~chinese @@ -477,6 +507,12 @@ public: } }; + /// \~chinese + /// @brief 创建滑轮关节 + /// @param world 物理世界 + /// @param param 关节参数 + static PulleyJointPtr Create(World* world, Param const& param); + PulleyJoint(); /// \~chinese @@ -555,6 +591,12 @@ public: } }; + /// \~chinese + /// @brief 创建旋转关节 + /// @param world 物理世界 + /// @param param 关节参数 + static RevoluteJointPtr Create(World* world, Param const& param); + RevoluteJoint(); /// \~chinese @@ -650,6 +692,12 @@ public: } }; + /// \~chinese + /// @brief 创建绳关节 + /// @param world 物理世界 + /// @param param 关节参数 + static RopeJointPtr Create(World* world, Param const& param); + RopeJoint(); /// \~chinese @@ -695,6 +743,12 @@ public: } }; + /// \~chinese + /// @brief 创建焊接关节 + /// @param world 物理世界 + /// @param param 关节参数 + static WeldJointPtr Create(World* world, Param const& param); + WeldJoint(); /// \~chinese @@ -765,6 +819,12 @@ public: } }; + /// \~chinese + /// @brief 创建轮关节 + /// @param world 物理世界 + /// @param param 关节参数 + static WheelJointPtr Create(World* world, Param const& param); + WheelJoint(); /// \~chinese @@ -863,6 +923,12 @@ public: } }; + /// \~chinese + /// @brief 创建鼠标关节 + /// @param world 物理世界 + /// @param param 关节参数 + static MouseJointPtr Create(World* world, Param const& param); + MouseJoint(); /// \~chinese diff --git a/src/kiwano-physics/Shape.cpp b/src/kiwano-physics/Shape.cpp deleted file mode 100644 index 709bf2c3..00000000 --- a/src/kiwano-physics/Shape.cpp +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright (c) 2018-2019 Kiwano - Nomango -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include -#include - -namespace kiwano -{ -namespace physics -{ -Shape::Shape() - : shape_(nullptr) -{ -} - -Shape::Shape(b2Shape* shape) - : shape_(shape) -{ -} - -b2Shape* Shape::GetB2Shape() const -{ - return shape_; -} - -void Shape::SetB2Shape(b2Shape* shape) -{ - shape_ = shape; -} - -// -// CircleShape -// - -CircleShape::CircleShape() - : Shape(&circle_) - , circle_() - , radius_(0.f) -{ -} - -CircleShape::CircleShape(float radius, Point const& offset) - : CircleShape() -{ - Set(radius, offset); -} - -void CircleShape::Set(float radius, Point const& offset) -{ - radius_ = radius; - offset_ = offset; -} - -void CircleShape::FitWorld(World* world) -{ - KGE_ASSERT(world); - circle_.m_radius = world->Stage2World(radius_); - circle_.m_p = world->Stage2World(offset_); -} - -// -// BoxShape -// - -BoxShape::BoxShape() - : Shape(&polygon_) - , polygon_() - , rotation_(0.f) -{ -} - -BoxShape::BoxShape(Vec2 const& size, Point const& offset, float rotation) - : BoxShape() -{ - Set(size, offset, rotation); -} - -void BoxShape::Set(Vec2 const& size, Point const& offset, float rotation) -{ - box_size_ = size; - offset_ = offset; - rotation_ = rotation; -} - -void BoxShape::FitWorld(World* world) -{ - KGE_ASSERT(world); - - b2Vec2 box = world->Stage2World(box_size_); - b2Vec2 offset = world->Stage2World(offset_); - polygon_.SetAsBox(box.x / 2, box.y / 2, offset, rotation_); -} - -// -// PolygonShape -// - -PolygonShape::PolygonShape() - : Shape(&polygon_) - , polygon_() -{ -} - -PolygonShape::PolygonShape(Vector const& vertexs) - : PolygonShape() -{ - Set(vertexs); -} - -void PolygonShape::Set(Vector const& vertexs) -{ - vertexs_ = vertexs; -} - -void PolygonShape::FitWorld(World* world) -{ - KGE_ASSERT(world); - - Vector b2vertexs; - b2vertexs.reserve(vertexs_.size()); - for (const auto& v : vertexs_) - { - b2vertexs.push_back(world->Stage2World(v)); - } - - polygon_.Set(&b2vertexs[0], static_cast(b2vertexs.size())); -} - -// -// EdgeShape -// - -EdgeShape::EdgeShape() - : Shape(&edge_) - , edge_() -{ -} - -EdgeShape::EdgeShape(Point const& p1, Point const& p2) - : EdgeShape() -{ - Set(p1, p2); -} - -void EdgeShape::Set(Point const& p1, Point const& p2) -{ - p_[0] = p1; - p_[1] = p2; -} - -void EdgeShape::FitWorld(World* world) -{ - KGE_ASSERT(world); - - b2Vec2 p1 = world->Stage2World(p_[0]); - b2Vec2 p2 = world->Stage2World(p_[1]); - edge_.Set(p1, p2); -} - -// -// ChainShape -// - -ChainShape::ChainShape() - : Shape(&chain_) - , chain_() - , loop_(false) -{ -} - -ChainShape::ChainShape(Vector const& vertexs, bool loop) - : ChainShape() -{ - Set(vertexs, loop); -} - -void ChainShape::Set(Vector const& vertexs, bool loop) -{ - vertexs_ = vertexs; - loop_ = loop; -} - -void ChainShape::FitWorld(World* world) -{ - KGE_ASSERT(world); - - Vector b2vertexs; - b2vertexs.reserve(vertexs_.size()); - for (const auto& v : vertexs_) - { - b2vertexs.push_back(world->Stage2World(v)); - } - - if (loop_) - { - chain_.CreateLoop(&b2vertexs[0], static_cast(b2vertexs.size())); - } - else - { - chain_.CreateChain(&b2vertexs[0], static_cast(b2vertexs.size())); - } -} - -} // namespace physics -} // namespace kiwano diff --git a/src/kiwano-physics/Shape.h b/src/kiwano-physics/Shape.h deleted file mode 100644 index b6f7e9fa..00000000 --- a/src/kiwano-physics/Shape.h +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (c) 2018-2019 Kiwano - Nomango -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#pragma once -#include - -namespace kiwano -{ -namespace physics -{ -class World; -class Fixture; - -/** - * \addtogroup Physics - * @{ - */ - -/// \~chinese -/// @brief 形状基类 -class KGE_API Shape -{ - friend class Fixture; - -public: - Shape(); - Shape(b2Shape* shape); - - b2Shape* GetB2Shape() const; - void SetB2Shape(b2Shape* shape); - -private: - virtual void FitWorld(World* world) {} - -private: - b2Shape* shape_; -}; - -/// \~chinese -/// @brief 圆形形状 -class KGE_API CircleShape : public Shape -{ -public: - CircleShape(); - - CircleShape(float radius, Point const& offset = Point()); - - void Set(float radius, Point const& offset = Point()); - -private: - void FitWorld(World* world) override; - -private: - float radius_; - Point offset_; - b2CircleShape circle_; -}; - -/// \~chinese -/// @brief 盒子形状 -class KGE_API BoxShape : public Shape -{ -public: - BoxShape(); - - BoxShape(Vec2 const& size, Point const& offset = Point(), float rotation = 0.f); - - void Set(Vec2 const& size, Point const& offset = Point(), float rotation = 0.f); - -private: - void FitWorld(World* world) override; - -private: - float rotation_; - Vec2 box_size_; - Point offset_; - b2PolygonShape polygon_; -}; - -/// \~chinese -/// @brief 多边形形状 -class KGE_API PolygonShape : public Shape -{ -public: - PolygonShape(); - - PolygonShape(Vector const& vertexs); - - void Set(Vector const& vertexs); - -private: - void FitWorld(World* world) override; - -private: - Vector vertexs_; - b2PolygonShape polygon_; -}; - -/// \~chinese -/// @brief 线段形状, 用于表示一条边 -class KGE_API EdgeShape : public Shape -{ -public: - EdgeShape(); - - EdgeShape(Point const& p1, Point const& p2); - - void Set(Point const& p1, Point const& p2); - -private: - void FitWorld(World* world) override; - -private: - Point p_[2]; - b2EdgeShape edge_; -}; - -/// \~chinese -/// @brief 链式形状 -class KGE_API ChainShape : public Shape -{ -public: - ChainShape(); - - ChainShape(Vector const& vertexs, bool loop = false); - - void Set(Vector const& vertexs, bool loop = false); - -private: - void FitWorld(World* world) override; - -private: - bool loop_; - Vector vertexs_; - b2ChainShape chain_; -}; - -/** @} */ -} // namespace physics -} // namespace kiwano diff --git a/src/kiwano-physics/World.cpp b/src/kiwano-physics/World.cpp index 31b981da..86e828a6 100644 --- a/src/kiwano-physics/World.cpp +++ b/src/kiwano-physics/World.cpp @@ -62,14 +62,20 @@ public: { } - void BeginContact(b2Contact* contact) override + void BeginContact(b2Contact* b2contact) override { + Contact contact; + contact.SetB2Contact(b2contact); + ContactBeginEventPtr evt = new ContactBeginEvent(contact); world_->DispatchEvent(evt.get()); } - void EndContact(b2Contact* contact) override + void EndContact(b2Contact* b2contact) override { + Contact contact; + contact.SetB2Contact(b2contact); + ContactEndEventPtr evt = new ContactEndEvent(contact); world_->DispatchEvent(evt.get()); } @@ -229,7 +235,9 @@ void World::SetGravity(Vec2 gravity) ContactList World::GetContactList() { - return ContactList(Contact(world_.GetContactList())); + Contact contact; + contact.SetB2Contact(world_.GetContactList()); + return ContactList(contact); } void World::Update(Duration dt) diff --git a/src/kiwano-physics/kiwano-physics.h b/src/kiwano-physics/kiwano-physics.h index b10153d3..b0e92e43 100644 --- a/src/kiwano-physics/kiwano-physics.h +++ b/src/kiwano-physics/kiwano-physics.h @@ -25,5 +25,4 @@ #include #include #include -#include #include diff --git a/src/kiwano/2d/Actor.cpp b/src/kiwano/2d/Actor.cpp index 73793a26..141d2fa6 100644 --- a/src/kiwano/2d/Actor.cpp +++ b/src/kiwano/2d/Actor.cpp @@ -27,8 +27,10 @@ namespace kiwano { namespace { + float default_anchor_x = 0.f; float default_anchor_y = 0.f; + } // namespace void Actor::SetDefaultAnchor(float anchor_x, float anchor_y) @@ -37,6 +39,12 @@ void Actor::SetDefaultAnchor(float anchor_x, float anchor_y) default_anchor_y = anchor_y; } +ActorPtr Actor::Create() +{ + ActorPtr ptr = new (std::nothrow) Actor; + return ptr; +} + Actor::Actor() : visible_(true) , visible_in_rt_(true) diff --git a/src/kiwano/2d/Actor.h b/src/kiwano/2d/Actor.h index f8fa0f2a..1892183c 100644 --- a/src/kiwano/2d/Actor.h +++ b/src/kiwano/2d/Actor.h @@ -19,13 +19,12 @@ // THE SOFTWARE. #pragma once -#include #include #include #include #include #include -#include +#include namespace kiwano { @@ -71,6 +70,10 @@ public: /// @brief 角色更新回调函数 using UpdateCallback = Function; + /// \~chinese + /// @brief 创建角色 + static ActorPtr Create(); + Actor(); virtual ~Actor(); diff --git a/src/kiwano/2d/Button.cpp b/src/kiwano/2d/Button.cpp index 7206af50..1fb5b324 100644 --- a/src/kiwano/2d/Button.cpp +++ b/src/kiwano/2d/Button.cpp @@ -30,21 +30,6 @@ Button::Button() { } -Button::Button(const Callback& click) - : Button() -{ - this->SetClickCallback(click); -} - -Button::Button(Callback const& click, Callback const& pressed, Callback const& mouse_over, Callback const& mouse_out) - : Button() -{ - this->SetClickCallback(click); - this->SetPressedCallback(pressed); - this->SetMouseOverCallback(mouse_over); - this->SetMouseOutCallback(mouse_out); -} - Button::~Button() {} bool Button::IsEnable() const @@ -157,18 +142,6 @@ void Button::UpdateStatus(Event* evt) } SpriteButton::SpriteButton() - : SpriteButton(nullptr, nullptr, nullptr, nullptr) -{ -} - -SpriteButton::SpriteButton(Callback const& click) - : SpriteButton(click, nullptr, nullptr, nullptr) -{ -} - -SpriteButton::SpriteButton(Callback const& click, Callback const& pressed, Callback const& mouse_over, - Callback const& mouse_out) - : Button(click, pressed, mouse_over, mouse_out) { SetResponsible(true); @@ -180,19 +153,31 @@ SpriteButton::SpriteButton(Callback const& click, Callback const& pressed, Callb AddListener(handler); } +SpriteButtonPtr SpriteButton::Create(Callback const& click) +{ + SpriteButtonPtr ptr = new (std::nothrow) SpriteButton; + if (ptr) + { + ptr->SetClickCallback(click); + } + return ptr; +} + +SpriteButtonPtr SpriteButton::Create(Callback const& click, Callback const& pressed, Callback const& mouse_over, + Callback const& mouse_out) +{ + SpriteButtonPtr ptr = new (std::nothrow) SpriteButton; + if (ptr) + { + ptr->SetClickCallback(click); + ptr->SetPressedCallback(pressed); + ptr->SetMouseOverCallback(mouse_over); + ptr->SetMouseOutCallback(mouse_out); + } + return ptr; +} + TextButton::TextButton() - : TextButton(nullptr, nullptr, nullptr, nullptr) -{ -} - -TextButton::TextButton(Callback const& click) - : TextButton(click, nullptr, nullptr, nullptr) -{ -} - -TextButton::TextButton(Callback const& click, Callback const& pressed, Callback const& mouse_over, - Callback const& mouse_out) - : Button(click, pressed, mouse_over, mouse_out) { SetResponsible(true); @@ -204,4 +189,28 @@ TextButton::TextButton(Callback const& click, Callback const& pressed, Callback AddListener(handler); } +TextButtonPtr TextButton::Create(Callback const& click) +{ + TextButtonPtr ptr = new (std::nothrow) TextButton; + if (ptr) + { + ptr->SetClickCallback(click); + } + return ptr; +} + +TextButtonPtr TextButton::Create(Callback const& click, Callback const& pressed, Callback const& mouse_over, + Callback const& mouse_out) +{ + TextButtonPtr ptr = new (std::nothrow) TextButton; + if (ptr) + { + ptr->SetClickCallback(click); + ptr->SetPressedCallback(pressed); + ptr->SetMouseOverCallback(mouse_over); + ptr->SetMouseOutCallback(mouse_out); + } + return ptr; +} + } // namespace kiwano diff --git a/src/kiwano/2d/Button.h b/src/kiwano/2d/Button.h index 5947afe8..68fa60b9 100644 --- a/src/kiwano/2d/Button.h +++ b/src/kiwano/2d/Button.h @@ -41,19 +41,6 @@ public: Button(); - /// \~chinese - /// @brief 构造按钮 - /// @param click 按钮点击回调函数 - explicit Button(Callback const& click); - - /// \~chinese - /// @brief 构造按钮 - /// @param click 按钮点击回调函数 - /// @param pressed 按钮按下回调函数 - /// @param mouse_over 按钮移入回调函数 - /// @param mouse_out 按钮移出回调函数 - Button(Callback const& click, Callback const& pressed, Callback const& mouse_over, Callback const& mouse_out); - virtual ~Button(); /// \~chinese @@ -126,17 +113,18 @@ public: SpriteButton(); /// \~chinese - /// @brief 构造精灵按钮 + /// @brief 创建精灵按钮 /// @param click 按钮点击回调函数 - explicit SpriteButton(Callback const& click); + static SpriteButtonPtr Create(Callback const& click); /// \~chinese - /// @brief 构造精灵按钮 + /// @brief 创建精灵按钮 /// @param click 按钮点击回调函数 /// @param pressed 按钮按下回调函数 /// @param mouse_over 按钮移入回调函数 /// @param mouse_out 按钮移出回调函数 - SpriteButton(Callback const& click, Callback const& pressed, Callback const& mouse_over, Callback const& mouse_out); + static SpriteButtonPtr Create(Callback const& click, Callback const& pressed, Callback const& mouse_over, + Callback const& mouse_out); }; /// \~chinese @@ -149,16 +137,16 @@ public: TextButton(); /// \~chinese - /// @brief 构造文字按钮 + /// @brief 创建文字按钮 /// @param click 按钮点击回调函数 - explicit TextButton(Callback const& click); + static TextButtonPtr Create(Callback const& click); /// \~chinese - /// @brief 构造文字按钮 + /// @brief 创建文字按钮 /// @param click 按钮点击回调函数 /// @param pressed 按钮按下回调函数 /// @param mouse_over 按钮移入回调函数 /// @param mouse_out 按钮移出回调函数 - TextButton(Callback const& click, Callback const& pressed, Callback const& mouse_over, Callback const& mouse_out); + static TextButtonPtr Create(Callback const& click, Callback const& pressed, Callback const& mouse_over, Callback const& mouse_out); }; } // namespace kiwano diff --git a/src/kiwano/2d/Canvas.cpp b/src/kiwano/2d/Canvas.cpp index 23693168..1905fece 100644 --- a/src/kiwano/2d/Canvas.cpp +++ b/src/kiwano/2d/Canvas.cpp @@ -24,6 +24,13 @@ namespace kiwano { + +CanvasPtr Canvas::Create() +{ + CanvasPtr ptr = new (std::nothrow) Canvas; + return ptr; +} + Canvas::Canvas() : cache_expired_(false) , stroke_width_(1.0f) diff --git a/src/kiwano/2d/Canvas.h b/src/kiwano/2d/Canvas.h index 9bafaa47..900aa6d3 100644 --- a/src/kiwano/2d/Canvas.h +++ b/src/kiwano/2d/Canvas.h @@ -25,6 +25,7 @@ namespace kiwano { + KGE_DECLARE_SMART_PTR(Canvas); /** @@ -39,6 +40,10 @@ KGE_DECLARE_SMART_PTR(Canvas); class KGE_API Canvas : public Actor { public: + /// \~chinese + /// @brief 创建画布 + static CanvasPtr Create(); + /// \~chinese /// @brief 构建空画布 Canvas(); @@ -215,7 +220,7 @@ public: /// \~chinese /// @brief 设置轮廓样式 /// @param stroke_style 轮廓样式 - void SetStrokeStyle(const StrokeStyle& stroke_style); + void SetStrokeStyle(StrokeStylePtr stroke_style); /// \~chinese /// @brief 设置文字画刷样式 @@ -279,12 +284,12 @@ private: void UpdateCache() const; private: - float stroke_width_; - TextStyle text_style_; - StrokeStyle stroke_style_; - ShapeSink shape_sink_; - BrushPtr fill_brush_; - BrushPtr stroke_brush_; + float stroke_width_; + TextStyle text_style_; + StrokeStylePtr stroke_style_; + ShapeSink shape_sink_; + BrushPtr fill_brush_; + BrushPtr stroke_brush_; mutable bool cache_expired_; mutable TexturePtr texture_cached_; @@ -298,7 +303,7 @@ inline void Canvas::SetStrokeWidth(float width) stroke_width_ = std::max(width, 0.f); } -inline void Canvas::SetStrokeStyle(const StrokeStyle& stroke_style) +inline void Canvas::SetStrokeStyle(StrokeStylePtr stroke_style) { stroke_style_ = stroke_style; } diff --git a/src/kiwano/2d/Frame.cpp b/src/kiwano/2d/Frame.cpp index a069d04c..69b98ef3 100644 --- a/src/kiwano/2d/Frame.cpp +++ b/src/kiwano/2d/Frame.cpp @@ -23,6 +23,39 @@ namespace kiwano { + +FramePtr Frame::Create(String const& file_path) +{ + FramePtr ptr = new (std::nothrow) Frame; + if (ptr) + { + if (!ptr->Load(file_path)) + return nullptr; + } + return ptr; +} + +FramePtr Frame::Create(Resource const& res) +{ + FramePtr ptr = new (std::nothrow) Frame; + if (ptr) + { + if (!ptr->Load(res)) + return nullptr; + } + return ptr; +} + +FramePtr Frame::Create(TexturePtr texture) +{ + FramePtr ptr = new (std::nothrow) Frame; + if (ptr) + { + ptr->SetTexture(texture); + } + return ptr; +} + Frame::Frame() {} bool Frame::Load(String const& file_path) diff --git a/src/kiwano/2d/Frame.h b/src/kiwano/2d/Frame.h index 78ca3fc7..3f47cd59 100644 --- a/src/kiwano/2d/Frame.h +++ b/src/kiwano/2d/Frame.h @@ -33,6 +33,21 @@ KGE_DECLARE_SMART_PTR(Frame); class KGE_API Frame : public virtual ObjectBase { public: + /// \~chinese + /// @brief 创建图像帧 + /// @param file_path 图像路径 + static FramePtr Create(String const& file_path); + + /// \~chinese + /// @brief 创建图像帧 + /// @param res 图像资源 + static FramePtr Create(Resource const& res); + + /// \~chinese + /// @brief 创建图像帧 + /// @param texture 纹理 + static FramePtr Create(TexturePtr texture); + /// \~chinese /// @brief 构建空图像帧 Frame(); @@ -94,28 +109,35 @@ inline bool Frame::IsValid() const { return texture_ && texture_->IsValid(); } + inline float Frame::GetWidth() const { return crop_rect_.GetWidth(); } + inline float Frame::GetHeight() const { return crop_rect_.GetHeight(); } + inline Size Frame::GetSize() const { return crop_rect_.GetSize(); } + inline Point Frame::GetCropPoint() const { return crop_rect_.GetLeftTop(); } + inline Rect const& Frame::GetCropRect() const { return crop_rect_; } + inline TexturePtr Frame::GetTexture() const { return texture_; } + } // namespace kiwano diff --git a/src/kiwano/2d/FrameSequence.cpp b/src/kiwano/2d/FrameSequence.cpp index e1ad26ec..48caeb99 100644 --- a/src/kiwano/2d/FrameSequence.cpp +++ b/src/kiwano/2d/FrameSequence.cpp @@ -23,13 +23,19 @@ namespace kiwano { -FrameSequence::FrameSequence() {} -FrameSequence::FrameSequence(Vector const& frames) +FrameSequencePtr FrameSequence::Create(Vector const& frames) { - this->AddFrames(frames); + FrameSequencePtr ptr = new (std::nothrow) FrameSequence; + if (ptr) + { + ptr->AddFrames(frames); + } + return ptr; } +FrameSequence::FrameSequence() {} + FrameSequence::~FrameSequence() {} void FrameSequence::AddFrame(FramePtr frame) diff --git a/src/kiwano/2d/FrameSequence.h b/src/kiwano/2d/FrameSequence.h index 07a90df7..a067a355 100644 --- a/src/kiwano/2d/FrameSequence.h +++ b/src/kiwano/2d/FrameSequence.h @@ -35,13 +35,13 @@ class KGE_API FrameSequence : public virtual ObjectBase { public: /// \~chinese - /// @brief 构建空序列帧 - FrameSequence(); + /// @brief 创建序列帧 + /// @param frames 图像帧集合 + static FrameSequencePtr Create(Vector const& frames); /// \~chinese - /// @brief 构建序列帧 - /// @param frames 图像帧集合 - explicit FrameSequence(Vector const& frames); + /// @brief 构建空序列帧 + FrameSequence(); virtual ~FrameSequence(); diff --git a/src/kiwano/2d/GifSprite.cpp b/src/kiwano/2d/GifSprite.cpp index b2092779..86b2b158 100644 --- a/src/kiwano/2d/GifSprite.cpp +++ b/src/kiwano/2d/GifSprite.cpp @@ -24,6 +24,39 @@ namespace kiwano { + +GifSpritePtr GifSprite::Create(String const& file_path) +{ + GifSpritePtr ptr = new (std::nothrow) GifSprite; + if (ptr) + { + if (!ptr->Load(file_path)) + return nullptr; + } + return ptr; +} + +GifSpritePtr GifSprite::Create(Resource const& res) +{ + GifSpritePtr ptr = new (std::nothrow) GifSprite; + if (ptr) + { + if (!ptr->Load(res)) + return nullptr; + } + return ptr; +} + +GifSpritePtr GifSprite::Create(GifImagePtr gif) +{ + GifSpritePtr ptr = new (std::nothrow) GifSprite; + if (ptr) + { + ptr->SetGifImage(gif); + } + return ptr; +} + GifSprite::GifSprite() : animating_(false) , next_index_(0) diff --git a/src/kiwano/2d/GifSprite.h b/src/kiwano/2d/GifSprite.h index 854a0cf6..7b6de011 100644 --- a/src/kiwano/2d/GifSprite.h +++ b/src/kiwano/2d/GifSprite.h @@ -48,6 +48,21 @@ public: /// @brief GIF播放结束回调 using DoneCallback = Function; + /// \~chinese + /// @brief 创建GIF精灵 + /// @param file_path GIF图片路径 + static GifSpritePtr Create(String const& file_path); + + /// \~chinese + /// @brief 创建GIF精灵 + /// @param res GIF图片资源 + static GifSpritePtr Create(Resource const& res); + + /// \~chinese + /// @brief 创建GIF精灵 + /// @param gif GIF图片 + static GifSpritePtr Create(GifImagePtr gif); + GifSprite(); /// \~chinese diff --git a/src/kiwano/2d/Layer.cpp b/src/kiwano/2d/Layer.cpp index 827da390..f49a6fec 100644 --- a/src/kiwano/2d/Layer.cpp +++ b/src/kiwano/2d/Layer.cpp @@ -24,6 +24,13 @@ namespace kiwano { + +LayerPtr Layer::Create() +{ + LayerPtr ptr = new (std::nothrow) Layer; + return ptr; +} + Layer::Layer() : swallow_(false) { diff --git a/src/kiwano/2d/Layer.h b/src/kiwano/2d/Layer.h index f3bd42e5..95fddb14 100644 --- a/src/kiwano/2d/Layer.h +++ b/src/kiwano/2d/Layer.h @@ -39,6 +39,10 @@ KGE_DECLARE_SMART_PTR(Layer); class KGE_API Layer : public Actor { public: + /// \~chinese + /// @brief 创建图层 + static LayerPtr Create(); + Layer(); virtual ~Layer(); diff --git a/src/kiwano/2d/ShapeActor.cpp b/src/kiwano/2d/ShapeActor.cpp index a69de2fd..34f0074d 100644 --- a/src/kiwano/2d/ShapeActor.cpp +++ b/src/kiwano/2d/ShapeActor.cpp @@ -24,6 +24,11 @@ namespace kiwano { +ShapeActorPtr ShapeActor::Create() +{ + ShapeActorPtr ptr = new (std::nothrow) ShapeActor; + return ptr; +} ShapeActor::ShapeActor() : stroke_width_(1.f) @@ -59,7 +64,7 @@ void ShapeActor::SetStrokeWidth(float width) stroke_width_ = std::max(width, 0.f); } -void ShapeActor::SetStrokeStyle(const StrokeStyle& stroke_style) +void ShapeActor::SetStrokeStyle(StrokeStylePtr stroke_style) { stroke_style_ = stroke_style; } @@ -106,6 +111,16 @@ bool ShapeActor::CheckVisibility(RenderContext& ctx) const // LineActor //------------------------------------------------------- +LineActorPtr LineActor::Create(Point const& begin, Point const& end) +{ + LineActorPtr ptr = new (std::nothrow) LineActor; + if (ptr) + { + ptr->SetLine(begin, end); + } + return ptr; +} + LineActor::LineActor() {} LineActor::~LineActor() {} @@ -124,6 +139,16 @@ void LineActor::SetLine(Point const& begin, Point const& end) // RectActor //------------------------------------------------------- +RectActorPtr RectActor::Create(Size const& size) +{ + RectActorPtr ptr = new (std::nothrow) RectActor; + if (ptr) + { + ptr->SetRectSize(size); + } + return ptr; +} + RectActor::RectActor() {} RectActor::~RectActor() {} @@ -138,24 +163,34 @@ void RectActor::SetRectSize(Size const& size) } //------------------------------------------------------- -// RoundRectActor +// RoundedRectActor //------------------------------------------------------- -RoundRectActor::RoundRectActor() {} +RoundedRectActorPtr RoundedRectActor::Create(Size const& size, Vec2 const& radius) +{ + RoundedRectActorPtr ptr = new (std::nothrow) RoundedRectActor; + if (ptr) + { + ptr->SetRoundedRect(size, radius); + } + return ptr; +} -RoundRectActor::~RoundRectActor() {} +RoundedRectActor::RoundedRectActor() {} -void RoundRectActor::SetRadius(Vec2 const& radius) +RoundedRectActor::~RoundedRectActor() {} + +void RoundedRectActor::SetRadius(Vec2 const& radius) { SetRoundedRect(GetSize(), radius); } -void RoundRectActor::SetRectSize(Size const& size) +void RoundedRectActor::SetRectSize(Size const& size) { SetRoundedRect(size, radius_); } -void RoundRectActor::SetRoundedRect(Size const& size, Vec2 const& radius) +void RoundedRectActor::SetRoundedRect(Size const& size, Vec2 const& radius) { if (rect_size_ != size || radius_ != radius) { @@ -169,6 +204,16 @@ void RoundRectActor::SetRoundedRect(Size const& size, Vec2 const& radius) // CircleActor //------------------------------------------------------- +CircleActorPtr CircleActor::Create(float radius) +{ + CircleActorPtr ptr = new (std::nothrow) CircleActor; + if (ptr) + { + ptr->SetRadius(radius); + } + return ptr; +} + CircleActor::CircleActor() : radius_(0.f) { @@ -189,6 +234,16 @@ void CircleActor::SetRadius(float radius) // EllipseActor //------------------------------------------------------- +EllipseActorPtr EllipseActor::Create(Vec2 const& radius) +{ + EllipseActorPtr ptr = new (std::nothrow) EllipseActor; + if (ptr) + { + ptr->SetRadius(radius); + } + return ptr; +} + EllipseActor::EllipseActor() {} EllipseActor::~EllipseActor() {} @@ -206,6 +261,16 @@ void EllipseActor::SetRadius(Vec2 const& radius) // PolygonActor //------------------------------------------------------- +PolygonActorPtr PolygonActor::Create(Vector const& points) +{ + PolygonActorPtr ptr = new (std::nothrow) PolygonActor; + if (ptr) + { + ptr->SetVertices(points); + } + return ptr; +} + PolygonActor::PolygonActor() {} PolygonActor::~PolygonActor() {} diff --git a/src/kiwano/2d/ShapeActor.h b/src/kiwano/2d/ShapeActor.h index b39076b5..cfe9b3b1 100644 --- a/src/kiwano/2d/ShapeActor.h +++ b/src/kiwano/2d/ShapeActor.h @@ -27,10 +27,11 @@ namespace kiwano { + KGE_DECLARE_SMART_PTR(ShapeActor); KGE_DECLARE_SMART_PTR(LineActor); KGE_DECLARE_SMART_PTR(RectActor); -KGE_DECLARE_SMART_PTR(RoundRectActor); +KGE_DECLARE_SMART_PTR(RoundedRectActor); KGE_DECLARE_SMART_PTR(CircleActor); KGE_DECLARE_SMART_PTR(EllipseActor); KGE_DECLARE_SMART_PTR(PolygonActor); @@ -42,13 +43,17 @@ KGE_DECLARE_SMART_PTR(PolygonActor); /** * \~chinese - * @brief 二维形状角色 + * @brief 形状角色 */ class KGE_API ShapeActor : public Actor { public: /// \~chinese - /// @brief 构造二维形状角色 + /// @brief 创建形状角色 + static ShapeActorPtr Create(); + + /// \~chinese + /// @brief 构造形状角色 ShapeActor(); virtual ~ShapeActor(); @@ -67,7 +72,7 @@ public: /// \~chinese /// @brief 获取线条样式 - const StrokeStyle& GetStrokeStyle() const; + StrokeStylePtr GetStrokeStyle() const; /// \~chinese /// @brief 获取形状 @@ -111,7 +116,7 @@ public: /// \~chinese /// @brief 设置线条样式 - void SetStrokeStyle(const StrokeStyle& stroke_style); + void SetStrokeStyle(StrokeStylePtr stroke_style); /// \~chinese /// @brief 设置形状 @@ -123,19 +128,25 @@ protected: bool CheckVisibility(RenderContext& ctx) const override; private: - BrushPtr fill_brush_; - BrushPtr stroke_brush_; - float stroke_width_; - StrokeStyle stroke_style_; - Rect bounds_; - ShapePtr shape_; + BrushPtr fill_brush_; + BrushPtr stroke_brush_; + float stroke_width_; + StrokeStylePtr stroke_style_; + Rect bounds_; + ShapePtr shape_; }; /// \~chinese -/// @brief 线段图形角色 +/// @brief 线段角色 class KGE_API LineActor : public ShapeActor { public: + /// \~chinese + /// @brief 创建线段角色 + /// @param begin 线段起点 + /// @param end 线段终点 + static LineActorPtr Create(Point const& begin, Point const& end); + LineActor(); virtual ~LineActor(); @@ -159,7 +170,7 @@ public: void SetEndPoint(Point const& end); /// \~chinese - /// @brief 设置矩形大小 + /// @brief 设置线段起点和终点 /// @param begin 线段起点 /// @param end 线段终点 void SetLine(Point const& begin, Point const& end); @@ -174,6 +185,11 @@ private: class KGE_API RectActor : public ShapeActor { public: + /// \~chinese + /// @brief 创建矩形角色 + /// @param size 矩形大小 + static RectActorPtr Create(Size const& size); + RectActor(); virtual ~RectActor(); @@ -193,12 +209,18 @@ private: /// \~chinese /// @brief 圆角矩形角色 -class KGE_API RoundRectActor : public ShapeActor +class KGE_API RoundedRectActor : public ShapeActor { public: - RoundRectActor(); + /// \~chinese + /// @brief 创建圆角矩形角色 + /// @param size 圆角矩形大小 + /// @param radius 圆角半径 + static RoundedRectActorPtr Create(Size const& size, Vec2 const& radius); - virtual ~RoundRectActor(); + RoundedRectActor(); + + virtual ~RoundedRectActor(); /// \~chinese /// @brief 获取圆角半径 @@ -234,6 +256,11 @@ private: class KGE_API CircleActor : public ShapeActor { public: + /// \~chinese + /// @brief 创建圆形角色 + /// @param radius 圆形半径 + static CircleActorPtr Create(float radius); + CircleActor(); virtual ~CircleActor(); @@ -256,6 +283,11 @@ private: class KGE_API EllipseActor : public ShapeActor { public: + /// \~chinese + /// @brief 创建椭圆角色 + /// @param radius 椭圆半径 + static EllipseActorPtr Create(Vec2 const& radius); + EllipseActor(); virtual ~EllipseActor(); @@ -278,6 +310,11 @@ private: class KGE_API PolygonActor : public ShapeActor { public: + /// \~chinese + /// @brief 创建多边形角色 + /// @param points 多边形端点集合 + static PolygonActorPtr Create(Vector const& points); + PolygonActor(); virtual ~PolygonActor(); @@ -329,7 +366,7 @@ inline float ShapeActor::GetStrokeWidth() const { return stroke_width_; } -inline const StrokeStyle& ShapeActor::GetStrokeStyle() const +inline StrokeStylePtr ShapeActor::GetStrokeStyle() const { return stroke_style_; } @@ -360,11 +397,11 @@ inline Size const& RectActor::GetRectSize() const return rect_size_; } -inline Vec2 RoundRectActor::GetRadius() const +inline Vec2 RoundedRectActor::GetRadius() const { return radius_; } -inline Size RoundRectActor::GetRectSize() const +inline Size RoundedRectActor::GetRectSize() const { return GetSize(); } diff --git a/src/kiwano/2d/Sprite.cpp b/src/kiwano/2d/Sprite.cpp index fac7e224..b6080fb9 100644 --- a/src/kiwano/2d/Sprite.cpp +++ b/src/kiwano/2d/Sprite.cpp @@ -23,6 +23,39 @@ namespace kiwano { + +SpritePtr Sprite::Create(String const& file_path) +{ + SpritePtr ptr = new (std::nothrow) Sprite; + if (ptr) + { + if (!ptr->Load(file_path)) + return nullptr; + } + return ptr; +} + +SpritePtr Sprite::Create(Resource const& res) +{ + SpritePtr ptr = new (std::nothrow) Sprite; + if (ptr) + { + if (!ptr->Load(res)) + return nullptr; + } + return ptr; +} + +SpritePtr Sprite::Create(FramePtr frame) +{ + SpritePtr ptr = new (std::nothrow) Sprite; + if (ptr) + { + ptr->SetFrame(frame); + } + return ptr; +} + Sprite::Sprite() {} Sprite::~Sprite() {} diff --git a/src/kiwano/2d/Sprite.h b/src/kiwano/2d/Sprite.h index bb49260c..ec006057 100644 --- a/src/kiwano/2d/Sprite.h +++ b/src/kiwano/2d/Sprite.h @@ -38,6 +38,21 @@ KGE_DECLARE_SMART_PTR(Sprite); class KGE_API Sprite : public Actor { public: + /// \~chinese + /// @brief 创建精灵 + /// @param file_path 本地图片路径 + static SpritePtr Create(String const& file_path); + + /// \~chinese + /// @brief 创建精灵 + /// @param res 图片资源 + static SpritePtr Create(Resource const& res); + + /// \~chinese + /// @brief 创建精灵 + /// @param frame 图像帧 + static SpritePtr Create(FramePtr frame); + Sprite(); virtual ~Sprite(); diff --git a/src/kiwano/2d/Stage.cpp b/src/kiwano/2d/Stage.cpp index e9711c2f..a0292ac5 100644 --- a/src/kiwano/2d/Stage.cpp +++ b/src/kiwano/2d/Stage.cpp @@ -24,6 +24,13 @@ namespace kiwano { + +StagePtr Stage::Create() +{ + StagePtr ptr = new (std::nothrow) Stage; + return ptr; +} + Stage::Stage() { SetStage(this); diff --git a/src/kiwano/2d/Stage.h b/src/kiwano/2d/Stage.h index e0a3dbef..4f92704e 100644 --- a/src/kiwano/2d/Stage.h +++ b/src/kiwano/2d/Stage.h @@ -43,6 +43,10 @@ class KGE_API Stage : public Actor friend class Director; public: + /// \~chinese + /// @brief 进入舞台时 + static StagePtr Create(); + Stage(); virtual ~Stage(); diff --git a/src/kiwano/2d/TextActor.cpp b/src/kiwano/2d/TextActor.cpp index 5866d1b5..28be3a67 100644 --- a/src/kiwano/2d/TextActor.cpp +++ b/src/kiwano/2d/TextActor.cpp @@ -25,22 +25,31 @@ namespace kiwano { +TextActorPtr TextActor::Create(const String& text) +{ + TextActorPtr ptr = new (std::nothrow) TextActor; + if (ptr) + { + ptr->SetText(text); + } + return ptr; +} + +TextActorPtr TextActor::Create(const String& text, const TextStyle& style) +{ + TextActorPtr ptr = new (std::nothrow) TextActor; + if (ptr) + { + ptr->SetText(text); + ptr->SetStyle(style); + } + return ptr; +} + TextActor::TextActor() - : TextActor(String()) -{ -} - -TextActor::TextActor(String const& text) - : TextActor(text, TextStyle()) -{ -} - -TextActor::TextActor(String const& text, const TextStyle& style) : show_underline_(false) , show_strikethrough_(false) { - SetText(text); - SetStyle(style); } TextActor::~TextActor() {} diff --git a/src/kiwano/2d/TextActor.h b/src/kiwano/2d/TextActor.h index d6f8f64a..21f36eee 100644 --- a/src/kiwano/2d/TextActor.h +++ b/src/kiwano/2d/TextActor.h @@ -40,19 +40,17 @@ class KGE_API TextActor : public Actor { public: /// \~chinese - /// @brief 构建空的文本角色 - TextActor(); - - /// \~chinese - /// @brief 构建文本角色 + /// @brief 创建文本角色 /// @param text 文字内容 - explicit TextActor(const String& text); + static TextActorPtr Create(const String& text); /// \~chinese - /// @brief 构建文本角色 + /// @brief 创建文本角色 /// @param text 文字内容 /// @param style 文本样式 - TextActor(const String& text, const TextStyle& style); + static TextActorPtr Create(const String& text, const TextStyle& style); + + TextActor(); virtual ~TextActor(); @@ -146,7 +144,7 @@ public: /// \~chinese /// @brief 设置文字描边线相交样式 - void SetOutlineStroke(const StrokeStyle& outline_stroke); + void SetOutlineStroke(StrokeStylePtr outline_stroke); /// \~chinese /// @brief 设置是否显示下划线(默认值为 false) @@ -286,7 +284,7 @@ inline void TextActor::SetOutlineWidth(float outline_width) text_layout_.SetOutlineWidth(outline_width); } -inline void TextActor::SetOutlineStroke(const StrokeStyle& outline_stroke) +inline void TextActor::SetOutlineStroke(StrokeStylePtr outline_stroke) { text_layout_.SetOutlineStroke(outline_stroke); } diff --git a/src/kiwano/2d/Transform.h b/src/kiwano/2d/Transform.h deleted file mode 100644 index b2f96b9c..00000000 --- a/src/kiwano/2d/Transform.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2016-2018 Kiwano - Nomango -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#pragma once -#include - -namespace kiwano -{ -/** - * \~chinese - * @brief 二维放射变换 - */ -class Transform -{ -public: - float rotation; ///< 旋转 - Point position; ///< 坐标 - Point scale; ///< 缩放 - Point skew; ///< 错切角度 - -public: - Transform(); - - /// \~chinese - /// @brief 将二维放射变换转换为矩阵 - Matrix3x2 ToMatrix() const; - - bool operator==(const Transform& rhs) const; -}; -} // namespace kiwano diff --git a/src/kiwano/2d/Transition.cpp b/src/kiwano/2d/Transition.cpp index 2d2f6e34..bec5700c 100644 --- a/src/kiwano/2d/Transition.cpp +++ b/src/kiwano/2d/Transition.cpp @@ -31,9 +31,9 @@ namespace kiwano // Transition //------------------------------------------------------- -Transition::Transition(Duration duration) +Transition::Transition() : done_(false) - , duration_(duration) + , duration_() , delta_() , process_(0) , window_size_() @@ -126,11 +126,18 @@ void Transition::Stop() // BoxTransition //------------------------------------------------------- -BoxTransition::BoxTransition(Duration duration) - : Transition(duration) +BoxTransitionPtr BoxTransition::Create(Duration duration) { + BoxTransitionPtr ptr = new (std::nothrow) BoxTransition; + if (ptr) + { + ptr->SetDuration(duration); + } + return ptr; } +BoxTransition::BoxTransition() {} + void BoxTransition::Init(StagePtr prev, StagePtr next) { Transition::Init(prev, next); @@ -160,11 +167,18 @@ void BoxTransition::Update(Duration dt) // EmergeTransition //------------------------------------------------------- -EmergeTransition::EmergeTransition(Duration duration) - : Transition(duration) +EmergeTransitionPtr EmergeTransition::Create(Duration duration) { + EmergeTransitionPtr ptr = new (std::nothrow) EmergeTransition; + if (ptr) + { + ptr->SetDuration(duration); + } + return ptr; } +EmergeTransition::EmergeTransition() {} + void EmergeTransition::Init(StagePtr prev, StagePtr next) { Transition::Init(prev, next); @@ -185,11 +199,18 @@ void EmergeTransition::Update(Duration dt) // FadeTransition //------------------------------------------------------- -FadeTransition::FadeTransition(Duration duration) - : Transition(duration) +FadeTransitionPtr FadeTransition::Create(Duration duration) { + FadeTransitionPtr ptr = new (std::nothrow) FadeTransition; + if (ptr) + { + ptr->SetDuration(duration); + } + return ptr; } +FadeTransition::FadeTransition() {} + void FadeTransition::Init(StagePtr prev, StagePtr next) { Transition::Init(prev, next); @@ -218,9 +239,19 @@ void FadeTransition::Update(Duration dt) // MoveTransition //------------------------------------------------------- -MoveTransition::MoveTransition(Duration duration, Type type) - : Transition(duration) - , type_(type) +MoveTransitionPtr MoveTransition::Create(Duration duration, Type type) +{ + MoveTransitionPtr ptr = new (std::nothrow) MoveTransition; + if (ptr) + { + ptr->type_ = type; + ptr->SetDuration(duration); + } + return ptr; +} + +MoveTransition::MoveTransition() + : type_(Type::Left) { } @@ -297,9 +328,19 @@ void MoveTransition::Reset() // RotationTransition //------------------------------------------------------- -RotationTransition::RotationTransition(Duration duration, float rotation) - : Transition(duration) - , rotation_(rotation) +RotationTransitionPtr RotationTransition::Create(Duration duration, float rotation) +{ + RotationTransitionPtr ptr = new (std::nothrow) RotationTransition; + if (ptr) + { + ptr->rotation_ = rotation; + ptr->SetDuration(duration); + } + return ptr; +} + +RotationTransition::RotationTransition() + : rotation_(0.0f) { } diff --git a/src/kiwano/2d/Transition.h b/src/kiwano/2d/Transition.h index 088de4c9..d99a18d6 100644 --- a/src/kiwano/2d/Transition.h +++ b/src/kiwano/2d/Transition.h @@ -43,15 +43,16 @@ class KGE_API Transition : public virtual ObjectBase friend class Director; public: - /** - * \~chinese - * @brief 构建空的场景过渡动画 - * @param duration 动画时长 - */ - explicit Transition(Duration duration); + Transition(); virtual ~Transition(); + /** + * \~chinese + * @brief 设置动画时长 + */ + void SetDuration(Duration dt); + /** * \~chinese * @brief 场景过渡动画是否已结束 @@ -115,10 +116,12 @@ class FadeTransition : public Transition public: /** * \~chinese - * @brief 构建淡入淡出过渡动画 + * @brief 创建淡入淡出过渡动画 * @param duration 动画时长 */ - explicit FadeTransition(Duration duration); + static FadeTransitionPtr Create(Duration duration); + + FadeTransition(); protected: void Update(Duration dt) override; @@ -136,10 +139,12 @@ class EmergeTransition : public Transition public: /** * \~chinese - * @brief 构建渐变过渡动画 + * @brief 创建渐变过渡动画 * @param duration 动画时长 */ - explicit EmergeTransition(Duration duration); + static EmergeTransitionPtr Create(Duration duration); + + EmergeTransition(); protected: void Update(Duration dt) override; @@ -157,10 +162,12 @@ class BoxTransition : public Transition public: /** * \~chinese - * @brief 构建盒状过渡动画 + * @brief 创建盒状过渡动画 * @param duration 动画时长 */ - explicit BoxTransition(Duration duration); + static BoxTransitionPtr Create(Duration duration); + + BoxTransition(); protected: void Update(Duration dt) override; @@ -190,11 +197,13 @@ public: /** * \~chinese - * @brief 位移过渡动画 + * @brief 创建位移过渡动画 * @param duration 动画时长 * @param type 位移方式 */ - explicit MoveTransition(Duration duration, Type type); + static MoveTransitionPtr Create(Duration duration, Type type); + + MoveTransition(); protected: void Update(Duration dt) override; @@ -219,11 +228,13 @@ class RotationTransition : public Transition public: /** * \~chinese - * @brief 构建旋转过渡动画 + * @brief 创建旋转过渡动画 * @param duration 动画时长 * @param rotation 旋转度数 */ - explicit RotationTransition(Duration duration, float rotation = 360); + static RotationTransitionPtr Create(Duration duration, float rotation = 360.0f); + + RotationTransition(); protected: void Update(Duration dt) override; @@ -235,4 +246,11 @@ protected: private: float rotation_; }; + + +inline void Transition::SetDuration(Duration dt) +{ + duration_ = dt; +} + } // namespace kiwano diff --git a/src/kiwano/2d/action/Action.h b/src/kiwano/2d/action/Action.h index 2660bbe1..639f4cb0 100644 --- a/src/kiwano/2d/action/Action.h +++ b/src/kiwano/2d/action/Action.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include namespace kiwano { diff --git a/src/kiwano/core/AsyncTask.cpp b/src/kiwano/core/AsyncTask.cpp index 6747066d..cd0fc277 100644 --- a/src/kiwano/core/AsyncTask.cpp +++ b/src/kiwano/core/AsyncTask.cpp @@ -23,17 +23,22 @@ namespace kiwano { + +AsyncTaskPtr AsyncTask::Create(AsyncTaskFunc func) +{ + AsyncTaskPtr ptr = new (std::nothrow) AsyncTask; + if (ptr) + { + ptr->Then(func); + } + return ptr; +} + AsyncTask::AsyncTask() : thread_(Closure(this, &AsyncTask::TaskThread)) { } -AsyncTask::AsyncTask(AsyncTaskFunc func) - : AsyncTask() -{ - Then(func); -} - AsyncTask::~AsyncTask() {} void AsyncTask::Start() diff --git a/src/kiwano/core/AsyncTask.h b/src/kiwano/core/AsyncTask.h index f5e3185e..3fb9fb70 100644 --- a/src/kiwano/core/AsyncTask.h +++ b/src/kiwano/core/AsyncTask.h @@ -42,13 +42,13 @@ class AsyncTask : public virtual ObjectBase { public: /// \~chinese - /// @brief 构造异步任务 - AsyncTask(); + /// @brief 创建异步任务 + /// @param func 异步回调函数 + static AsyncTaskPtr Create(AsyncTaskFunc func); /// \~chinese /// @brief 构造异步任务 - /// @param func 异步回调函数 - AsyncTask(AsyncTaskFunc func); + AsyncTask(); virtual ~AsyncTask(); diff --git a/src/kiwano/core/EventDispatcher.cpp b/src/kiwano/core/EventDispatcher.cpp index b6063108..01214939 100644 --- a/src/kiwano/core/EventDispatcher.cpp +++ b/src/kiwano/core/EventDispatcher.cpp @@ -63,13 +63,13 @@ EventListener* EventDispatcher::AddListener(EventListener* listener) EventListener* EventDispatcher::AddListener(String const& name, EventType type, EventListener::Callback callback) { - EventListenerPtr listener = new EventListener(name, type, callback); + EventListenerPtr listener = EventListener::Create(name, type, callback); return AddListener(listener); } EventListener* EventDispatcher::AddListener(EventType type, EventListener::Callback callback) { - EventListenerPtr listener = new EventListener(type, callback); + EventListenerPtr listener = EventListener::Create(type, callback); return AddListener(listener); } diff --git a/src/kiwano/core/EventListener.cpp b/src/kiwano/core/EventListener.cpp index b240585e..ce398d31 100644 --- a/src/kiwano/core/EventListener.cpp +++ b/src/kiwano/core/EventListener.cpp @@ -23,6 +23,30 @@ namespace kiwano { + +EventListenerPtr EventListener::Create(EventType type, Callback const& callback) +{ + EventListenerPtr ptr = new (std::nothrow) EventListener; + if (ptr) + { + ptr->SetEventType(type); + ptr->SetCallback(callback); + } + return ptr; +} + +EventListenerPtr EventListener::Create(String const& name, EventType type, Callback const& callback) +{ + EventListenerPtr ptr = new (std::nothrow) EventListener; + if (ptr) + { + ptr->SetName(name); + ptr->SetEventType(type); + ptr->SetCallback(callback); + } + return ptr; +} + EventListener::EventListener() : type_() , callback_() @@ -32,19 +56,6 @@ EventListener::EventListener() { } -EventListener::EventListener(EventType type, Callback const& callback) - : EventListener(String(), type, callback) -{ -} - -EventListener::EventListener(String const& name, EventType type, Callback const& callback) - : EventListener() -{ - SetName(name); - SetEventType(type); - SetCallback(callback); -} - EventListener::~EventListener() {} } // namespace kiwano diff --git a/src/kiwano/core/EventListener.h b/src/kiwano/core/EventListener.h index 40db2996..ea50fa0c 100644 --- a/src/kiwano/core/EventListener.h +++ b/src/kiwano/core/EventListener.h @@ -50,43 +50,41 @@ public: using Callback = Function; /// \~chinese - /// @brief 构造空监听器 + /// @brief 创建监听器 + /// @param type 监听的事件类型 + /// @param callback 回调函数 + static EventListenerPtr Create(EventType type, Callback const& callback); + + /// \~chinese + /// @brief 创建监听器 + /// @param name 监听器名称 + /// @param type 监听的事件类型 + /// @param callback 回调函数 + static EventListenerPtr Create(String const& name, EventType type, Callback const& callback); + + /// \~chinese + /// @brief 创建监听器 + /// @tparam _EventTy 事件类型 + /// @param callback 回调函数 + template ::value, int>::type> + static inline EventListenerPtr Create(Callback const& callback) + { + return EventListener::Create(KGE_EVENT(_EventTy), callback); + } + + /// \~chinese + /// @brief 创建监听器 + /// @tparam _EventTy 事件类型 + /// @param name 监听器名称 + /// @param callback 回调函数 + template ::value, int>::type> + static inline EventListenerPtr Create(String const& name, Callback const& callback) + { + return EventListener::Create(name, KGE_EVENT(_EventTy), callback); + } + EventListener(); - /// \~chinese - /// @brief 构造监听器 - /// @param type 监听的事件类型 - /// @param callback 回调函数 - EventListener(EventType type, Callback const& callback); - - /// \~chinese - /// @brief 构造监听器 - /// @param name 监听器名称 - /// @param type 监听的事件类型 - /// @param callback 回调函数 - EventListener(String const& name, EventType type, Callback const& callback); - - /// \~chinese - /// @brief 构造监听器 - /// @tparam _EventTy 事件类型 - /// @param callback 回调函数 - template ::value, int>::type> - inline EventListener(Callback const& callback) - : EventListener(KGE_EVENT(_EventTy), callback) - { - } - - /// \~chinese - /// @brief 构造监听器 - /// @tparam _EventTy 事件类型 - /// @param name 监听器名称 - /// @param callback 回调函数 - template ::value, int>::type> - inline EventListener(String const& name, Callback const& callback) - : EventListener(name, KGE_EVENT(_EventTy), callback) - { - } - virtual ~EventListener(); /// \~chinese diff --git a/src/kiwano/core/Timer.cpp b/src/kiwano/core/Timer.cpp index d173b703..727d458f 100644 --- a/src/kiwano/core/Timer.cpp +++ b/src/kiwano/core/Timer.cpp @@ -23,6 +23,31 @@ namespace kiwano { +TimerPtr Timer::Create(Callback const& cb, Duration interval, int times) +{ + TimerPtr ptr = new (std::nothrow) Timer; + if (ptr) + { + ptr->SetCallback(cb); + ptr->SetInterval(interval); + ptr->SetTotalRunTimes(times); + } + return ptr; +} + +TimerPtr Timer::Create(String const& name, Callback const& cb, Duration interval, int times) +{ + TimerPtr ptr = new (std::nothrow) Timer; + if (ptr) + { + ptr->SetName(name); + ptr->SetCallback(cb); + ptr->SetInterval(interval); + ptr->SetTotalRunTimes(times); + } + return ptr; +} + Timer::Timer() : running_(true) , removeable_(false) @@ -34,20 +59,6 @@ Timer::Timer() { } -Timer::Timer(Callback const& cb, Duration interval, int times) - : Timer(String(), cb, interval, times) -{ -} - -Timer::Timer(String const& name, Callback const& cb, Duration interval, int times) - : Timer() -{ - SetName(name); - SetCallback(cb); - SetInterval(interval); - SetTotalRunTimes(times); -} - void Timer::Update(Duration dt) { if (total_times_ == 0) diff --git a/src/kiwano/core/Timer.h b/src/kiwano/core/Timer.h index 76378cfc..29f25d53 100644 --- a/src/kiwano/core/Timer.h +++ b/src/kiwano/core/Timer.h @@ -46,23 +46,23 @@ public: using Callback = Function; /// \~chinese - /// @brief 构造空定时器 - Timer(); - - /// \~chinese - /// @brief 构造定时器 + /// @brief 创建定时器 /// @param cb 回调函数 /// @param interval 时间间隔 /// @param times 执行次数(设 -1 为永久执行) - Timer(Callback const& cb, Duration interval, int times = -1); + static TimerPtr Create(Callback const& cb, Duration interval, int times = -1); /// \~chinese - /// @brief 构造定时器 + /// @brief 创建定时器 /// @param name 名称 /// @param cb 回调函数 /// @param interval 时间间隔 /// @param times 执行次数(设 -1 为永久执行) - Timer(String const& name, Callback const& cb, Duration interval, int times = -1); + static TimerPtr Create(String const& name, Callback const& cb, Duration interval, int times = -1); + + /// \~chinese + /// @brief 构造空定时器 + Timer(); /// \~chinese /// @brief 启动定时器 diff --git a/src/kiwano/core/TimerManager.cpp b/src/kiwano/core/TimerManager.cpp index fe316b53..098474ba 100644 --- a/src/kiwano/core/TimerManager.cpp +++ b/src/kiwano/core/TimerManager.cpp @@ -47,7 +47,7 @@ Timer* TimerManager::AddTimer(Timer::Callback const& cb, Duration interval, int Timer* TimerManager::AddTimer(String const& name, Timer::Callback const& cb, Duration interval, int times) { - TimerPtr timer = new Timer(name, cb, interval, times); + TimerPtr timer = Timer::Create(name, cb, interval, times); return AddTimer(timer); } diff --git a/src/kiwano/core/event/Event.h b/src/kiwano/core/event/Event.h index de6df3a3..496c5707 100644 --- a/src/kiwano/core/event/Event.h +++ b/src/kiwano/core/event/Event.h @@ -21,7 +21,7 @@ #pragma once #include #include -#include +#include namespace kiwano { diff --git a/src/kiwano/core/event/MouseEvent.h b/src/kiwano/core/event/MouseEvent.h index 899654d6..ebdcafbc 100644 --- a/src/kiwano/core/event/MouseEvent.h +++ b/src/kiwano/core/event/MouseEvent.h @@ -21,7 +21,7 @@ #pragma once #include #include -#include +#include namespace kiwano { diff --git a/src/kiwano/kiwano.h b/src/kiwano/kiwano.h index 75c80195..af1bf455 100644 --- a/src/kiwano/kiwano.h +++ b/src/kiwano/kiwano.h @@ -30,12 +30,14 @@ // math // -#include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include // // core @@ -89,7 +91,6 @@ #include #include #include -#include #include #include #include diff --git a/src/kiwano/math/constants.h b/src/kiwano/math/Constants.h similarity index 100% rename from src/kiwano/math/constants.h rename to src/kiwano/math/Constants.h diff --git a/src/kiwano/math/ease.h b/src/kiwano/math/EaseFunctions.h similarity index 99% rename from src/kiwano/math/ease.h rename to src/kiwano/math/EaseFunctions.h index 8bed2008..4793c3e9 100644 --- a/src/kiwano/math/ease.h +++ b/src/kiwano/math/EaseFunctions.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include +#include namespace kiwano { diff --git a/src/kiwano/math/math.h b/src/kiwano/math/Math.h similarity index 88% rename from src/kiwano/math/math.h rename to src/kiwano/math/Math.h index dfee1f3b..e44c9337 100644 --- a/src/kiwano/math/math.h +++ b/src/kiwano/math/Math.h @@ -20,12 +20,13 @@ #pragma once #include -#include -#include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include namespace kiwano { @@ -33,6 +34,7 @@ namespace kiwano using Vec2 = kiwano::math::Vec2T; using Rect = kiwano::math::RectT; using Matrix3x2 = kiwano::math::Matrix3x2T; +using Transform = kiwano::math::TransformT; using Point = Vec2; using Size = Vec2; diff --git a/src/kiwano/math/Matrix.hpp b/src/kiwano/math/Matrix.hpp index 9a63d02c..8fe80195 100644 --- a/src/kiwano/math/Matrix.hpp +++ b/src/kiwano/math/Matrix.hpp @@ -33,9 +33,9 @@ struct MatrixMultiply; template struct Matrix3x2T { - using value_type = _Ty; - using vec2_type = Vec2T; - using rect_type = RectT; + using ValueType = _Ty; + using Vec2Type = Vec2T; + using RectType = RectT; union { struct @@ -59,7 +59,7 @@ struct Matrix3x2T { } - Matrix3x2T(value_type _11, value_type _12, value_type _21, value_type _22, value_type _31, value_type _32) + Matrix3x2T(ValueType _11, ValueType _12, ValueType _21, ValueType _22, ValueType _31, ValueType _32) : _11(_11) , _12(_12) , _21(_21) @@ -69,7 +69,7 @@ struct Matrix3x2T { } - explicit Matrix3x2T(const value_type* p) + explicit Matrix3x2T(const ValueType* p) { for (int i = 0; i < 6; i++) m[i] = p[i]; @@ -97,12 +97,12 @@ KGE_SUPPRESS_WARNING(26495) // ignore warning "always initialize member variabl KGE_SUPPRESS_WARNING_POP - inline value_type operator[](uint32_t index) const + inline ValueType operator[](uint32_t index) const { return m[index]; } - inline value_type& operator[](uint32_t index) + inline ValueType& operator[](uint32_t index) { return m[index]; } @@ -115,7 +115,7 @@ KGE_SUPPRESS_WARNING_POP } template - inline Matrix3x2T& operator=(MatrixMultiply const& other) + inline Matrix3x2T& operator=(MatrixMultiply const& other) { Matrix3x2T result(other); (*this) = result; @@ -144,7 +144,7 @@ KGE_SUPPRESS_WARNING_POP inline Matrix3x2T Invert() const { - value_type det = 1.f / Determinant(); + ValueType det = 1.f / Determinant(); return Matrix3x2T(det * _22, -det * _12, -det * _21, det * _11, det * (_21 * _32 - _22 * _31), det * (_12 * _31 - _11 * _32)); } @@ -154,84 +154,84 @@ KGE_SUPPRESS_WARNING_POP return 0 != Determinant(); } - inline value_type Determinant() const + inline ValueType Determinant() const { return (_11 * _22) - (_12 * _21); } - inline vec2_type Transform(const vec2_type& v) const + inline Vec2Type Transform(const Vec2Type& v) const { - return vec2_type(v.x * _11 + v.y * _21 + _31, v.x * _12 + v.y * _22 + _32); + return Vec2Type(v.x * _11 + v.y * _21 + _31, v.x * _12 + v.y * _22 + _32); } - rect_type Transform(const rect_type& rect) const + RectType Transform(const RectType& rect) const { - vec2_type top_left = Transform(rect.GetLeftTop()); - vec2_type top_right = Transform(rect.GetRightTop()); - vec2_type bottom_left = Transform(rect.GetLeftBottom()); - vec2_type bottom_right = Transform(rect.GetRightBottom()); + Vec2Type top_left = Transform(rect.GetLeftTop()); + Vec2Type top_right = Transform(rect.GetRightTop()); + Vec2Type bottom_left = Transform(rect.GetLeftBottom()); + Vec2Type bottom_right = Transform(rect.GetRightBottom()); - value_type left = std::min(std::min(top_left.x, top_right.x), std::min(bottom_left.x, bottom_right.x)); - value_type right = std::max(std::max(top_left.x, top_right.x), std::max(bottom_left.x, bottom_right.x)); - value_type top = std::min(std::min(top_left.y, top_right.y), std::min(bottom_left.y, bottom_right.y)); - value_type bottom = std::max(std::max(top_left.y, top_right.y), std::max(bottom_left.y, bottom_right.y)); + ValueType left = std::min(std::min(top_left.x, top_right.x), std::min(bottom_left.x, bottom_right.x)); + ValueType right = std::max(std::max(top_left.x, top_right.x), std::max(bottom_left.x, bottom_right.x)); + ValueType top = std::min(std::min(top_left.y, top_right.y), std::min(bottom_left.y, bottom_right.y)); + ValueType bottom = std::max(std::max(top_left.y, top_right.y), std::max(bottom_left.y, bottom_right.y)); - return rect_type{ left, top, right, bottom }; + return RectType{ left, top, right, bottom }; } - inline void Translate(const vec2_type& v) + inline void Translate(const Vec2Type& v) { _31 += _11 * v.x + _21 * v.y; _32 += _12 * v.x + _22 * v.y; } - static inline Matrix3x2T Translation(const vec2_type& v) + static inline Matrix3x2T Translation(const Vec2Type& v) { return Matrix3x2T(1.f, 0.f, 0.f, 1.f, v.x, v.y); } - static inline Matrix3x2T Scaling(const vec2_type& v) + static inline Matrix3x2T Scaling(const Vec2Type& v) { return Matrix3x2T(v.x, 0.f, 0.f, v.y, 0.f, 0.f); } - static inline Matrix3x2T Scaling(const vec2_type& v, const vec2_type& center) + static inline Matrix3x2T Scaling(const Vec2Type& v, const Vec2Type& center) { return Matrix3x2T(v.x, 0.f, 0.f, v.y, center.x - v.x * center.x, center.y - v.y * center.y); } - static inline Matrix3x2T Rotation(value_type angle) + static inline Matrix3x2T Rotation(ValueType angle) { - value_type s = math::Sin(angle); - value_type c = math::Cos(angle); + ValueType s = math::Sin(angle); + ValueType c = math::Cos(angle); return Matrix3x2T(c, s, -s, c, 0.f, 0.f); } - static inline Matrix3x2T Rotation(value_type angle, const vec2_type& center) + static inline Matrix3x2T Rotation(ValueType angle, const Vec2Type& center) { - value_type s = math::Sin(angle); - value_type c = math::Cos(angle); + ValueType s = math::Sin(angle); + ValueType c = math::Cos(angle); return Matrix3x2T(c, s, -s, c, center.x * (1 - c) + center.y * s, center.y * (1 - c) - center.x * s); } - static inline Matrix3x2T SRT(const vec2_type& trans, const vec2_type& scale, value_type angle) + static inline Matrix3x2T SRT(const Vec2Type& trans, const Vec2Type& scale, ValueType angle) { - value_type s = math::Sin(angle); - value_type c = math::Cos(angle); + ValueType s = math::Sin(angle); + ValueType c = math::Cos(angle); return Matrix3x2T(c * scale.x, s * scale.x, -s * scale.y, c * scale.y, trans.x, trans.y); } - static inline Matrix3x2T Skewing(const vec2_type& angle) + static inline Matrix3x2T Skewing(const Vec2Type& angle) { - value_type tx = math::Tan(angle.x); - value_type ty = math::Tan(angle.y); + ValueType tx = math::Tan(angle.x); + ValueType ty = math::Tan(angle.y); return Matrix3x2T(1.f, -ty, -tx, 1.f, 0.f, 0.f); } - static inline Matrix3x2T Skewing(const vec2_type& angle, const vec2_type& center) + static inline Matrix3x2T Skewing(const Vec2Type& angle, const Vec2Type& center) { - value_type tx = math::Tan(angle.x); - value_type ty = math::Tan(angle.y); + ValueType tx = math::Tan(angle.x); + ValueType ty = math::Tan(angle.y); return Matrix3x2T(1.f, -ty, -tx, 1.f, center.y * tx, center.x * ty); } }; diff --git a/src/kiwano/math/rand.h b/src/kiwano/math/Random.h similarity index 100% rename from src/kiwano/math/rand.h rename to src/kiwano/math/Random.h diff --git a/src/kiwano/math/Rect.hpp b/src/kiwano/math/Rect.hpp index cc2dfa4d..0d148a48 100644 --- a/src/kiwano/math/Rect.hpp +++ b/src/kiwano/math/Rect.hpp @@ -29,21 +29,21 @@ template struct RectT { public: - using value_type = _Ty; + using ValueType = _Ty; - Vec2T left_top; - Vec2T right_bottom; + Vec2T left_top; + Vec2T right_bottom; public: RectT() {} - RectT(value_type left, value_type top, value_type right, value_type bottom) + RectT(ValueType left, ValueType top, ValueType right, ValueType bottom) : left_top(left, top) , right_bottom(right, bottom) { } - RectT(const Vec2T& left_top, const Vec2T& right_bottom) + RectT(const Vec2T& left_top, const Vec2T& right_bottom) : left_top(left_top) , right_bottom(right_bottom) { @@ -67,70 +67,70 @@ public: return (left_top == rect.left_top) && (right_bottom == rect.right_bottom); } - inline void Set(value_type left, value_type top, value_type right, value_type bottom) + inline void Set(ValueType left, ValueType top, ValueType right, ValueType bottom) { - left_top = Vec2T{ left, top }; - right_bottom = Vec2T{ right, bottom }; + left_top = Vec2T{ left, top }; + right_bottom = Vec2T{ right, bottom }; } - inline Vec2T GetCenter() const + inline Vec2T GetCenter() const { - return Vec2T{ (left_top.x + right_bottom.x) / 2, (left_top.y + right_bottom.y) / 2 }; + return Vec2T{ (left_top.x + right_bottom.x) / 2, (left_top.y + right_bottom.y) / 2 }; } - inline Vec2T GetLeftTop() const + inline Vec2T GetLeftTop() const { return left_top; } - inline Vec2T GetRightBottom() const + inline Vec2T GetRightBottom() const { return right_bottom; } - inline Vec2T GetRightTop() const + inline Vec2T GetRightTop() const { - return Vec2T{ right_bottom.x, left_top.y }; + return Vec2T{ right_bottom.x, left_top.y }; } - inline Vec2T GetLeftBottom() const + inline Vec2T GetLeftBottom() const { - return Vec2T{ left_top.x, right_bottom.y }; + return Vec2T{ left_top.x, right_bottom.y }; } - inline value_type GetLeft() const + inline ValueType GetLeft() const { return left_top.x; } - inline value_type GetTop() const + inline ValueType GetTop() const { return left_top.y; } - inline value_type GetRight() const + inline ValueType GetRight() const { return right_bottom.x; } - inline value_type GetBottom() const + inline ValueType GetBottom() const { return right_bottom.y; } - inline value_type GetWidth() const + inline ValueType GetWidth() const { return right_bottom.x - left_top.x; } - inline value_type GetHeight() const + inline ValueType GetHeight() const { return right_bottom.y - left_top.y; } - inline Vec2T GetSize() const + inline Vec2T GetSize() const { - return Vec2T{ GetWidth(), GetHeight() }; + return Vec2T{ GetWidth(), GetHeight() }; } inline bool IsEmpty() const @@ -138,7 +138,7 @@ public: return left_top.IsOrigin() && right_bottom.IsOrigin(); } - inline bool ContainsPoint(const Vec2T& point) const + inline bool ContainsPoint(const Vec2T& point) const { return point.x >= left_top.x && point.x <= right_bottom.x && point.y >= left_top.y && point.y <= right_bottom.y; } diff --git a/src/kiwano/math/scalar.h b/src/kiwano/math/Scalar.h similarity index 98% rename from src/kiwano/math/scalar.h rename to src/kiwano/math/Scalar.h index a4d40144..ed841d95 100644 --- a/src/kiwano/math/scalar.h +++ b/src/kiwano/math/Scalar.h @@ -20,7 +20,7 @@ #pragma once #include -#include +#include namespace kiwano { diff --git a/src/kiwano/2d/Transform.cpp b/src/kiwano/math/Transform.hpp similarity index 58% rename from src/kiwano/2d/Transform.cpp rename to src/kiwano/math/Transform.hpp index b5a25fa1..d9b375f0 100644 --- a/src/kiwano/2d/Transform.cpp +++ b/src/kiwano/math/Transform.hpp @@ -18,11 +18,42 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include +#pragma once +#include +#include namespace kiwano { -Transform::Transform() +namespace math +{ + +/** + * \~chinese + * @brief 二维放射变换 + */ +template +class TransformT +{ +public: + using ValueType = _Ty; + + float rotation; ///< 旋转 + Vec2T position; ///< 坐标 + Vec2T scale; ///< 缩放 + Vec2T skew; ///< 错切角度 + +public: + TransformT(); + + /// \~chinese + /// @brief 将二维放射变换转换为矩阵 + Matrix3x2T ToMatrix() const; + + bool operator==(const TransformT& rhs) const; +}; + +template +inline TransformT<_Ty>::TransformT() : position() , rotation(0.f) , scale(1.f, 1.f) @@ -30,17 +61,21 @@ Transform::Transform() { } -Matrix3x2 Transform::ToMatrix() const +template +Matrix3x2T<_Ty> TransformT<_Ty>::ToMatrix() const { if (!skew.IsOrigin()) { - return Matrix3x2::Skewing(skew) * Matrix3x2::SRT(position, scale, rotation); + return Matrix3x2T<_Ty>::Skewing(skew) * Matrix3x2T<_Ty>::SRT(position, scale, rotation); } - return Matrix3x2::SRT(position, scale, rotation); + return Matrix3x2T<_Ty>::SRT(position, scale, rotation); } -bool Transform::operator==(Transform const& rhs) const +template +bool TransformT<_Ty>::operator==(TransformT const& rhs) const { return position == rhs.position && rotation == rhs.rotation && scale == rhs.scale && skew == rhs.skew; } + +} // namespace math } // namespace kiwano diff --git a/src/kiwano/math/Vec2.hpp b/src/kiwano/math/Vec2.hpp index 5f44044b..fdf0c605 100644 --- a/src/kiwano/math/Vec2.hpp +++ b/src/kiwano/math/Vec2.hpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include +#include namespace kiwano { @@ -28,18 +28,18 @@ namespace math template struct Vec2T { - using value_type = _Ty; + using ValueType = _Ty; - value_type x; - value_type y; + ValueType x; + ValueType y; Vec2T() - : x(value_type(0)) - , y(value_type(0)) + : x(ValueType(0)) + , y(ValueType(0)) { } - Vec2T(value_type x, value_type y) + Vec2T(ValueType x, ValueType y) : x(x) , y(y) { @@ -51,9 +51,9 @@ struct Vec2T { } - inline value_type Length() const + inline ValueType Length() const { - return static_cast(math::Sqrt(static_cast(x * x + y * y))); + return static_cast(math::Sqrt(static_cast(x * x + y * y))); } inline bool IsOrigin() const @@ -61,7 +61,7 @@ struct Vec2T return (x == 0) && (y == 0); } - inline void Set(value_type x, value_type y) + inline void Set(ValueType x, ValueType y) { this->x = x; this->y = y; @@ -77,12 +77,12 @@ struct Vec2T return Vec2T(x - other.x, y - other.y); } - inline const Vec2T operator*(value_type val) const + inline const Vec2T operator*(ValueType val) const { return Vec2T(x * val, y * val); } - inline const Vec2T operator/(value_type val) const + inline const Vec2T operator/(ValueType val) const { return Vec2T(x / val, y / val); } @@ -106,14 +106,14 @@ struct Vec2T return (*this); } - inline Vec2T& operator*=(value_type val) + inline Vec2T& operator*=(ValueType val) { x *= val; y *= val; return (*this); } - inline Vec2T& operator/=(value_type val) + inline Vec2T& operator/=(ValueType val) { x /= val; y /= val; diff --git a/src/kiwano/platform/Input.h b/src/kiwano/platform/Input.h index aa6f2f18..adf81904 100644 --- a/src/kiwano/platform/Input.h +++ b/src/kiwano/platform/Input.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include namespace kiwano { diff --git a/src/kiwano/platform/Window.h b/src/kiwano/platform/Window.h index bee2916a..f505fae9 100644 --- a/src/kiwano/platform/Window.h +++ b/src/kiwano/platform/Window.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include namespace kiwano { diff --git a/src/kiwano/render/Brush.cpp b/src/kiwano/render/Brush.cpp index 01d7e734..b27b7464 100644 --- a/src/kiwano/render/Brush.cpp +++ b/src/kiwano/render/Brush.cpp @@ -55,6 +55,36 @@ RadialGradientStyle::RadialGradientStyle(Point const& center, Vec2 const& offset { } +BrushPtr Brush::Create(Color const& color) +{ + BrushPtr ptr = new (std::nothrow) Brush; + if (ptr) + { + ptr->SetColor(color); + } + return ptr; +} + +BrushPtr Brush::Create(LinearGradientStyle const& style) +{ + BrushPtr ptr = new (std::nothrow) Brush; + if (ptr) + { + ptr->SetStyle(style); + } + return ptr; +} + +BrushPtr Brush::Create(RadialGradientStyle const& style) +{ + BrushPtr ptr = new (std::nothrow) Brush; + if (ptr) + { + ptr->SetStyle(style); + } + return ptr; +} + Brush::Brush() : opacity_(1.f) , type_(Type::Unknown) @@ -92,17 +122,17 @@ void Brush::SetColor(Color const& color) return; } } - Renderer::Instance().CreateSolidBrush(*this, color); + Renderer::Instance().CreateBrush(*this, color); } void Brush::SetStyle(LinearGradientStyle const& style) { - Renderer::Instance().CreateLinearGradientBrush(*this, style); + Renderer::Instance().CreateBrush(*this, style); } void Brush::SetStyle(RadialGradientStyle const& style) { - Renderer::Instance().CreateRadialGradientBrush(*this, style); + Renderer::Instance().CreateBrush(*this, style); } void Brush::SetBrush(ComPtr brush, Type type) diff --git a/src/kiwano/render/Brush.h b/src/kiwano/render/Brush.h index c88b6ec3..d09cc4f2 100644 --- a/src/kiwano/render/Brush.h +++ b/src/kiwano/render/Brush.h @@ -94,7 +94,20 @@ class KGE_API Brush : public virtual ObjectBase public: /// \~chinese - /// @brief 构造默认画刷 + /// @brief 创建纯色画刷 + /// @param color 画刷颜色 + static BrushPtr Create(Color const& color); + + /// \~chinese + /// @brief 创建线性渐变样式 + /// @param style 线性渐变样式 + static BrushPtr Create(LinearGradientStyle const& style); + + /// \~chinese + /// @brief 创建径向渐变样式 + /// @param style 径向渐变样式 + static BrushPtr Create(RadialGradientStyle const& style); + Brush(); /// \~chinese diff --git a/src/kiwano/render/DirectX/helper.h b/src/kiwano/render/DirectX/helper.h index d29ba1eb..f9bb36d6 100644 --- a/src/kiwano/render/DirectX/helper.h +++ b/src/kiwano/render/DirectX/helper.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include +#include #include #include #include diff --git a/src/kiwano/render/Font.cpp b/src/kiwano/render/Font.cpp index f2f22383..fb8f610d 100644 --- a/src/kiwano/render/Font.cpp +++ b/src/kiwano/render/Font.cpp @@ -23,23 +23,36 @@ namespace kiwano { + +FontPtr Font::Create(String const& file) +{ + FontPtr ptr = new (std::nothrow) Font; + if (ptr) + { + if (!ptr->Load(file)) + return nullptr; + } + return ptr; +} + +FontPtr Font::Create(Resource const& resource) +{ + FontPtr ptr = new (std::nothrow) Font; + if (ptr) + { + if (!ptr->Load(resource)) + return nullptr; + } + return ptr; +} + Font::Font() {} bool Font::Load(String const& file) -{ - return Load(Vector{ file }); -} - -bool Font::Load(Resource const& resource) -{ - return Load(Vector{ resource }); -} - -bool Font::Load(Vector const& files) { try { - Renderer::Instance().CreateFontCollection(*this, files); + Renderer::Instance().CreateFontCollection(*this, file); } catch (std::runtime_error&) { @@ -48,11 +61,11 @@ bool Font::Load(Vector const& files) return true; } -bool Font::Load(Vector const& resources) +bool Font::Load(Resource const& resource) { try { - Renderer::Instance().CreateFontCollection(*this, resources); + Renderer::Instance().CreateFontCollection(*this, resource); } catch (std::runtime_error&) { diff --git a/src/kiwano/render/Font.h b/src/kiwano/render/Font.h index 2316e731..b5533d88 100644 --- a/src/kiwano/render/Font.h +++ b/src/kiwano/render/Font.h @@ -44,6 +44,14 @@ class Font : public virtual ObjectBase friend class Renderer; public: + /// \~chinese + /// @brief 创建字体 + static FontPtr Create(String const& file); + + /// \~chinese + /// @brief 创建字体 + static FontPtr Create(Resource const& resource); + Font(); /// \~chinese @@ -54,14 +62,6 @@ public: /// @brief 加载字体资源 bool Load(Resource const& resource); - /// \~chinese - /// @brief 加载多个字体文件 - bool Load(Vector const& files); - - /// \~chinese - /// @brief 加载多个字体资源 - bool Load(Vector const& resources); - private: ComPtr GetCollection() const; diff --git a/src/kiwano/render/GifImage.cpp b/src/kiwano/render/GifImage.cpp index 60f0b257..405d698d 100644 --- a/src/kiwano/render/GifImage.cpp +++ b/src/kiwano/render/GifImage.cpp @@ -24,6 +24,29 @@ namespace kiwano { + +GifImagePtr GifImage::Create(String const& file_path) +{ + GifImagePtr ptr = new (std::nothrow) GifImage; + if (ptr) + { + if (!ptr->Load(file_path)) + return nullptr; + } + return ptr; +} + +GifImagePtr GifImage::Create(Resource const& res) +{ + GifImagePtr ptr = new (std::nothrow) GifImage; + if (ptr) + { + if (!ptr->Load(res)) + return nullptr; + } + return ptr; +} + GifImage::GifImage() : frames_count_(0) , width_in_pixels_(0) diff --git a/src/kiwano/render/GifImage.h b/src/kiwano/render/GifImage.h index aaa51d3e..743be983 100644 --- a/src/kiwano/render/GifImage.h +++ b/src/kiwano/render/GifImage.h @@ -42,6 +42,14 @@ class KGE_API GifImage : public virtual ObjectBase friend class Renderer; public: + /// \~chinese + /// @brief 创建GIF图片 + static GifImagePtr Create(String const& file_path); + + /// \~chinese + /// @brief 创建GIF图片 + static GifImagePtr Create(Resource const& res); + GifImage(); /// \~chinese diff --git a/src/kiwano/render/RenderContext.cpp b/src/kiwano/render/RenderContext.cpp index a4c2c938..26a24e2c 100644 --- a/src/kiwano/render/RenderContext.cpp +++ b/src/kiwano/render/RenderContext.cpp @@ -101,15 +101,23 @@ void RenderContext::EndDraw() } } -void RenderContext::DrawShape(Shape const& shape, float stroke_width, const StrokeStyle& stroke) +void RenderContext::DrawShape(Shape const& shape, float stroke_width, StrokeStylePtr stroke) { KGE_ASSERT(render_target_ && "Render target has not been initialized!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!"); if (shape.IsValid()) { - render_target_->DrawGeometry(shape.GetGeometry().get(), current_brush_->GetBrush().get(), stroke_width, - stroke.GetStrokeStyle().get()); + if (stroke) + { + render_target_->DrawGeometry(shape.GetGeometry().get(), current_brush_->GetBrush().get(), stroke_width, + stroke->GetStrokeStyle().get()); + } + else + { + render_target_->DrawGeometry(shape.GetGeometry().get(), current_brush_->GetBrush().get(), stroke_width, + nullptr); + } IncreasePrimitivesCount(); } @@ -128,24 +136,40 @@ void RenderContext::FillShape(Shape const& shape) } } -void RenderContext::DrawLine(Point const& point1, Point const& point2, float stroke_width, const StrokeStyle& stroke) +void RenderContext::DrawLine(Point const& point1, Point const& point2, float stroke_width, StrokeStylePtr stroke) { KGE_ASSERT(render_target_ && "Render target has not been initialized!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!"); - render_target_->DrawLine(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2), - current_brush_->GetBrush().get(), stroke_width, stroke.GetStrokeStyle().get()); + if (stroke) + { + render_target_->DrawLine(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2), + current_brush_->GetBrush().get(), stroke_width, stroke->GetStrokeStyle().get()); + } + else + { + render_target_->DrawLine(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2), + current_brush_->GetBrush().get(), stroke_width, nullptr); + } IncreasePrimitivesCount(); } -void RenderContext::DrawRectangle(Rect const& rect, float stroke_width, const StrokeStyle& stroke) +void RenderContext::DrawRectangle(Rect const& rect, float stroke_width, StrokeStylePtr stroke) { KGE_ASSERT(render_target_ && "Render target has not been initialized!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!"); - render_target_->DrawRectangle(DX::ConvertToRectF(rect), current_brush_->GetBrush().get(), stroke_width, - stroke.GetStrokeStyle().get()); + if (stroke) + { + render_target_->DrawRectangle(DX::ConvertToRectF(rect), current_brush_->GetBrush().get(), stroke_width, + stroke->GetStrokeStyle().get()); + } + else + { + render_target_->DrawRectangle(DX::ConvertToRectF(rect), current_brush_->GetBrush().get(), stroke_width, + nullptr); + } IncreasePrimitivesCount(); } @@ -161,14 +185,24 @@ void RenderContext::FillRectangle(Rect const& rect) } void RenderContext::DrawRoundedRectangle(Rect const& rect, Vec2 const& radius, float stroke_width, - const StrokeStyle& stroke) + StrokeStylePtr stroke) { KGE_ASSERT(render_target_ && "Render target has not been initialized!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!"); - render_target_->DrawRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y), - current_brush_->GetBrush().get(), stroke_width, stroke.GetStrokeStyle().get()); + if (stroke) + { + render_target_->DrawRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y), + current_brush_->GetBrush().get(), stroke_width, + stroke->GetStrokeStyle().get()); + } + else + { + render_target_->DrawRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y), + current_brush_->GetBrush().get(), stroke_width, nullptr); + + } IncreasePrimitivesCount(); } @@ -183,13 +217,21 @@ void RenderContext::FillRoundedRectangle(Rect const& rect, Vec2 const& radius) IncreasePrimitivesCount(); } -void RenderContext::DrawEllipse(Point const& center, Vec2 const& radius, float stroke_width, const StrokeStyle& stroke) +void RenderContext::DrawEllipse(Point const& center, Vec2 const& radius, float stroke_width, StrokeStylePtr stroke) { KGE_ASSERT(render_target_ && "Render target has not been initialized!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!"); - render_target_->DrawEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y), - current_brush_->GetBrush().get(), stroke_width, stroke.GetStrokeStyle().get()); + if (stroke) + { + render_target_->DrawEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y), + current_brush_->GetBrush().get(), stroke_width, stroke->GetStrokeStyle().get()); + } + else + { + render_target_->DrawEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y), + current_brush_->GetBrush().get(), stroke_width, nullptr); + } IncreasePrimitivesCount(); } @@ -249,9 +291,19 @@ void RenderContext::DrawTextLayout(TextLayout const& layout, Point const& offset outline_brush->SetOpacity(brush_opacity_); } - HRESULT hr = text_renderer_->DrawTextLayout(layout.GetTextLayout().get(), offset.x, offset.y, fill_brush.get(), - outline_brush.get(), style.outline_width, - style.outline_stroke.GetStrokeStyle().get()); + HRESULT hr = S_OK; + + if (style.outline_stroke) + { + hr = text_renderer_->DrawTextLayout(layout.GetTextLayout().get(), offset.x, offset.y, fill_brush.get(), + outline_brush.get(), style.outline_width, + style.outline_stroke->GetStrokeStyle().get()); + } + else + { + hr = text_renderer_->DrawTextLayout(layout.GetTextLayout().get(), offset.x, offset.y, fill_brush.get(), + outline_brush.get(), style.outline_width, nullptr); + } if (SUCCEEDED(hr)) { diff --git a/src/kiwano/render/RenderContext.h b/src/kiwano/render/RenderContext.h index 379c7ad1..715e8a6f 100644 --- a/src/kiwano/render/RenderContext.h +++ b/src/kiwano/render/RenderContext.h @@ -73,7 +73,7 @@ public: /// \~chinese /// @brief 是否有效 - void DrawShape(Shape const& shape, float stroke_width, const StrokeStyle& stroke = StrokeStyle()); + void DrawShape(Shape const& shape, float stroke_width, StrokeStylePtr stroke = nullptr); /// \~chinese /// @brief 是否有效 @@ -81,12 +81,11 @@ public: /// \~chinese /// @brief 是否有效 - void DrawLine(Point const& point1, Point const& point2, float stroke_width, - const StrokeStyle& stroke = StrokeStyle()); + void DrawLine(Point const& point1, Point const& point2, float stroke_width, StrokeStylePtr stroke = nullptr); /// \~chinese /// @brief 是否有效 - void DrawRectangle(Rect const& rect, float stroke_width, const StrokeStyle& stroke = StrokeStyle()); + void DrawRectangle(Rect const& rect, float stroke_width, StrokeStylePtr stroke = nullptr); /// \~chinese /// @brief 是否有效 @@ -95,7 +94,7 @@ public: /// \~chinese /// @brief 是否有效 void DrawRoundedRectangle(Rect const& rect, Vec2 const& radius, float stroke_width, - const StrokeStyle& stroke = StrokeStyle()); + StrokeStylePtr stroke = nullptr); /// \~chinese /// @brief 是否有效 @@ -103,8 +102,7 @@ public: /// \~chinese /// @brief 是否有效 - void DrawEllipse(Point const& center, Vec2 const& radius, float stroke_width, - const StrokeStyle& stroke = StrokeStyle()); + void DrawEllipse(Point const& center, Vec2 const& radius, float stroke_width, StrokeStylePtr stroke = nullptr); /// \~chinese /// @brief 是否有效 diff --git a/src/kiwano/render/Renderer.cpp b/src/kiwano/render/Renderer.cpp index f387fd82..2ba38d62 100644 --- a/src/kiwano/render/Renderer.cpp +++ b/src/kiwano/render/Renderer.cpp @@ -502,7 +502,7 @@ void Renderer::CreateGifImageFrame(GifImage::Frame& frame, GifImage const& gif, } } -void Renderer::CreateFontCollection(Font& font, Vector const& file_paths) +void Renderer::CreateFontCollection(Font& font, String const& file_path) { HRESULT hr = S_OK; if (!d2d_res_) @@ -510,34 +510,28 @@ void Renderer::CreateFontCollection(Font& font, Vector const& file_paths hr = E_UNEXPECTED; } - Vector full_paths(file_paths); - if (SUCCEEDED(hr)) { - for (auto& file_path : full_paths) + if (!FileSystem::Instance().IsFileExists(file_path)) { - if (!FileSystem::Instance().IsFileExists(file_path)) - { - KGE_WARN(L"Font file '%s' not found!", file_path.c_str()); - hr = E_FAIL; - } - - file_path = FileSystem::Instance().GetFullPathForFile(file_path); + KGE_WARN(L"Font file '%s' not found!", file_path.c_str()); + hr = E_FAIL; } } if (SUCCEEDED(hr)) { - LPVOID collection_key = nullptr; - uint32_t collection_key_size = 0; + LPVOID key = nullptr; + uint32_t key_size = 0; + String full_path = FileSystem::Instance().GetFullPathForFile(file_path); - hr = font_collection_loader_->AddFilePaths(full_paths, &collection_key, &collection_key_size); + hr = font_collection_loader_->AddFilePaths({ full_path }, &key, &key_size); if (SUCCEEDED(hr)) { ComPtr font_collection; - hr = d2d_res_->GetDWriteFactory()->CreateCustomFontCollection(font_collection_loader_.get(), collection_key, - collection_key_size, &font_collection); + hr = d2d_res_->GetDWriteFactory()->CreateCustomFontCollection(font_collection_loader_.get(), key, key_size, + &font_collection); if (SUCCEEDED(hr)) { @@ -549,7 +543,7 @@ void Renderer::CreateFontCollection(Font& font, Vector const& file_paths win32::ThrowIfFailed(hr); } -void Renderer::CreateFontCollection(Font& font, Vector const& res_arr) +void Renderer::CreateFontCollection(Font& font, Resource const& res) { HRESULT hr = S_OK; if (!d2d_res_) @@ -559,16 +553,16 @@ void Renderer::CreateFontCollection(Font& font, Vector const& res_arr) if (SUCCEEDED(hr)) { - LPVOID collection_key = nullptr; - uint32_t collection_key_size = 0; + LPVOID key = nullptr; + uint32_t key_size = 0; - hr = res_font_collection_loader_->AddResources(res_arr, &collection_key, &collection_key_size); + hr = res_font_collection_loader_->AddResources(Vector{ res }, &key, &key_size); if (SUCCEEDED(hr)) { ComPtr font_collection; - hr = d2d_res_->GetDWriteFactory()->CreateCustomFontCollection( - res_font_collection_loader_.get(), collection_key, collection_key_size, &font_collection); + hr = d2d_res_->GetDWriteFactory()->CreateCustomFontCollection(res_font_collection_loader_.get(), key, + key_size, &font_collection); if (SUCCEEDED(hr)) { @@ -789,7 +783,7 @@ void Renderer::CreateTextureRenderTarget(TextureRenderContextPtr& render_context win32::ThrowIfFailed(hr); } -void Renderer::CreateSolidBrush(Brush& brush, Color const& color) +void Renderer::CreateBrush(Brush& brush, Color const& color) { HRESULT hr = S_OK; if (!d2d_res_) @@ -811,7 +805,7 @@ void Renderer::CreateSolidBrush(Brush& brush, Color const& color) win32::ThrowIfFailed(hr); } -void Renderer::CreateLinearGradientBrush(Brush& brush, LinearGradientStyle const& style) +void Renderer::CreateBrush(Brush& brush, LinearGradientStyle const& style) { HRESULT hr = S_OK; if (!d2d_res_) @@ -843,7 +837,7 @@ void Renderer::CreateLinearGradientBrush(Brush& brush, LinearGradientStyle const win32::ThrowIfFailed(hr); } -void Renderer::CreateRadialGradientBrush(Brush& brush, RadialGradientStyle const& style) +void Renderer::CreateBrush(Brush& brush, RadialGradientStyle const& style) { HRESULT hr = S_OK; if (!d2d_res_) diff --git a/src/kiwano/render/Renderer.h b/src/kiwano/render/Renderer.h index 3028fbf3..971666df 100644 --- a/src/kiwano/render/Renderer.h +++ b/src/kiwano/render/Renderer.h @@ -114,13 +114,13 @@ public: /// @brief 创建字体集 /// @param[out] font 字体 /// @param[in] file_paths 字体文件路径 - void CreateFontCollection(Font& font, Vector const& file_paths); + void CreateFontCollection(Font& font, String const& file_path); /// \~chinese /// @brief 创建字体集 /// @param[out] font 字体 /// @param[in] res_arr 字体资源 - void CreateFontCollection(Font& font, Vector const& res_arr); + void CreateFontCollection(Font& font, Resource const& res); /// \~chinese /// @brief 创建文字格式 @@ -173,19 +173,19 @@ public: /// @brief 创建纯色画刷 /// @param[out] brush 画刷 /// @param[in] color 颜色 - void CreateSolidBrush(Brush& brush, Color const& color); + void CreateBrush(Brush& brush, Color const& color); /// \~chinese /// @brief 创建线性渐变画刷 /// @param[out] brush 画刷 /// @param[in] style 线性渐变样式 - void CreateLinearGradientBrush(Brush& brush, LinearGradientStyle const& style); + void CreateBrush(Brush& brush, LinearGradientStyle const& style); /// \~chinese /// @brief 创建径向渐变画刷 /// @param[out] brush 画刷 /// @param[in] style 径向渐变样式 - void CreateRadialGradientBrush(Brush& brush, RadialGradientStyle const& style); + void CreateBrush(Brush& brush, RadialGradientStyle const& style); /// \~chinese /// @brief 创建线条样式 diff --git a/src/kiwano/render/Shape.h b/src/kiwano/render/Shape.h index 9a3da106..62dabab0 100644 --- a/src/kiwano/render/Shape.h +++ b/src/kiwano/render/Shape.h @@ -46,6 +46,35 @@ class KGE_API Shape : public virtual ObjectBase friend class ShapeSink; public: + /// \~chinese + /// @brief 创建线段形状 + /// @param begin 线段起点 + /// @param end 线段终点 + static ShapePtr CreateLine(Point const& begin, Point const& end); + + /// \~chinese + /// @brief 创建矩形 + /// @param rect 矩形 + static ShapePtr CreateRect(Rect const& rect); + + /// \~chinese + /// @brief 创建圆角矩形 + /// @param rect 矩形 + /// @param radius 矩形圆角半径 + static ShapePtr CreateRoundedRect(Rect const& rect, Vec2 const& radius); + + /// \~chinese + /// @brief 创建圆形 + /// @param center 圆形原点 + /// @param radius 圆形半径 + static ShapePtr CreateCircle(Point const& center, float radius); + + /// \~chinese + /// @brief 创建椭圆形 + /// @param center 椭圆原点 + /// @param radius 椭圆半径 + static ShapePtr CreateEllipse(Point const& center, Vec2 const& radius); + Shape(); /// \~chinese @@ -86,36 +115,6 @@ public: /// @brief 清除形状 void Clear(); -public: - /// \~chinese - /// @brief 创建线段 - /// @param begin 线段起点 - /// @param end 线段终点 - static ShapePtr CreateLine(Point const& begin, Point const& end); - - /// \~chinese - /// @brief 创建矩形 - /// @param rect 矩形 - static ShapePtr CreateRect(Rect const& rect); - - /// \~chinese - /// @brief 创建圆角矩形 - /// @param rect 矩形 - /// @param radius 矩形圆角半径 - static ShapePtr CreateRoundedRect(Rect const& rect, Vec2 const& radius); - - /// \~chinese - /// @brief 创建圆形 - /// @param center 圆形原点 - /// @param radius 圆形半径 - static ShapePtr CreateCircle(Point const& center, float radius); - - /// \~chinese - /// @brief 创建椭圆形 - /// @param center 椭圆原点 - /// @param radius 椭圆半径 - static ShapePtr CreateEllipse(Point const& center, Vec2 const& radius); - private: ComPtr GetGeometry() const; diff --git a/src/kiwano/render/ShapeSink.cpp b/src/kiwano/render/ShapeSink.cpp index 63918f10..941093fa 100644 --- a/src/kiwano/render/ShapeSink.cpp +++ b/src/kiwano/render/ShapeSink.cpp @@ -137,17 +137,20 @@ ShapeSink& ShapeSink::AddArc(Point const& point, Size const& radius, float rotat return (*this); } -ShapeSink& ShapeSink::Combine(Shape const& geo_a, Shape const& geo_b, CombineMode mode, const Matrix3x2* matrix) +ShapeSink& ShapeSink::Combine(ShapePtr shape_a, ShapePtr shape_b, CombineMode mode, const Matrix3x2* matrix) { if (!IsOpened()) { Open(); } - ComPtr geo_a_raw = geo_a.geo_; - ComPtr geo_b_raw = geo_b.geo_; - win32::ThrowIfFailed(geo_a_raw->CombineWithGeometry(geo_b_raw.get(), D2D1_COMBINE_MODE(mode), - DX::ConvertToMatrix3x2F(matrix), sink_.get())); + if (shape_a && shape_b) + { + ComPtr geo_a_raw = shape_a->geo_; + ComPtr geo_b_raw = shape_b->geo_; + win32::ThrowIfFailed(geo_a_raw->CombineWithGeometry(geo_b_raw.get(), D2D1_COMBINE_MODE(mode), + DX::ConvertToMatrix3x2F(matrix), sink_.get())); + } return (*this); } diff --git a/src/kiwano/render/ShapeSink.h b/src/kiwano/render/ShapeSink.h index c107a534..7f0c3d8a 100644 --- a/src/kiwano/render/ShapeSink.h +++ b/src/kiwano/render/ShapeSink.h @@ -54,7 +54,6 @@ public: /// \~chinese /// @brief 打开输入流 - /// @details 打开流后可以使用 void Open(); /// \~chinese @@ -123,13 +122,12 @@ public: /// \~chinese /// @brief 组合形状,并将结果输出到流中 - /// @param geo_a 输入的形状A - /// @param geo_b 输入的形状B + /// @param shape_a 输入的形状A + /// @param shape_b 输入的形状B /// @param mode 组合方式 /// @param matrix 应用到输入形状B上的二维变换 /// @note 若还未打开输入流,则自动打开 - ShapeSink& Combine(Shape const& geo_a, Shape const& geo_b, CombineMode mode, - const Matrix3x2* matrix = nullptr); + ShapeSink& Combine(ShapePtr shape_a, ShapePtr shape_b, CombineMode mode, const Matrix3x2* matrix = nullptr); /// \~chinese /// @brief 清空图形 diff --git a/src/kiwano/render/StrokeStyle.cpp b/src/kiwano/render/StrokeStyle.cpp index b44c664f..89c42c6e 100644 --- a/src/kiwano/render/StrokeStyle.cpp +++ b/src/kiwano/render/StrokeStyle.cpp @@ -24,9 +24,7 @@ namespace kiwano { -StrokeStyle::StrokeStyle() {} - -StrokeStyle StrokeStyle::Create(CapStyle cap, LineJoinStyle line_join, DashStyle dash, float dash_offset) +StrokeStylePtr StrokeStyle::Create(CapStyle cap, LineJoinStyle line_join, DashStyle dash, float dash_offset) { switch (dash) { @@ -62,15 +60,20 @@ StrokeStyle StrokeStyle::Create(CapStyle cap, LineJoinStyle line_join, DashStyle default: break; } - return StrokeStyle(); + return nullptr; } -StrokeStyle StrokeStyle::Create(CapStyle cap, LineJoinStyle line_join, const float* dash_array, size_t dash_size, - float dash_offset) +StrokeStylePtr StrokeStyle::Create(CapStyle cap, LineJoinStyle line_join, const float* dash_array, size_t dash_size, + float dash_offset) { - StrokeStyle stroke_style; - Renderer::Instance().CreateStrokeStyle(stroke_style, cap, line_join, dash_array, dash_size, dash_offset); - return stroke_style; + StrokeStylePtr ptr = new (std::nothrow) StrokeStyle; + if (ptr) + { + Renderer::Instance().CreateStrokeStyle(*ptr, cap, line_join, dash_array, dash_size, dash_offset); + } + return ptr; } +StrokeStyle::StrokeStyle() {} + } // namespace kiwano diff --git a/src/kiwano/render/StrokeStyle.h b/src/kiwano/render/StrokeStyle.h index 92ce71db..faa3a41f 100644 --- a/src/kiwano/render/StrokeStyle.h +++ b/src/kiwano/render/StrokeStyle.h @@ -19,6 +19,7 @@ // THE SOFTWARE. #pragma once +#include #include namespace kiwano @@ -26,6 +27,8 @@ namespace kiwano class RenderContext; class Renderer; +KGE_DECLARE_SMART_PTR(StrokeStyle); + /** * \addtogroup Render * @{ @@ -66,26 +69,20 @@ enum class DashStyle /// \~chinese /// @brief 线条样式 -class StrokeStyle +class StrokeStyle : public virtual ObjectBase { friend class RenderContext; friend class Renderer; public: - StrokeStyle(); - - /// \~chinese - /// @brief 是否有效 - bool IsValid() const; - /// \~chinese /// @brief 创建线条样式 /// @param cap 线条端点样式 /// @param line_join 线条交点样式 /// @param dash 线条虚线样式 /// @param dash_offset 线条虚线偏移量 - static StrokeStyle Create(CapStyle cap, LineJoinStyle line_join = LineJoinStyle::Miter, - DashStyle dash = DashStyle::Solid, float dash_offset = 0.0f); + static StrokeStylePtr Create(CapStyle cap, LineJoinStyle line_join = LineJoinStyle::Miter, + DashStyle dash = DashStyle::Solid, float dash_offset = 0.0f); /// \~chinese /// @brief 创建线条样式 @@ -94,8 +91,8 @@ public: /// @param dash_array 线条虚线的长度与间隙数组 /// @param dash_size 线条虚线数组大小 /// @param dash_offset 线条虚线偏移量 - static StrokeStyle Create(CapStyle cap, LineJoinStyle line_join = LineJoinStyle::Miter, - const float* dash_array = nullptr, size_t dash_size = 0, float dash_offset = 0.0f); + static StrokeStylePtr Create(CapStyle cap, LineJoinStyle line_join = LineJoinStyle::Miter, + const float* dash_array = nullptr, size_t dash_size = 0, float dash_offset = 0.0f); /// \~chinese /// @brief 创建线条样式 @@ -105,12 +102,18 @@ public: /// @param dash_array 线条虚线的长度与间隙数组 /// @param dash_offset 线条虚线偏移量 template - static StrokeStyle Create(CapStyle cap, LineJoinStyle line_join = LineJoinStyle::Miter, - float (&dash_array)[_DashSize] = nullptr, float dash_offset = 0.0f) + static StrokeStylePtr Create(CapStyle cap, LineJoinStyle line_join = LineJoinStyle::Miter, + float (&dash_array)[_DashSize] = nullptr, float dash_offset = 0.0f) { return StrokeStyle::Create(cap, line_join, dash_array, _DashSize, dash_offset); } + StrokeStyle(); + + /// \~chinese + /// @brief 是否有效 + bool IsValid() const; + private: ComPtr GetStrokeStyle() const; diff --git a/src/kiwano/render/TextLayout.h b/src/kiwano/render/TextLayout.h index eaa6e14c..68c85a17 100644 --- a/src/kiwano/render/TextLayout.h +++ b/src/kiwano/render/TextLayout.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include +#include #include namespace kiwano @@ -135,7 +135,7 @@ public: /// \~chinese /// @brief 设置文字描边线相交样式 - void SetOutlineStroke(const StrokeStyle& outline_stroke); + void SetOutlineStroke(StrokeStylePtr outline_stroke); /// \~chinese /// @brief 设置下划线 @@ -261,7 +261,7 @@ inline void TextLayout::SetOutlineWidth(float outline_width) style_.outline_width = outline_width; } -inline void TextLayout::SetOutlineStroke(const StrokeStyle& outline_stroke) +inline void TextLayout::SetOutlineStroke(StrokeStylePtr outline_stroke) { style_.outline_stroke = outline_stroke; } diff --git a/src/kiwano/render/TextStyle.hpp b/src/kiwano/render/TextStyle.hpp index b5da6f56..e8ccd9f2 100644 --- a/src/kiwano/render/TextStyle.hpp +++ b/src/kiwano/render/TextStyle.hpp @@ -69,18 +69,18 @@ struct FontWeight class KGE_API TextStyle { public: - FontPtr font; ///< 字体 - String font_family; ///< 字体族 - float font_size; ///< 字号 - uint32_t font_weight; ///< 粗细值 - bool italic; ///< 是否斜体 - TextAlign alignment; ///< 对齐方式 - float wrap_width; ///< 自动换行宽度 - float line_spacing; ///< 行间距 - BrushPtr fill_brush; ///< 填充画刷 - BrushPtr outline_brush; ///< 描边画刷 - float outline_width; ///< 描边线宽 - StrokeStyle outline_stroke; ///< 描边线样式 + FontPtr font; ///< 字体 + String font_family; ///< 字体族 + float font_size; ///< 字号 + uint32_t font_weight; ///< 粗细值 + bool italic; ///< 是否斜体 + TextAlign alignment; ///< 对齐方式 + float wrap_width; ///< 自动换行宽度 + float line_spacing; ///< 行间距 + BrushPtr fill_brush; ///< 填充画刷 + BrushPtr outline_brush; ///< 描边画刷 + float outline_width; ///< 描边线宽 + StrokeStylePtr outline_stroke; ///< 描边线样式 public: /** diff --git a/src/kiwano/render/Texture.cpp b/src/kiwano/render/Texture.cpp index 66e52329..78e7eeec 100644 --- a/src/kiwano/render/Texture.cpp +++ b/src/kiwano/render/Texture.cpp @@ -23,8 +23,31 @@ namespace kiwano { + InterpolationMode Texture::default_interpolation_mode_ = InterpolationMode::Linear; +TexturePtr Texture::Create(String const& file_path) +{ + TexturePtr ptr = new (std::nothrow) Texture; + if (ptr) + { + if (!ptr->Load(file_path)) + return nullptr; + } + return ptr; +} + +TexturePtr Texture::Create(Resource const& res) +{ + TexturePtr ptr = new (std::nothrow) Texture; + if (ptr) + { + if (!ptr->Load(res)) + return nullptr; + } + return ptr; +} + Texture::Texture() : interpolation_mode_(default_interpolation_mode_) { diff --git a/src/kiwano/render/Texture.h b/src/kiwano/render/Texture.h index 70191976..18438148 100644 --- a/src/kiwano/render/Texture.h +++ b/src/kiwano/render/Texture.h @@ -58,6 +58,14 @@ class KGE_API Texture : public virtual ObjectBase friend class Renderer; public: + /// \~chinese + /// @brief 从本地文件创建纹理 + static TexturePtr Create(String const& file_path); + + /// \~chinese + /// @brief 从资源创建纹理 + static TexturePtr Create(Resource const& res); + Texture(); virtual ~Texture(); diff --git a/src/kiwano/utils/LocalStorage.h b/src/kiwano/utils/LocalStorage.h index 8f4dc9e7..fd30f6ac 100644 --- a/src/kiwano/utils/LocalStorage.h +++ b/src/kiwano/utils/LocalStorage.h @@ -20,10 +20,13 @@ #pragma once #include -#include +#include namespace kiwano { + +KGE_DECLARE_SMART_PTR(LocalStorage); + /// \~chinese /// @brief 本地存储 /// @details LocalStorage是一个简易的持久化工具,存放(字符串-值)的键值对 @@ -34,7 +37,7 @@ namespace kiwano /// data.SaveInt(L"best-score", 20); // 保存最高分 20 /// int best = data.GetInt(L"best-score"); // 读取之前储存的最高分 /// @endcode -class KGE_API LocalStorage +class KGE_API LocalStorage : public virtual ObjectBase { public: /// \~chinese diff --git a/src/kiwano/utils/ResourceCache.cpp b/src/kiwano/utils/ResourceCache.cpp index ccc40ef1..703b7492 100644 --- a/src/kiwano/utils/ResourceCache.cpp +++ b/src/kiwano/utils/ResourceCache.cpp @@ -215,10 +215,9 @@ size_t ResourceCache::AddFrameSequence(String const& id, Vector const& if (frames.empty()) return 0; - FrameSequencePtr fs = new (std::nothrow) FrameSequence(frames); + FrameSequencePtr fs = FrameSequence::Create(frames); if (fs) { - fs->AddFrames(frames); AddObject(id, fs); return fs->GetFramesCount(); } @@ -356,8 +355,11 @@ bool LoadTexturesFromData(ResourceCache* loader, GlobalData* gdata, const String frames.push_back(frame); } } - FrameSequencePtr frame_seq = new FrameSequence(frames); - return !!loader->AddObject(*id, frame_seq); + FrameSequencePtr frame_seq = FrameSequence::Create(frames); + if (frame_seq) + { + return !!loader->AddObject(*id, frame_seq); + } } return false; }