Add factory functions

This commit is contained in:
Nomango 2020-02-06 16:54:47 +08:00
parent e608cf43cc
commit 832576d0aa
96 changed files with 1828 additions and 1099 deletions

View File

@ -19,7 +19,6 @@
<ClInclude Include="..\..\src\kiwano-physics\helper.h" />
<ClInclude Include="..\..\src\kiwano-physics\Joint.h" />
<ClInclude Include="..\..\src\kiwano-physics\kiwano-physics.h" />
<ClInclude Include="..\..\src\kiwano-physics\Shape.h" />
<ClInclude Include="..\..\src\kiwano-physics\World.h" />
</ItemGroup>
<ItemGroup>
@ -29,7 +28,6 @@
<ClCompile Include="..\..\src\kiwano-physics\ContactEvent.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\Fixture.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\Joint.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\Shape.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\World.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">

View File

@ -5,7 +5,6 @@
<ClInclude Include="..\..\src\kiwano-physics\Body.h" />
<ClInclude Include="..\..\src\kiwano-physics\World.h" />
<ClInclude Include="..\..\src\kiwano-physics\Joint.h" />
<ClInclude Include="..\..\src\kiwano-physics\Shape.h" />
<ClInclude Include="..\..\src\kiwano-physics\helper.h" />
<ClInclude Include="..\..\src\kiwano-physics\Fixture.h" />
<ClInclude Include="..\..\src\kiwano-physics\Contact.h" />
@ -16,7 +15,6 @@
<ClCompile Include="..\..\src\kiwano-physics\Body.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\World.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\Joint.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\Shape.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\Fixture.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\Contact.cpp" />
<ClCompile Include="..\..\src\kiwano-physics\ContactEvent.cpp" />

View File

@ -35,7 +35,6 @@
<ClInclude Include="..\..\src\kiwano\2d\Stage.h" />
<ClInclude Include="..\..\src\kiwano\2d\Sprite.h" />
<ClInclude Include="..\..\src\kiwano\2d\TextActor.h" />
<ClInclude Include="..\..\src\kiwano\2d\Transform.h" />
<ClInclude Include="..\..\src\kiwano\2d\Transition.h" />
<ClInclude Include="..\..\src\kiwano\core\AsyncTask.h" />
<ClInclude Include="..\..\src\kiwano\core\Component.h" />
@ -48,13 +47,14 @@
<ClInclude Include="..\..\src\kiwano\core\SmartPtr.hpp" />
<ClInclude Include="..\..\src\kiwano\core\Timer.h" />
<ClInclude Include="..\..\src\kiwano\core\TimerManager.h" />
<ClInclude Include="..\..\src\kiwano\math\constants.h" />
<ClInclude Include="..\..\src\kiwano\math\ease.h" />
<ClInclude Include="..\..\src\kiwano\math\math.h" />
<ClInclude Include="..\..\src\kiwano\math\Constants.h" />
<ClInclude Include="..\..\src\kiwano\math\EaseFunctions.h" />
<ClInclude Include="..\..\src\kiwano\math\Math.h" />
<ClInclude Include="..\..\src\kiwano\math\Matrix.hpp" />
<ClInclude Include="..\..\src\kiwano\math\rand.h" />
<ClInclude Include="..\..\src\kiwano\math\Random.h" />
<ClInclude Include="..\..\src\kiwano\math\Rect.hpp" />
<ClInclude Include="..\..\src\kiwano\math\scalar.h" />
<ClInclude Include="..\..\src\kiwano\math\Scalar.h" />
<ClInclude Include="..\..\src\kiwano\math\Transform.hpp" />
<ClInclude Include="..\..\src\kiwano\math\Vec2.hpp" />
<ClInclude Include="..\..\src\kiwano\platform\Application.h" />
<ClInclude Include="..\..\src\kiwano\platform\FileSystem.h" />
@ -108,7 +108,6 @@
<ClCompile Include="..\..\src\kiwano\2d\Stage.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\Sprite.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\TextActor.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\Transform.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\Transition.cpp" />
<ClCompile Include="..\..\src\kiwano\core\AsyncTask.cpp" />
<ClCompile Include="..\..\src\kiwano\core\Component.cpp" />

