add Flag & Property

This commit is contained in:
Nomango 2020-10-07 01:48:24 +08:00
parent d8309c1a75
commit 439cd29026
9 changed files with 530 additions and 67 deletions

View File

@ -20,10 +20,12 @@
<ClInclude Include="..\..\src\kiwano\base\RefPtr.h" /> <ClInclude Include="..\..\src\kiwano\base\RefPtr.h" />
<ClInclude Include="..\..\src\kiwano\core\Allocator.h" /> <ClInclude Include="..\..\src\kiwano\core\Allocator.h" />
<ClInclude Include="..\..\src\kiwano\core\Any.h" /> <ClInclude Include="..\..\src\kiwano\core\Any.h" />
<ClInclude Include="..\..\src\kiwano\core\BitOperator.h" />
<ClInclude Include="..\..\src\kiwano\core\Cloneable.h" /> <ClInclude Include="..\..\src\kiwano\core\Cloneable.h" />
<ClInclude Include="..\..\src\kiwano\core\Common.h" /> <ClInclude Include="..\..\src\kiwano\core\Common.h" />
<ClInclude Include="..\..\src\kiwano\core\Defer.h" /> <ClInclude Include="..\..\src\kiwano\core\Defer.h" />
<ClInclude Include="..\..\src\kiwano\core\Exception.h" /> <ClInclude Include="..\..\src\kiwano\core\Exception.h" />
<ClInclude Include="..\..\src\kiwano\core\Flag.h" />
<ClInclude Include="..\..\src\kiwano\core\Function.h" /> <ClInclude Include="..\..\src\kiwano\core\Function.h" />
<ClInclude Include="..\..\src\kiwano\core\IntrusiveList.h" /> <ClInclude Include="..\..\src\kiwano\core\IntrusiveList.h" />
<ClInclude Include="..\..\src\kiwano\core\Keys.h" /> <ClInclude Include="..\..\src\kiwano\core\Keys.h" />
@ -32,6 +34,7 @@
<ClInclude Include="..\..\src\kiwano\core\Singleton.h" /> <ClInclude Include="..\..\src\kiwano\core\Singleton.h" />
<ClInclude Include="..\..\src\kiwano\core\String.h" /> <ClInclude Include="..\..\src\kiwano\core\String.h" />
<ClInclude Include="..\..\src\kiwano\core\Time.h" /> <ClInclude Include="..\..\src\kiwano\core\Time.h" />
<ClInclude Include="..\..\src\kiwano\core\Property.h" />
<ClInclude Include="..\..\src\kiwano\event\Event.h" /> <ClInclude Include="..\..\src\kiwano\event\Event.h" />
<ClInclude Include="..\..\src\kiwano\event\EventDispatcher.h" /> <ClInclude Include="..\..\src\kiwano\event\EventDispatcher.h" />
<ClInclude Include="..\..\src\kiwano\event\EventListener.h" /> <ClInclude Include="..\..\src\kiwano\event\EventListener.h" />

View File

@ -357,6 +357,15 @@
<ClInclude Include="..\..\src\kiwano\render\TextStyle.h"> <ClInclude Include="..\..\src\kiwano\render\TextStyle.h">
<Filter>render</Filter> <Filter>render</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\core\Property.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\BitOperator.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\Flag.h">
<Filter>core</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp"> <ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp">

View File

