From 465b8d3384c36047c1b56a8270a5d4838a28c51c Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Thu, 12 Oct 2017 23:34:13 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E4=BA=86EScene,EObject,ENode?= =?UTF-8?q?=E5=92=8CEObjectManager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Easy2D/Base/{App.cpp => EApp.cpp} | 117 ++++++--- Easy2D/Base/EObject.cpp | 31 +++ Easy2D/Base/{Scene.cpp => EScene.cpp} | 39 +-- Easy2D/Base/FreePool.cpp | 48 ---- Easy2D/Easy2D.vcxproj | 13 +- Easy2D/Easy2D.vcxproj.filters | 39 ++- Easy2D/Msg/KeyMsg.cpp | 6 +- Easy2D/Msg/MouseMsg.cpp | 6 +- Easy2D/{Object => Node}/BatchNode.cpp | 0 Easy2D/{Object => Node}/BatchSprite.cpp | 0 Easy2D/{Object => Node}/Button/Button.cpp | 0 .../{Object => Node}/Button/ImageButton.cpp | 0 Easy2D/{Object => Node}/Button/TextButton.cpp | 0 Easy2D/Node/ENode.cpp | 186 ++++++++++++++ Easy2D/{Object => Node}/Image.cpp | 0 Easy2D/{Object => Node}/Layer.cpp | 0 Easy2D/{Object => Node}/MouseNode.cpp | 0 Easy2D/{Object => Node}/RectNode.cpp | 0 Easy2D/{Object => Node}/Shape/Circle.cpp | 0 Easy2D/{Object => Node}/Shape/Rectangle.cpp | 0 Easy2D/{Object => Node}/Shape/Shape.cpp | 0 Easy2D/{Object => Node}/Sprite.cpp | 0 Easy2D/{Object => Node}/Text.cpp | 0 Easy2D/Object/Node.cpp | 106 -------- Easy2D/Object/Object.cpp | 30 --- Easy2D/Tool/ActionManager.cpp | 6 +- Easy2D/Tool/EObjectManager.cpp | 51 ++++ Easy2D/Tool/Timer.cpp | 6 +- Easy2D/easy2d.h | 209 +--------------- Easy2D/ebase.h | 234 ++++++++++++++++++ Easy2D/ecommon.h | 17 +- Easy2D/emacros.h | 13 +- Easy2D/enodes.h | 164 ++++++++++++ Easy2D/etools.h | 23 ++ 34 files changed, 858 insertions(+), 486 deletions(-) rename Easy2D/Base/{App.cpp => EApp.cpp} (82%) create mode 100644 Easy2D/Base/EObject.cpp rename Easy2D/Base/{Scene.cpp => EScene.cpp} (71%) delete mode 100644 Easy2D/Base/FreePool.cpp rename Easy2D/{Object => Node}/BatchNode.cpp (100%) rename Easy2D/{Object => Node}/BatchSprite.cpp (100%) rename Easy2D/{Object => Node}/Button/Button.cpp (100%) rename Easy2D/{Object => Node}/Button/ImageButton.cpp (100%) rename Easy2D/{Object => Node}/Button/TextButton.cpp (100%) create mode 100644 Easy2D/Node/ENode.cpp rename Easy2D/{Object => Node}/Image.cpp (100%) rename Easy2D/{Object => Node}/Layer.cpp (100%) rename Easy2D/{Object => Node}/MouseNode.cpp (100%) rename Easy2D/{Object => Node}/RectNode.cpp (100%) rename Easy2D/{Object => Node}/Shape/Circle.cpp (100%) rename Easy2D/{Object => Node}/Shape/Rectangle.cpp (100%) rename Easy2D/{Object => Node}/Shape/Shape.cpp (100%) rename Easy2D/{Object => Node}/Sprite.cpp (100%) rename Easy2D/{Object => Node}/Text.cpp (100%) delete mode 100644 Easy2D/Object/Node.cpp delete mode 100644 Easy2D/Object/Object.cpp create mode 100644 Easy2D/Tool/EObjectManager.cpp create mode 100644 Easy2D/ebase.h create mode 100644 Easy2D/enodes.h create mode 100644 Easy2D/etools.h diff --git a/Easy2D/Base/App.cpp b/Easy2D/Base/EApp.cpp similarity index 82% rename from Easy2D/Base/App.cpp rename to Easy2D/Base/EApp.cpp index 0864f5a6..b19cb5e7 100644 --- a/Easy2D/Base/App.cpp +++ b/Easy2D/Base/EApp.cpp @@ -1,4 +1,4 @@ -#include "..\easy2d.h" +#include "..\ebase.h" #include "..\Win\winbase.h" #include #include @@ -13,8 +13,8 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase; #endif -EApp * s_pInstance = nullptr; -std::stack s_SceneStack; +e2d::EApp * s_pInstance = nullptr; +std::stack s_SceneStack; e2d::EApp::EApp() : m_bRunning(false) @@ -33,18 +33,18 @@ e2d::EApp::~EApp() SafeReleaseInterface(&GetRenderTarget()); } -EApp * e2d::EApp::get() +e2d::EApp * e2d::EApp::get() { - Assert(s_pInstance); // 断言实例存在 + ASSERT(s_pInstance != nullptr); return s_pInstance; // 获取 EApp 的唯一实例 } -bool e2d::EApp::init(EString title, ESize size, bool bShowConsole /* = false */) +bool e2d::EApp::init(e2d::EString title, e2d::ESize size, bool bShowConsole /* = false */) { - return init(title, size.width, size.height, bShowConsole); + return init(title, size.cx, size.cy, bShowConsole); } -bool e2d::EApp::init(EString title, UINT32 width, UINT32 height, bool bShowConsole /* = false */) +bool e2d::EApp::init(e2d::EString title, UINT32 width, UINT32 height, bool bShowConsole /* = false */) { m_sTitle = title; @@ -60,7 +60,7 @@ bool e2d::EApp::init(EString title, UINT32 width, UINT32 height, bool bShowConso if (hwnd) { - hr = ShowWindow(hwnd, SW_HIDE); + ShowWindow(hwnd, SW_HIDE); } } } @@ -69,7 +69,7 @@ bool e2d::EApp::init(EString title, UINT32 width, UINT32 height, bool bShowConso { // 初始化 device-indpendent 资源 // 比如 Direct2D factory. - hr = CreateDeviceIndependentResources(); + hr = _createDeviceIndependentResources(); if (SUCCEEDED(hr)) { @@ -115,6 +115,11 @@ bool e2d::EApp::init(EString title, UINT32 width, UINT32 height, bool bShowConso } } + if (FAILED(hr)) + { + MessageBox(nullptr, L"Initialize Failed!", L"Error", MB_OK); + } + return SUCCEEDED(hr); } @@ -131,19 +136,25 @@ void e2d::EApp::run() while (m_bRunning) { - // 处理窗口消息 if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { + // 处理窗口消息 if (msg.message == WM_QUIT) { m_bRunning = false; + break; } TranslateMessage(&msg); DispatchMessage(&msg); } - // 执行主循环 - _mainLoop(); + else + { + // 执行主循环 + _mainLoop(); + } } + // 游戏结束后再执行一次循环 + _mainLoop(); // 关闭窗口 close(); // 释放所有内存占用 @@ -196,13 +207,13 @@ void e2d::EApp::_onControl() _enterNextScene(); } // 断言当前场景非空 - Assert(m_pCurrentScene); + ASSERT(m_pCurrentScene != nullptr); //MouseMsg::__exec(); // 鼠标检测 //KeyMsg::__exec(); // 键盘按键检测 //Timer::__exec(); // 定时器执行程序 //ActionManager::__exec(); // 动作管理器执行程序 - //FreePool::__flush(); // 刷新内存池 + //EObjectManager::__flush(); // 刷新内存池 } // This method discards device-specific @@ -212,7 +223,7 @@ bool e2d::EApp::_onRender() { HRESULT hr = S_OK; - hr = CreateDeviceResources(); + hr = _createDeviceResources(); if (SUCCEEDED(hr)) { @@ -230,7 +241,7 @@ bool e2d::EApp::_onRender() if (hr == D2DERR_RECREATE_TARGET) { hr = S_OK; - DiscardDeviceResources(); + _discardDeviceResources(); } return SUCCEEDED(hr); @@ -264,12 +275,12 @@ void e2d::EApp::setWindowSize(int width, int height) ); } -void e2d::EApp::setWindowSize(ESize size) +void e2d::EApp::setWindowSize(e2d::ESize size) { - setWindowSize(size.width, size.height); + setWindowSize(size.cx, size.cy); } -void e2d::EApp::setWindowTitle(EString title) +void e2d::EApp::setWindowTitle(e2d::EString title) { // 设置窗口标题 SetWindowText(GetHWnd(), title.c_str()); @@ -277,22 +288,27 @@ void e2d::EApp::setWindowTitle(EString title) m_sTitle = title; } -EString e2d::EApp::getTitle() +e2d::EString e2d::EApp::getTitle() { return m_sTitle; } -int e2d::EApp::getWidth() +e2d::ESize e2d::EApp::getSize() +{ + return e2d::ESize(GetRenderTarget()->GetPixelSize().width, GetRenderTarget()->GetPixelSize().height); +} + +UINT32 e2d::EApp::getWidth() { return GetRenderTarget()->GetPixelSize().width; } -int e2d::EApp::getHeight() +UINT32 e2d::EApp::getHeight() { return GetRenderTarget()->GetPixelSize().height; } -void e2d::EApp::enterScene(Scene * scene, bool save /* = true */) +void e2d::EApp::enterScene(EScene * scene, bool save /* = true */) { // 保存下一场景的指针 m_pNextScene = scene; @@ -319,27 +335,32 @@ void e2d::EApp::clearScene() } } -Scene * e2d::EApp::getCurrentScene() +e2d::EScene * e2d::EApp::getCurrentScene() { return m_pCurrentScene; } -Scene * e2d::EApp::getLoadingScene() +e2d::EScene * e2d::EApp::getLoadingScene() { return m_pLoadingScene; } -void e2d::EApp::setAppName(EString appname) +void e2d::EApp::setLoadingScene(EScene * scene) +{ + m_pLoadingScene = scene; +} + +void e2d::EApp::setAppName(e2d::EString appname) { s_pInstance->m_sAppName = appname; } -EString e2d::EApp::getAppName() +e2d::EString e2d::EApp::getAppName() { return s_pInstance->m_sAppName; } -void EApp::setBkColor(EColor::Enum color) +void e2d::EApp::setBkColor(EColor::Enum color) { m_ClearColor = color; } @@ -354,7 +375,7 @@ void e2d::EApp::show() ShowWindow(GetHWnd(), SW_NORMAL); } -void EApp::free() +void e2d::EApp::free() { // 释放场景内存 SafeDelete(&m_pCurrentScene); @@ -372,20 +393,20 @@ void EApp::free() //KeyMsg::clearAllListeners(); //ActionManager::clearAllActions(); // 删除所有对象 - //FreePool::__clearAllObjects(); + //EObjectManager::__clearAllObjects(); } -void EApp::quit() +void e2d::EApp::quit() { m_bRunning = false; } -void EApp::end() +void e2d::EApp::end() { m_bRunning = false; } -void EApp::_enterNextScene() +void e2d::EApp::_enterNextScene() { bool bBackScene = false; @@ -444,21 +465,26 @@ void EApp::_enterNextScene() // Creates resources that are not bound to a particular device. // Their lifetime effectively extends for the duration of the // application. -HRESULT e2d::EApp::CreateDeviceIndependentResources() +HRESULT e2d::EApp::_createDeviceIndependentResources() { HRESULT hr = S_OK; // Create a Direct2D factory. hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &GetFactory()); + if (FAILED(hr)) + { + MessageBox(nullptr, L"Create Device Independent Resources Fail!", L"Error", MB_OK); + } + return hr; } // Creates resources that are bound to a particular // Direct3D device. These resources need to be recreated -// if the Direct3D device dissapears, such as when the display +// if the Direct3D device dissapears, such as when the isVisiable // changes, the window is remoted, etc. -HRESULT e2d::EApp::CreateDeviceResources() +HRESULT e2d::EApp::_createDeviceResources() { HRESULT hr = S_OK; @@ -485,13 +511,13 @@ HRESULT e2d::EApp::CreateDeviceResources() // Discards device-dependent resources. These resources must be // recreated when the Direct3D device is lost. -void e2d::EApp::DiscardDeviceResources() +void e2d::EApp::_discardDeviceResources() { SafeReleaseInterface(&GetRenderTarget()); } // If the application receives a WM_SIZE message, this method -// resizes the render target appropriately. +// re2d::ESizes the render target appropriately. void e2d::EApp::_onResize(UINT width, UINT height) { if (GetRenderTarget()) @@ -535,6 +561,17 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam { switch (message) { + /*case WM_ACTIVATE: + { + if (LOWORD(wParam) == WA_INACTIVE) + { + MSG msg; + do + { + GetMessage(&msg, nullptr, 0, 0); + } while (msg.wParam != WA_ACTIVE); + } + }*/ case WM_SIZE: { UINT width = LOWORD(lParam); @@ -580,5 +617,3 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam return result; } - - diff --git a/Easy2D/Base/EObject.cpp b/Easy2D/Base/EObject.cpp new file mode 100644 index 00000000..82c063be --- /dev/null +++ b/Easy2D/Base/EObject.cpp @@ -0,0 +1,31 @@ +#include "..\ebase.h" +#include "..\etools.h" + +e2d::EObject::EObject() + : m_nRefCount(0) + , m_bManaged(false) + , m_bAutoRelease(false) +{ + EObjectManager::add(this); // 将该对象放入释放池中 +} + +e2d::EObject::~EObject() +{ +} + +// 引用计数加一 +void e2d::EObject::retain() +{ + m_nRefCount++; +} + +// 引用计数减一 +void e2d::EObject::release() +{ + m_nRefCount--; +} + +void e2d::EObject::autoRelease() +{ + m_bAutoRelease = true; +} diff --git a/Easy2D/Base/Scene.cpp b/Easy2D/Base/EScene.cpp similarity index 71% rename from Easy2D/Base/Scene.cpp rename to Easy2D/Base/EScene.cpp index 57309427..a33dc05d 100644 --- a/Easy2D/Base/Scene.cpp +++ b/Easy2D/Base/EScene.cpp @@ -1,24 +1,23 @@ -#include "..\easy2d.h" -#include +#include "..\ebase.h" +#include "..\enodes.h" -Scene::Scene() +e2d::EScene::EScene() { - EApp::get()->m_pLoadingScene = this; + EApp::get()->setLoadingScene(this); } -Scene::~Scene() +e2d::EScene::~EScene() { clearAllChildren(); } -void Scene::_exec() +void e2d::EScene::_exec() { // active 标志画面是否取得焦点 bool active = true; // 逆序执行,最后绘制的节点(即位于画面最上方)最先被访问 for (int i = int(m_vChildren.size()) - 1; i >= 0; i--) { - assert(m_vChildren[i]); if (m_vChildren[i]->_exec(active)) // 执行节点程序 { active = false; // 若子节点取得焦点,将标志置 false @@ -26,32 +25,33 @@ void Scene::_exec() } } -void Scene::_onDraw() +void e2d::EScene::_onDraw() { // 绘制所有节点 for (auto child : m_vChildren) { - assert(child); child->_onDraw(); } } -void Scene::init() +void e2d::EScene::init() { } -void Scene::onEnter() +void e2d::EScene::onEnter() { } -void Scene::onExit() +void e2d::EScene::onExit() { } -void Scene::add(Node * child, int zOrder) +void e2d::EScene::add(ENode * child, int zOrder) { // 断言添加的节点非空 - assert(child); + ASSERT(child != nullptr); + // 忽略空指针 + if (child == nullptr) return; // 设置节点的父场景 child->setParentScene(this); // 设置 z 轴顺序 @@ -80,12 +80,12 @@ void Scene::add(Node * child, int zOrder) } } -bool Scene::del(Node * child) +bool e2d::EScene::del(ENode * child) { if (child == nullptr) return false; // 寻找是否有相同节点 - std::vector::iterator iter; + std::vector::iterator iter; for (iter = m_vChildren.begin(); iter != m_vChildren.end(); iter++) { // 找到相同节点 @@ -102,7 +102,12 @@ bool Scene::del(Node * child) return false; } -void Scene::clearAllChildren() +std::vector& e2d::EScene::getChildren() +{ + return m_vChildren; +} + +void e2d::EScene::clearAllChildren() { // 所有节点的引用计数减一 for (auto child : m_vChildren) diff --git a/Easy2D/Base/FreePool.cpp b/Easy2D/Base/FreePool.cpp deleted file mode 100644 index 57c901a7..00000000 --- a/Easy2D/Base/FreePool.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "..\easy2d.h" -#include - -// FreePool 释放池的实现机制: -/// Object 类中的引用计数(m_nRefCount)保证了指针的使用安全 -/// 它记录了对象被使用的次数,当计数为 0 时,FreePool 会自动释放这个对象 -/// 所有的 Object 对象都应在被使用时(例如 Text 添加到了场景中) -/// 调用 retain 函数保证该对象不被删除,并在不再使用时调用 release 函数 -/// 让其自动释放 - -// 释放池容器 -static std::vector s_vPool; - -void FreePool::__flush() -{ - // 创建迭代器 - std::vector::iterator iter; - // 循环遍历容器中的所有对象 - for (iter = s_vPool.begin(); iter != s_vPool.end();) - { - // 若对象的引用的计数为 0 - if ((*iter)->m_nRefCount == 0) - { - // 释放该对象 - delete (*iter); - // 从释放池中删除该对象 - iter = s_vPool.erase(iter); - } - else - { - iter++; // 移动迭代器 - } - } -} - -void FreePool::__add(Object * nptr) -{ - s_vPool.push_back(nptr); // 将一个对象放入释放池中 -} - -void FreePool::__clearAllObjects() -{ - for (auto o : s_vPool) - { - delete o; - } - s_vPool.clear(); -} diff --git a/Easy2D/Easy2D.vcxproj b/Easy2D/Easy2D.vcxproj index e7210351..4315f90b 100644 --- a/Easy2D/Easy2D.vcxproj +++ b/Easy2D/Easy2D.vcxproj @@ -1,4 +1,4 @@ - +锘 @@ -363,15 +363,20 @@ - - - + + + + + + + + diff --git a/Easy2D/Easy2D.vcxproj.filters b/Easy2D/Easy2D.vcxproj.filters index 158f09de..a6bbd9f1 100644 --- a/Easy2D/Easy2D.vcxproj.filters +++ b/Easy2D/Easy2D.vcxproj.filters @@ -19,20 +19,32 @@ {2f0f3d30-bfc2-4aea-a170-258bbaacaa79} + + {51864c81-02ee-4043-bf09-9ce3cbe5b6da} + + + {42d46a92-c043-4667-8c20-358319e5c313} + - - 婧愭枃浠禱Base - - - 婧愭枃浠禱Base - - - 婧愭枃浠禱Base - 婧愭枃浠禱Win + + 婧愭枃浠禱Base + + + 婧愭枃浠禱Base + + + 婧愭枃浠禱Node + + + 婧愭枃浠禱Tool + + + 婧愭枃浠禱Base + @@ -47,5 +59,14 @@ 婧愭枃浠禱Win + + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 + \ No newline at end of file diff --git a/Easy2D/Msg/KeyMsg.cpp b/Easy2D/Msg/KeyMsg.cpp index a7e8569b..b3a76b14 100644 --- a/Easy2D/Msg/KeyMsg.cpp +++ b/Easy2D/Msg/KeyMsg.cpp @@ -189,7 +189,7 @@ void KeyMsg::delListener(TString name) } } -void KeyMsg::notifyAllSceneListeners(Scene * scene) +void KeyMsg::notifyAllSceneListeners(EScene * scene) { for (auto l : s_vListeners) { @@ -200,7 +200,7 @@ void KeyMsg::notifyAllSceneListeners(Scene * scene) } } -void KeyMsg::waitAllSceneListeners(Scene * scene) +void KeyMsg::waitAllSceneListeners(EScene * scene) { for (auto l : s_vListeners) { @@ -211,7 +211,7 @@ void KeyMsg::waitAllSceneListeners(Scene * scene) } } -void KeyMsg::clearAllSceneListeners(Scene * scene) +void KeyMsg::clearAllSceneListeners(EScene * scene) { // 创建迭代器 std::vector::iterator iter; diff --git a/Easy2D/Msg/MouseMsg.cpp b/Easy2D/Msg/MouseMsg.cpp index 9d4eeecd..8234e7ef 100644 --- a/Easy2D/Msg/MouseMsg.cpp +++ b/Easy2D/Msg/MouseMsg.cpp @@ -139,7 +139,7 @@ void MouseMsg::clearAllListeners() s_vListeners.clear(); } -void MouseMsg::notifyAllSceneListeners(Scene * scene) +void MouseMsg::notifyAllSceneListeners(EScene * scene) { for (auto l : s_vListeners) { @@ -150,7 +150,7 @@ void MouseMsg::notifyAllSceneListeners(Scene * scene) } } -void MouseMsg::waitAllSceneListeners(Scene * scene) +void MouseMsg::waitAllSceneListeners(EScene * scene) { for (auto l : s_vListeners) { @@ -161,7 +161,7 @@ void MouseMsg::waitAllSceneListeners(Scene * scene) } } -void MouseMsg::clearAllSceneListeners(Scene * scene) +void MouseMsg::clearAllSceneListeners(EScene * scene) { // 创建迭代器 std::vector::iterator iter; diff --git a/Easy2D/Object/BatchNode.cpp b/Easy2D/Node/BatchNode.cpp similarity index 100% rename from Easy2D/Object/BatchNode.cpp rename to Easy2D/Node/BatchNode.cpp diff --git a/Easy2D/Object/BatchSprite.cpp b/Easy2D/Node/BatchSprite.cpp similarity index 100% rename from Easy2D/Object/BatchSprite.cpp rename to Easy2D/Node/BatchSprite.cpp diff --git a/Easy2D/Object/Button/Button.cpp b/Easy2D/Node/Button/Button.cpp similarity index 100% rename from Easy2D/Object/Button/Button.cpp rename to Easy2D/Node/Button/Button.cpp diff --git a/Easy2D/Object/Button/ImageButton.cpp b/Easy2D/Node/Button/ImageButton.cpp similarity index 100% rename from Easy2D/Object/Button/ImageButton.cpp rename to Easy2D/Node/Button/ImageButton.cpp diff --git a/Easy2D/Object/Button/TextButton.cpp b/Easy2D/Node/Button/TextButton.cpp similarity index 100% rename from Easy2D/Object/Button/TextButton.cpp rename to Easy2D/Node/Button/TextButton.cpp diff --git a/Easy2D/Node/ENode.cpp b/Easy2D/Node/ENode.cpp new file mode 100644 index 00000000..8f6eea95 --- /dev/null +++ b/Easy2D/Node/ENode.cpp @@ -0,0 +1,186 @@ +#include "..\enodes.h" + +e2d::ENode::ENode() + : m_nZOrder(0) + , m_bVisiable(true) +{ +} + +e2d::ENode::ENode(EPoint p) + : ENode() +{ + setPos(p); +} + +e2d::ENode::ENode(int x, int y) + : ENode() +{ + setPos(x, y); +} + +e2d::ENode::~ENode() +{ +} + +bool e2d::ENode::_exec(bool active) +{ + return false; +} + +void e2d::ENode::_onDraw() +{ +} + +int e2d::ENode::getX() const +{ + if (m_pParent) + { + return m_pParent->getX() + m_Rect.TopLeft().x; + } + return m_Rect.TopLeft().x; +} + +int e2d::ENode::getY() const +{ + if (m_pParent) + { + return m_pParent->getY() + m_Rect.TopLeft().y; + } + return m_Rect.TopLeft().y; +} + +CPoint e2d::ENode::getPos() const +{ + if (m_pParent) + { + return m_pParent->getPos() + m_Rect.TopLeft(); + } + return m_Rect.TopLeft(); +} + +UINT32 e2d::ENode::getWidth() const +{ + return UINT32(m_Rect.Size().cx); +} + +UINT32 e2d::ENode::getHeight() const +{ + return UINT32(m_Rect.Size().cy); +} + +e2d::ESize e2d::ENode::getSize() const +{ + return e2d::ESize(m_Rect.Size()); +} + +e2d::ERect e2d::ENode::getRect() const +{ + return e2d::ERect(m_Rect); +} + +void e2d::ENode::setX(int x) +{ + m_Rect.TopLeft().x = x; +} + +void e2d::ENode::setY(int y) +{ + m_Rect.TopLeft().y = y; +} + +void e2d::ENode::setPos(int x, int y) +{ + m_Rect.TopLeft().SetPoint(x, y); +} + +void e2d::ENode::setPos(EPoint p) +{ + m_Rect.TopLeft() = p; +} + +void e2d::ENode::move(int x, int y) +{ + m_Rect.OffsetRect(x, y); +} + +void e2d::ENode::move(EVector v) +{ + m_Rect.OffsetRect(v); +} + +void e2d::ENode::setWidth(UINT32 width) +{ + m_Rect.BottomRight().x = m_Rect.TopLeft().x + width; +} + +void e2d::ENode::setHeight(UINT32 height) +{ + m_Rect.BottomRight().y = m_Rect.TopLeft().y + height; +} + +void e2d::ENode::setSize(UINT32 width, UINT32 height) +{ + setWidth(width); + setHeight(height); +} + +void e2d::ENode::setSize(e2d::ESize size) +{ + setSize(size.cx, size.cy); +} + +void e2d::ENode::setRect(int x1, int y1, int x2, int y2) +{ + m_Rect.SetRect(x1, y1, x2, y2); +} + +void e2d::ENode::setRect(EPoint leftTop, EPoint rightBottom) +{ + m_Rect.TopLeft() = leftTop; + m_Rect.BottomRight() = rightBottom; +} + +void e2d::ENode::setRect(e2d::ERect rect) +{ + m_Rect = rect; +} + +int e2d::ENode::getZOrder() const +{ + return m_nZOrder; +} + +void e2d::ENode::setZOrder(int z) +{ + m_nZOrder = z; +} + +void e2d::ENode::setParent(e2d::ENode * parent) +{ + m_pParent = parent; +} + +e2d::ENode *& e2d::ENode::getParent() +{ + return m_pParent; +} + +e2d::EScene * &e2d::ENode::getParentScene() +{ + return m_pParentScene; +} + +void e2d::ENode::setParentScene(e2d::EScene * scene) +{ + m_pParentScene = scene; +} + +void e2d::ENode::setVisiable(bool value) +{ + m_bVisiable = value; +} + +bool e2d::ENode::isVisiable() const +{ + return m_bVisiable; +} \ No newline at end of file diff --git a/Easy2D/Object/Image.cpp b/Easy2D/Node/Image.cpp similarity index 100% rename from Easy2D/Object/Image.cpp rename to Easy2D/Node/Image.cpp diff --git a/Easy2D/Object/Layer.cpp b/Easy2D/Node/Layer.cpp similarity index 100% rename from Easy2D/Object/Layer.cpp rename to Easy2D/Node/Layer.cpp diff --git a/Easy2D/Object/MouseNode.cpp b/Easy2D/Node/MouseNode.cpp similarity index 100% rename from Easy2D/Object/MouseNode.cpp rename to Easy2D/Node/MouseNode.cpp diff --git a/Easy2D/Object/RectNode.cpp b/Easy2D/Node/RectNode.cpp similarity index 100% rename from Easy2D/Object/RectNode.cpp rename to Easy2D/Node/RectNode.cpp diff --git a/Easy2D/Object/Shape/Circle.cpp b/Easy2D/Node/Shape/Circle.cpp similarity index 100% rename from Easy2D/Object/Shape/Circle.cpp rename to Easy2D/Node/Shape/Circle.cpp diff --git a/Easy2D/Object/Shape/Rectangle.cpp b/Easy2D/Node/Shape/Rectangle.cpp similarity index 100% rename from Easy2D/Object/Shape/Rectangle.cpp rename to Easy2D/Node/Shape/Rectangle.cpp diff --git a/Easy2D/Object/Shape/Shape.cpp b/Easy2D/Node/Shape/Shape.cpp similarity index 100% rename from Easy2D/Object/Shape/Shape.cpp rename to Easy2D/Node/Shape/Shape.cpp diff --git a/Easy2D/Object/Sprite.cpp b/Easy2D/Node/Sprite.cpp similarity index 100% rename from Easy2D/Object/Sprite.cpp rename to Easy2D/Node/Sprite.cpp diff --git a/Easy2D/Object/Text.cpp b/Easy2D/Node/Text.cpp similarity index 100% rename from Easy2D/Object/Text.cpp rename to Easy2D/Node/Text.cpp diff --git a/Easy2D/Object/Node.cpp b/Easy2D/Object/Node.cpp deleted file mode 100644 index 51ff9e75..00000000 --- a/Easy2D/Object/Node.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "..\easy2d.h" - -Node::Node() : - m_nZOrder(0), - m_bDisplay(true) -{ -} - -Node::Node(CPoint p) : - m_Pos(p) -{ -} - -Node::Node(int x, int y) : - m_nZOrder(0), - m_bDisplay(true) -{ -} - -Node::~Node() -{ -} - -bool Node::_exec(bool active) -{ - return false; -} - -void Node::_onDraw() -{ -} - -int Node::getX() const -{ - return m_Pos.x; -} - -int Node::getY() const -{ - return m_Pos.y; -} - -CPoint Node::getPos() const -{ - return m_Pos; -} - -void Node::setX(int x) -{ - m_Pos.x = x; -} - -void Node::setY(int y) -{ - m_Pos.y = y; -} - -void Node::setPos(int x, int y) -{ - m_Pos.SetPoint(x, y); -} - -void Node::setPos(CPoint p) -{ - m_Pos = p; -} - -void Node::move(int x, int y) -{ - m_Pos.Offset(x, y); -} - -void Node::move(CVector v) -{ - m_Pos.Offset(v); -} - -int Node::getZOrder() const -{ - return m_nZOrder; -} - -void Node::setZOrder(int z) -{ - m_nZOrder = z; -} - -Scene * Node::getParentScene() -{ - return m_pScene; -} - -void Node::setParentScene(Scene * scene) -{ - m_pScene = scene; -} - -void Node::setDisplay(bool value) -{ - m_bDisplay = value; -} - -bool Node::display() const -{ - return m_bDisplay; -} \ No newline at end of file diff --git a/Easy2D/Object/Object.cpp b/Easy2D/Object/Object.cpp deleted file mode 100644 index 66411ea6..00000000 --- a/Easy2D/Object/Object.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "..\easy2d.h" - -Object::Object() : - m_nRefCount(0), - m_bAutoRelease(false) -{ -} - -Object::~Object() -{ -} - -void Object::retain() -{ - m_nRefCount++; // 引用计数加一 -} - -void Object::release() -{ - m_nRefCount--; // 引用计数减一 -} - -void Object::autoRelease() -{ - if (!m_bAutoRelease) - { - m_bAutoRelease = true; - FreePool::__add(this); // 将该对象放入释放池中 - } -} diff --git a/Easy2D/Tool/ActionManager.cpp b/Easy2D/Tool/ActionManager.cpp index 8fd455c7..f9f62b6e 100644 --- a/Easy2D/Tool/ActionManager.cpp +++ b/Easy2D/Tool/ActionManager.cpp @@ -51,7 +51,7 @@ void ActionManager::addAction(Action * action) } } -void ActionManager::notifyAllSceneActions(Scene * scene) +void ActionManager::notifyAllSceneActions(EScene * scene) { for (auto action : s_vActions) { @@ -62,7 +62,7 @@ void ActionManager::notifyAllSceneActions(Scene * scene) } } -void ActionManager::waitAllSceneActions(Scene * scene) +void ActionManager::waitAllSceneActions(EScene * scene) { for (auto action : s_vActions) { @@ -73,7 +73,7 @@ void ActionManager::waitAllSceneActions(Scene * scene) } } -void ActionManager::stopAllSceneActions(Scene * scene) +void ActionManager::stopAllSceneActions(EScene * scene) { for (auto action : s_vActions) { diff --git a/Easy2D/Tool/EObjectManager.cpp b/Easy2D/Tool/EObjectManager.cpp new file mode 100644 index 00000000..acf65928 --- /dev/null +++ b/Easy2D/Tool/EObjectManager.cpp @@ -0,0 +1,51 @@ +#include "..\etools.h" +#include + +// EObjectManager 释放池的实现机制: +/// EObject 类中的引用计数(m_nRefCount)保证了指针的使用安全 +/// 它记录了对象被使用的次数,当计数为 0 时,EObjectManager 会自动释放这个对象 +/// 所有的 EObject 对象都应在被使用时(例如 Text 添加到了场景中) +/// 调用 retain 函数保证该对象不被删除,并在不再使用时调用 release 函数 +/// 让其自动释放 + +// 释放池容器 +static std::vector s_vPool; + +void e2d::EObjectManager::__flush() +{ + // 创建迭代器 + static std::vector::iterator iter; + // 循环遍历容器中的所有对象 + for (iter = s_vPool.begin(); iter != s_vPool.end();) + { + if ((*iter)->m_bAutoRelease && (*iter)->m_nRefCount == 0) + { + // 若对象的引用的计数为 0, 释放该对象 + delete (*iter); + // 从释放池中删除该对象 + iter = s_vPool.erase(iter); + } + else + { + iter++; // 移动迭代器 + } + } +} + +void e2d::EObjectManager::add(e2d::EObject * nptr) +{ + if (!nptr->m_bManaged) + { + nptr->m_bManaged = true; + s_vPool.push_back(nptr); // 将一个对象放入释放池中 + } +} + +void e2d::EObjectManager::clearAllObjects() +{ + for (auto o : s_vPool) + { + delete o; + } + s_vPool.clear(); +} diff --git a/Easy2D/Tool/Timer.cpp b/Easy2D/Tool/Timer.cpp index bbea8a29..e3c44ce7 100644 --- a/Easy2D/Tool/Timer.cpp +++ b/Easy2D/Tool/Timer.cpp @@ -179,7 +179,7 @@ void Timer::clearAllTimers() s_vTimers.clear(); } -void Timer::notifyAllSceneTimers(Scene * scene) +void Timer::notifyAllSceneTimers(EScene * scene) { for (auto t : s_vTimers) { @@ -190,7 +190,7 @@ void Timer::notifyAllSceneTimers(Scene * scene) } } -void Timer::waitAllSceneTimers(Scene * scene) +void Timer::waitAllSceneTimers(EScene * scene) { for (auto t : s_vTimers) { @@ -201,7 +201,7 @@ void Timer::waitAllSceneTimers(Scene * scene) } } -void Timer::clearAllSceneTimers(Scene * scene) +void Timer::clearAllSceneTimers(EScene * scene) { // 创建迭代器 std::vector::iterator iter; diff --git a/Easy2D/easy2d.h b/Easy2D/easy2d.h index c05135da..199ac9a7 100644 --- a/Easy2D/easy2d.h +++ b/Easy2D/easy2d.h @@ -41,6 +41,7 @@ #include "emacros.h" #include "ecommon.h" +#include "ebase.h" #if defined(UNICODE) && (_DEBUG) @@ -54,214 +55,6 @@ #endif -// Classes Declare - -namespace e2d -{ - class EApp; - class Scene; - class Object; -} - - -// Classes - -namespace e2d -{ - -class EApp -{ -public: - EApp(); - ~EApp(); - - // 获取程序实例 - static EApp * get(); - - // Register the window class and call methods for instantiating drawing resources - bool init( - EString title, - ESize size, - bool bShowConsole = false - ); - - // Register the window class and call methods for instantiating drawing resources - bool init( - EString title, - UINT32 width, - UINT32 height, - bool bShowConsole = false - ); - - // 启动程序 - void run(); - - // 修改窗口大小 - void setWindowSize( - int width, - int height - ); - - // 修改窗口大小 - void setWindowSize( - ESize size - ); - - // 设置窗口标题 - void setWindowTitle( - EString title - ); - - // 获取窗口标题 - EString getTitle(); - - // 获取窗口宽度 - int getWidth(); - - // 获取窗口高度 - int getHeight(); - - // 切换场景 - void enterScene( - Scene * scene, - bool save = true - ); - - // 返回上一场景 - void backScene(); - - // 清空保存的所有场景 - void clearScene(); - - // 获取当前场景 - Scene * getCurrentScene(); - - // 获取正处于加载中的场景 - Scene * getLoadingScene(); - - // 设置 AppName - void setAppName( - EString appname - ); - - // 获取 AppName - EString getAppName(); - - // 修改窗口背景色 - void setBkColor( - EColor::Enum color - ); - - // 释放所有内存资源 - void free(); - - // 关闭窗口 - void close(); - - // 显示窗口 - void show(); - - // 终止程序 - void quit(); - - // 终止程序 - void end(); - -protected: - // Initialize device-independent resources. - HRESULT CreateDeviceIndependentResources(); - - // Initialize device-dependent resources. - HRESULT CreateDeviceResources(); - - // Release device-dependent resource. - void DiscardDeviceResources(); - - void _mainLoop(); - - void _onControl(); - - // Draw content. - bool _onRender(); - - void _enterNextScene(); - - // Resize the render target. - void _onResize( - UINT width, - UINT height - ); - - // The windows procedure. - static LRESULT CALLBACK WndProc( - HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam - ); - -protected: - bool m_bRunning; - bool m_bSaveScene; - EString m_sTitle; - EString m_sAppName; - EColor::Enum m_ClearColor; - - Scene * m_pCurrentScene; - Scene * m_pNextScene; - Scene * m_pLoadingScene; -}; - -class Scene -{ - friend EApp; -public: - Scene(); - ~Scene(); - - // 重写这个函数,初始化这个场景 - virtual void init(); - // 重写这个函数,它将在进入这个场景时自动执行 - virtual void onEnter(); - // 重写这个函数,它将在离开这个场景时自动执行 - virtual void onExit(); - // 添加子成员到场景 - void add(Node * child, int zOrder = 0); - // 删除子成员 - bool del(Node * child); - // 清空所有子成员 - void clearAllChildren(); - -protected: - //std::vector m_vChildren; - -protected: - void _exec(); - void _onDraw(); -}; - -class Object -{ - friend FreePool; -public: - Object(); - virtual ~Object(); - - // 保留这个对象 - void retain(); - // 释放这个对象 - void release(); - // 让引擎自动释放这个对象 - void autoRelease(); - -protected: - int m_nRefCount; - bool m_bAutoRelease; -}; - -} // End of easy2d namespace - - // Functions Declare using namespace e2d; \ No newline at end of file diff --git a/Easy2D/ebase.h b/Easy2D/ebase.h new file mode 100644 index 00000000..176eed1c --- /dev/null +++ b/Easy2D/ebase.h @@ -0,0 +1,234 @@ +#pragma once +#include "emacros.h" +#include "ecommon.h" +#include + +// Base Classes + +namespace e2d +{ + +class EScene; +class ENode; +class EObjectManager; + +class EApp +{ +public: + EApp(); + + ~EApp(); + + // 获取程序实例 + static EApp * get(); + + // Register the window class and call methods for instantiating drawing resources + bool init( + e2d::EString title, + e2d::ESize size, + bool bShowConsole = false + ); + + // Register the window class and call methods for instantiating drawing resources + bool init( + e2d::EString title, + UINT32 width, + UINT32 height, + bool bShowConsole = false + ); + + // 启动程序 + void run(); + + // 修改窗口大小 + void setWindowSize( + int width, + int height + ); + + // 修改窗口大小 + void setWindowSize( + e2d::ESize size + ); + + // 设置窗口标题 + void setWindowTitle( + e2d::EString title + ); + + // 获取窗口标题 + e2d::EString getTitle(); + + // 获取窗口大小 + e2d::ESize getSize(); + + // 获取窗口宽度 + UINT32 getWidth(); + + // 获取窗口高度 + UINT32 getHeight(); + + // 切换场景 + void enterScene( + EScene * scene, + bool save = true + ); + + // 返回上一场景 + void backScene(); + + // 清空保存的所有场景 + void clearScene(); + + // 获取当前场景 + EScene * getCurrentScene(); + + // 获取正处于加载中的场景 + EScene * getLoadingScene(); + + // 设置正处于加载中的场景 + void setLoadingScene(EScene * scene); + + // 获取 AppName + e2d::EString getAppName(); + + // 设置 AppName + void setAppName( + e2d::EString appname + ); + + // 修改窗口背景色 + void setBkColor( + EColor::Enum color + ); + + // 释放所有内存资源 + void free(); + + // 关闭窗口 + void close(); + + // 显示窗口 + void show(); + + // 终止程序 + void quit(); + + // 终止程序 + void end(); + +protected: + // Initialize device-independent resources. + HRESULT _createDeviceIndependentResources(); + + // Initialize device-dependent resources. + HRESULT _createDeviceResources(); + + // Release device-dependent resource. + void _discardDeviceResources(); + + void _mainLoop(); + + void _onControl(); + + // Draw content. + bool _onRender(); + + void _enterNextScene(); + + // ReSize the render target. + void _onResize( + UINT width, + UINT height + ); + + // The windows procedure. + static LRESULT CALLBACK WndProc( + HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam + ); + +protected: + bool m_bRunning; + bool m_bSaveScene; + EString m_sTitle; + EString m_sAppName; + EColor::Enum m_ClearColor; + + EScene * m_pCurrentScene; + EScene * m_pNextScene; + EScene * m_pLoadingScene; +}; + + +class EScene +{ +public: + + EScene(); + + ~EScene(); + + // 重写这个函数,初始化这个场景 + virtual void init(); + + // 重写这个函数,它将在进入这个场景时自动执行 + virtual void onEnter(); + + // 重写这个函数,它将在离开这个场景时自动执行 + virtual void onExit(); + + // 添加子成员到场景 + void add( + e2d::ENode * child, + int zOrder = 0 + ); + + // 删除子成员 + bool del( + e2d::ENode * child + ); + + // 获取所有子节点 + std::vector &getChildren(); + + // 清空所有子成员 + void clearAllChildren(); + +protected: + friend EApp; + std::vector m_vChildren; + +protected: + void _exec(); + + void _onDraw(); +}; + + +class EObject +{ +public: + EObject(); + + virtual ~EObject(); + + // 引用计数加一 + void retain(); + + // 引用计数减一 + void release(); + + // 让引擎自动释放这个对象 + void autoRelease(); + +private: + friend EObjectManager; + int m_nRefCount; + bool m_bManaged; + bool m_bAutoRelease; +}; + +} \ No newline at end of file diff --git a/Easy2D/ecommon.h b/Easy2D/ecommon.h index 9ddabd66..a8b59b26 100644 --- a/Easy2D/ecommon.h +++ b/Easy2D/ecommon.h @@ -1,15 +1,18 @@ #pragma once #include #include +#include + +namespace e2d +{ typedef std::wstring EString; -typedef struct -{ - UINT32 width; - UINT32 height; -} ESize; +typedef CSize ESize; +typedef CPoint EPoint; +typedef EPoint EVector; +typedef CRect ERect; typedef struct @@ -167,4 +170,6 @@ public: YellowGreen = 0x9ACD32, }; -}; \ No newline at end of file +}; + +} \ No newline at end of file diff --git a/Easy2D/emacros.h b/Easy2D/emacros.h index e0ae5d89..dedf3f0e 100644 --- a/Easy2D/emacros.h +++ b/Easy2D/emacros.h @@ -1,15 +1,18 @@ #pragma once -#ifndef Assert - +#ifndef ASSERT_IF #if defined( DEBUG ) || defined( _DEBUG ) - #define Assert(b) do {if (!(b)) {OutputDebugStringA("Assert: " #b "\n");}} while(0) + #define ASSERT(b) do {if (!(b)) { OutputDebugStringA("Assert: " #b "\n"); }} while(0) #else - #define Assert(b) + #define ASSERT(b) #endif //DEBUG || _DEBUG - #endif +#ifndef WARN_IF +#define WARN_IF(b, m) do {if (b) { fprintf(stderr, "Warning: " #m "/n"); }} while(0) +#endif + + template inline void SafeDelete(T** p) { if (*p) { delete *p; *p = nullptr; } } \ No newline at end of file diff --git a/Easy2D/enodes.h b/Easy2D/enodes.h new file mode 100644 index 00000000..2a374487 --- /dev/null +++ b/Easy2D/enodes.h @@ -0,0 +1,164 @@ +#pragma once +#include "ebase.h" + +namespace e2d +{ + +class ENode : + public EObject +{ +public: + ENode(); + + ENode( + EPoint p + ); + + ENode( + int x, + int y + ); + + virtual ~ENode(); + + // 节点是否显示 + virtual bool isVisiable() const; + + // 获取节点绘图顺序 + virtual int getZOrder() const; + + // 获取节点横坐标 + virtual int getX() const; + + // 获取节点纵坐标 + virtual int getY() const; + + // 获取节点坐标 + virtual EPoint getPos() const; + + // 获取节点宽度 + virtual UINT32 getWidth() const; + + // 获取节点高度 + virtual UINT32 getHeight() const; + + // 获取节点大小 + virtual e2d::ESize getSize() const; + + // 获取节点所在的矩形 + virtual e2d::ERect getRect() const; + + // 获取父节点 + virtual e2d::ENode* &getParent(); + + // 获取节点所在场景 + e2d::EScene * &getParentScene(); + + // 设置节点是否显示 + virtual void setVisiable( + bool value + ); + + // 设置节点横坐标 + virtual void setX( + int x + ); + + // 设置节点纵坐标 + virtual void setY( + int y + ); + + // 设置节点坐标 + virtual void setPos( + int x, + int y + ); + + // 设置节点坐标 + virtual void setPos( + EPoint p + ); + + // 移动节点 + virtual void move( + int x, + int y + ); + + // 移动节点 + virtual void move( + EVector v + ); + + // 设置节点宽度 + virtual void setWidth( + UINT32 width + ); + + // 设置节点高度 + virtual void setHeight( + UINT32 height + ); + + // 设置节点大小 + virtual void setSize( + UINT32 width, + UINT32 height + ); + + // 设置节点大小 + virtual void setSize( + e2d::ESize size + ); + + // 设置节点所在的矩形 + virtual void setRect( + int x1, + int y1, + int x2, + int y2 + ); + + // 设置节点所在的矩形 + virtual void setRect( + EPoint leftTop, + EPoint rightBottom + ); + + // 设置节点所在的矩形 + virtual void setRect( + e2d::ERect rect + ); + + // 设置节点绘图顺序(0为最先绘制,显示在最底层) + virtual void setZOrder( + int z + ); + + // 设置父节点 + virtual void setParent( + e2d::ENode* parent + ); + + // 设置节点所在场景 + void setParentScene( + e2d::EScene * scene + ); + +protected: + friend e2d::EScene; + int m_nZOrder; + bool m_bVisiable; + e2d::ERect m_Rect; + EScene * m_pParentScene; + ENode * m_pParent; + +protected: + + virtual bool _exec(bool active); + + virtual void _onDraw() = 0; +}; + +} \ No newline at end of file diff --git a/Easy2D/etools.h b/Easy2D/etools.h new file mode 100644 index 00000000..8c41cc10 --- /dev/null +++ b/Easy2D/etools.h @@ -0,0 +1,23 @@ +#pragma once +#include "ebase.h" + +namespace e2d +{ + +class EObjectManager +{ +public: + // 将一个节点放入释放池 + static void add(e2d::EObject * nptr); + + // 删除所有节点 + static void clearAllObjects(); + +private: + friend EApp; + + // 刷新内存池 + static void __flush(); +}; + +} \ No newline at end of file