View File

@ -60,9 +60,6 @@
<ClInclude Include="..\..\src\kiwano\math\Matrix.hpp">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\math\rand.h">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\math\Rect.hpp">
<Filter>math</Filter>
</ClInclude>
@ -138,24 +135,9 @@
<ClInclude Include="..\..\src\kiwano\core\Logger.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\math\math.h">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\ObjectBase.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\2d\Transform.h">
<Filter>2d</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\math\constants.h">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\math\ease.h">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\math\scalar.h">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\utils\LocalStorage.h">
<Filter>utils</Filter>
</ClInclude>
@ -285,6 +267,24 @@
<ClInclude Include="..\..\src\kiwano\render\ShapeSink.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\math\Transform.hpp">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\math\Constants.h">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\math\EaseFunctions.h">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\math\Math.h">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\math\Random.h">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\math\Scalar.h">
<Filter>math</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp">
@ -371,9 +371,6 @@
<ClCompile Include="..\..\src\kiwano\core\ObjectBase.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\2d\Transform.cpp">
<Filter>2d</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\core\Component.cpp">
<Filter>core</Filter>
</ClCompile>

View File

@ -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)

View File

@ -40,13 +40,23 @@ KGE_DECLARE_SMART_PTR(Sound);
/**
* \~chinese
* @brief <EFBFBD>
* @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();

View File

@ -24,6 +24,13 @@ namespace kiwano
{
namespace audio
{
SoundPlayerPtr SoundPlayer::Create()
{
SoundPlayerPtr ptr = new (std::nothrow) SoundPlayer;
return ptr;
}
SoundPlayer::SoundPlayer()
: volume_(1.f)
{

View File

@ -40,6 +40,10 @@ KGE_DECLARE_SMART_PTR(SoundPlayer);
class KGE_API SoundPlayer : public virtual ObjectBase
{
public:
/// \~chinese
/// @brief 创建音频播放器
static SoundPlayerPtr Create();
SoundPlayer();
~SoundPlayer();

View File

@ -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);

View File

@ -38,6 +38,16 @@ using ImGuiPipeline = Function<void()>;
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();

View File

@ -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:

View File

@ -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

View File

@ -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<void(HttpRequest* /* request */, HttpResponse* /* response */)>;
/// \~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<String, String> 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_;
}

View File

@ -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<Point> const& vertexs, float density)
Fixture* Body::AddPolygonShape(Vector<Point> 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<Point> const& vertexs, bool loop, float density)
Fixture* Body::AddChainShape(Vector<Point> 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);

View File

@ -21,7 +21,6 @@
#pragma once
#include <kiwano-physics/ContactEdge.h>
#include <kiwano-physics/Fixture.h>
#include <kiwano-physics/Shape.h>
#include <kiwano-physics/helper.h>
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<Point> const& vertexs, float density = 0.f);
Fixture* AddPolygonShape(Vector<Point> 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<Point> const& vertexs, bool loop, float density = 0.f);
Fixture* AddChainShape(Vector<Point> 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<FixturePtr> 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<Fixture*>(body_->GetFixtureList()->GetUserData());
return FixtureList(fixture);
}
inline ContactEdgeList Body::GetContactList() const

View File

