diff --git a/core/base/Action.hpp b/core/base/Action.hpp index 5ade761e..f47c17ee 100644 --- a/core/base/Action.hpp +++ b/core/base/Action.hpp @@ -75,7 +75,7 @@ namespace easy2d this->Reset(); } - virtual void Init(Node* target) {} + virtual void Init(Node* target) { initialized_ = true; } virtual void Update(Node* target, Duration const& dt) { diff --git a/core/base/ActionFiniteTime.cpp b/core/base/ActionFiniteTime.cpp index 25395946..44340bc2 100644 --- a/core/base/ActionFiniteTime.cpp +++ b/core/base/ActionFiniteTime.cpp @@ -356,8 +356,8 @@ namespace easy2d RotateBy::RotateBy(Duration const& duration, float rotation) : FiniteTimeAction(duration) + , delta_val_(rotation) { - delta_val_ = rotation; } void RotateBy::Init(Node* target) diff --git a/core/base/Image.cpp b/core/base/Image.cpp index 0c4ba8f6..ab6a9dc9 100644 --- a/core/base/Image.cpp +++ b/core/base/Image.cpp @@ -68,12 +68,14 @@ namespace easy2d bool Image::Load(Resource& res) { - HRESULT hr = devices::Graphics::Instance().CreateBitmapFromResource(res, &bitmap_); + ID2D1Bitmap* bitmap; + HRESULT hr = devices::Graphics::Instance().CreateBitmapFromResource(res, &bitmap); if (FAILED(hr)) { logs::Trace(L"Load Image from resource failed!", hr); return false; } + this->SetBitmap(bitmap); return true; } @@ -92,12 +94,14 @@ namespace easy2d // 默认搜索路径,所以需要通过 File::GetPath 获取完整路径 String image_file_path = image_file.GetPath(); - HRESULT hr = devices::Graphics::Instance().CreateBitmapFromFile(image_file_path, &bitmap_); + ID2D1Bitmap* bitmap; + HRESULT hr = devices::Graphics::Instance().CreateBitmapFromFile(image_file_path, &bitmap); if (FAILED(hr)) { logs::Trace(L"Load Image from file failed!", hr); return false; } + this->SetBitmap(bitmap); return true; } diff --git a/core/base/Input.cpp b/core/base/Input.cpp index a6a4e95e..0deef824 100644 --- a/core/base/Input.cpp +++ b/core/base/Input.cpp @@ -19,6 +19,7 @@ // THE SOFTWARE. #include "input.h" +#include namespace easy2d { @@ -28,6 +29,7 @@ namespace easy2d : initialized(false) { ZeroMemory(keys_, sizeof(keys_)); + ZeroMemory(keys_cache_, sizeof(keys_cache_)); } InputDevice::~InputDevice() @@ -44,11 +46,12 @@ namespace easy2d void InputDevice::Update(HWND hwnd, float scale_x, float scale_y) { - ::GetKeyboardState(keys_); + memcpy(keys_cache_, keys_, sizeof(keys_cache_)); + GetKeyboardState(keys_); POINT client_cursor_pos; - ::GetCursorPos(&client_cursor_pos); - ::ScreenToClient(hwnd, &client_cursor_pos); + GetCursorPos(&client_cursor_pos); + ScreenToClient(hwnd, &client_cursor_pos); mouse_pos_ = Point(client_cursor_pos.x * scale_x, client_cursor_pos.y * scale_y); } @@ -67,6 +70,22 @@ namespace easy2d return false; } + bool InputDevice::WasPressed(KeyCode code) + { + if (keys_cache_[static_cast(code)] & 0x80 && + !(keys_[static_cast(code)] & 0x80)) + return true; + return false; + } + + bool InputDevice::WasPressed(MouseCode code) + { + if (keys_cache_[static_cast(code)] & 0x80 && + !(keys_[static_cast(code)] & 0x80)) + return true; + return false; + } + float InputDevice::GetMouseX() { return mouse_pos_.x; diff --git a/core/base/Input.h b/core/base/Input.h index 2e875570..8e48e963 100644 --- a/core/base/Input.h +++ b/core/base/Input.h @@ -45,6 +45,16 @@ namespace easy2d MouseCode code ); + // 检测键盘某按键是否点击 + bool WasPressed( + KeyCode code + ); + + // 检测鼠标按键是否点击 + bool WasPressed( + MouseCode code + ); + // 获得鼠标X轴坐标值 float GetMouseX(); @@ -69,6 +79,7 @@ namespace easy2d protected: bool initialized; BYTE keys_[256]; + BYTE keys_cache_[256]; Point mouse_pos_; }; diff --git a/core/base/IntrusivePtr.hpp b/core/base/IntrusivePtr.hpp index 378818dd..220e2211 100644 --- a/core/base/IntrusivePtr.hpp +++ b/core/base/IntrusivePtr.hpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include +#include "macros.h" namespace easy2d { @@ -51,7 +51,11 @@ namespace easy2d IntrusivePtrAddRef(ptr_); } - IntrusivePtr(IntrusivePtr&& other) : ptr_(::std::move(other.ptr_)) {} + IntrusivePtr(IntrusivePtr&& other) + { + ptr_ = other.ptr_; + other.ptr_ = nullptr; + } ~IntrusivePtr() { @@ -67,14 +71,14 @@ namespace easy2d inline ElemType* operator ->() const { - assert(ptr_ && ptr_->GetRefCount() > 0 && + E2D_WARNING_IF(!ptr_ || ptr_->GetRefCount() <= 0, "Invalid pointer!"); return ptr_; } inline ElemType& operator *() const { - assert(ptr_ && ptr_->GetRefCount() > 0 && + E2D_WARNING_IF(!ptr_ || ptr_->GetRefCount() <= 0, "Invalid pointer!"); return *ptr_; } @@ -89,6 +93,14 @@ namespace easy2d return *this; } + inline IntrusivePtr& operator =(IntrusivePtr&& other) + { + IntrusivePtrRelease(ptr_); + ptr_ = other.ptr_; + other.ptr_ = nullptr; + return *this; + } + inline IntrusivePtr& operator =(ElemType* p) { IntrusivePtr(p).Swap(*this); diff --git a/core/base/Node.cpp b/core/base/Node.cpp index ba70b52c..3eb6c2cd 100644 --- a/core/base/Node.cpp +++ b/core/base/Node.cpp @@ -23,7 +23,6 @@ #include "Task.h" #include "Action.hpp" #include "render.h" -#include namespace easy2d { @@ -56,14 +55,16 @@ namespace easy2d if (!visible_) return; + auto& graphics = devices::Graphics::Instance(); + if (clip_enabled_) { - devices::Graphics::Instance().PushClip(final_matrix_, transform_.size); + graphics.PushClip(final_matrix_, transform_.size); } if (children_.empty()) { - devices::Graphics::Instance().SetTransform(final_matrix_); + graphics.SetTransform(final_matrix_); OnDraw(); } else @@ -72,8 +73,8 @@ namespace easy2d if (dirty_sort_) { std::sort( - std::begin(children_), - std::end(children_), + children_.begin(), + children_.end(), [](spNode const& n1, spNode const& n2) { return n1->GetOrder() < n2->GetOrder(); } ); @@ -95,7 +96,7 @@ namespace easy2d } } - devices::Graphics::Instance().SetTransform(final_matrix_); + graphics.SetTransform(final_matrix_); OnDraw(); // 访问剩余节点 @@ -105,7 +106,7 @@ namespace easy2d if (clip_enabled_) { - devices::Graphics::Instance().PopClip(); + graphics.PopClip(); } } @@ -170,13 +171,9 @@ namespace easy2d dirty_transform_ = false; final_matrix_ = transform_.ToMatrix(); - - // 根据自身支点计算 Initial 矩阵,子节点将根据这个矩阵进行变换 - auto pivot = Point( - transform_.size.width * transform_.pivot.x, - transform_.size.height * transform_.pivot.y + initial_matrix_ = final_matrix_ * math::Matrix::Translation( + Point{ transform_.size.width * transform_.pivot.x, transform_.size.height * transform_.pivot.y } ); - initial_matrix_ = final_matrix_ * math::Matrix::Translation(pivot); if (parent_) { @@ -186,13 +183,11 @@ namespace easy2d // 重新构造轮廓 SafeRelease(border_); - ThrowIfFailed( devices::Graphics::Instance().CreateRectGeometry(final_matrix_, transform_.size, &border_) ); - // 通知子节点进行转换 - for (const auto& child : children_) + for (auto& child : children_) { child->dirty_transform_ = true; } diff --git a/core/base/macros.h b/core/base/macros.h index ff5aa84a..90b564d1 100644 --- a/core/base/macros.h +++ b/core/base/macros.h @@ -85,8 +85,10 @@ #if VS_VER >= VS_2015 # define E2D_NOEXCEPT noexcept +# define E2D_CONSTEXPR constexpr #else # define E2D_NOEXCEPT throw() +# define E2D_CONSTEXPR const #endif diff --git a/core/math/Matrix.hpp b/core/math/Matrix.hpp index 7fb25aa9..34cde770 100644 --- a/core/math/Matrix.hpp +++ b/core/math/Matrix.hpp @@ -26,127 +26,105 @@ namespace easy2d { namespace math { + class Matrix; + + template + struct MatrixMultiply; + + inline MatrixMultiply + operator *(Matrix const& lhs, Matrix const& rhs); + + template + inline MatrixMultiply, Matrix> + operator *(MatrixMultiply const& lhs, Matrix const& rhs); + + class Matrix { - float _11; - float _12; - float _21; - float _22; - float _31; - float _32; + float m[6]; // m[3][2] public: Matrix() - : _11(1.f) - , _12(0.f) - , _21(0.f) - , _22(1.f) - , _31(0.f) - , _32(0.f) { + m[0] = 1.f; m[1] = 0.f; + m[2] = 0.f; m[3] = 1.f; + m[4] = 0.f; m[5] = 0.f; } - Matrix( - float _11, - float _12, - float _21, - float _22, - float _31, - float _32) + Matrix(float val[6]) { - this->_11 = _11; - this->_12 = _12; - this->_21 = _21; - this->_22 = _22; - this->_31 = _31; - this->_32 = _32; + m[0] = val[0]; m[1] = val[1]; + m[2] = val[2]; m[3] = val[3]; + m[4] = val[4]; m[5] = val[5]; } - inline const Matrix operator*(const Matrix &matrix) const + Matrix(float _11, float _12, float _21, float _22, float _31, float _32) { - return Matrix( - _11 * matrix._11 + _12 * matrix._21, - _11 * matrix._12 + _12 * matrix._22, - _21 * matrix._11 + _22 * matrix._21, - _21 * matrix._12 + _22 * matrix._22, - _31 * matrix._11 + _32 * matrix._21 + matrix._31, - _31 * matrix._12 + _32 * matrix._22 + matrix._32 - ); + m[0] = _11; m[1] = _12; + m[2] = _21; m[3] = _22; + m[4] = _31; m[5] = _32; + } + + Matrix(Matrix const& other) + { + m[0] = other.m[0]; m[1] = other.m[1]; + m[2] = other.m[2]; m[3] = other.m[3]; + m[4] = other.m[4]; m[5] = other.m[5]; + } + + template + Matrix(T const& other) + { + m[0] = other[0]; m[1] = other[1]; + m[2] = other[2]; m[3] = other[3]; + m[4] = other[4]; m[5] = other[5]; + } + + inline float operator [](unsigned int index) const { return m[index]; } + + template + inline Matrix& operator =(T const& other) + { + m[0] = other[0]; m[1] = other[1]; + m[2] = other[2]; m[3] = other[3]; + m[4] = other[4]; m[5] = other[5]; + return *this; } inline operator D2D1_MATRIX_3X2_F () const { return D2D1_MATRIX_3X2_F{ - _11, _12, - _21, _22, - _31, _32 + m[0], m[1], + m[2], m[3], + m[4], m[5] }; } inline Matrix& Identity() { - _11 = 1.f; - _12 = 0.f; - _21 = 0.f; - _22 = 1.f; - _31 = 0.f; - _32 = 0.f; - return *this; - } - - inline Matrix& Translate(const Vector2& v) - { - *this = *this * Matrix::Translation(v); - return *this; - } - - inline Matrix& Translate(float x, float y) - { - *this = *this * Matrix::Translation(x, y); - return *this; - } - - inline Matrix& Scale(const Vector2& v, const Vector2& center) - { - *this = *this * Matrix::Scaling(v, center); - return *this; - } - - inline Matrix& Scale(float scale_x, float scale_y, const Vector2& center) - { - *this = *this * Matrix::Scaling(scale_x, scale_y, center); - return *this; - } - - inline Matrix& Rotate(float angle, const Vector2& center) - { - *this = *this * Matrix::Rotation(angle, center); - return *this; - } - - inline Matrix& Skew(float angle_x, float angle_y, const Vector2& center) - { - *this = *this * Matrix::Skewing(angle_x, angle_y, center); + m[0] = 1.f; m[1] = 0.f; + m[2] = 0.f; m[3] = 1.f; + m[4] = 0.f; m[5] = 0.f; return *this; } inline float Determinant() const { - return (_11 * _22) - (_12 * _21); + return (m[0] * m[3]) - (m[1] * m[2]); } inline bool IsIdentity() const { - return _11 == 1.f && _12 == 0.f && - _21 == 0.f && _22 == 1.f && - _31 == 0.f && _32 == 0.f; + return m[0] == 1.f && m[1] == 0.f && + m[2] == 0.f && m[3] == 1.f && + m[4] == 0.f && m[5] == 0.f; } Vector2 Transform(const Vector2& v) const { return Vector2( - v.x * _11 + v.y * _21 + _31, - v.x * _12 + v.y * _22 + _32 + v.x * m[0] + v.y * m[2] + m[4], + v.x * m[1] + v.y * m[3] + m[5] ); } @@ -214,5 +192,50 @@ namespace easy2d ); } }; + + + template + struct MatrixMultiply + { + L const& lhs; + R const& rhs; + + MatrixMultiply(L const& lhs, R const& rhs) + : lhs(lhs) + , rhs(rhs) + {} + + inline float operator [](unsigned int index) const + { + switch (index) + { + case 0: + return lhs[0] * rhs[0] + lhs[1] * rhs[2]; + case 1: + return lhs[0] * rhs[1] + lhs[1] * rhs[3]; + case 2: + return lhs[2] * rhs[0] + lhs[3] * rhs[2]; + case 3: + return lhs[2] * rhs[1] + lhs[3] * rhs[3]; + case 4: + return lhs[4] * rhs[0] + lhs[5] * rhs[2] + rhs[4]; + case 5: + return lhs[4] * rhs[1] + lhs[5] * rhs[3] + rhs[5]; + default: + return 0.f; + } + } + }; + + inline MatrixMultiply operator *(Matrix const& lhs, Matrix const& rhs) + { + return MatrixMultiply(lhs, rhs); + } + + template + inline MatrixMultiply, Matrix> operator *(MatrixMultiply const& lhs, Matrix const& rhs) + { + return MatrixMultiply, Matrix>(lhs, rhs); + } } } diff --git a/core/math/Transform.hpp b/core/math/Transform.hpp index fde7d9bd..d15f762d 100644 --- a/core/math/Transform.hpp +++ b/core/math/Transform.hpp @@ -49,10 +49,10 @@ namespace easy2d inline Matrix ToMatrix() const { auto center = Vector2{ size.width * pivot.x, size.height * pivot.y }; - return Matrix{}.Scale(scale.x, scale.y, center) - .Skew(skew.x, skew.y, center) - .Rotate(rotation, center) - .Translate(position - center); + return Matrix{} * Matrix::Scaling(scale.x, scale.y, center) + * Matrix::Skewing(skew.x, skew.y, center) + * Matrix::Rotation(rotation, center) + * Matrix::Translation(position - center); } bool operator== (const Transform& other) const diff --git a/core/math/scalar.hpp b/core/math/scalar.hpp index 84653ffc..feaf8a82 100644 --- a/core/math/scalar.hpp +++ b/core/math/scalar.hpp @@ -21,10 +21,23 @@ #pragma once #include +#if _MSC_VER >= 1900 +# define E2D_CONSTEXPR constexpr +#else +# define E2D_CONSTEXPR const +#endif + + namespace easy2d { namespace math { + namespace constants + { + E2D_CONSTEXPR auto PIf = 3.14159265358979f; + E2D_CONSTEXPR auto PId = 3.14159265358979323846; + } + inline int Abs(int val) { return ::abs(val); } inline float Abs(float val) { return ::fabsf(val); } @@ -41,17 +54,17 @@ namespace easy2d inline double Sign(double val) { return val < 0 ? -1.0 : 1.0; } - inline float Sin(float val) { return ::sinf(val); } + inline float Sin(float val) { return ::sinf(val * constants::PIf / 180.f); } - inline double Sin(double val) { return ::sin(val); } + inline double Sin(double val) { return ::sin(val * constants::PId / 180.0); } - inline float Cos(float val) { return ::cosf(val); } + inline float Cos(float val) { return ::cosf(val * constants::PIf / 180.f); } - inline double Cos(double val) { return ::cos(val); } + inline double Cos(double val) { return ::cos(val * constants::PId / 180.0); } - inline float Tan(float val) { return ::tanf(val); } + inline float Tan(float val) { return ::tanf(val * constants::PIf / 180.f); } - inline double Tan(double val) { return ::tan(val); } + inline double Tan(double val) { return ::tan(val * constants::PId / 180.0); } inline float Ceil(float val) { return ::ceil(val); } diff --git a/core/utils/File.cpp b/core/utils/File.cpp index fc34d7bf..be285348 100644 --- a/core/utils/File.cpp +++ b/core/utils/File.cpp @@ -160,7 +160,7 @@ namespace easy2d auto iter = std::find(search_paths_.cbegin(), search_paths_.cend(), tmp); if (iter == search_paths_.cend()) { - search_paths_.push_front(path); + search_paths_.push_front(tmp); } }