diff --git a/core/base/Action.hpp b/core/base/Action.hpp index 43cf2616..7d1b43ec 100644 --- a/core/base/Action.hpp +++ b/core/base/Action.hpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include "base.hpp" +#include "include-forwards.h" #include "time.h" #include "noncopyable.hpp" #include "intrusive/List.hpp" @@ -29,7 +29,7 @@ namespace easy2d class ActionManager; class Action - : public ObjectBase + : public Object , protected intrusive::ListItem { friend class ActionManager; @@ -53,7 +53,7 @@ namespace easy2d virtual void Pause() { running_ = false; } // 停止动作 - virtual void Stop() { if (!done_) { done_ = true; cb_(); } } + virtual void Stop() { if (!done_) { done_ = true; if (cb_) cb_(); } } // 获取动作的拷贝 virtual spAction Clone() const = 0; diff --git a/core/base/ActionManager.cpp b/core/base/ActionManager.cpp index 6b618a1e..b5681757 100644 --- a/core/base/ActionManager.cpp +++ b/core/base/ActionManager.cpp @@ -57,7 +57,7 @@ namespace easy2d if (actions_.IsEmpty()) return; - for (auto action = actions_.First(); action; action = action->NextItem()) + for (auto action = actions_.First().Get(); action; action = action->NextItem().Get()) { action->Resume(); } @@ -68,7 +68,7 @@ namespace easy2d if (actions_.IsEmpty()) return; - for (auto action = actions_.First(); action; action = action->NextItem()) + for (auto action = actions_.First().Get(); action; action = action->NextItem().Get()) { action->Pause(); } @@ -79,7 +79,7 @@ namespace easy2d if (actions_.IsEmpty()) return; - for (auto action = actions_.First(); action; action = action->NextItem()) + for (auto action = actions_.First().Get(); action; action = action->NextItem().Get()) { action->Stop(); } diff --git a/core/base/ActionTween.cpp b/core/base/ActionTween.cpp index 7df730f6..0bd64bf9 100644 --- a/core/base/ActionTween.cpp +++ b/core/base/ActionTween.cpp @@ -20,7 +20,7 @@ #include "ActionTween.h" #include "Geometry.h" -#include "base.hpp" +#include "include-forwards.h" #include "Node.h" #include #include @@ -56,13 +56,13 @@ namespace easy2d case EaseFunc::Linear: ease_func_ = math::Linear; break; - case EaseFunc::In: + case EaseFunc::EaseIn: ease_func_ = MakeEaseIn(2.f); break; - case EaseFunc::Out: + case EaseFunc::EaseOut: ease_func_ = MakeEaseOut(2.f); break; - case EaseFunc::InOut: + case EaseFunc::EaseInOut: ease_func_ = MakeEaseInOut(2.f); break; case EaseFunc::ExpoIn: @@ -552,6 +552,16 @@ namespace easy2d return new PathAction(duration_, geo_, rotating_, end_, start_, ease_type_); } + void PathAction::Init(Node * target) + { + Tween::Init(target); + + if (target) + { + start_pos_ = target->GetPosition(); + } + } + void PathAction::UpdateStep(Node* target, float step) { if (target) @@ -561,7 +571,7 @@ namespace easy2d Point point, tangent; if (geo_->ComputePointAt(length, &point, &tangent)) { - target->SetPosition(point); + target->SetPosition(start_pos_ + point); if (rotating_) { diff --git a/core/base/ActionTween.h b/core/base/ActionTween.h index 212f6b4d..5c9dba02 100644 --- a/core/base/ActionTween.h +++ b/core/base/ActionTween.h @@ -30,9 +30,9 @@ namespace easy2d enum class EaseFunc { Linear, // 线性 - In, // 由慢变快 - Out, // 由快变慢 - InOut, // 由慢变快, 再由快变慢 + EaseIn, // 由慢变快 + EaseOut, // 由快变慢 + EaseInOut, // 由慢变快, 再由快变慢 ExpoIn, // 由慢变极快 ExpoOut, // 由极快变慢 ExpoInOut, // 由慢至极快, 再由极快边慢 @@ -473,12 +473,15 @@ namespace easy2d virtual spAction Reverse() const override; protected: + virtual void Init(Node* target) override; + virtual void UpdateStep(Node* target, float step) override; protected: bool rotating_; float start_; float end_; + Point start_pos_; spGeometry geo_; }; } diff --git a/core/base/Canvas.cpp b/core/base/Canvas.cpp index b1926b09..b295922a 100644 --- a/core/base/Canvas.cpp +++ b/core/base/Canvas.cpp @@ -160,7 +160,7 @@ namespace easy2d void Canvas::SetBrushTransform(math::Matrix const & transform) { - render_target_->SetTransform(ConvertToD2DMatrix(transform)); + render_target_->SetTransform(transform); } void Canvas::DrawLine(const Point & begin, const Point & end) @@ -262,7 +262,7 @@ namespace easy2d } } - void Canvas::DrawText(String const & text, Point const & point) + void Canvas::DrawText(std::wstring const & text, Point const & point) { if (text.empty()) return; diff --git a/core/base/Canvas.h b/core/base/Canvas.h index e8997ee1..2db1419a 100644 --- a/core/base/Canvas.h +++ b/core/base/Canvas.h @@ -91,7 +91,7 @@ namespace easy2d // 画文字 void DrawText( - String const& text, /* 文字 */ + std::wstring const& text, /* 文字 */ Point const& point /* 文字位置 */ ); diff --git a/core/base/Debuger.cpp b/core/base/DebugNode.cpp similarity index 66% rename from core/base/Debuger.cpp rename to core/base/DebugNode.cpp index 79b06a17..6395670c 100644 --- a/core/base/Debuger.cpp +++ b/core/base/DebugNode.cpp @@ -18,7 +18,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include "Debuger.h" +#include "DebugNode.h" +#include "render.h" #include "../utils/string.h" #include #include @@ -28,10 +29,10 @@ namespace easy2d { - DebugerNode::DebugerNode() + DebugNodeImpl::DebugNodeImpl() { debug_text_ = new Text(); - debug_text_->SetPosition(10, 10); + debug_text_->SetPosition(15, 15); this->AddChild(debug_text_); Font font; @@ -41,18 +42,15 @@ namespace easy2d TextStyle style; style.wrap = false; - style.line_spacing = 18.f; + style.line_spacing = 20.f; debug_text_->SetStyle(style); - - ObjectBase::__RemoveObjectFromTracingList(this); - ObjectBase::__RemoveObjectFromTracingList(debug_text_.Get()); } - DebugerNode::~DebugerNode() + DebugNodeImpl::~DebugNodeImpl() { } - void DebugerNode::AddDebugText(String const & text) + void DebugNodeImpl::AddDebugText(std::wstring const & text) { try { @@ -63,12 +61,29 @@ namespace easy2d } } - void DebugerNode::ClearDebugText() + void DebugNodeImpl::ClearDebugText() { texts_.clear(); } - void DebugerNode::Update(Duration const & dt) + void DebugNodeImpl::OnRender() + { + auto graphics = Graphics::Instance(); + + graphics->SetTransform(math::Matrix{}); + + graphics->GetSolidBrush()->SetColor(Color(0.0f, 0.0f, 0.0f, 0.5f)); + + graphics->GetRenderTarget()->FillRoundedRectangle( + D2D1::RoundedRect( + D2D1_RECT_F{ 10, 10, 200, 120 }, + 6.f, + 6.f), + graphics->GetSolidBrush().Get() + ); + } + + void DebugNodeImpl::OnUpdate(Duration const & dt) { try { @@ -85,20 +100,19 @@ namespace easy2d } std::wstringstream ss; - ss << "fps=" << frame_time_.size() << std::endl; + ss << "Fps: " << frame_time_.size() << std::endl; #ifdef E2D_DEBUG - - ss << "objects=" << ObjectBase::__GetTracingObjects().size() << std::endl; - + ss << "Objects: " << Object::__GetTracingObjects().size() << std::endl; #endif + ss << "Render: " << Graphics::Instance()->GetStatus().duration.Milliseconds() << "ms" << std::endl; + + ss << "Primitives / sec: " << Graphics::Instance()->GetStatus().primitives * frame_time_.size() << std::endl; + PROCESS_MEMORY_COUNTERS_EX pmc; GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)); - if (pmc.PrivateUsage > 1024 * 1024) - ss << "memory=" << pmc.PrivateUsage / 1024 / 1024 << "Mb " << (pmc.PrivateUsage / 1024) % 1024 << "Kb"; - else - ss << "memory=" << pmc.PrivateUsage / 1024 << "Kb"; + ss << "Memory: " << pmc.PrivateUsage / 1024 << "kb"; for (const auto& text : texts_) ss << std::endl << text; diff --git a/core/base/Debuger.h b/core/base/DebugNode.h similarity index 80% rename from core/base/Debuger.h rename to core/base/DebugNode.h index c585251f..d63d48d9 100644 --- a/core/base/Debuger.h +++ b/core/base/DebugNode.h @@ -25,27 +25,29 @@ namespace easy2d { - class DebugerNode + class DebugNodeImpl : public Node { - E2D_DECLARE_SINGLETON(DebugerNode); + E2D_DECLARE_SINGLETON(DebugNodeImpl); public: - DebugerNode(); + DebugNodeImpl(); - virtual ~DebugerNode(); + virtual ~DebugNodeImpl(); - void AddDebugText(String const& text); + void AddDebugText(std::wstring const& text); void ClearDebugText(); - void Update(Duration const& dt) override; + void OnRender() override; + + void OnUpdate(Duration const& dt) override; protected: spText debug_text_; std::vector frame_time_; - std::vector texts_; + std::vector texts_; }; - E2D_DECLARE_SINGLETON_TYPE(DebugerNode, Debuger); + E2D_DECLARE_SINGLETON_TYPE(DebugNodeImpl, DebugNode); } diff --git a/core/base/Event.hpp b/core/base/Event.hpp index ee1fa0b0..fda759c1 100644 --- a/core/base/Event.hpp +++ b/core/base/Event.hpp @@ -30,6 +30,8 @@ namespace easy2d public: Event(EventType type) : type(type), has_target(false) {} + virtual ~Event() {} + EventType type; bool has_target; }; diff --git a/core/base/EventDispatcher.cpp b/core/base/EventDispatcher.cpp index 427c2b29..d93112bb 100644 --- a/core/base/EventDispatcher.cpp +++ b/core/base/EventDispatcher.cpp @@ -50,7 +50,7 @@ namespace easy2d } } - void EventDispatcher::AddListener(EventType type, EventCallback callback, String const& name) + void EventDispatcher::AddListener(EventType type, EventCallback callback, std::wstring const& name) { spEventListener listener = new EventListener(type, callback, name); if (listener) @@ -59,7 +59,7 @@ namespace easy2d } } - void EventDispatcher::StartListeners(String const & listener_name) + void EventDispatcher::StartListeners(std::wstring const & listener_name) { for (auto listener = listeners_.First(); listener; listener = listener->NextItem()) { @@ -70,7 +70,7 @@ namespace easy2d } } - void EventDispatcher::StopListeners(String const & listener_name) + void EventDispatcher::StopListeners(std::wstring const & listener_name) { for (auto listener = listeners_.First(); listener; listener = listener->NextItem()) { @@ -81,7 +81,7 @@ namespace easy2d } } - void EventDispatcher::RemoveListeners(String const & listener_name) + void EventDispatcher::RemoveListeners(std::wstring const & listener_name) { spEventListener next; for (auto listener = listeners_.First(); listener; listener = next) diff --git a/core/base/EventDispatcher.h b/core/base/EventDispatcher.h index e8a6c1c7..2e53f547 100644 --- a/core/base/EventDispatcher.h +++ b/core/base/EventDispatcher.h @@ -37,22 +37,22 @@ namespace easy2d void AddListener( EventType type, EventCallback callback, - String const& name = L"" + std::wstring const& name = L"" ); // 启动监听器 void StartListeners( - String const& listener_name + std::wstring const& listener_name ); // 停止监听器 void StopListeners( - String const& listener_name + std::wstring const& listener_name ); // 移除监听器 void RemoveListeners( - String const& listener_name + std::wstring const& listener_name ); // 启动监听器 diff --git a/core/base/EventListener.cpp b/core/base/EventListener.cpp index 47eab905..da6ca97e 100644 --- a/core/base/EventListener.cpp +++ b/core/base/EventListener.cpp @@ -23,7 +23,7 @@ namespace easy2d { - EventListener::EventListener(EventType type, EventCallback const & callback, String const & name) + EventListener::EventListener(EventType type, EventCallback const & callback, std::wstring const & name) : type_(type) , callback_(callback) , name_(name) @@ -50,12 +50,12 @@ namespace easy2d return running_; } - String const & EventListener::GetName() const + std::wstring const & EventListener::GetName() const { return name_; } - void EventListener::SetName(String const & name) + void EventListener::SetName(std::wstring const & name) { name_ = name; } diff --git a/core/base/EventListener.h b/core/base/EventListener.h index 159636e5..fbdc890a 100644 --- a/core/base/EventListener.h +++ b/core/base/EventListener.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include "base.hpp" +#include "include-forwards.h" #include "intrusive/List.hpp" #include "Event.hpp" @@ -31,7 +31,7 @@ namespace easy2d class EventDispatcher; class EventListener - : public RefCounter + : public Object , protected intrusive::ListItem { friend class EventDispatcher; @@ -41,7 +41,7 @@ namespace easy2d EventListener( EventType type, EventCallback const& callback, - String const& name = L"" + std::wstring const& name = L"" ); virtual ~EventListener(); @@ -50,15 +50,15 @@ namespace easy2d void Stop(); - void SetName(String const& name); + void SetName(std::wstring const& name); bool IsRunning() const; - String const& GetName() const; + std::wstring const& GetName() const; protected: bool running_; - String name_; + std::wstring name_; EventType type_; EventCallback callback_; }; diff --git a/core/base/Factory.cpp b/core/base/Factory.cpp index cc8c0100..c733552f 100644 --- a/core/base/Factory.cpp +++ b/core/base/Factory.cpp @@ -150,7 +150,7 @@ namespace easy2d return hr; } - HRESULT FactoryImpl::CreateBitmapFromFile(cpBitmap & bitmap, cpRenderTarget const & rt, String const & file_path) + HRESULT FactoryImpl::CreateBitmapFromFile(cpBitmap & bitmap, cpRenderTarget const & rt, std::wstring const & file_path) { if (imaging_factory_ == nullptr) { @@ -361,7 +361,7 @@ namespace easy2d cpTransformedGeometry transformed_tmp; HRESULT hr = factory_->CreateTransformedGeometry( geo.Get(), - ConvertToD2DMatrix(matrix), + matrix, &transformed_tmp ); @@ -418,7 +418,7 @@ namespace easy2d return hr; } - HRESULT FactoryImpl::CreateTextLayout(cpTextLayout & text_layout, Size& layout_size, String const & text, cpTextFormat const& text_format, TextStyle const & text_style) const + HRESULT FactoryImpl::CreateTextLayout(cpTextLayout & text_layout, Size& layout_size, std::wstring const & text, cpTextFormat const& text_format, TextStyle const & text_style) const { if (!write_factory_) return E_UNEXPECTED; diff --git a/core/base/Factory.h b/core/base/Factory.h index d84eed04..26f558c9 100644 --- a/core/base/Factory.h +++ b/core/base/Factory.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include "base.hpp" +#include "include-forwards.h" #include "Singleton.hpp" #include "Font.hpp" #include "Resource.h" @@ -52,7 +52,7 @@ namespace easy2d HRESULT CreateBitmapFromFile( cpBitmap& bitmap, cpRenderTarget const& rt, - String const& file_path + std::wstring const& file_path ); HRESULT CreateBitmapFromResource( @@ -99,7 +99,7 @@ namespace easy2d HRESULT CreateTextLayout( cpTextLayout& text_layout, Size& layout_size, - String const& text, + std::wstring const& text, cpTextFormat const& text_format, TextStyle const& text_style ) const; diff --git a/core/base/Frames.h b/core/base/Frames.h index 12363e1e..766bc198 100644 --- a/core/base/Frames.h +++ b/core/base/Frames.h @@ -19,14 +19,14 @@ // THE SOFTWARE. #pragma once -#include "base.hpp" +#include "include-forwards.h" #include "time.h" namespace easy2d { // 帧集合 class Frames - : public ObjectBase + : public Object { using Images = std::vector< spImage >; diff --git a/core/base/Game.cpp b/core/base/Game.cpp index f2aa48a3..402eab8a 100644 --- a/core/base/Game.cpp +++ b/core/base/Game.cpp @@ -23,7 +23,7 @@ #include "modules.h" #include "Factory.h" #include "Scene.h" -#include "Debuger.h" +#include "DebugNode.h" #include "Transition.h" #include "KeyEvent.hpp" #include "MouseEvent.hpp" @@ -206,7 +206,7 @@ namespace easy2d next_scene_->Update(dt); if (debug_) - Debuger::Instance()->Update(dt); + DebugNode::Instance()->Update(dt); if (transition_) { @@ -250,22 +250,7 @@ namespace easy2d } if (debug_) - { - graphics->SetTransform(math::Matrix()); - graphics->SetOpacity(1.f); - - if (curr_scene_) - { - curr_scene_->DrawBorder(); - } - - if (next_scene_) - { - next_scene_->DrawBorder(); - } - - Debuger::Instance()->Render(); - } + DebugNode::Instance()->Render(); ThrowIfFailed( graphics->EndDraw() diff --git a/core/base/Game.h b/core/base/Game.h index d032a24f..8ac0f898 100644 --- a/core/base/Game.h +++ b/core/base/Game.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include "base.hpp" +#include "include-forwards.h" #include "time.h" #include "window.h" #include "render.h" @@ -31,7 +31,7 @@ namespace easy2d { struct Options { - String title; // 标题 + std::wstring title; // 标题 int width; // 宽度 int height; // 高度 LPCWSTR icon; // 图标 diff --git a/core/base/Geometry.cpp b/core/base/Geometry.cpp index 117e3472..26349a21 100644 --- a/core/base/Geometry.cpp +++ b/core/base/Geometry.cpp @@ -44,10 +44,7 @@ namespace easy2d D2D1_RECT_F rect; // no matter it failed or not - geo_->GetBounds( - ConvertToD2DMatrix(GetTransformMatrix()), - &rect - ); + geo_->GetBounds(D2D1::Matrix3x2F::Identity(), &rect); return rect; } @@ -57,10 +54,7 @@ namespace easy2d if (geo_) { // no matter it failed or not - geo_->ComputeLength( - ConvertToD2DMatrix(GetTransformMatrix()), - &length - ); + geo_->ComputeLength(D2D1::Matrix3x2F::Identity(), &length); } return length; } @@ -72,7 +66,7 @@ namespace easy2d D2D1_POINT_2F point_tmp, tangent_tmp; if (SUCCEEDED(geo_->ComputePointAtLength( length, - ConvertToD2DMatrix(GetTransformMatrix()), + D2D1::Matrix3x2F::Identity(), &point_tmp, &tangent_tmp))) { @@ -93,10 +87,7 @@ namespace easy2d float area = 0.f; // no matter it failed or not - geo_->ComputeArea( - ConvertToD2DMatrix(GetTransformMatrix()), - &area - ); + geo_->ComputeArea(D2D1::Matrix3x2F::Identity(), &area); return area; } @@ -109,37 +100,12 @@ namespace easy2d // no matter it failed or not geo_->FillContainsPoint( point, - ConvertToD2DMatrix(GetTransformMatrix()), + D2D1::Matrix3x2F::Identity(), &ret ); return !!ret; } - GeometryRelation Geometry::GetRelationWith(spGeometry const & other) - { - if (!geo_ || !other->geo_) - return GeometryRelation::Unknown; - - cpTransformedGeometry transformed; - HRESULT hr = Factory::Instance()->CreateTransformedGeometry( - transformed, - GetTransformMatrix(), - geo_.Get() - ); - - D2D1_GEOMETRY_RELATION relation = D2D1_GEOMETRY_RELATION_UNKNOWN; - - if (SUCCEEDED(hr)) - { - transformed->CompareWithGeometry( - other->geo_.Get(), - ConvertToD2DMatrix(other->GetTransformMatrix()), - &relation - ); - } - return GeometryRelation(relation); - } - //------------------------------------------------------- // LineGeometry diff --git a/core/base/Geometry.h b/core/base/Geometry.h index 31c572e1..1e59dc2f 100644 --- a/core/base/Geometry.h +++ b/core/base/Geometry.h @@ -19,25 +19,13 @@ // THE SOFTWARE. #pragma once -#include "base.hpp" -#include "Unit.h" +#include "include-forwards.h" namespace easy2d { - // 几何图形间相交关系 - enum class GeometryRelation : int - { - Unknown, - Disjoin, // 无交集 - IsContained, // 被包含 - Contains, // 包含 - Overlap // 重叠 - }; - - // 几何抽象 class Geometry - : public Unit + : public RefCounter { friend class Canvas; friend class GeometryNode; @@ -55,11 +43,6 @@ namespace easy2d Point const& point ); - // 判断两图形相交状态 - GeometryRelation GetRelationWith( - spGeometry const& other - ); - // 获取图形展开成一条直线的长度 float GetLength(); diff --git a/core/base/GeometryNode.cpp b/core/base/GeometryNode.cpp index 955b34c2..86c29fb6 100644 --- a/core/base/GeometryNode.cpp +++ b/core/base/GeometryNode.cpp @@ -72,11 +72,6 @@ namespace easy2d { auto graphics = Graphics::Instance(); - if (geometry_->GetTransformMatrix().IsIdentity()) - graphics->SetTransform(GetTransformMatrix()); - else - graphics->SetTransform(geometry_->GetTransformMatrix() * GetTransformMatrix()); - graphics->FillGeometry( geometry_->geo_, fill_color_ diff --git a/core/base/Image.cpp b/core/base/Image.cpp index e08d7b9c..b22e8788 100644 --- a/core/base/Image.cpp +++ b/core/base/Image.cpp @@ -22,6 +22,7 @@ #include "render.h" #include "logs.h" #include "../utils/File.h" +#include "../utils/string.h" namespace easy2d { @@ -44,13 +45,13 @@ namespace easy2d this->Crop(crop_rect); } - Image::Image(String const& file_name) + Image::Image(std::wstring const& file_name) : Image() { this->Load(file_name); } - Image::Image(String const& file_name, const Rect & crop_rect) + Image::Image(std::wstring const& file_name, const Rect & crop_rect) : Image() { this->Load(file_name); @@ -80,18 +81,18 @@ namespace easy2d return true; } - bool Image::Load(String const& file_name) + bool Image::Load(std::wstring const& file_name) { File image_file; if (!image_file.Open(file_name)) { - logs::Warningln("Image file '%s' not found!", file_name.c_str()); + logs::Warningln("Image file '%s' not found!", StringWideCharToMultiByte(file_name).c_str()); return false; } // 用户输入的路径不一定是完整路径,因为用户可能通过 File::AddSearchPath 添加 // 默认搜索路径,所以需要通过 File::GetPath 获取完整路径 - String image_file_path = image_file.GetPath(); + std::wstring image_file_path = image_file.GetPath(); cpBitmap bitmap; HRESULT hr = Graphics::Instance()->CreateBitmapFromFile(bitmap, image_file_path); diff --git a/core/base/Image.h b/core/base/Image.h index caacf7bf..ae8a196d 100644 --- a/core/base/Image.h +++ b/core/base/Image.h @@ -19,14 +19,14 @@ // THE SOFTWARE. #pragma once -#include "base.hpp" +#include "include-forwards.h" #include "Resource.h" namespace easy2d { // 图片 class Image - : public ObjectBase + : public Object { public: Image(); @@ -41,11 +41,11 @@ namespace easy2d ); explicit Image( - String const& file_name + std::wstring const& file_name ); explicit Image( - String const& file_name, + std::wstring const& file_name, Rect const& crop_rect /* 裁剪矩形 */ ); @@ -62,7 +62,7 @@ namespace easy2d // 加载图片资源 bool Load( - String const& file_name + std::wstring const& file_name ); // 将图片裁剪为矩形 diff --git a/core/base/Input.h b/core/base/Input.h index 16ccb403..cc21cc87 100644 --- a/core/base/Input.h +++ b/core/base/Input.h @@ -19,11 +19,21 @@ // THE SOFTWARE. #pragma once -#include "base.hpp" +#include "include-forwards.h" +#include "keys.hpp" #include "Singleton.hpp" namespace easy2d { + // 鼠标键值 + enum class MouseButton : int + { + Left = VK_LBUTTON, // 鼠标左键 + Right = VK_RBUTTON, // 鼠标右键 + Middle = VK_MBUTTON // 鼠标中键 + }; + + class InputDevice : protected Noncopyable { diff --git a/core/base/KeyEvent.hpp b/core/base/KeyEvent.hpp index a73362e3..4bc00188 100644 --- a/core/base/KeyEvent.hpp +++ b/core/base/KeyEvent.hpp @@ -20,7 +20,7 @@ #pragma once #include "Event.hpp" -#include "BaseTypes.hpp" +#include "keys.hpp" namespace easy2d { diff --git a/core/base/Music.cpp b/core/base/Music.cpp index 35eaa1ed..334eb3d7 100644 --- a/core/base/Music.cpp +++ b/core/base/Music.cpp @@ -21,6 +21,7 @@ #include "Music.h" #include "../utils/Transcoder.h" #include "../utils/File.h" +#include "../utils/string.h" #include "modules.h" #include "audio.h" #include "logs.h" @@ -36,7 +37,7 @@ namespace easy2d { } - Music::Music(String const& file_path) + Music::Music(std::wstring const& file_path) : opened_(false) , playing_(false) , wave_data_(nullptr) @@ -61,7 +62,7 @@ namespace easy2d Close(); } - bool Music::Load(String const& file_path) + bool Music::Load(std::wstring const& file_path) { if (opened_) { @@ -71,13 +72,13 @@ namespace easy2d File music_file; if (!music_file.Open(file_path)) { - logs::Warningln("Media file '%s' not found", file_path.c_str()); + logs::Warningln("Media file '%s' not found", StringWideCharToMultiByte(file_path).c_str()); return false; } // 用户输入的路径不一定是完整路径,因为用户可能通过 File::AddSearchPath 添加 // 默认搜索路径,所以需要通过 File::GetPath 获取完整路径 - String music_file_path = music_file.GetPath(); + std::wstring music_file_path = music_file.GetPath(); Transcoder transcoder; HRESULT hr = transcoder.LoadMediaFile(music_file_path.c_str(), &wave_data_, &size_); diff --git a/core/base/Music.h b/core/base/Music.h index 48e05afb..61dbb8cb 100644 --- a/core/base/Music.h +++ b/core/base/Music.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include "base.hpp" +#include "include-forwards.h" #include "audio.h" #include "Resource.h" @@ -27,13 +27,13 @@ namespace easy2d { // 音乐 class Music - : public ObjectBase + : public Object { public: Music(); Music( - String const& file_path /* 音乐文件路径 */ + std::wstring const& file_path /* 音乐文件路径 */ ); Music( @@ -44,7 +44,7 @@ namespace easy2d // 打开音乐文件 bool Load( - String const& file_path /* 音乐文件路径 */ + std::wstring const& file_path /* 音乐文件路径 */ ); // 打开音乐资源 diff --git a/core/base/Node.cpp b/core/base/Node.cpp index c1beaabd..ea1f6d24 100644 --- a/core/base/Node.cpp +++ b/core/base/Node.cpp @@ -32,7 +32,6 @@ namespace easy2d { float default_pivot_x = 0.f; float default_pivot_y = 0.f; - bool border_enabled = false; } void Node::SetDefaultPivot(float pivot_x, float pivot_y) @@ -41,58 +40,30 @@ namespace easy2d default_pivot_y = pivot_y; } - void easy2d::Node::EnableBorder() - { - border_enabled = true; - } - - void easy2d::Node::DisableBorder() - { - border_enabled = false; - } - Node::Node() - : inited_(false) - , visible_(true) - , dirty_sort_(false) + : visible_(true) + , dirty_transform_(false) , parent_(nullptr) , hash_name_(0) , z_order_(0) , opacity_(1.f) , display_opacity_(1.f) - , children_() - , border_color_(Color::Red, 0.6f) - , initial_matrix_() - , final_matrix_() , pivot_(default_pivot_x, default_pivot_y) - , size_() { } - void Node::Init() - { - inited_ = true; - } - - void Node::OnRender() - { - // normal node renders nothing - } - void Node::Update(Duration const & dt) { - if (!inited_) - { - Init(); - } - + OnUpdate(dt); UpdateActions(this, dt); UpdateTasks(dt); if (!children_.IsEmpty()) { - for (auto child = children_.First(); child; child = child->NextItem()) + spNode next; + for (auto child = children_.First(); child; child = next) { + next = child->NextItem(); child->Update(dt); } } @@ -109,39 +80,33 @@ namespace easy2d if (children_.IsEmpty()) { - graphics->SetTransform(final_matrix_); + graphics->SetTransform(transform_matrix_); graphics->SetOpacity(display_opacity_); OnRender(); } else { - SortChildren(); - // render children those are less than 0 in Z-Order - spNode child = children_.First(); - for (spNode next; child; child = next) + Node* child = children_.First().Get(); + while (child) { - next = child->NextItem(); - if (child->GetZOrder() < 0) - { - child->Render(); - } - else - { + if (child->GetZOrder() >= 0) break; - } + + child->Render(); + child = child->NextItem().Get(); } - graphics->SetTransform(final_matrix_); + graphics->SetTransform(transform_matrix_); graphics->SetOpacity(display_opacity_); OnRender(); - for (spNode next; child; child = next) + while (child) { - next = child->NextItem(); child->Render(); + child = child->NextItem().Get(); } } } @@ -169,38 +134,10 @@ namespace easy2d } } - void Node::DrawBorder() - { - if (visible_) - { - if (border_) - { - Graphics::Instance()->DrawGeometry(border_, border_color_, 1.5f); - } - - for (auto child = children_.First(); child; child = child->NextItem()) - { - child->DrawBorder(); - } - } - } - - void Node::SortChildren() - { - if (dirty_sort_) - { - children_.Sort( - [](spNode const& n1, spNode const& n2) { return n1->GetZOrder() < n2->GetZOrder(); } - ); - - dirty_sort_ = false; - } - } - math::Matrix const & Node::GetTransformMatrix() { UpdateTransform(); - return final_matrix_; + return transform_matrix_; } spNode Node::GetParent() const @@ -220,58 +157,21 @@ namespace easy2d dirty_transform_ = false; - Point center{ size_.width * pivot_.x, size_.height * pivot_.y }; - final_matrix_ = math::Matrix::Scaling(transform_.scale, center) - * math::Matrix::Skewing(transform_.skew.x, transform_.skew.y, center) - * math::Matrix::Rotation(transform_.rotation, center) - * math::Matrix::Translation(transform_.position - center); + // matrix multiplication is optimized by expression template + transform_matrix_ = math::Matrix::Scaling(transform_.scale) + * math::Matrix::Skewing(transform_.skew.x, transform_.skew.y) + * math::Matrix::Rotation(transform_.rotation) + * math::Matrix::Translation(transform_.position); - initial_matrix_ = final_matrix_ * math::Matrix::Translation( - Point{ size_.width * pivot_.x, size_.height * pivot_.y } - ); + Point offset{ -size_.width * pivot_.x, -size_.height * pivot_.y }; + transform_matrix_.Translate(offset); if (parent_) - { - initial_matrix_ = initial_matrix_ * parent_->initial_matrix_; - final_matrix_ = final_matrix_ * parent_->initial_matrix_; - } + transform_matrix_ = transform_matrix_ * parent_->transform_matrix_; // update children's transform - for (auto child = children_.First(); child; child = child->NextItem()) - { + for (Node* child = children_.First().Get(); child; child = child->NextItem().Get()) child->dirty_transform_ = true; - } - - // update border - if (border_enabled) - { - UpdateBorder(); - } - } - - void Node::UpdateBorder() - { - cpRectangleGeometry rect; - cpTransformedGeometry transformed; - - HRESULT hr = Factory::Instance()->CreateRectangleGeometry( - rect, - Rect(Point{}, size_) - ); - - if (SUCCEEDED(hr)) - { - hr = Factory::Instance()->CreateTransformedGeometry( - transformed, - final_matrix_, - rect - ); - } - - if (SUCCEEDED(hr)) - { - border_ = transformed; - } } void Node::UpdateOpacity() @@ -280,7 +180,7 @@ namespace easy2d { display_opacity_ = opacity_ * parent_->display_opacity_; } - for (auto child = children_.First(); child; child = child->NextItem()) + for (Node* child = children_.First().Get(); child; child = child->NextItem().Get()) { child->UpdateOpacity(); } @@ -289,21 +189,44 @@ namespace easy2d void Node::SetScene(Scene * scene) { scene_ = scene; - for (auto child = children_.First(); child; child = child->NextItem()) + for (Node* child = children_.First().Get(); child; child = child->NextItem().Get()) { child->scene_ = scene; } } - void Node::SetZOrder(int order) + void Node::SetZOrder(int zorder) { - if (z_order_ == order) + if (z_order_ == zorder) return; - z_order_ = order; + z_order_ = zorder; + if (parent_) { - parent_->dirty_sort_ = true; + spNode me = this; + + parent_->children_.Remove(me); + + Node* sibling = parent_->children_.Last().Get(); + + if (sibling && sibling->GetZOrder() > zorder) + { + while (sibling = sibling->PrevItem().Get()) + { + if (sibling->GetZOrder() <= zorder) + break; + } + } + + if (sibling) + { + parent_->children_.InsertAfter(me, spNode(sibling)); + } + else + { + parent_->children_.PushFront(me); + } } } @@ -367,26 +290,110 @@ namespace easy2d dirty_transform_ = true; } - void Node::SetBorderColor(Color const& color) - { - border_color_ = color; - } - void Node::SetVisible(bool val) { visible_ = val; } - void Node::SetName(String const& name) + void Node::SetName(std::wstring const& name) { if (name_ != name) { name_ = name; - hash_name_ = std::hash{}(name); + hash_name_ = std::hash{}(name); } } - void Node::AddChild(spNode const& child, int z_order) + void Node::SetPositionX(float x) + { + this->SetPosition(x, transform_.position.y); + } + + void Node::SetPositionY(float y) + { + this->SetPosition(transform_.position.x, y); + } + + void Node::SetPosition(const Point & p) + { + this->SetPosition(p.x, p.y); + } + + void Node::SetPosition(float x, float y) + { + if (transform_.position.x == x && transform_.position.y == y) + return; + + transform_.position.x = x; + transform_.position.y = y; + dirty_transform_ = true; + } + + void Node::Move(float x, float y) + { + this->SetPosition(transform_.position.x + x, transform_.position.y + y); + } + + void Node::Move(const Point & v) + { + this->Move(v.x, v.y); + } + + void Node::SetScaleX(float scale_x) + { + this->SetScale(scale_x, transform_.scale.y); + } + + void Node::SetScaleY(float scale_y) + { + this->SetScale(transform_.scale.x, scale_y); + } + + void Node::SetScale(float scale) + { + this->SetScale(scale, scale); + } + + void Node::SetScale(float scale_x, float scale_y) + { + if (transform_.scale.x == scale_x && transform_.scale.y == scale_y) + return; + + transform_.scale.x = scale_x; + transform_.scale.y = scale_y; + dirty_transform_ = true; + } + + void Node::SetSkewX(float skew_x) + { + this->SetSkew(skew_x, transform_.skew.y); + } + + void Node::SetSkewY(float skew_y) + { + this->SetSkew(transform_.skew.x, skew_y); + } + + void Node::SetSkew(float skew_x, float skew_y) + { + if (transform_.skew.x == skew_x && transform_.skew.y == skew_y) + return; + + transform_.skew.x = skew_x; + transform_.skew.y = skew_y; + dirty_transform_ = true; + } + + void Node::SetRotation(float angle) + { + if (transform_.rotation == angle) + return; + + transform_.rotation = angle; + dirty_transform_ = true; + } + + void Node::AddChild(spNode const& child) { E2D_ASSERT(child && "Node::AddChild failed, NULL pointer exception"); @@ -407,18 +414,16 @@ namespace easy2d child->parent_ = this; child->SetScene(this->scene_); child->dirty_transform_ = true; - child->SetZOrder(z_order); child->UpdateOpacity(); - - dirty_sort_ = true; + child->SetZOrder(child->GetZOrder()); } } - void Node::AddChild(const Nodes& nodes, int z_order) + void Node::AddChildren(const Nodes& children) { - for (const auto& node : nodes) + for (const auto& node : children) { - this->AddChild(node, z_order); + this->AddChild(node); } } @@ -427,12 +432,12 @@ namespace easy2d return Rect(Point{}, size_); } - Node::Nodes Node::GetChildren(String const& name) const + Node::Nodes Node::GetChildren(std::wstring const& name) const { Nodes children; - size_t hash_code = std::hash{}(name); + size_t hash_code = std::hash{}(name); - for (auto child = children_.First(); child != children_.Last(); child = child->NextItem()) + for (Node* child = children_.First().Get(); child; child = child->NextItem().Get()) { if (child->hash_name_ == hash_code && child->name_ == name) { @@ -442,11 +447,11 @@ namespace easy2d return children; } - spNode Node::GetChild(String const& name) const + spNode Node::GetChild(std::wstring const& name) const { - size_t hash_code = std::hash{}(name); + size_t hash_code = std::hash{}(name); - for (auto child = children_.First(); child != children_.Last(); child = child->NextItem()) + for (Node* child = children_.First().Get(); child; child = child->NextItem().Get()) { if (child->hash_name_ == hash_code && child->name_ == name) { @@ -470,6 +475,11 @@ namespace easy2d } bool Node::RemoveChild(spNode const& child) + { + return RemoveChild(child.Get()); + } + + bool Node::RemoveChild(Node * child) { E2D_ASSERT(child && "Node::RemoveChild failed, NULL pointer exception"); @@ -480,24 +490,25 @@ namespace easy2d { child->parent_ = nullptr; if (child->scene_) child->SetScene(nullptr); - children_.Remove(Node::ItemType(child)); + children_.Remove(spNode(child)); return true; } return false; } - void Node::RemoveChildren(String const& child_name) + void Node::RemoveChildren(std::wstring const& child_name) { if (children_.IsEmpty()) { return; } - size_t hash_code = std::hash{}(child_name); - spNode next; - for (auto child = children_.First(); child; child = next) + size_t hash_code = std::hash{}(child_name); + + Node* next; + for (Node* child = children_.First().Get(); child; child = next) { - next = child->NextItem(); + next = child->NextItem().Get(); if (child->hash_name_ == hash_code && child->name_ == child_name) { @@ -529,11 +540,7 @@ namespace easy2d BOOL ret = 0; // no matter it failed or not - border->FillContainsPoint( - point, - ConvertToD2DMatrix(final_matrix_), - &ret - ); + border->FillContainsPoint(point, transform_matrix_, &ret); return !!ret; } } diff --git a/core/base/Node.h b/core/base/Node.h index 30b5adfd..feafcb49 100644 --- a/core/base/Node.h +++ b/core/base/Node.h @@ -19,9 +19,9 @@ // THE SOFTWARE. #pragma once -#include "base.hpp" +#include "include-forwards.h" #include "time.h" -#include "Unit.h" +#include "Transform.hpp" #include "TaskManager.h" #include "ActionManager.h" #include "EventDispatcher.h" @@ -29,11 +29,11 @@ namespace easy2d { - class Game; + class Game; // 节点 class Node - : public Unit + : public Object , public TaskManager , public ActionManager , public EventDispatcher @@ -50,53 +50,86 @@ namespace easy2d public: Node(); - // 初始化节点 - virtual void Init(); - // 更新节点 - virtual void Update(Duration const& dt); + virtual void OnUpdate(Duration const& dt) {} // 渲染节点 - virtual void OnRender(); + virtual void OnRender() {} // 处理事件 virtual void HandleEvent(Event* e); // 获取显示状态 - bool IsVisible() const { return visible_; } + bool IsVisible() const { return visible_; } // 获取名称 - String const& GetName() const { return name_; } + std::wstring const& GetName() const { return name_; } // 获取名称的 Hash 值 - size_t GetHashName() const { return hash_name_; } + size_t GetHashName() const { return hash_name_; } // 获取 Z 轴顺序 - int GetZOrder() const { return z_order_; } + int GetZOrder() const { return z_order_; } + + // 获取坐标 + Point const& GetPosition() const { return transform_.position; } + + // 获取 x 坐标 + float GetPositionX() const { return transform_.position.x; } + + // 获取 y 坐标 + float GetPositionY() const { return transform_.position.y; } + + // 获取横向缩放比例 + float GetScaleX() const { return transform_.scale.x; } + + // 获取纵向缩放比例 + float GetScaleY() const { return transform_.scale.y; } + + // 获取横向错切角度 + float GetSkewX() const { return transform_.skew.x; } + + // 获取纵向错切角度 + float GetSkewY() const { return transform_.skew.y; } + + // 获取旋转角度 + float GetRotation() const { return transform_.rotation; } // 获取宽度 - virtual float GetWidth() const { return size_.width * transform_.scale.x; } + float GetWidth() const { return size_.width; } // 获取高度 - virtual float GetHeight() const { return size_.height * transform_.scale.y; } + float GetHeight() const { return size_.height; } // 获取大小 - Size GetSize() const { return Size{ GetWidth(), GetHeight() }; } + Size const& GetSize() const { return size_; } + + // 获取缩放后的宽度 + float GetScaledWidth() const { return size_.width * transform_.scale.x; } + + // 获取缩放后的高度 + float GetScaledHeight() const { return size_.height * transform_.scale.y; } + + // 获取缩放后的大小 + Size GetScaledSize() const { return Size{ GetScaledWidth(), GetScaledHeight() }; } // 获取 x 方向支点 - virtual float GetPivotX() const { return pivot_.x; } + float GetPivotX() const { return pivot_.x; } // 获取 y 方向支点 - virtual float GetPivotY() const { return pivot_.y; } + float GetPivotY() const { return pivot_.y; } // 获取透明度 - virtual float GetOpacity() const { return opacity_; } + float GetOpacity() const { return opacity_; } + + // 获取变换 + Transform const& GetTransform() const { return transform_; } // 获取包围盒 virtual Rect GetBounds(); // 获取二维变换矩阵 - virtual math::Matrix const& GetTransformMatrix() override; + math::Matrix const& GetTransformMatrix(); // 获取父节点 spNode GetParent() const; @@ -111,7 +144,89 @@ namespace easy2d // 设置名称 void SetName( - String const& name + std::wstring const& name + ); + + // 设置横坐标 + void SetPositionX( + float x + ); + + // 设置纵坐标 + void SetPositionY( + float y + ); + + // 设置坐标 + void SetPosition( + const Point & point + ); + + // 设置坐标 + void SetPosition( + float x, + float y + ); + + // 移动 + void Move( + float x, + float y + ); + + // 移动 + void Move( + const Point & vector + ); + + // 设置横向缩放比例 + // 默认为 1.0 + void SetScaleX( + float scale_x + ); + + // 设置纵向缩放比例 + // 默认为 1.0 + void SetScaleY( + float scale_y + ); + + // 设置缩放比例 + // 默认为 (1.0, 1.0) + void SetScale( + float scale_x, + float scale_y + ); + + // 设置缩放比例 + // 默认为 1.0 + void SetScale( + float scale + ); + + // 设置横向错切角度 + // 默认为 0 + void SetSkewX( + float skew_x + ); + + // 设置纵向错切角度 + // 默认为 0 + void SetSkewY( + float skew_y + ); + + // 设置错切角度 + // 默认为 (0, 0) + void SetSkew( + float skew_x, + float skew_y + ); + + // 设置旋转角度 + // 默认为 0 + void SetRotation( + float rotation ); // 设置支点的横向位置 @@ -154,9 +269,9 @@ namespace easy2d const Size & size ); - virtual void SetTransform( + void SetTransform( Transform const& transform - ) override; + ); // 设置透明度 // 默认为 1.0, 范围 [0, 1] @@ -167,12 +282,7 @@ namespace easy2d // 设置 Z 轴顺序 // 默认为 0 void SetZOrder( - int order - ); - - // 设置边框颜色 - void SetBorderColor( - const Color& color + int zorder ); // 判断点是否在节点内 @@ -182,24 +292,22 @@ namespace easy2d // 添加子节点 void AddChild( - spNode const& child, - int z_order = 0 /* Z 轴顺序 */ + spNode const& child ); // 添加多个子节点 - void AddChild( - const Nodes& nodes, /* 节点数组 */ - int z_order = 0 /* Z 轴顺序 */ + void AddChildren( + const Nodes& children ); // 获取所有名称相同的子节点 Nodes GetChildren( - String const& name + std::wstring const& name ) const; // 获取名称相同的子节点 spNode GetChild( - String const& name + std::wstring const& name ) const; // 获取全部子节点 @@ -210,9 +318,14 @@ namespace easy2d spNode const& child ); + // 移除子节点 + bool RemoveChild( + Node* child + ); + // 移除所有名称相同的子节点 void RemoveChildren( - String const& child_name + std::wstring const& child_name ); // 移除所有节点 @@ -229,21 +342,11 @@ namespace easy2d float pivot_y ); - // 启用边框自动生成 - static void EnableBorder(); - - // 禁用边框自动生成 - static void DisableBorder(); - protected: + void Update(Duration const& dt); + void Render(); - void DrawBorder(); - - void SortChildren(); - - void UpdateBorder(); - void UpdateTransform(); void UpdateOpacity(); @@ -251,22 +354,19 @@ namespace easy2d void SetScene(Scene* scene); protected: - bool inited_; - bool visible_; - bool dirty_sort_; - int z_order_; - float opacity_; - float display_opacity_; - String name_; - size_t hash_name_; - Node* parent_; - Scene* scene_; - Color border_color_; - Children children_; - cpGeometry border_; - Point pivot_; - Size size_; - math::Matrix initial_matrix_; - math::Matrix final_matrix_; + bool visible_; + bool dirty_transform_; + int z_order_; + float opacity_; + float display_opacity_; + std::wstring name_; + size_t hash_name_; + Transform transform_; + math::Matrix transform_matrix_; + Point pivot_; + Size size_; + Node* parent_; + Scene* scene_; + Children children_; }; } diff --git a/core/base/ObjectBase.cpp b/core/base/Object.cpp similarity index 76% rename from core/base/ObjectBase.cpp rename to core/base/Object.cpp index 50938cc6..04daa4fa 100644 --- a/core/base/ObjectBase.cpp +++ b/core/base/Object.cpp @@ -18,51 +18,61 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include "ObjectBase.h" +#include "Object.h" namespace easy2d { namespace { bool tracing_leaks = true; - std::vector tracing_objects; + std::vector tracing_objects; } - ObjectBase::ObjectBase() + Object::Object() : tracing_leak_(false) { #ifdef E2D_DEBUG - ObjectBase::__AddObjectToTracingList(this); + Object::__AddObjectToTracingList(this); #endif } - ObjectBase::~ObjectBase() + Object::~Object() { #ifdef E2D_DEBUG - ObjectBase::__RemoveObjectFromTracingList(this); + Object::__RemoveObjectFromTracingList(this); #endif } - void ObjectBase::StartTracingLeaks() + void * Object::GetUserData() const + { + return user_data_; + } + + void Object::SetUserData(void * data) + { + user_data_ = data; + } + + void Object::StartTracingLeaks() { tracing_leaks = true; } - void ObjectBase::StopTracingLeaks() + void Object::StopTracingLeaks() { tracing_leaks = false; } - std::vector const& easy2d::ObjectBase::__GetTracingObjects() + std::vector const& easy2d::Object::__GetTracingObjects() { return tracing_objects; } - void ObjectBase::__AddObjectToTracingList(ObjectBase * obj) + void Object::__AddObjectToTracingList(Object * obj) { #ifdef E2D_DEBUG @@ -75,7 +85,7 @@ namespace easy2d #endif } - void ObjectBase::__RemoveObjectFromTracingList(ObjectBase * obj) + void Object::__RemoveObjectFromTracingList(Object * obj) { #ifdef E2D_DEBUG diff --git a/core/base/ObjectBase.h b/core/base/Object.h similarity index 81% rename from core/base/ObjectBase.h rename to core/base/Object.h index a74d824c..0544f864 100644 --- a/core/base/ObjectBase.h +++ b/core/base/Object.h @@ -20,29 +20,35 @@ #pragma once #include "RefCounter.hpp" +#include namespace easy2d { - class ObjectBase + class Object : public RefCounter { public: - ObjectBase(); + Object(); - virtual ~ObjectBase(); + virtual ~Object(); + + void* GetUserData() const; + + void SetUserData(void* data); static void StartTracingLeaks(); static void StopTracingLeaks(); - static std::vector const& __GetTracingObjects(); + static std::vector const& __GetTracingObjects(); protected: - static void __AddObjectToTracingList(ObjectBase*); + static void __AddObjectToTracingList(Object*); - static void __RemoveObjectFromTracingList(ObjectBase*); + static void __RemoveObjectFromTracingList(Object*); private: bool tracing_leak_; + void* user_data_; }; } diff --git a/core/base/Point.hpp b/core/base/Point.hpp index 5aaf610b..c90b9a1e 100644 --- a/core/base/Point.hpp +++ b/core/base/Point.hpp @@ -76,9 +76,14 @@ namespace easy2d return (x == other.x) && (y == other.y); } - inline operator D2D1_POINT_2F () const + inline operator D2D1_POINT_2F const& () const { - return D2D1_POINT_2F{ x, y }; + return reinterpret_cast(*this); + } + + inline operator D2D1_POINT_2F& () + { + return reinterpret_cast(*this); } }; } diff --git a/core/base/Size.hpp b/core/base/Size.hpp index ce9806c4..d1370823 100644 --- a/core/base/Size.hpp +++ b/core/base/Size.hpp @@ -19,6 +19,7 @@ // THE SOFTWARE. #pragma once +#include "Point.hpp" #include namespace easy2d @@ -54,6 +55,12 @@ namespace easy2d height = other.height; } + Size(const Point & p) + { + width = p.x; + height = p.y; + } + inline const Size operator+(const Size & other) const { return Size(width + other.width, height + other.height); @@ -84,9 +91,19 @@ namespace easy2d return (width == other.width) && (height == other.height); } - inline operator D2D1_SIZE_F () const + inline operator Point () const { - return D2D1_SIZE_F{ width, height }; + return Point{ width, height }; + } + + inline operator D2D1_SIZE_F const& () const + { + return reinterpret_cast(*this); + } + + inline operator D2D1_SIZE_F& () + { + return reinterpret_cast(*this); } }; } diff --git a/core/base/Sprite.cpp b/core/base/Sprite.cpp index 47fdc7b6..38e4cb5b 100644 --- a/core/base/Sprite.cpp +++ b/core/base/Sprite.cpp @@ -48,13 +48,13 @@ namespace easy2d Crop(crop_rect); } - Sprite::Sprite(String const& file_name) + Sprite::Sprite(std::wstring const& file_name) : image_(nullptr) { Load(file_name); } - Sprite::Sprite(String const& file_name, const Rect & crop_rect) + Sprite::Sprite(std::wstring const& file_name, const Rect & crop_rect) : image_(nullptr) { Load(file_name); @@ -95,7 +95,7 @@ namespace easy2d return false; } - bool Sprite::Load(String const& file_name) + bool Sprite::Load(std::wstring const& file_name) { if (!image_) { diff --git a/core/base/Sprite.h b/core/base/Sprite.h index fd13eb62..fdb4d0f9 100644 --- a/core/base/Sprite.h +++ b/core/base/Sprite.h @@ -45,11 +45,11 @@ namespace easy2d ); explicit Sprite( - String const& file_name + std::wstring const& file_name ); explicit Sprite( - String const& file_name, + std::wstring const& file_name, const Rect& crop_rect /* 裁剪矩形 */ ); @@ -62,7 +62,7 @@ namespace easy2d // 加载图片文件 bool Load( - String const& file_name + std::wstring const& file_name ); // 加载图片 diff --git a/core/base/Task.cpp b/core/base/Task.cpp index 090c64e3..58516343 100644 --- a/core/base/Task.cpp +++ b/core/base/Task.cpp @@ -22,14 +22,13 @@ namespace easy2d { - Task::Task(const Callback & func, String const& name) + Task::Task(const Callback & func, std::wstring const& name) : Task(func, Duration{}, -1, name) { } - Task::Task(Callback const& func, Duration const& delay, int times, String const& name) + Task::Task(Callback const& func, Duration const& delay, int times, std::wstring const& name) : running_(true) - , stopped_(false) , run_times_(0) , total_times_(times) , delay_(delay) @@ -42,7 +41,6 @@ namespace easy2d void Task::Start() { running_ = true; - delta_ = Duration{}; } void Task::Stop() @@ -50,14 +48,14 @@ namespace easy2d running_ = false; } - void Task::Update(Duration const& dt) + void Task::Update(Duration const& dt, bool& remove_after_update) { if (!running_) return; if (total_times_ == 0) { - stopped_ = true; + remove_after_update = true; return; } @@ -77,7 +75,7 @@ namespace easy2d if (run_times_ == total_times_) { - stopped_ = true; + remove_after_update = true; return; } } @@ -85,6 +83,7 @@ namespace easy2d void Task::Reset() { delta_ = Duration{}; + run_times_ = 0; } bool Task::IsRunning() const @@ -92,8 +91,9 @@ namespace easy2d return running_; } - String const& Task::GetName() const + std::wstring const& Task::GetName() const { return name_; } + } \ No newline at end of file diff --git a/core/base/Task.h b/core/base/Task.h index 615eb82f..1a77b31f 100644 --- a/core/base/Task.h +++ b/core/base/Task.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include "base.hpp" +#include "include-forwards.h" #include "time.h" #include "intrusive/List.hpp" #include @@ -30,7 +30,7 @@ namespace easy2d // 定时任务 class Task - : public ObjectBase + : public Object , protected intrusive::ListItem { friend class TaskManager; @@ -41,14 +41,14 @@ namespace easy2d public: explicit Task( const Callback& func, /* 执行函数 */ - String const& name = L"" /* 任务名称 */ + std::wstring const& name = L"" /* 任务名称 */ ); explicit Task( Callback const& func, /* 执行函数 */ Duration const& delay, /* 时间间隔(秒) */ int times = -1, /* 执行次数(设 -1 为永久执行) */ - String const& name = L"" /* 任务名称 */ + std::wstring const& name = L"" /* 任务名称 */ ); // 启动任务 @@ -61,19 +61,18 @@ namespace easy2d bool IsRunning() const; // 获取任务名称 - String const& GetName() const; + std::wstring const& GetName() const; protected: - void Update(Duration const& dt); + void Update(Duration const& dt, bool& remove_after_update); void Reset(); protected: bool running_; - bool stopped_; int run_times_; int total_times_; - String name_; + std::wstring name_; Duration delay_; Duration delta_; Callback callback_; diff --git a/core/base/TaskManager.cpp b/core/base/TaskManager.cpp index fad15594..756f8c38 100644 --- a/core/base/TaskManager.cpp +++ b/core/base/TaskManager.cpp @@ -33,9 +33,10 @@ namespace easy2d { next = task->NextItem(); - task->Update(dt); + bool remove_after_update = false; + task->Update(dt, remove_after_update); - if (task->stopped_) + if (remove_after_update) tasks_.Remove(task); } } @@ -51,9 +52,12 @@ namespace easy2d } } - void TaskManager::StopTasks(String const& name) + void TaskManager::StopTasks(std::wstring const& name) { - for (auto task = tasks_.First(); task; task = task->NextItem()) + if (tasks_.IsEmpty()) + return; + + for (auto task = tasks_.First().Get(); task; task = task->NextItem().Get()) { if (task->GetName() == name) { @@ -62,9 +66,12 @@ namespace easy2d } } - void TaskManager::StartTasks(String const& name) + void TaskManager::StartTasks(std::wstring const& name) { - for (auto task = tasks_.First(); task; task = task->NextItem()) + if (tasks_.IsEmpty()) + return; + + for (auto task = tasks_.First().Get(); task; task = task->NextItem().Get()) { if (task->GetName() == name) { @@ -73,20 +80,28 @@ namespace easy2d } } - void TaskManager::RemoveTasks(String const& name) + void TaskManager::RemoveTasks(std::wstring const& name) { - for (auto task = tasks_.First(); task; task = task->NextItem()) + if (tasks_.IsEmpty()) + return; + + spTask next; + for (auto task = tasks_.First(); task; task = next) { + next = task->NextItem(); if (task->GetName() == name) { - task->stopped_ = true; + tasks_.Remove(task); } } } void TaskManager::StopAllTasks() { - for (auto task = tasks_.First(); task; task = task->NextItem()) + if (tasks_.IsEmpty()) + return; + + for (auto task = tasks_.First().Get(); task; task = task->NextItem().Get()) { task->Stop(); } @@ -94,7 +109,10 @@ namespace easy2d void TaskManager::StartAllTasks() { - for (auto task = tasks_.First(); task; task = task->NextItem()) + if (tasks_.IsEmpty()) + return; + + for (auto task = tasks_.First().Get(); task; task = task->NextItem().Get()) { task->Start(); } @@ -102,10 +120,7 @@ namespace easy2d void TaskManager::RemoveAllTasks() { - for (auto task = tasks_.First(); task; task = task->NextItem()) - { - task->stopped_ = true; - } + tasks_.Clear(); } const TaskManager::Tasks & TaskManager::GetAllTasks() const diff --git a/core/base/TaskManager.h b/core/base/TaskManager.h index 12a24e45..95c35c78 100644 --- a/core/base/TaskManager.h +++ b/core/base/TaskManager.h @@ -35,17 +35,17 @@ namespace easy2d // 启动任务 void StartTasks( - String const& task_name + std::wstring const& task_name ); // 停止任务 void StopTasks( - String const& task_name + std::wstring const& task_name ); // 移除任务 void RemoveTasks( - String const& task_name + std::wstring const& task_name ); // 启动所有任务 diff --git a/core/base/Text.cpp b/core/base/Text.cpp index 47199dc0..ea6ca42b 100644 --- a/core/base/Text.cpp +++ b/core/base/Text.cpp @@ -21,7 +21,7 @@ #include "Text.h" #include "Factory.h" #include "render.h" -#include "base.hpp" +#include "include-forwards.h" #include "logs.h" namespace easy2d @@ -48,22 +48,22 @@ namespace easy2d { } - Text::Text(String const& text) + Text::Text(std::wstring const& text) : Text(text, text_default_font, text_default_style) { } - Text::Text(String const& text, const Font & font) + Text::Text(std::wstring const& text, const Font & font) : Text(text, font, text_default_style) { } - Text::Text(String const& text, const TextStyle & style) + Text::Text(std::wstring const& text, const TextStyle & style) : Text(text, text_default_font, style) { } - Text::Text(String const& text, const Font & font, const TextStyle & style) + Text::Text(std::wstring const& text, const Font & font, const TextStyle & style) : font_(font) , style_(style) , text_(text) @@ -75,7 +75,7 @@ namespace easy2d { } - String const& Text::GetText() const + std::wstring const& Text::GetText() const { return text_; } @@ -90,7 +90,7 @@ namespace easy2d return style_; } - String const& Text::GetFontFamily() const + std::wstring const& Text::GetFontFamily() const { return font_.family; } @@ -158,7 +158,7 @@ namespace easy2d return style_.outline; } - void Text::SetText(String const& text) + void Text::SetText(std::wstring const& text) { text_ = text; UpdateLayout(); @@ -176,7 +176,7 @@ namespace easy2d UpdateLayout(); } - void Text::SetFontFamily(String const& family) + void Text::SetFontFamily(std::wstring const& family) { if (font_.family != family) { diff --git a/core/base/Text.h b/core/base/Text.h index 275571c4..686d47c8 100644 --- a/core/base/Text.h +++ b/core/base/Text.h @@ -33,21 +33,21 @@ namespace easy2d Text(); explicit Text( - String const& text /* 文字内容 */ + std::wstring const& text /* 文字内容 */ ); explicit Text( - String const& text, /* 文字内容 */ + std::wstring const& text, /* 文字内容 */ const Font& font /* 字体 */ ); explicit Text( - String const& text, /* 文字内容 */ + std::wstring const& text, /* 文字内容 */ const TextStyle& style /* 文本样式 */ ); explicit Text( - String const& text, /* 文字内容 */ + std::wstring const& text, /* 文字内容 */ const Font& font, /* 字体 */ const TextStyle& style /* 文本样式 */ ); @@ -55,7 +55,7 @@ namespace easy2d virtual ~Text(); // 获取文本 - String const& GetText() const; + std::wstring const& GetText() const; // 获取字体 const Font& GetFont() const; @@ -64,7 +64,7 @@ namespace easy2d const TextStyle& GetStyle() const; // 获取字体族 - String const& GetFontFamily() const; + std::wstring const& GetFontFamily() const; // 获取当前字号 float GetFontSize() const; @@ -101,7 +101,7 @@ namespace easy2d // 设置文本 void SetText( - String const& text + std::wstring const& text ); // 设置文本样式 @@ -116,7 +116,7 @@ namespace easy2d // 设置字体族 void SetFontFamily( - String const& family + std::wstring const& family ); // 设置字号(默认值为 22) @@ -205,7 +205,7 @@ namespace easy2d void UpdateLayout(); protected: - String text_; + std::wstring text_; Font font_; TextStyle style_; cpTextFormat text_format_; diff --git a/core/base/TextRenderer.cpp b/core/base/TextRenderer.cpp index 539067af..fb086521 100644 --- a/core/base/TextRenderer.cpp +++ b/core/base/TextRenderer.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "TextRenderer.h" -#include "base.hpp" +#include "include-forwards.h" #include "render.h" namespace easy2d diff --git a/core/base/TextRenderer.h b/core/base/TextRenderer.h index 3e393138..2c339cc2 100644 --- a/core/base/TextRenderer.h +++ b/core/base/TextRenderer.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include "d2dres.hpp" +#include "d2dhelper.hpp" namespace easy2d { diff --git a/core/base/TextStyle.hpp b/core/base/TextStyle.hpp index 37583ff9..f154d523 100644 --- a/core/base/TextStyle.hpp +++ b/core/base/TextStyle.hpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include "base.hpp" +#include "include-forwards.h" namespace easy2d { diff --git a/core/base/Transform.hpp b/core/base/Transform.hpp index c4663ca2..9ac5cfd8 100644 --- a/core/base/Transform.hpp +++ b/core/base/Transform.hpp @@ -50,13 +50,4 @@ namespace easy2d rotation == other.rotation; } }; - - inline D2D1_MATRIX_3X2_F ConvertToD2DMatrix(math::Matrix const& matrix) - { - return D2D1_MATRIX_3X2_F{ - matrix.m[0], matrix.m[1], - matrix.m[2], matrix.m[3], - matrix.m[4], matrix.m[5] - }; - } } diff --git a/core/base/Transition.h b/core/base/Transition.h index 2b38275d..a277aa43 100644 --- a/core/base/Transition.h +++ b/core/base/Transition.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include "base.hpp" +#include "include-forwards.h" #include "time.h" namespace easy2d @@ -28,7 +28,7 @@ namespace easy2d // 场景过渡 class Transition - : public ObjectBase + : public Object { friend class Game; diff --git a/core/base/Unit.cpp b/core/base/Unit.cpp deleted file mode 100644 index a3779a46..00000000 --- a/core/base/Unit.cpp +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (c) 2016-2018 Easy2D - 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 "Unit.h" - -namespace easy2d -{ - Unit::Unit() - : transform_() - , dirty_transform_(false) - { - } - - Unit::~Unit() - { - } - - math::Matrix const & Unit::GetTransformMatrix() - { - if (dirty_transform_) - { - UpdateMatrix(); - dirty_transform_ = false; - } - return matrix_cached_; - } - - void Unit::SetPositionX(float x) - { - this->SetPosition(x, transform_.position.y); - } - - void Unit::SetPositionY(float y) - { - this->SetPosition(transform_.position.x, y); - } - - void Unit::SetPosition(const Point & p) - { - this->SetPosition(p.x, p.y); - } - - void Unit::SetPosition(float x, float y) - { - if (transform_.position.x == x && transform_.position.y == y) - return; - - transform_.position.x = x; - transform_.position.y = y; - dirty_transform_ = true; - } - - void Unit::Move(float x, float y) - { - this->SetPosition(transform_.position.x + x, transform_.position.y + y); - } - - void Unit::Move(const Point & v) - { - this->Move(v.x, v.y); - } - - void Unit::SetScaleX(float scale_x) - { - this->SetScale(scale_x, transform_.scale.y); - } - - void Unit::SetScaleY(float scale_y) - { - this->SetScale(transform_.scale.x, scale_y); - } - - void Unit::SetScale(float scale) - { - this->SetScale(scale, scale); - } - - void Unit::SetScale(float scale_x, float scale_y) - { - if (transform_.scale.x == scale_x && transform_.scale.y == scale_y) - return; - - transform_.scale.x = scale_x; - transform_.scale.y = scale_y; - dirty_transform_ = true; - } - - void Unit::SetSkewX(float skew_x) - { - this->SetSkew(skew_x, transform_.skew.y); - } - - void Unit::SetSkewY(float skew_y) - { - this->SetSkew(transform_.skew.x, skew_y); - } - - void Unit::SetSkew(float skew_x, float skew_y) - { - if (transform_.skew.x == skew_x && transform_.skew.y == skew_y) - return; - - transform_.skew.x = skew_x; - transform_.skew.y = skew_y; - dirty_transform_ = true; - } - - void Unit::SetRotation(float angle) - { - if (transform_.rotation == angle) - return; - - transform_.rotation = angle; - dirty_transform_ = true; - } - - void Unit::SetTransform(Transform const& transform) - { - transform_ = transform; - } - - void Unit::UpdateMatrix() - { - Point center; - matrix_cached_ = math::Matrix::Scaling(transform_.scale, center) - * math::Matrix::Skewing(transform_.skew.x, transform_.skew.y, center) - * math::Matrix::Rotation(transform_.rotation, center) - * math::Matrix::Translation(transform_.position - center); - } - -} diff --git a/core/base/Unit.h b/core/base/Unit.h deleted file mode 100644 index bef6f6ec..00000000 --- a/core/base/Unit.h +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (c) 2016-2018 Easy2D - 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 "base.hpp" -#include "Transform.hpp" - -namespace easy2d -{ - class Unit - : public ObjectBase - { - public: - Unit(); - - virtual ~Unit(); - - // 获取坐标 - virtual const Point& GetPosition() const { return transform_.position; } - - // 获取横向缩放比例 - virtual float GetScaleX() const { return transform_.scale.x; } - - // 获取纵向缩放比例 - virtual float GetScaleY() const { return transform_.scale.y; } - - // 获取横向错切角度 - virtual float GetSkewX() const { return transform_.skew.x; } - - // 获取纵向错切角度 - virtual float GetSkewY() const { return transform_.skew.y; } - - // 获取旋转角度 - virtual float GetRotation() const { return transform_.rotation; } - - Transform const& GetTransform() const { return transform_; } - - // 设置横坐标 - void SetPositionX( - float x - ); - - // 设置纵坐标 - void SetPositionY( - float y - ); - - // 设置坐标 - void SetPosition( - const Point & point - ); - - // 设置坐标 - virtual void SetPosition( - float x, - float y - ); - - // 移动 - void Move( - float x, - float y - ); - - // 移动 - void Move( - const Point & vector - ); - - // 设置横向缩放比例 - // 默认为 1.0 - void SetScaleX( - float scale_x - ); - - // 设置纵向缩放比例 - // 默认为 1.0 - void SetScaleY( - float scale_y - ); - - // 设置缩放比例 - // 默认为 (1.0, 1.0) - virtual void SetScale( - float scale_x, - float scale_y - ); - - // 设置缩放比例 - // 默认为 1.0 - void SetScale( - float scale - ); - - // 设置横向错切角度 - // 默认为 0 - void SetSkewX( - float skew_x - ); - - // 设置纵向错切角度 - // 默认为 0 - void SetSkewY( - float skew_y - ); - - // 设置错切角度 - // 默认为 (0, 0) - virtual void SetSkew( - float skew_x, - float skew_y - ); - - // 设置旋转角度 - // 默认为 0 - virtual void SetRotation( - float rotation - ); - - virtual void SetTransform( - Transform const& transform - ); - - // 获取二维变换矩阵 - virtual math::Matrix const& GetTransformMatrix(); - - protected: - virtual void UpdateMatrix(); - - protected: - bool dirty_transform_; - Transform transform_; - math::Matrix matrix_cached_; - }; -} diff --git a/core/base/audio.cpp b/core/base/audio.cpp index 3c8fffe5..836d57b6 100644 --- a/core/base/audio.cpp +++ b/core/base/audio.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "audio.h" -#include "base.hpp" +#include "include-forwards.h" #include "modules.h" #include "logs.h" #include diff --git a/core/base/d2dres.hpp b/core/base/d2dhelper.hpp similarity index 99% rename from core/base/d2dres.hpp rename to core/base/d2dhelper.hpp index 13fc9788..b8459ed8 100644 --- a/core/base/d2dres.hpp +++ b/core/base/d2dhelper.hpp @@ -19,7 +19,6 @@ // THE SOFTWARE. #pragma once -#include "macros.h" #include "intrusive/SmartPointer.hpp" #include #include diff --git a/core/base/base.hpp b/core/base/helper.hpp similarity index 94% rename from core/base/base.hpp rename to core/base/helper.hpp index 89d55905..c1137404 100644 --- a/core/base/base.hpp +++ b/core/base/helper.hpp @@ -19,11 +19,8 @@ // THE SOFTWARE. #pragma once -#include "BaseTypes.hpp" #include "RefCounter.hpp" -#include "ObjectBase.h" #include "intrusive/SmartPointer.hpp" -#include "d2dres.hpp" #ifndef E2D_DECLARE_SMART_PTR #define E2D_DECLARE_SMART_PTR(class_name)\ @@ -53,7 +50,7 @@ namespace easy2d E2D_DECLARE_SMART_PTR(CircleGeometry); E2D_DECLARE_SMART_PTR(EllipseGeometry); E2D_DECLARE_SMART_PTR(PathGeometry); - + E2D_DECLARE_SMART_PTR(Node); E2D_DECLARE_SMART_PTR(Scene); E2D_DECLARE_SMART_PTR(Sprite); @@ -94,17 +91,17 @@ namespace easy2d template - inline Dest* SafeCast(Src* ptr) + inline Dest SafeCast(Src ptr) { if (!ptr) return nullptr; #ifdef E2D_DEBUG - Dest* cast = dynamic_cast(ptr); + Dest cast = dynamic_cast(ptr); E2D_ASSERT(cast); return cast; +#else + return static_cast(ptr); #endif - - return static_cast(ptr); } } diff --git a/core/base/include-forwards.h b/core/base/include-forwards.h new file mode 100644 index 00000000..a4374ac9 --- /dev/null +++ b/core/base/include-forwards.h @@ -0,0 +1,65 @@ +// Copyright (c) 2016-2018 Easy2D - 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 "macros.h" +#include "Point.hpp" +#include "Size.hpp" +#include "Rect.hpp" +#include "Color.h" +#include "Object.h" +#include "helper.hpp" +#include "d2dhelper.hpp" + +namespace easy2d +{ + // 画笔样式 + enum class StrokeStyle : int + { + Miter = 0, /* 斜切 */ + Bevel = 1, /* 斜角 */ + Round = 2 /* 圆角 */ + }; + + // 方向 + enum class Direction : int + { + Up, /* 上 */ + Down, /* 下 */ + Left, /* 左 */ + Right /* 右 */ + }; + + // 文字抗锯齿属性 + enum class TextAntialias + { + Default, // 系统默认 + ClearType, // ClearType 抗锯齿 + GrayScale, // 灰度抗锯齿 + None // 不启用抗锯齿 + }; + + // 图层属性 + struct LayerProperties + { + Rect area; + float opacity; + }; +} diff --git a/core/base/intrusive/List.hpp b/core/base/intrusive/List.hpp index 35104804..6e304710 100644 --- a/core/base/intrusive/List.hpp +++ b/core/base/intrusive/List.hpp @@ -130,7 +130,7 @@ namespace easy2d DEBUG_CHECK_LIST(this); } - void Insert(T& child, T& before) + void InsertBefore(T& child, T& before) { if (child->prev_) child->prev_->next_ = child->next_; @@ -149,6 +149,25 @@ namespace easy2d DEBUG_CHECK_LIST(this); } + void InsertAfter(T& child, T& after) + { + if (child->prev_) + child->prev_->next_ = child->next_; + if (child->next_) + child->next_->prev_ = child->prev_; + + if (after->next_) + after->next_->prev_ = child; + else + last_ = child; + + child->next_ = after->next_; + child->prev_ = after; + after->next_ = child; + + DEBUG_CHECK_LIST(this); + } + void Remove(T& child) { #ifdef E2D_DEBUG @@ -202,42 +221,6 @@ namespace easy2d last_ = nullptr; } - void Sort(std::function const& if_lt) - { - if (IsEmpty() || first_ == last_) - return; - - std::vector temp_vec; - for (ItemType p = first_; p; p = p->NextItem()) - { - temp_vec.push_back(p); - } - std::sort(temp_vec.begin(), temp_vec.end(), if_lt); - - size_t size = temp_vec.size(); - for (size_t i = 0; i < size; ++i) - { - if (i == 0) - temp_vec[i]->prev_ = nullptr; - else - { - temp_vec[i]->prev_ = temp_vec[i - 1]; - temp_vec[i - 1]->next_ = temp_vec[i]; - } - if (i == size - 1) - temp_vec[i]->next_ = nullptr; - else - { - temp_vec[i]->next_ = temp_vec[i + 1]; - temp_vec[i + 1]->prev_ = temp_vec[i]; - } - } - first_ = *temp_vec.begin(); - last_ = *temp_vec.rbegin(); - - DEBUG_CHECK_LIST(this); - } - #ifdef E2D_DEBUG private: diff --git a/core/base/intrusive/SmartPointer.hpp b/core/base/intrusive/SmartPointer.hpp index aeb06c02..1e8eed16 100644 --- a/core/base/intrusive/SmartPointer.hpp +++ b/core/base/intrusive/SmartPointer.hpp @@ -74,19 +74,19 @@ namespace easy2d inline Type* operator ->() const { - E2D_ASSERT(ptr_ != nullptr, "Invalid pointer"); + E2D_ASSERT(ptr_ != nullptr && "Invalid pointer"); return ptr_; } inline Type& operator *() const { - E2D_ASSERT(ptr_ != nullptr, "Invalid pointer"); + E2D_ASSERT(ptr_ != nullptr && "Invalid pointer"); return *ptr_; } inline Type** operator &() { - E2D_ASSERT(ptr_ == nullptr, "Memory leak"); + E2D_ASSERT(ptr_ == nullptr && "Memory leak"); return &ptr_; } diff --git a/core/base/BaseTypes.hpp b/core/base/keys.hpp similarity index 76% rename from core/base/BaseTypes.hpp rename to core/base/keys.hpp index 56404b80..b5c90101 100644 --- a/core/base/BaseTypes.hpp +++ b/core/base/keys.hpp @@ -20,47 +20,9 @@ #pragma once #include "macros.h" -#include "Point.hpp" -#include "Size.hpp" -#include "Rect.hpp" -#include "Color.h" namespace easy2d { - using String = std::wstring; - - // 方向 - enum class Direction : int - { - Up, /* 上 */ - Down, /* 下 */ - Left, /* 左 */ - Right /* 右 */ - }; - - // 画笔样式 - enum class StrokeStyle : int - { - Miter = 0, /* 斜切 */ - Bevel = 1, /* 斜角 */ - Round = 2 /* 圆角 */ - }; - - // 图层属性 - struct LayerProperties - { - Rect area; - float opacity; - }; - - // 鼠标键值 - enum class MouseButton : int - { - Left = VK_LBUTTON, // 鼠标左键 - Right = VK_RBUTTON, // 鼠标右键 - Middle = VK_MBUTTON // 鼠标中键 - }; - // 按键键值 enum class KeyCode : int { diff --git a/core/base/render.cpp b/core/base/render.cpp index 9641ada0..c9c1fb34 100644 --- a/core/base/render.cpp +++ b/core/base/render.cpp @@ -19,8 +19,6 @@ // THE SOFTWARE. #include "render.h" -#include "time.h" -#include "base.hpp" #include "logs.h" #include "Factory.h" #include "Image.h" @@ -33,6 +31,7 @@ namespace easy2d , fps_text_layout_(nullptr) , clear_color_(D2D1::ColorF(D2D1::ColorF::Black)) , opacity_(1.f) + , debug_(false) , window_occluded_(false) , vsync_enabled_(true) , antialias_(true) @@ -51,19 +50,22 @@ namespace easy2d { E2D_LOG("Initing graphics device"); - HRESULT hr = CreateResources(hwnd); + vsync_enabled_ = vsync; + debug_ = debug; - if (SUCCEEDED(hr)) - { - vsync_enabled_ = vsync; - } - return hr; + return CreateResources(hwnd); } HRESULT GraphicsDevice::BeginDraw(HWND hwnd) { HRESULT hr = CreateResources(hwnd); + if (debug_) + { + status_.start = time::Now(); + status_.primitives = 0; + } + if (SUCCEEDED(hr)) { window_occluded_ = !!(render_target_->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED); @@ -74,13 +76,18 @@ namespace easy2d render_target_->Clear(clear_color_); } } - return hr; } HRESULT GraphicsDevice::EndDraw() { HRESULT hr = S_OK; + + if (debug_) + { + status_.duration = time::Now() - status_.start; + } + if (!window_occluded_) { hr = render_target_->EndDraw(); @@ -101,6 +108,16 @@ namespace easy2d bitmap_cache_.clear(); } + cpHwndRenderTarget const & GraphicsDevice::GetRenderTarget() const + { + return render_target_; + } + + cpSolidColorBrush const & GraphicsDevice::GetSolidBrush() const + { + return solid_brush_; + } + HRESULT GraphicsDevice::CreateLayer(cpLayer& layer) { if (!render_target_) @@ -144,6 +161,9 @@ namespace easy2d stroke_width, stroke_style.Get() ); + + if (debug_) + ++status_.primitives; return S_OK; } @@ -161,6 +181,9 @@ namespace easy2d geometry.Get(), solid_brush_.Get() ); + + if (debug_) + ++status_.primitives; return S_OK; } @@ -182,6 +205,9 @@ namespace easy2d D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, image->GetCropRect() ); + + if (debug_) + ++status_.primitives; return S_OK; } @@ -204,6 +230,9 @@ namespace easy2d D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, rect ); + + if (debug_) + ++status_.primitives; return S_OK; } @@ -215,6 +244,8 @@ namespace easy2d if (window_occluded_) return S_OK; + if (debug_) + ++status_.primitives; return text_layout->Draw(nullptr, text_renderer_.Get(), 0, 0); } @@ -226,7 +257,7 @@ namespace easy2d if (window_occluded_) return S_OK; - render_target_->SetTransform(ConvertToD2DMatrix(clip_matrix)); + render_target_->SetTransform(clip_matrix); render_target_->PushAxisAlignedClip( D2D1::RectF(0, 0, clip_size.width, clip_size.height), D2D1_ANTIALIAS_MODE_PER_PRIMITIVE @@ -293,14 +324,14 @@ namespace easy2d return S_OK; } - HRESULT GraphicsDevice::CreateBitmapFromFile(cpBitmap& bitmap, String const& file_path) + HRESULT GraphicsDevice::CreateBitmapFromFile(cpBitmap& bitmap, std::wstring const& file_path) { if (render_target_ == nullptr) { return E_UNEXPECTED; } - size_t hash_code = std::hash{}(file_path); + size_t hash_code = std::hash{}(file_path); if (bitmap_cache_.find(hash_code) != bitmap_cache_.end()) { bitmap = bitmap_cache_[hash_code]; @@ -373,7 +404,7 @@ namespace easy2d if (!render_target_) return E_UNEXPECTED; - render_target_->SetTransform(ConvertToD2DMatrix(matrix)); + render_target_->SetTransform(matrix); return S_OK; } @@ -454,6 +485,11 @@ namespace easy2d return S_OK; } + GraphicsDevice::Status const & GraphicsDevice::GetStatus() const + { + return status_; + } + HRESULT GraphicsDevice::CreateResources(HWND hwnd) { HRESULT hr = S_OK; diff --git a/core/base/render.h b/core/base/render.h index 830a8f65..1f65b8ea 100644 --- a/core/base/render.h +++ b/core/base/render.h @@ -19,30 +19,29 @@ // THE SOFTWARE. #pragma once -#include "base.hpp" -#include "Singleton.hpp" +#include "include-forwards.h" +#include "time.h" #include "Font.hpp" #include "Resource.h" #include "TextRenderer.h" #include "TextStyle.hpp" +#include "Singleton.hpp" #include "../math/Matrix.hpp" namespace easy2d { - enum class TextAntialias - { - Default, // 系统默认 - ClearType, // ClearType 抗锯齿 - GrayScale, // 灰度抗锯齿 - None // 不启用抗锯齿 - }; - - class GraphicsDevice : protected Noncopyable { E2D_DECLARE_SINGLETON(GraphicsDevice); + struct Status + { + TimePoint start; + Duration duration; + int primitives; + }; + public: HRESULT Init(HWND hwnd, bool vsync, bool debug); @@ -67,6 +66,8 @@ namespace easy2d TextAntialias mode ); + Status const& GetStatus() const; + HRESULT CreateResources( HWND hwnd ); @@ -83,7 +84,7 @@ namespace easy2d HRESULT CreateBitmapFromFile( cpBitmap& bitmap, - String const& file_path + std::wstring const& file_path ); HRESULT CreateBitmapFromResource( @@ -160,21 +161,27 @@ namespace easy2d void ClearImageCache(); + cpHwndRenderTarget const& GetRenderTarget() const; + + cpSolidColorBrush const& GetSolidBrush() const; + protected: GraphicsDevice(); ~GraphicsDevice(); protected: + bool debug_; bool window_occluded_; bool vsync_enabled_; bool antialias_; - TextAntialias text_antialias_; float opacity_; + D2D1_COLOR_F clear_color_; + TextAntialias text_antialias_; + Status status_; cpTextRenderer text_renderer_; cpSolidColorBrush solid_brush_; cpHwndRenderTarget render_target_; - D2D1_COLOR_F clear_color_; cpTextFormat fps_text_format_; cpTextLayout fps_text_layout_; std::map bitmap_cache_; diff --git a/core/base/window.cpp b/core/base/window.cpp index 15ef7303..224c6cdf 100644 --- a/core/base/window.cpp +++ b/core/base/window.cpp @@ -47,7 +47,7 @@ namespace easy2d E2D_LOG("Destroying window"); } - HRESULT WindowImpl::Init(String title, int width, int height, LPCWSTR icon, WNDPROC proc, bool debug) + HRESULT WindowImpl::Init(std::wstring title, int width, int height, LPCWSTR icon, WNDPROC proc, bool debug) { E2D_LOG("Creating window"); @@ -105,7 +105,7 @@ namespace easy2d return S_OK; } - String WindowImpl::GetTitle() const + std::wstring WindowImpl::GetTitle() const { if (handle) { @@ -113,10 +113,10 @@ namespace easy2d GetWindowTextW(handle, title, 256); return title; } - return String(); + return std::wstring(); } - void WindowImpl::SetTitle(String const& title) + void WindowImpl::SetTitle(std::wstring const& title) { if (handle) ::SetWindowText(handle, title.c_str()); diff --git a/core/base/window.h b/core/base/window.h index 8380bef1..100755a9 100644 --- a/core/base/window.h +++ b/core/base/window.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include "base.hpp" +#include "include-forwards.h" #include "Singleton.hpp" namespace easy2d @@ -31,7 +31,7 @@ namespace easy2d public: HRESULT Init( - String title, + std::wstring title, int width, int height, LPCWSTR icon, @@ -40,10 +40,10 @@ namespace easy2d ); // 获取标题 - String GetTitle() const; + std::wstring GetTitle() const; // 设置标题 - void SetTitle(String const& title); + void SetTitle(std::wstring const& title); // 获取窗口大小 Size GetSize() const; diff --git a/core/easy2d.h b/core/easy2d.h index 06036d49..7e2850a4 100644 --- a/core/easy2d.h +++ b/core/easy2d.h @@ -31,7 +31,6 @@ // #include "base/macros.h" -#include "base/base.hpp" #include "base/modules.h" #include "base/render.h" #include "base/window.h" @@ -54,19 +53,20 @@ #include "base/intrusive/SmartPointer.hpp" #include "base/intrusive/List.hpp" -#include "base/ObjectBase.h" +#include "base/Object.h" #include "base/Image.h" #include "base/Frames.h" #include "base/Music.h" +#include "base/Geometry.h" #include "base/Task.h" +#include "base/TaskManager.h" #include "base/Action.hpp" #include "base/ActionCombined.h" #include "base/ActionTween.h" #include "base/Animation.h" #include "base/Delay.h" -#include "base/Transition.h" -#include "base/TaskManager.h" #include "base/ActionManager.h" +#include "base/Transition.h" #include "base/Event.hpp" #include "base/MouseEvent.hpp" @@ -74,15 +74,13 @@ #include "base/EventListener.h" #include "base/EventDispatcher.h" -#include "base/Unit.h" -#include "base/Geometry.h" #include "base/Node.h" #include "base/Scene.h" #include "base/Sprite.h" #include "base/Text.h" #include "base/Canvas.h" #include "base/GeometryNode.h" -#include "base/Debuger.h" +#include "base/DebugNode.h" #include "base/Factory.h" #include "base/Game.h" diff --git a/core/math/Matrix.hpp b/core/math/Matrix.hpp index e3f46f0b..c66637ef 100644 --- a/core/math/Matrix.hpp +++ b/core/math/Matrix.hpp @@ -20,6 +20,7 @@ #pragma once #include "vector.hpp" +#include namespace easy2d { @@ -40,85 +41,112 @@ namespace easy2d class Matrix { - public: - float m[6]; // m[3][2] + union + { + struct + { + float m[6]; // m[3][2] + }; + + struct + { + float + _11, _12, + _21, _22, + _31, _32; + }; + }; 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 val[6]) - { - m[0] = val[0]; m[1] = val[1]; - m[2] = val[2]; m[3] = val[3]; - m[4] = val[4]; m[5] = val[5]; } Matrix(float _11, float _12, float _21, float _22, float _31, float _32) + : _11(_11), _12(_12), _21(_21), _22(_22), _31(_31), _32(_32) { - m[0] = _11; m[1] = _12; - m[2] = _21; m[3] = _22; - m[4] = _31; m[5] = _32; + } + + Matrix(const float* p) + { + for (int i = 0; i < 6; i++) + m[i] = p[i]; } Matrix(Matrix const& other) + : _11(other._11), _12(other._12) + , _21(other._21), _22(other._22) + , _31(other._31), _32(other._32) { - 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]; + for (int i = 0; i < 6; i++) + m[i] = other[i]; } - inline float operator [](unsigned int index) const { return m[index]; } + 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]; + for (int i = 0; i < 6; i++) + m[i] = other[i]; return *this; } inline Matrix& Identity() { - m[0] = 1.f; m[1] = 0.f; - m[2] = 0.f; m[3] = 1.f; - m[4] = 0.f; m[5] = 0.f; + _11 = 1.f; _12 = 0.f; + _21 = 0.f; _12 = 1.f; + _31 = 0.f; _32 = 0.f; return *this; } inline float Determinant() const { - return (m[0] * m[3]) - (m[1] * m[2]); + return (_11 * _22) - (_12 * _21); } inline bool IsIdentity() const { - 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; + return _11 == 1.f && _12 == 0.f && + _21 == 0.f && _22 == 1.f && + _31 == 0.f && _32 == 0.f; } Vector2 Transform(const Vector2& v) const { return Vector2( - v.x * m[0] + v.y * m[2] + m[4], - v.x * m[1] + v.y * m[3] + m[5] + v.x * _11 + v.y * _21 + _31, + v.x * _12 + v.y * _22 + _32 ); } + void Translate(const Vector2& v) + { + _31 += _11 * v.x + _21 * v.y; + _32 += _12 * v.x + _22 * v.y; + } + + inline operator D2D1_MATRIX_3X2_F const& () const + { + return reinterpret_cast(*this); + } + + inline operator D2D1_MATRIX_3X2_F& () + { + return reinterpret_cast(*this); + } + static Matrix Translation(const Vector2& v) { return Matrix( diff --git a/core/utils/Data.cpp b/core/utils/Data.cpp index 546b2f15..d0b155c1 100644 --- a/core/utils/Data.cpp +++ b/core/utils/Data.cpp @@ -20,10 +20,11 @@ #include "Data.h" #include "Path.h" +#include "../base/macros.h" namespace easy2d { - Data::Data(String const& key, String const& field) + Data::Data(std::wstring const& key, std::wstring const& field) : key_(key) , field_(field) , data_path_(Path::GetDataPath()) @@ -88,7 +89,7 @@ namespace easy2d return ret == TRUE; } - bool Data::SaveString(String const& val) + bool Data::SaveString(std::wstring const& val) { BOOL ret = ::WritePrivateProfileStringW( field_.c_str(), @@ -133,7 +134,7 @@ namespace easy2d return nValue == TRUE; } - String Data::GetString() + std::wstring Data::GetString() { wchar_t temp[256] = { 0 }; ::GetPrivateProfileStringW( diff --git a/core/utils/Data.h b/core/utils/Data.h index 449b644d..b035e885 100644 --- a/core/utils/Data.h +++ b/core/utils/Data.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include "../base/base.hpp" +#include namespace easy2d { @@ -28,8 +28,8 @@ namespace easy2d { public: Data( - String const& key, /* 键值 */ - String const& field = L"Defalut" /* 字段名称 */ + std::wstring const& key, /* 键值 */ + std::wstring const& field = L"Defalut" /* 字段名称 */ ); // 该数据是否存在 @@ -55,9 +55,9 @@ namespace easy2d bool val ); - // 保存 String 类型的值 + // 保存 std::wstring 类型的值 bool SaveString( - String const& val + std::wstring const& val ); // 获取 int 类型的值 @@ -73,11 +73,11 @@ namespace easy2d bool GetBool() const; // 获取 字符串 类型的值 - String GetString(); + std::wstring GetString(); protected: - String key_; - String field_; - String const& data_path_; + std::wstring key_; + std::wstring field_; + std::wstring const& data_path_; }; } diff --git a/core/utils/File.cpp b/core/utils/File.cpp index 0c297af8..1fbe47fc 100644 --- a/core/utils/File.cpp +++ b/core/utils/File.cpp @@ -24,14 +24,14 @@ namespace easy2d { - std::list File::search_paths_; + std::list File::search_paths_; File::File() : file_path_() { } - File::File(String const& file_name) + File::File(std::wstring const& file_name) : file_path_(file_name) { this->Open(file_name); @@ -41,12 +41,12 @@ namespace easy2d { } - bool File::Open(String const& file_name) + bool File::Open(std::wstring const& file_name) { if (file_name.empty()) return false; - auto FindFile = [](String const& path) -> bool + auto FindFile = [](std::wstring const& path) -> bool { if (modules::Shlwapi().PathFileExistsW(path.c_str())) return true; @@ -77,16 +77,16 @@ namespace easy2d return false; } - String const& File::GetPath() const + std::wstring const& File::GetPath() const { return file_path_; } - String File::GetExtension() const + std::wstring File::GetExtension() const { - String file_ext; + std::wstring file_ext; size_t pos = file_path_.find_last_of(L'.'); - if (pos != String::npos) + if (pos != std::wstring::npos) { file_ext = file_path_.substr(pos); std::transform(file_ext.begin(), file_ext.end(), file_ext.begin(), std::towlower); @@ -101,7 +101,7 @@ namespace easy2d return false; } - File File::Extract(Resource& res, String const& dest_file_name) + File File::Extract(Resource& res, std::wstring const& dest_file_name) { File file; HANDLE file_handle = ::CreateFile( @@ -136,11 +136,11 @@ namespace easy2d return file; } - void File::AddSearchPath(String const& path) + void File::AddSearchPath(std::wstring const& path) { - String tmp = path; + std::wstring tmp = path; size_t pos = 0; - while ((pos = tmp.find(L"/", pos)) != String::npos) + while ((pos = tmp.find(L"/", pos)) != std::wstring::npos) { tmp.replace(pos, 1, L"\\"); pos++; diff --git a/core/utils/File.h b/core/utils/File.h index e66c8b48..c1a90fe7 100644 --- a/core/utils/File.h +++ b/core/utils/File.h @@ -19,8 +19,8 @@ // THE SOFTWARE. #pragma once -#include "../base/base.hpp" #include "../base/Resource.h" +#include namespace easy2d { @@ -31,14 +31,14 @@ namespace easy2d File(); File( - String const& file_name + std::wstring const& file_name ); virtual ~File(); // 打开文件 bool Open( - String const& file_name + std::wstring const& file_name ); // 文件是否存在 @@ -48,38 +48,25 @@ namespace easy2d bool Delete(); // 获取文件路径 - String const& GetPath() const; + std::wstring const& GetPath() const; // 获取文件扩展名 - String GetExtension() const; + std::wstring GetExtension() const; // 释放资源到临时文件目录 static File Extract( Resource& res, /* 资源 */ - String const& dest_file_name /* 目标文件名 */ + std::wstring const& dest_file_name /* 目标文件名 */ ); // 添加文件搜索路径 static void AddSearchPath( - String const& path - ); - - // 弹出打开文件对话框 - static File ShowOpenDialog( - String const& title = L"打开", /* 对话框标题 */ - String const& filter = L"" /* 筛选扩展名,例如 "*.jpg;*.jpeg" */ - ); - - // 弹出保存文件对话框 - static File ShowSaveDialog( - String const& title = L"保存", /* 对话框标题 */ - String const& def_file = L"", /* 默认保存的文件名 */ - String const& def_ext = L"" /* 默认追加的扩展名,例如 "txt" */ + std::wstring const& path ); protected: - String file_path_; + std::wstring file_path_; - static std::list search_paths_; + static std::list search_paths_; }; } diff --git a/core/utils/Path.cpp b/core/utils/Path.cpp index 8b7b29ce..b067fc46 100644 --- a/core/utils/Path.cpp +++ b/core/utils/Path.cpp @@ -28,7 +28,7 @@ namespace easy2d namespace { // 创建指定文件夹 - bool CreateFolder(String const& dir_path) + bool CreateFolder(std::wstring const& dir_path) { if (dir_path.empty() || dir_path.size() >= MAX_PATH) return false; @@ -55,15 +55,15 @@ namespace easy2d } - String const& Path::GetDataPath() + std::wstring const& Path::GetDataPath() { - static String data_path; + static std::wstring data_path; if (data_path.empty()) { // 设置数据的保存路径 - String local_app_data_path = Path::GetLocalAppDataPath(); - String title = Window::Instance()->GetTitle(); - String folder_name = std::to_wstring(std::hash{}(title)); + std::wstring local_app_data_path = Path::GetLocalAppDataPath(); + std::wstring title = Window::Instance()->GetTitle(); + std::wstring folder_name = std::to_wstring(std::hash{}(title)); if (!local_app_data_path.empty()) { @@ -83,15 +83,15 @@ namespace easy2d return data_path; } - String const& Path::GetTemporaryPath() + std::wstring const& Path::GetTemporaryPath() { - static String temp_path; + static std::wstring temp_path; if (temp_path.empty()) { // 设置临时文件保存路径 wchar_t path[_MAX_PATH]; - String title = Window::Instance()->GetTitle(); - String folder_name = std::to_wstring(std::hash{}(title)); + std::wstring title = Window::Instance()->GetTitle(); + std::wstring folder_name = std::to_wstring(std::hash{}(title)); if (0 != ::GetTempPath(_MAX_PATH, path)) { @@ -110,9 +110,9 @@ namespace easy2d return temp_path; } - String const& Path::GetLocalAppDataPath() + std::wstring const& Path::GetLocalAppDataPath() { - static String local_app_data_path; + static std::wstring local_app_data_path; if (local_app_data_path.empty()) { // 获取 AppData/Local 文件夹的路径 @@ -124,9 +124,9 @@ namespace easy2d return local_app_data_path; } - String const& Path::GetExeFilePath() + std::wstring const& Path::GetExeFilePath() { - static String exe_file_path; + static std::wstring exe_file_path; if (exe_file_path.empty()) { TCHAR path[_MAX_PATH] = { 0 }; diff --git a/core/utils/Path.h b/core/utils/Path.h index fd43373b..e0b3a630 100644 --- a/core/utils/Path.h +++ b/core/utils/Path.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include "../base/base.hpp" +#include namespace easy2d { @@ -28,15 +28,15 @@ namespace easy2d { public: // 获取数据的默认保存路径 - static String const& GetDataPath(); + static std::wstring const& GetDataPath(); // 获取临时文件目录 - static String const& GetTemporaryPath(); + static std::wstring const& GetTemporaryPath(); // 获取 LocalAppData 目录 - static String const& GetLocalAppDataPath(); + static std::wstring const& GetLocalAppDataPath(); // 获取当前程序的运行路径 - static String const& GetExeFilePath(); + static std::wstring const& GetExeFilePath(); }; } diff --git a/core/utils/Player.cpp b/core/utils/Player.cpp index 862f0d8e..9d749519 100644 --- a/core/utils/Player.cpp +++ b/core/utils/Player.cpp @@ -33,7 +33,7 @@ namespace easy2d ClearCache(); } - bool Player::Load(String const& file_path) + bool Player::Load(std::wstring const& file_path) { if (file_path.empty()) return false; @@ -46,7 +46,7 @@ namespace easy2d { music->SetVolume(volume_); - size_t hash_code = std::hash{}(file_path); + size_t hash_code = std::hash{}(file_path); musics_cache_.insert(std::make_pair(hash_code, music)); return true; } @@ -54,14 +54,14 @@ namespace easy2d return false; } - bool Player::Play(String const& file_path, int loop_count) + bool Player::Play(std::wstring const& file_path, int loop_count) { if (file_path.empty()) return false; if (Load(file_path)) { - auto music = musics_cache_[std::hash{}(file_path)]; + auto music = musics_cache_[std::hash{}(file_path)]; if (music->Play(loop_count)) { return true; @@ -70,42 +70,42 @@ namespace easy2d return false; } - void Player::Pause(String const& file_path) + void Player::Pause(std::wstring const& file_path) { if (file_path.empty()) return; - size_t hash_code = std::hash{}(file_path); + size_t hash_code = std::hash{}(file_path); if (musics_cache_.end() != musics_cache_.find(hash_code)) musics_cache_[hash_code]->Pause(); } - void Player::Resume(String const& file_path) + void Player::Resume(std::wstring const& file_path) { if (file_path.empty()) return; - size_t hash_code = std::hash{}(file_path); + size_t hash_code = std::hash{}(file_path); if (musics_cache_.end() != musics_cache_.find(hash_code)) musics_cache_[hash_code]->Resume(); } - void Player::Stop(String const& file_path) + void Player::Stop(std::wstring const& file_path) { if (file_path.empty()) return; - size_t hash_code = std::hash{}(file_path); + size_t hash_code = std::hash{}(file_path); if (musics_cache_.end() != musics_cache_.find(hash_code)) musics_cache_[hash_code]->Stop(); } - bool Player::IsPlaying(String const& file_path) + bool Player::IsPlaying(std::wstring const& file_path) { if (file_path.empty()) return false; - size_t hash_code = std::hash{}(file_path); + size_t hash_code = std::hash{}(file_path); if (musics_cache_.end() != musics_cache_.find(hash_code)) return musics_cache_[hash_code]->IsPlaying(); return false; diff --git a/core/utils/Player.h b/core/utils/Player.h index bcc5050d..1ae745a1 100644 --- a/core/utils/Player.h +++ b/core/utils/Player.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include "../base/base.hpp" +#include "../base/include-forwards.h" #include "../base/Resource.h" namespace easy2d @@ -35,33 +35,33 @@ namespace easy2d // 预加载音乐资源 bool Load( - String const& file_path /* 音乐文件路径 */ + std::wstring const& file_path /* 音乐文件路径 */ ); // 播放音乐 bool Play( - String const& file_path, /* 音乐文件路径 */ - int loop_count = 0 /* 播放循环次数 (-1 为循环播放) */ + std::wstring const& file_path, /* 音乐文件路径 */ + int loop_count = 0 /* 播放循环次数 (-1 为循环播放) */ ); // 暂停音乐 void Pause( - String const& file_path /* 音乐文件路径 */ + std::wstring const& file_path /* 音乐文件路径 */ ); // 继续播放音乐 void Resume( - String const& file_path /* 音乐文件路径 */ + std::wstring const& file_path /* 音乐文件路径 */ ); // 停止音乐 void Stop( - String const& file_path /* 音乐文件路径 */ + std::wstring const& file_path /* 音乐文件路径 */ ); // 获取音乐播放状态 bool IsPlaying( - String const& file_path /* 音乐文件路径 */ + std::wstring const& file_path /* 音乐文件路径 */ ); // 预加载音乐资源 diff --git a/core/utils/Transcoder.cpp b/core/utils/Transcoder.cpp index 533f2c88..a56f16f2 100644 --- a/core/utils/Transcoder.cpp +++ b/core/utils/Transcoder.cpp @@ -19,13 +19,15 @@ // THE SOFTWARE. #include "Transcoder.h" -#include "../base/base.hpp" +#include "../base/d2dhelper.hpp" #include "../base/modules.h" #include "../base/logs.h" #include namespace easy2d { + using namespace intrusive; + Transcoder::Transcoder() : wave_format_(nullptr) { @@ -49,7 +51,7 @@ namespace easy2d { HRESULT hr = S_OK; - IMFSourceReader* reader = nullptr; + SmartPointer reader; hr = modules::MediaFoundation().MFCreateSourceReaderFromURL( file_path, @@ -59,22 +61,20 @@ namespace easy2d if (SUCCEEDED(hr)) { - hr = ReadSource(reader, wave_data, wave_data_size); + hr = ReadSource(reader.Get(), wave_data, wave_data_size); } - SafeRelease(reader); - return hr; } HRESULT Transcoder::LoadMediaResource(Resource const& res, BYTE** wave_data, UINT32* wave_data_size) { HRESULT hr = S_OK; + HINSTANCE hinstance = GetModuleHandle(nullptr); - HINSTANCE hinstance = GetModuleHandle(nullptr); - IStream* stream = nullptr; - IMFByteStream* byte_stream = nullptr; - IMFSourceReader* reader = nullptr; + SmartPointer stream; + SmartPointer byte_stream; + SmartPointer reader; ResourceData buffer; if (!res.Load(&buffer)) { return false; } @@ -92,13 +92,13 @@ namespace easy2d if (SUCCEEDED(hr)) { - hr = modules::MediaFoundation().MFCreateMFByteStreamOnStream(stream, &byte_stream); + hr = modules::MediaFoundation().MFCreateMFByteStreamOnStream(stream.Get(), &byte_stream); } if (SUCCEEDED(hr)) { hr = modules::MediaFoundation().MFCreateSourceReaderFromByteStream( - byte_stream, + byte_stream.Get(), nullptr, &reader ); @@ -106,13 +106,9 @@ namespace easy2d if (SUCCEEDED(hr)) { - hr = ReadSource(reader, wave_data, wave_data_size); + hr = ReadSource(reader.Get(), wave_data, wave_data_size); } - SafeRelease(stream); - SafeRelease(byte_stream); - SafeRelease(reader); - return hr; } @@ -121,8 +117,8 @@ namespace easy2d HRESULT hr = S_OK; DWORD max_stream_size = 0; - IMFMediaType* partial_type = nullptr; - IMFMediaType* uncompressed_type = nullptr; + SmartPointer partial_type; + SmartPointer uncompressed_type; hr = modules::MediaFoundation().MFCreateMediaType(&partial_type); @@ -142,7 +138,7 @@ namespace easy2d hr = reader->SetCurrentMediaType( MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, - partial_type + partial_type.Get() ); } @@ -169,7 +165,7 @@ namespace easy2d { UINT32 size = 0; hr = modules::MediaFoundation().MFCreateWaveFormatExFromMFMediaType( - uncompressed_type, + uncompressed_type.Get(), &wave_format_, &size, MFWaveFormatExConvertFlag_Normal @@ -200,10 +196,10 @@ namespace easy2d { DWORD flags = 0; DWORD position = 0; + BYTE* data = new (std::nothrow) BYTE[max_stream_size]; - IMFSample* sample = nullptr; - IMFMediaBuffer* buffer = nullptr; - BYTE* data = new (std::nothrow) BYTE[max_stream_size]; + SmartPointer sample; + SmartPointer buffer; if (data == nullptr) { @@ -251,9 +247,9 @@ namespace easy2d hr = buffer->Unlock(); } } - SafeRelease(buffer); + buffer = nullptr; } - SafeRelease(sample); + sample = nullptr; if (FAILED(hr)) { break; } } @@ -266,9 +262,6 @@ namespace easy2d } } - SafeRelease(partial_type); - SafeRelease(uncompressed_type); - return hr; } } \ No newline at end of file diff --git a/project/vs2013/Easy2D.vcxproj b/project/vs2013/Easy2D.vcxproj index 66b2556c..d8e08658 100644 --- a/project/vs2013/Easy2D.vcxproj +++ b/project/vs2013/Easy2D.vcxproj @@ -25,12 +25,10 @@ - - - - + + @@ -41,11 +39,14 @@ + + + @@ -53,7 +54,7 @@ - + @@ -71,7 +72,6 @@ - @@ -97,7 +97,7 @@ - + @@ -112,7 +112,7 @@ - + @@ -123,7 +123,6 @@ - diff --git a/project/vs2013/Easy2D.vcxproj.filters b/project/vs2013/Easy2D.vcxproj.filters index 313c07e6..948b455d 100644 --- a/project/vs2013/Easy2D.vcxproj.filters +++ b/project/vs2013/Easy2D.vcxproj.filters @@ -134,12 +134,6 @@ base\intrusive - - base - - - base - base @@ -149,30 +143,18 @@ base - - base - base - - base - utils - - base - base base - - base - math @@ -206,6 +188,24 @@ base + + base + + + base + + + base + + + base + + + base + + + base + @@ -321,24 +321,15 @@ base - - base - utils - - base - base base - - base - base @@ -357,5 +348,11 @@ base + + base + + + base + \ No newline at end of file diff --git a/project/vs2015/Easy2D.vcxproj b/project/vs2015/Easy2D.vcxproj index a8d319f5..041378a0 100644 --- a/project/vs2015/Easy2D.vcxproj +++ b/project/vs2015/Easy2D.vcxproj @@ -25,12 +25,10 @@ - - - - + + @@ -41,11 +39,14 @@ + + + @@ -53,7 +54,7 @@ - + @@ -71,7 +72,6 @@ - @@ -97,7 +97,7 @@ - + @@ -112,7 +112,7 @@ - + @@ -123,7 +123,6 @@ - diff --git a/project/vs2015/Easy2D.vcxproj.filters b/project/vs2015/Easy2D.vcxproj.filters index 313c07e6..948b455d 100644 --- a/project/vs2015/Easy2D.vcxproj.filters +++ b/project/vs2015/Easy2D.vcxproj.filters @@ -134,12 +134,6 @@ base\intrusive - - base - - - base - base @@ -149,30 +143,18 @@ base - - base - base - - base - utils - - base - base base - - base - math @@ -206,6 +188,24 @@ base + + base + + + base + + + base + + + base + + + base + + + base + @@ -321,24 +321,15 @@ base - - base - utils - - base - base base - - base - base @@ -357,5 +348,11 @@ base + + base + + + base + \ No newline at end of file diff --git a/project/vs2017/Easy2D.vcxproj b/project/vs2017/Easy2D.vcxproj index 8bfa00c2..e8629361 100644 --- a/project/vs2017/Easy2D.vcxproj +++ b/project/vs2017/Easy2D.vcxproj @@ -25,12 +25,10 @@ - - - - + + @@ -41,11 +39,14 @@ + + + @@ -53,7 +54,7 @@ - + @@ -71,7 +72,6 @@ - @@ -97,7 +97,7 @@ - + @@ -112,7 +112,7 @@ - + @@ -123,7 +123,6 @@ - diff --git a/project/vs2017/Easy2D.vcxproj.filters b/project/vs2017/Easy2D.vcxproj.filters index 313c07e6..948b455d 100644 --- a/project/vs2017/Easy2D.vcxproj.filters +++ b/project/vs2017/Easy2D.vcxproj.filters @@ -134,12 +134,6 @@ base\intrusive - - base - - - base - base @@ -149,30 +143,18 @@ base - - base - base - - base - utils - - base - base base - - base - math @@ -206,6 +188,24 @@ base + + base + + + base + + + base + + + base + + + base + + + base + @@ -321,24 +321,15 @@ base - - base - utils - - base - base base - - base - base @@ -357,5 +348,11 @@ base + + base + + + base + \ No newline at end of file