@ -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<Fixture*>(contact_->GetFixtureA()->GetUserData());
return fixture;
}
Fixture Contact::GetFixtureB() const
Fixture* Contact::GetFixtureB() const
{
KGE_ASSERT(contact_);
return Fixture(contact_->GetFixtureB());
Fixture* fixture = static_cast<Fixture*>(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();

View File

@ -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<Contact>
class ContactList
{
template <typename _Ty>
class IteratorImpl : public std::iterator<std::forward_iterator_tag, _Ty>
@ -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:

View File

@ -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<Body*>(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_;

View File

@ -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<Point> const& vertexs)
{
KGE_ASSERT(body);
World* world = body->GetWorld();
Vector<b2Vec2> b2vertexs;
b2vertexs.reserve(vertexs.size());
for (const auto& v : vertexs)
{
b2vertexs.push_back(world->Stage2World(v));
}
b2PolygonShape shape;
shape.Set(&b2vertexs[0], static_cast<int32>(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<Point> const& vertexs, bool loop)
{
KGE_ASSERT(body);
World* world = body->GetWorld();
Vector<b2Vec2> 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<int32>(b2vertexs.size()));
}
else
{
shape.CreateChain(&b2vertexs[0], static_cast<int32>(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<Body*>(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_);

View File

@ -19,7 +19,6 @@
// THE SOFTWARE.
#pragma once
#include <kiwano-physics/Shape.h>
#include <kiwano-physics/helper.h>
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<Point> 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<Point> 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<Fixture>
class FixtureList
{
template <typename _Ty>
class IteratorImpl : public std::iterator<std::forward_iterator_tag, _Ty>
@ -135,31 +174,37 @@ class FixtureList : public List<Fixture>
using herit = std::iterator<std::forward_iterator_tag, _Ty>;
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<typename herit::reference>(elem_);
return const_cast<typename herit::reference>(*elem_);
}
inline typename herit::pointer operator->() const
inline pointer operator->() const
{
return std::pointer_traits<typename herit::pointer>::pointer_to(**this);
}
inline IteratorImpl& operator++()
{
elem_ = elem_.GetB2Fixture()->GetNext();
b2Fixture* next = elem_->GetB2Fixture()->GetNext();
elem_ = static_cast<Fixture*>(next->GetUserData());
return *this;
}
inline IteratorImpl operator++(int)
{
IteratorImpl old = *this;
operator++();
operator++();
return old;
}
@ -174,7 +219,7 @@ class FixtureList : public List<Fixture>
}
private:
_Ty elem_;
pointer elem_;
};
public:
@ -182,21 +227,24 @@ public:
using iterator = IteratorImpl<value_type>;
using const_iterator = IteratorImpl<const value_type>;
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

View File

@ -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)

View File

@ -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

View File

@ -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 <kiwano-physics/Shape.h>
#include <kiwano-physics/World.h>
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<Point> const& vertexs)
: PolygonShape()
{
Set(vertexs);
}
void PolygonShape::Set(Vector<Point> const& vertexs)
{
vertexs_ = vertexs;
}
void PolygonShape::FitWorld(World* world)
{
KGE_ASSERT(world);
Vector<b2Vec2> b2vertexs;
b2vertexs.reserve(vertexs_.size());
for (const auto& v : vertexs_)
{
b2vertexs.push_back(world->Stage2World(v));
}
polygon_.Set(&b2vertexs[0], static_cast<int32>(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<Point> const& vertexs, bool loop)
: ChainShape()
{
Set(vertexs, loop);
}
void ChainShape::Set(Vector<Point> const& vertexs, bool loop)
{
vertexs_ = vertexs;
loop_ = loop;
}
void ChainShape::FitWorld(World* world)
{
KGE_ASSERT(world);
Vector<b2Vec2> b2vertexs;
b2vertexs.reserve(vertexs_.size());
for (const auto& v : vertexs_)
{
b2vertexs.push_back(world->Stage2World(v));
}
if (loop_)
{
chain_.CreateLoop(&b2vertexs[0], static_cast<int32>(b2vertexs.size()));
}
else
{
chain_.CreateChain(&b2vertexs[0], static_cast<int32>(b2vertexs.size()));
}
}
} // namespace physics
} // namespace kiwano

View File

@ -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 <kiwano-physics/helper.h>
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<Point> const& vertexs);
void Set(Vector<Point> const& vertexs);
private:
void FitWorld(World* world) override;
private:
Vector<Point> 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<Point> const& vertexs, bool loop = false);
void Set(Vector<Point> const& vertexs, bool loop = false);
private:
void FitWorld(World* world) override;
private:
bool loop_;
Vector<Point> vertexs_;
b2ChainShape chain_;
};
/** @} */
} // namespace physics
} // namespace kiwano

View File

@ -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)

View File

@ -25,5 +25,4 @@
#include <kiwano-physics/ContactEvent.h>
#include <kiwano-physics/Fixture.h>
#include <kiwano-physics/Joint.h>
#include <kiwano-physics/Shape.h>
#include <kiwano-physics/World.h>

View File

@ -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)

View File