@ -47,13 +47,10 @@ Actor::Actor()
, hover_(false) , hover_(false)
, pressed_(false) , pressed_(false)
, responsible_(false) , responsible_(false)
, dirty_visibility_(true)
, dirty_transform_(false)
, dirty_transform_inverse_(false)
, cascade_opacity_(true) , cascade_opacity_(true)
, show_border_(false) , show_border_(false)
, is_fast_transform_(true)
, evt_dispatch_enabled_(true) , evt_dispatch_enabled_(true)
, dirty_flag_(DirtyFlag::DirtyVisibility)
, parent_(nullptr) , parent_(nullptr)
, stage_(nullptr) , stage_(nullptr)
, physic_body_(nullptr) , physic_body_(nullptr)
@ -102,6 +99,7 @@ void Actor::Render(RenderContext& ctx)
return; return;
UpdateTransform(); UpdateTransform();
UpdateOpacity();
if (children_.IsEmpty()) if (children_.IsEmpty())
{ {
@ -172,9 +170,9 @@ void Actor::RenderBorder(RenderContext& ctx)
bool Actor::CheckVisibility(RenderContext& ctx) const bool Actor::CheckVisibility(RenderContext& ctx) const
{ {
if (dirty_visibility_) if (dirty_flag_.Has(DirtyFlag::DirtyVisibility))
{ {
dirty_visibility_ = false; dirty_flag_.Unset(DirtyFlag::DirtyVisibility);
if (size_.IsOrigin()) if (size_.IsOrigin())
{ {
@ -305,10 +303,10 @@ const Matrix3x2& Actor::GetTransformMatrix() const
const Matrix3x2& Actor::GetTransformInverseMatrix() const const Matrix3x2& Actor::GetTransformInverseMatrix() const
{ {
UpdateTransform(); UpdateTransform();
if (dirty_transform_inverse_) if (dirty_flag_.Has(DirtyFlag::DirtyTransformInverse))
{ {
dirty_flag_.Unset(DirtyFlag::DirtyTransformInverse);
transform_matrix_inverse_ = transform_matrix_.Invert(); transform_matrix_inverse_ = transform_matrix_.Invert();
dirty_transform_inverse_ = false;
} }
return transform_matrix_inverse_; return transform_matrix_inverse_;
} }
@ -321,14 +319,14 @@ const Matrix3x2& Actor::GetTransformMatrixToParent() const
void Actor::UpdateTransform() const void Actor::UpdateTransform() const
{ {
if (!dirty_transform_) if (!dirty_flag_.Has(DirtyFlag::DirtyTransform))
return; return;
dirty_transform_ = false; dirty_flag_.Unset(DirtyFlag::DirtyTransform);
dirty_transform_inverse_ = true; dirty_flag_.Set(DirtyFlag::DirtyTransformInverse);
dirty_visibility_ = true; dirty_flag_.Set(DirtyFlag::DirtyVisibility);
if (is_fast_transform_) if (transform_.IsFast())
{ {
transform_matrix_to_parent_ = Matrix3x2::Translation(transform_.position); transform_matrix_to_parent_ = Matrix3x2::Translation(transform_.position);
} }
@ -349,11 +347,16 @@ void Actor::UpdateTransform() const
// update children's transform // update children's transform
for (const auto& child : children_) for (const auto& child : children_)
child->dirty_transform_ = true; child->dirty_flag_.Set(DirtyFlag::DirtyTransform);
} }
void Actor::UpdateOpacity() void Actor::UpdateOpacity()
{ {
if (!dirty_flag_.Has(DirtyFlag::DirtyOpacity))
return;
dirty_flag_.Unset(DirtyFlag::DirtyOpacity);
if (parent_ && parent_->IsCascadeOpacityEnabled()) if (parent_ && parent_->IsCascadeOpacityEnabled())
{ {
displayed_opacity_ = opacity_ * parent_->displayed_opacity_; displayed_opacity_ = opacity_ * parent_->displayed_opacity_;
@ -363,10 +366,8 @@ void Actor::UpdateOpacity()
displayed_opacity_ = opacity_; displayed_opacity_ = opacity_;
} }
for (auto& child : children_) for (const auto& child : children_)
{ child->dirty_flag_.Set(DirtyFlag::DirtyOpacity);
child->UpdateOpacity();
}
} }
void Actor::SetStage(Stage* stage) void Actor::SetStage(Stage* stage)
@ -428,7 +429,7 @@ void Actor::SetOpacity(float opacity)
return; return;
displayed_opacity_ = opacity_ = std::min(std::max(opacity, 0.f), 1.f); displayed_opacity_ = opacity_ = std::min(std::max(opacity, 0.f), 1.f);
UpdateOpacity(); dirty_flag_.Set(DirtyFlag::DirtyOpacity);
} }
void Actor::SetCascadeOpacityEnabled(bool enabled) void Actor::SetCascadeOpacityEnabled(bool enabled)
@ -437,7 +438,7 @@ void Actor::SetCascadeOpacityEnabled(bool enabled)
return; return;
cascade_opacity_ = enabled; cascade_opacity_ = enabled;
UpdateOpacity(); dirty_flag_.Set(DirtyFlag::DirtyOpacity);
} }
void Actor::SetAnchor(const Vec2& anchor) void Actor::SetAnchor(const Vec2& anchor)
@ -445,8 +446,8 @@ void Actor::SetAnchor(const Vec2& anchor)
if (anchor_ == anchor) if (anchor_ == anchor)
return; return;
anchor_ = anchor; anchor_ = anchor;
dirty_transform_ = true; dirty_flag_.Set(DirtyFlag::DirtyTransform);
} }
void Actor::SetSize(const Size& size) void Actor::SetSize(const Size& size)
@ -454,15 +455,14 @@ void Actor::SetSize(const Size& size)
if (size_ == size) if (size_ == size)
return; return;
size_ = size; size_ = size;
dirty_transform_ = true; dirty_flag_.Set(DirtyFlag::DirtyTransform);
} }
void Actor::SetTransform(const Transform& transform) void Actor::SetTransform(const Transform& transform)
{ {
transform_ = transform; transform_ = transform;
dirty_transform_ = true; dirty_flag_.Set(DirtyFlag::DirtyTransform);
is_fast_transform_ = false;
} }
void Actor::SetVisible(bool val) void Actor::SetVisible(bool val)
@ -472,11 +472,8 @@ void Actor::SetVisible(bool val)
void Actor::SetName(const String& name) void Actor::SetName(const String& name)
{ {
if (!IsName(name)) ObjectBase::SetName(name);
{ hash_name_ = std::hash<String>{}(name);
ObjectBase::SetName(name);
hash_name_ = std::hash<String>{}(name);
}
} }
void Actor::SetPosition(const Point& pos) void Actor::SetPosition(const Point& pos)
@ -485,7 +482,7 @@ void Actor::SetPosition(const Point& pos)
return; return;
transform_.position = pos; transform_.position = pos;
dirty_transform_ = true; dirty_flag_.Set(DirtyFlag::DirtyTransform);
} }
void Actor::SetScale(const Vec2& scale) void Actor::SetScale(const Vec2& scale)
@ -493,9 +490,8 @@ void Actor::SetScale(const Vec2& scale)
if (transform_.scale == scale) if (transform_.scale == scale)
return; return;
transform_.scale = scale; transform_.scale = scale;
dirty_transform_ = true; dirty_flag_.Set(DirtyFlag::DirtyTransform);
is_fast_transform_ = false;
} }
void Actor::SetSkew(const Vec2& skew) void Actor::SetSkew(const Vec2& skew)
@ -503,9 +499,8 @@ void Actor::SetSkew(const Vec2& skew)
if (transform_.skew == skew) if (transform_.skew == skew)
return; return;
transform_.skew = skew; transform_.skew = skew;
dirty_transform_ = true; dirty_flag_.Set(DirtyFlag::DirtyTransform);
is_fast_transform_ = false;
} }
void Actor::SetRotation(float angle) void Actor::SetRotation(float angle)
@ -514,8 +509,7 @@ void Actor::SetRotation(float angle)
return; return;
transform_.rotation = angle; transform_.rotation = angle;
dirty_transform_ = true; dirty_flag_.Set(DirtyFlag::DirtyTransform);
is_fast_transform_ = false;
} }
void Actor::AddChild(ActorPtr child) void Actor::AddChild(ActorPtr child)
@ -541,9 +535,9 @@ void Actor::AddChild(ActorPtr child)
child->parent_ = this; child->parent_ = this;
child->SetStage(this->stage_); child->SetStage(this->stage_);
child->dirty_transform_ = true; child->dirty_flag_.Set(DirtyFlag::DirtyTransform);
child->dirty_flag_.Set(DirtyFlag::DirtyOpacity);
child->Reorder(); child->Reorder();
child->UpdateOpacity();
} }
else else
{ {

View File

@ -446,6 +446,62 @@ public:
/// @brief 设置默认锚点 /// @brief 设置默认锚点
static void SetDefaultAnchor(float anchor_x, float anchor_y); static void SetDefaultAnchor(float anchor_x, float anchor_y);
/// \~chinese
/// @brief 获取可见性属性
inline Property<bool> VisibleProperty()
{
return Property<bool>(&visible_);
}
/// \~chinese
/// @brief 获取不透明度属性
inline Property<float, FlagUint8> OpacityProperty()
{
return Property<float, FlagUint8>(&opacity_, &dirty_flag_, DirtyFlag::DirtyOpacity);
}
/// \~chinese
/// @brief 获取锚点属性
inline Property<Point, FlagUint8> AnchorProperty()
{
return Property<Point, FlagUint8>(&anchor_, &dirty_flag_, DirtyFlag::DirtyTransform);
}
/// \~chinese
/// @brief 获取大小属性
inline Property<Size, FlagUint8> SizeProperty()
{
return Property<Size, FlagUint8>(&size_, &dirty_flag_, DirtyFlag::DirtyTransform);
}
/// \~chinese
/// @brief 获取位置属性
inline Property<Point, FlagUint8> PositionProperty()
{
return Property<Point, FlagUint8>(&transform_.position, &dirty_flag_, DirtyFlag::DirtyTransform);
}
/// \~chinese
/// @brief 获取旋转角度属性
inline Property<float, FlagUint8> RotationProperty()
{
return Property<float, FlagUint8>(&transform_.rotation, &dirty_flag_, DirtyFlag::DirtyTransform);
}
/// \~chinese
/// @brief 获取缩放属性
inline Property<Point, FlagUint8> ScaleProperty()
{
return Property<Point, FlagUint8>(&transform_.scale, &dirty_flag_, DirtyFlag::DirtyTransform);
}
/// \~chinese
/// @brief 获取错切角度属性
inline Property<Point, FlagUint8> SkewProperty()
{
return Property<Point, FlagUint8>(&transform_.skew, &dirty_flag_, DirtyFlag::DirtyTransform);
}
protected: protected:
/// \~chinese /// \~chinese
/// @brief 更新自身和所有子角色 /// @brief 更新自身和所有子角色
@ -494,33 +550,39 @@ protected:
friend physics::PhysicBody; friend physics::PhysicBody;
private: private:
bool visible_; bool visible_;
bool update_pausing_; bool update_pausing_;
bool cascade_opacity_; bool cascade_opacity_;
bool show_border_; bool show_border_;
bool hover_; bool hover_;
bool pressed_; bool pressed_;
bool responsible_; bool responsible_;
bool evt_dispatch_enabled_; bool evt_dispatch_enabled_;
int z_order_; mutable bool visible_in_rt_;
float opacity_;
float displayed_opacity_;
Actor* parent_;
Stage* stage_;
size_t hash_name_;
Point anchor_;
Size size_;
ActorList children_;
UpdateCallback cb_update_;
Transform transform_;
enum DirtyFlag : uint8_t
{
Clean = 0,
DirtyTransform = 1,
DirtyTransformInverse = 1 << 1,
DirtyOpacity = 1 << 2,
DirtyVisibility = 1 << 3
};
mutable Flag<uint8_t> dirty_flag_;
int z_order_;
float opacity_;
float displayed_opacity_;
Actor* parent_;
Stage* stage_;
physics::PhysicBody* physic_body_; physics::PhysicBody* physic_body_;
size_t hash_name_;
Point anchor_;
Size size_;
ActorList children_;
UpdateCallback cb_update_;
Transform transform_;
bool is_fast_transform_;
mutable bool visible_in_rt_;
mutable bool dirty_visibility_;
mutable bool dirty_transform_;
mutable bool dirty_transform_inverse_;
mutable Matrix3x2 transform_matrix_; mutable Matrix3x2 transform_matrix_;
mutable Matrix3x2 transform_matrix_inverse_; mutable Matrix3x2 transform_matrix_inverse_;
mutable Matrix3x2 transform_matrix_to_parent_; mutable Matrix3x2 transform_matrix_to_parent_;

View File

@ -0,0 +1,51 @@
// Copyright (c) 2019-2020 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 <type_traits> // std::is_arithmetic
namespace kiwano
{
namespace bits
{
template <typename _Ty>
inline void Set(_Ty& old, _Ty flag)
{
static_assert(std::is_arithmetic<_Ty>::value, "_Ty must be an arithmetic type");
old |= flag;
}
template <typename _Ty>
inline void Unset(_Ty& old, _Ty flag)
{
static_assert(std::is_arithmetic<_Ty>::value, "_Ty must be an arithmetic type");
old &= ~flag;
}
template <typename _Ty>
inline bool Has(_Ty old, _Ty flag)
{
static_assert(std::is_arithmetic<_Ty>::value, "_Ty must be an arithmetic type");
return !!(old & flag);
}
} // namespace bits
} // namespace kiwano

View File

@ -29,6 +29,9 @@
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <kiwano/macros.h> #include <kiwano/macros.h>
#include <kiwano/core/Property.h>
#include <kiwano/core/BitOperator.h>
#include <kiwano/core/Flag.h>
#include <kiwano/core/String.h> #include <kiwano/core/String.h>
#include <kiwano/core/Function.h> #include <kiwano/core/Function.h>
#include <kiwano/core/Singleton.h> #include <kiwano/core/Singleton.h>

234
src/kiwano/core/Flag.h Normal file
View File

@ -0,0 +1,234 @@
// Copyright (c) 2019-2020 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/core/BitOperator.h>
#include <cstdint> // uint8_t
namespace kiwano
{
template <typename _Ty>
class Flag
{
public:
static_assert(std::is_arithmetic<_Ty>::value, "_Ty must be an arithmetic type");
typedef _Ty value_type;
_Ty value;
inline Flag()
: value()
{
}
inline Flag(_Ty value)
: value(value)
{
}
inline void Set(_Ty value)
{
bits::Set(this->value, value);
}
inline void Unset(_Ty value)
{
bits::Unset(this->value, value);
}
inline bool Has(_Ty value) const
{
return bits::Has(this->value, value);
}
};
template <typename _Ty>
struct IsFlag : public std::false_type
{
};
template <typename _Ty>
struct IsFlag<Flag<_Ty>> : public std::true_type
{
};
typedef Flag<uint8_t> FlagUint8;
typedef Flag<uint16_t> FlagUint16;
typedef Flag<uint32_t> FlagUint32;
typedef Flag<uint64_t> FlagUint64;
typedef Flag<int8_t> FlagInt8;
typedef Flag<int16_t> FlagInt16;
typedef Flag<int32_t> FlagInt32;
typedef Flag<int64_t> FlagInt64;
namespace bits
{
template <>
inline void Set<FlagUint8>(FlagUint8& old, FlagUint8 flag)
{
old.Set(flag.value);
}
template <>
inline void Set<FlagUint16>(FlagUint16& old, FlagUint16 flag)
{
old.Set(flag.value);
}
template <>
inline void Set<FlagUint32>(FlagUint32& old, FlagUint32 flag)
{
old.Set(flag.value);
}
template <>
inline void Set<FlagUint64>(FlagUint64& old, FlagUint64 flag)
{
old.Set(flag.value);
}
template <>
inline void Set<FlagInt8>(FlagInt8& old, FlagInt8 flag)
{
old.Set(flag.value);
}
template <>
inline void Set<FlagInt16>(FlagInt16& old, FlagInt16 flag)
{
old.Set(flag.value);
}
template <>
inline void Set<FlagInt32>(FlagInt32& old, FlagInt32 flag)
{
old.Set(flag.value);
}
template <>
inline void Set<FlagInt64>(FlagInt64& old, FlagInt64 flag)
{
old.Set(flag.value);
}
template <>
inline void Unset<FlagUint8>(FlagUint8& old, FlagUint8 flag)
{
old.Unset(flag.value);
}
template <>
inline void Unset<FlagUint16>(FlagUint16& old, FlagUint16 flag)
{
old.Unset(flag.value);
}
template <>
inline void Unset<FlagUint32>(FlagUint32& old, FlagUint32 flag)
{
old.Unset(flag.value);
}
template <>
inline void Unset<FlagUint64>(FlagUint64& old, FlagUint64 flag)
{
old.Unset(flag.value);
}
template <>
inline void Unset<FlagInt8>(FlagInt8& old, FlagInt8 flag)
{
old.Unset(flag.value);
}
template <>
inline void Unset<FlagInt16>(FlagInt16& old, FlagInt16 flag)
{
old.Unset(flag.value);
}
template <>
inline void Unset<FlagInt32>(FlagInt32& old, FlagInt32 flag)
{
old.Unset(flag.value);
}
template <>
inline void Unset<FlagInt64>(FlagInt64& old, FlagInt64 flag)
{
old.Unset(flag.value);
}
template <>
inline bool Has<FlagUint8>(FlagUint8 old, FlagUint8 flag)
{
return old.Has(flag.value);
}
template <>
inline bool Has<FlagUint16>(FlagUint16 old, FlagUint16 flag)
{
return old.Has(flag.value);
}
template <>
inline bool Has<FlagUint32>(FlagUint32 old, FlagUint32 flag)
{
return old.Has(flag.value);
}
template <>
inline bool Has<FlagUint64>(FlagUint64 old, FlagUint64 flag)
{
return old.Has(flag.value);
}
template <>
inline bool Has<FlagInt8>(FlagInt8 old, FlagInt8 flag)
{
return old.Has(flag.value);
}
template <>
inline bool Has<FlagInt16>(FlagInt16 old, FlagInt16 flag)
{
return old.Has(flag.value);
}
template <>
inline bool Has<FlagInt32>(FlagInt32 old, FlagInt32 flag)
{
return old.Has(flag.value);
}
template <>
inline bool Has<FlagInt64>(FlagInt64 old, FlagInt64 flag)
{
return old.Has(flag.value);
}
} // namespace bits
} // namespace kiwano

View File

@ -0,0 +1,99 @@
// Copyright (c) 2019-2020 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/core/BitOperator.h>
#include <kiwano/core/Flag.h>
namespace kiwano
{
template <typename _Ty, typename _NotifierTy = void>
class Property;
template <typename _Ty>
class Property<_Ty, void>
{
public:
typedef _Ty value_type;
inline Property(_Ty* ptr)
: ptr_(ptr)
{
}
inline _Ty Get() const
{
return *ptr_;
}
inline void Set(const _Ty& value)
{
*ptr_ = value;
}
private:
_Ty* ptr_;
};
template <typename _Ty, typename _NotifierTy>
class Property
{
public:
typedef _Ty value_type;
typedef _NotifierTy notifier_type;
inline Property(_Ty* ptr)
: ptr_(ptr)
, notifier_(nullptr)
, notify_value_()
{
}
inline Property(_Ty* ptr, _NotifierTy* notifier, _NotifierTy notify_value)
: ptr_(ptr)
, notifier_(notifier)
, notify_value_(notify_value)
{
}
inline _Ty Get() const
{
return *ptr_;
}
inline void Set(const _Ty& value)
{
*ptr_ = value;
if (notifier_)
{
bits::Set(*notifier_, notify_value_);
}
}
private:
_Ty* ptr_;
_NotifierTy* notifier_;
_NotifierTy notify_value_;
};
}

View File

@ -49,6 +49,8 @@ public:
/// @brief 将二维放射变换转换为矩阵 /// @brief 将二维放射变换转换为矩阵
Matrix3x2T<ValueType> ToMatrix() const; Matrix3x2T<ValueType> ToMatrix() const;
bool IsFast() const;
bool operator==(const TransformT& rhs) const; bool operator==(const TransformT& rhs) const;
}; };
@ -71,6 +73,12 @@ Matrix3x2T<_Ty> TransformT<_Ty>::ToMatrix() const
return Matrix3x2T<_Ty>::SRT(position, scale, rotation); return Matrix3x2T<_Ty>::SRT(position, scale, rotation);
} }
template <typename _Ty>
inline bool TransformT<_Ty>::IsFast() const
{
return skew.x == 0.f && skew.y == 0.f && scale.x == 1.f && scale.y == 1.f && rotation == 0.f;
}
template <typename _Ty> template <typename _Ty>
bool TransformT<_Ty>::operator==(const TransformT& rhs) const bool TransformT<_Ty>::operator==(const TransformT& rhs) const
{ {