@ -19,13 +19,12 @@
// THE SOFTWARE.
#pragma once
#include <kiwano/2d/Transform.h>
#include <kiwano/2d/action/ActionManager.h>
#include <kiwano/core/EventDispatcher.h>
#include <kiwano/core/ObjectBase.h>
#include <kiwano/core/Time.h>
#include <kiwano/core/TimerManager.h>
#include <kiwano/math/math.h>
#include <kiwano/math/Math.h>
namespace kiwano
{
@ -71,6 +70,10 @@ public:
/// @brief 角色更新回调函数
using UpdateCallback = Function<void(Duration)>;
/// \~chinese
/// @brief ´´˝¨˝ÇÉŤ
static ActorPtr Create();
Actor();
virtual ~Actor();

View File

@ -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<MouseClickEvent>(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<MouseClickEvent>(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

View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -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)

View File

@ -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

View File

@ -23,13 +23,19 @@
namespace kiwano
{
FrameSequence::FrameSequence() {}
FrameSequence::FrameSequence(Vector<FramePtr> const& frames)
FrameSequencePtr FrameSequence::Create(Vector<FramePtr> 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)

View File

@ -35,13 +35,13 @@ class KGE_API FrameSequence : public virtual ObjectBase
{
public:
/// \~chinese
/// @brief ¹¹½¨¿ÕÐòÁÐÖ¡
FrameSequence();
/// @brief ´´½¨ÐòÁÐÖ¡
/// @param frames ͼÏñÖ¡¼¯ºÏ
static FrameSequencePtr Create(Vector<FramePtr> const& frames);
/// \~chinese
/// @brief ¹¹½¨ÐòÁÐÖ¡
/// @param frames ͼÏñÖ¡¼¯ºÏ
explicit FrameSequence(Vector<FramePtr> const& frames);
/// @brief ¹¹½¨¿ÕÐòÁÐÖ¡
FrameSequence();
virtual ~FrameSequence();

View File

@ -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)

View File

@ -48,6 +48,21 @@ public:
/// @brief GIF²¥·Å½áÊø»Øµ÷
using DoneCallback = Function<void()>;
/// \~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

View File

@ -24,6 +24,13 @@
namespace kiwano
{
LayerPtr Layer::Create()
{
LayerPtr ptr = new (std::nothrow) Layer;
return ptr;
}
Layer::Layer()
: swallow_(false)
{

View File

@ -39,6 +39,10 @@ KGE_DECLARE_SMART_PTR(Layer);
class KGE_API Layer : public Actor
{
public:
/// \~chinese
/// @brief ´´˝¨Íź˛ă
static LayerPtr Create();
Layer();
virtual ~Layer();

View File

@ -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<Point> const& points)
{
PolygonActorPtr ptr = new (std::nothrow) PolygonActor;
if (ptr)
{
ptr->SetVertices(points);
}
return ptr;
}
PolygonActor::PolygonActor() {}
PolygonActor::~PolygonActor() {}

View File

@ -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<Point> 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();
}

View File

@ -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() {}

View File

@ -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();

View File

@ -24,6 +24,13 @@
namespace kiwano
{
StagePtr Stage::Create()
{
StagePtr ptr = new (std::nothrow) Stage;
return ptr;
}
Stage::Stage()
{
SetStage(this);

View File

@ -43,6 +43,10 @@ class KGE_API Stage : public Actor
friend class Director;
public:
/// \~chinese
/// @brief 进入舞台时
static StagePtr Create();
Stage();
virtual ~Stage();

View File

@ -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() {}

View File

@ -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);
}

View File

@ -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 <kiwano/math/math.h>
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

View File

@ -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)
{
}

View File

@ -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

View File

@ -23,7 +23,7 @@
#include <kiwano/core/ObjectBase.h>
#include <kiwano/core/SmartPtr.hpp>
#include <kiwano/core/Time.h>
#include <kiwano/math/math.h>
#include <kiwano/math/Math.h>
namespace kiwano
{

View File

@ -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()

View File

@ -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();

View File

@ -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);
}

View File

@ -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

View File

@ -50,43 +50,41 @@ public:
using Callback = Function<void(Event*)>;
/// \~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 <typename _EventTy, typename = typename std::enable_if<IsEvent<_EventTy>::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 <typename _EventTy, typename = typename std::enable_if<IsEvent<_EventTy>::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 <typename _EventTy, typename = typename std::enable_if<IsEvent<_EventTy>::value, int>::type>
inline EventListener(Callback const& callback)
: EventListener(KGE_EVENT(_EventTy), callback)
{
}
/// \~chinese
/// @brief 构造监听器
/// @tparam _EventTy 事件类型
/// @param name 监听器名称
/// @param callback 回调函数
template <typename _EventTy, typename = typename std::enable_if<IsEvent<_EventTy>::value, int>::type>
inline EventListener(String const& name, Callback const& callback)
: EventListener(name, KGE_EVENT(_EventTy), callback)
{
}
virtual ~EventListener();
/// \~chinese

View File

@ -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)

View File

@ -46,23 +46,23 @@ public:
using Callback = Function<void(Timer* /* self */, Duration /* dt */)>;
/// \~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 启动定时器

View File

@ -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);
}

View File

@ -21,7 +21,7 @@
#pragma once
#include <kiwano/core/SmartPtr.hpp>
#include <kiwano/core/event/EventType.h>
#include <kiwano/math/math.h>
#include <kiwano/math/Math.h>
namespace kiwano
{

View File

@ -21,7 +21,7 @@
#pragma once
#include <kiwano/core/Keys.h>
#include <kiwano/core/event/Event.h>
#include <kiwano/math/math.h>
#include <kiwano/math/Math.h>
namespace kiwano
{

View File

@ -30,12 +30,14 @@
// math
//
#include <kiwano/math/Matrix.hpp>
#include <kiwano/math/Vec2.hpp>
#include <kiwano/math/constants.h>
#include <kiwano/math/ease.h>
#include <kiwano/math/rand.h>
#include <kiwano/math/scalar.h>
#include <kiwano/math/Rect.hpp>
#include <kiwano/math/Matrix.hpp>
#include <kiwano/math/Transform.hpp>
#include <kiwano/math/Constants.h>
#include <kiwano/math/EaseFunctions.h>
#include <kiwano/math/Random.h>
#include <kiwano/math/Scalar.h>
//
// core
@ -89,7 +91,6 @@
#include <kiwano/2d/Sprite.h>
#include <kiwano/2d/Stage.h>
#include <kiwano/2d/TextActor.h>
#include <kiwano/2d/Transform.h>
#include <kiwano/2d/Transition.h>
#include <kiwano/2d/action/Action.h>
#include <kiwano/2d/action/ActionDelay.h>

View File

@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
#include <kiwano/math/scalar.h>
#include <kiwano/math/Scalar.h>
namespace kiwano
{

View File

@ -20,12 +20,13 @@
#pragma once
#include <kiwano/core/Common.h>
#include <kiwano/math/Matrix.hpp>
#include <kiwano/math/Rect.hpp>
#include <kiwano/math/Vec2.hpp>
#include <kiwano/math/constants.h>
#include <kiwano/math/ease.h>
#include <kiwano/math/scalar.h>
#include <kiwano/math/Rect.hpp>
#include <kiwano/math/Matrix.hpp>
#include <kiwano/math/Transform.hpp>
#include <kiwano/math/Constants.h>
#include <kiwano/math/EaseFunctions.h>
#include <kiwano/math/Scalar.h>
namespace kiwano
{
@ -33,6 +34,7 @@ namespace kiwano
using Vec2 = kiwano::math::Vec2T<float>;
using Rect = kiwano::math::RectT<float>;
using Matrix3x2 = kiwano::math::Matrix3x2T<float>;
using Transform = kiwano::math::TransformT<float>;
using Point = Vec2;
using Size = Vec2;

View File

@ -33,9 +33,9 @@ struct MatrixMultiply;
template <typename _Ty>
struct Matrix3x2T
{
using value_type = _Ty;
using vec2_type = Vec2T<value_type>;
using rect_type = RectT<value_type>;
using ValueType = _Ty;
using Vec2Type = Vec2T<ValueType>;
using RectType = RectT<ValueType>;
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 <typename _Lty, typename _Rty>
inline Matrix3x2T& operator=(MatrixMultiply<value_type, _Lty, _Rty> const& other)
inline Matrix3x2T& operator=(MatrixMultiply<ValueType, _Lty, _Rty> 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);
}
};

View File

@ -29,21 +29,21 @@ template <typename _Ty>
struct RectT
{
public:
using value_type = _Ty;
using ValueType = _Ty;
Vec2T<value_type> left_top;
Vec2T<value_type> right_bottom;
Vec2T<ValueType> left_top;
Vec2T<ValueType> 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<value_type>& left_top, const Vec2T<value_type>& right_bottom)
RectT(const Vec2T<ValueType>& left_top, const Vec2T<ValueType>& 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<value_type>{ left, top };
right_bottom = Vec2T<value_type>{ right, bottom };
left_top = Vec2T<ValueType>{ left, top };
right_bottom = Vec2T<ValueType>{ right, bottom };
}
inline Vec2T<value_type> GetCenter() const
inline Vec2T<ValueType> GetCenter() const
{
return Vec2T<value_type>{ (left_top.x + right_bottom.x) / 2, (left_top.y + right_bottom.y) / 2 };
return Vec2T<ValueType>{ (left_top.x + right_bottom.x) / 2, (left_top.y + right_bottom.y) / 2 };
}
inline Vec2T<value_type> GetLeftTop() const
inline Vec2T<ValueType> GetLeftTop() const
{
return left_top;
}
inline Vec2T<value_type> GetRightBottom() const
inline Vec2T<ValueType> GetRightBottom() const
{
return right_bottom;
}
inline Vec2T<value_type> GetRightTop() const
inline Vec2T<ValueType> GetRightTop() const
{
return Vec2T<value_type>{ right_bottom.x, left_top.y };
return Vec2T<ValueType>{ right_bottom.x, left_top.y };
}
inline Vec2T<value_type> GetLeftBottom() const
inline Vec2T<ValueType> GetLeftBottom() const
{
return Vec2T<value_type>{ left_top.x, right_bottom.y };
return Vec2T<ValueType>{ 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<value_type> GetSize() const
inline Vec2T<ValueType> GetSize() const
{
return Vec2T<value_type>{ GetWidth(), GetHeight() };
return Vec2T<ValueType>{ GetWidth(), GetHeight() };
}
inline bool IsEmpty() const
@ -138,7 +138,7 @@ public:
return left_top.IsOrigin() && right_bottom.IsOrigin();
}
inline bool ContainsPoint(const Vec2T<value_type>& point) const
inline bool ContainsPoint(const Vec2T<ValueType>& point) const
{
return point.x >= left_top.x && point.x <= right_bottom.x && point.y >= left_top.y && point.y <= right_bottom.y;
}

View File

@ -20,7 +20,7 @@
#pragma once
#include <cmath>
#include <kiwano/math/constants.h>
#include <kiwano/math/Constants.h>
namespace kiwano
{

View File

@ -18,11 +18,42 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <kiwano/2d/Transform.h>
#pragma once
#include <kiwano/math/Vec2.hpp>
#include <kiwano/math/Matrix.hpp>
namespace kiwano
{
Transform::Transform()
namespace math
{
/**
* \~chinese
* @brief
*/
template <typename _Ty>
class TransformT
{
public:
using ValueType = _Ty;
float rotation; ///< 旋转
Vec2T<ValueType> position; ///< 坐标
Vec2T<ValueType> scale; ///< 缩放
Vec2T<ValueType> skew; ///< 错切角度
public:
TransformT();
/// \~chinese
/// @brief 将二维放射变换转换为矩阵
Matrix3x2T<ValueType> ToMatrix() const;
bool operator==(const TransformT& rhs) const;
};
template <typename _Ty>
inline TransformT<_Ty>::TransformT()
: position()
, rotation(0.f)
, scale(1.f, 1.f)
@ -30,17 +61,21 @@ Transform::Transform()
{
}
Matrix3x2 Transform::ToMatrix() const
template <typename _Ty>
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 <typename _Ty>
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

View File

@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
#include <kiwano/math/scalar.h>
#include <kiwano/math/Scalar.h>
namespace kiwano
{
@ -28,18 +28,18 @@ namespace math
template <typename _Ty>
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<value_type>(math::Sqrt(static_cast<float>(x * x + y * y)));
return static_cast<ValueType>(math::Sqrt(static_cast<float>(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;

View File

@ -24,7 +24,7 @@
#include <kiwano/core/Keys.h>
#include <kiwano/core/event/Event.h>
#include <kiwano/macros.h>
#include <kiwano/math/math.h>
#include <kiwano/math/Math.h>
namespace kiwano
{

View File

@ -22,7 +22,7 @@
#include <kiwano/core/Common.h>
#include <kiwano/core/event/Event.h>
#include <kiwano/macros.h>
#include <kiwano/math/math.h>
#include <kiwano/math/Math.h>
namespace kiwano
{

View File

@ -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<ID2D1Brush> brush, Type type)

View File

@ -94,7 +94,20 @@ class KGE_API Brush : public virtual ObjectBase
public:
/// \~chinese
/// @brief ケケヤ<EFBDB9>ャネマサュヒ「
/// @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

View File

@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
#include <kiwano/math/math.h>
#include <kiwano/math/Math.h>
#include <kiwano/render/Color.h>
#include <kiwano/platform/win32/ComPtr.hpp>
#include <kiwano/platform/win32/helper.h>

View File

@ -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<String>{ file });
}
bool Font::Load(Resource const& resource)
{
return Load(Vector<Resource>{ resource });
}
bool Font::Load(Vector<String> 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<String> const& files)
return true;
}
bool Font::Load(Vector<Resource> const& resources)
bool Font::Load(Resource const& resource)
{
try
{
Renderer::Instance().CreateFontCollection(*this, resources);
Renderer::Instance().CreateFontCollection(*this, resource);
}
catch (std::runtime_error&)
{

View File

@ -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<String> const& files);
/// \~chinese
/// @brief 加载多个字体资源
bool Load(Vector<Resource> const& resources);
private:
ComPtr<IDWriteFontCollection> GetCollection() const;

View File

@ -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)

View File

@ -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

View File

@ -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))
{

View File

@ -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 是否有效

View File

@ -502,7 +502,7 @@ void Renderer::CreateGifImageFrame(GifImage::Frame& frame, GifImage const& gif,
}
}
void Renderer::CreateFontCollection(Font& font, Vector<String> 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<String> const& file_paths
hr = E_UNEXPECTED;
}
Vector<String> 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<IDWriteFontCollection> 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<String> const& file_paths
win32::ThrowIfFailed(hr);
}
void Renderer::CreateFontCollection(Font& font, Vector<Resource> 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<Resource> 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<Resource>{ res }, &key, &key_size);
if (SUCCEEDED(hr))
{
ComPtr<IDWriteFontCollection> 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_)

View File

@ -114,13 +114,13 @@ public:
/// @brief 创建字体集
/// @param[out] font 字体
/// @param[in] file_paths 字体文件路径
void CreateFontCollection(Font& font, Vector<String> 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<Resource> 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 创建线条样式

View File

@ -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<ID2D1Geometry> GetGeometry() const;

View File

@ -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<ID2D1Geometry> geo_a_raw = geo_a.geo_;
ComPtr<ID2D1Geometry> 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<ID2D1Geometry> geo_a_raw = shape_a->geo_;
ComPtr<ID2D1Geometry> 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);
}

View File

@ -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 清空图形

View File

@ -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

View File

@ -19,6 +19,7 @@
// THE SOFTWARE.
#pragma once
#include <kiwano/core/ObjectBase.h>
#include <kiwano/render/DirectX/D2DDeviceResources.h>
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 <size_t _DashSize>
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<ID2D1StrokeStyle> GetStrokeStyle() const;

View File

@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
#include <kiwano/math/math.h>
#include <kiwano/math/Math.h>
#include <kiwano/render/TextStyle.hpp>
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;
}

View File

@ -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:
/**

View File

@ -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_)
{

View File

@ -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();

View File

@ -20,10 +20,13 @@
#pragma once
#include <kiwano/core/Common.h>
#include <kiwano/macros.h>
#include <kiwano/core/ObjectBase.h>
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

View File

@ -215,10 +215,9 @@ size_t ResourceCache::AddFrameSequence(String const& id, Vector<FramePtr> 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;
}