修复了无法完全回收游戏资源的问题

This commit is contained in:
Nomango 2018-04-21 18:22:01 +08:00
parent afc17339b1
commit b2e655226b
19 changed files with 130 additions and 66 deletions

View File

@ -14,7 +14,6 @@ e2d::Action::Action()
e2d::Action::~Action() e2d::Action::~Action()
{ {
ActionManager::__remove(this);
} }
bool e2d::Action::isRunning() bool e2d::Action::isRunning()
@ -74,6 +73,11 @@ e2d::Node * e2d::Action::getTarget()
return m_pTarget; return m_pTarget;
} }
void e2d::Action::destroy()
{
ActionManager::__remove(this);
}
void e2d::Action::_init() void e2d::Action::_init()
{ {
m_bInit = true; m_bInit = true;

View File

@ -12,7 +12,6 @@ e2d::ActionLoop::ActionLoop(Action * action, int times /* = -1 */)
e2d::ActionLoop::~ActionLoop() e2d::ActionLoop::~ActionLoop()
{ {
SafeRelease(&m_pAction);
} }
e2d::ActionLoop * e2d::ActionLoop::clone() const e2d::ActionLoop * e2d::ActionLoop::clone() const
@ -56,6 +55,12 @@ void e2d::ActionLoop::reset()
m_nTimes = 0; m_nTimes = 0;
} }
void e2d::ActionLoop::destroy()
{
Action::destroy();
SafeRelease(&m_pAction);
}
void e2d::ActionLoop::_resetTime() void e2d::ActionLoop::_resetTime()
{ {
m_pAction->_resetTime(); m_pAction->_resetTime();

View File

@ -29,10 +29,6 @@ e2d::ActionSequence::ActionSequence(int number, Action * action1, ...) :
e2d::ActionSequence::~ActionSequence() e2d::ActionSequence::~ActionSequence()
{ {
FOR_LOOP(action, m_vActions)
{
SafeRelease(&action);
}
} }
void e2d::ActionSequence::_init() void e2d::ActionSequence::_init()
@ -50,6 +46,15 @@ void e2d::ActionSequence::_init()
m_vActions[0]->_init(); m_vActions[0]->_init();
} }
void e2d::ActionSequence::destroy()
{
Action::destroy();
FOR_LOOP(action, m_vActions)
{
SafeRelease(&action);
}
}
void e2d::ActionSequence::_update() void e2d::ActionSequence::_update()
{ {
Action::_update(); Action::_update();

View File

@ -12,8 +12,6 @@ e2d::ActionTwo::ActionTwo(Action * pActionFirst, Action * pActionSecond, bool bA
e2d::ActionTwo::~ActionTwo() e2d::ActionTwo::~ActionTwo()
{ {
SafeRelease(&m_pFirstAction);
SafeRelease(&m_pSecondAction);
} }
e2d::ActionTwo * e2d::ActionTwo::clone() const e2d::ActionTwo * e2d::ActionTwo::clone() const
@ -83,6 +81,13 @@ void e2d::ActionTwo::reset()
m_pSecondAction->reset(); m_pSecondAction->reset();
} }
void e2d::ActionTwo::destroy()
{
Action::destroy();
SafeRelease(&m_pFirstAction);
SafeRelease(&m_pSecondAction);
}
void e2d::ActionTwo::_resetTime() void e2d::ActionTwo::_resetTime()
{ {
m_pFirstAction->_resetTime(); m_pFirstAction->_resetTime();

View File

@ -64,10 +64,6 @@ e2d::Animation::Animation(double interval, int number, Image * frame, ...)
e2d::Animation::~Animation() e2d::Animation::~Animation()
{ {
FOR_LOOP(frame, m_vFrames)
{
SafeRelease(&frame);
}
} }
void e2d::Animation::setInterval(double interval) void e2d::Animation::setInterval(double interval)
@ -113,6 +109,15 @@ void e2d::Animation::reset()
m_nFrameIndex = 0; m_nFrameIndex = 0;
} }
void e2d::Animation::destroy()
{
Action::destroy();
FOR_LOOP(frame, m_vFrames)
{
SafeRelease(&frame);
}
}
void e2d::Animation::add(Image * frame) void e2d::Animation::add(Image * frame)
{ {
if (frame) if (frame)

View File

@ -164,14 +164,14 @@ void e2d::Game::destroy()
ColliderManager::__uninit(); ColliderManager::__uninit();
// 删除动画 // 删除动画
ActionManager::__uninit(); ActionManager::__uninit();
// 删除所有对象
ObjectManager::__clear();
// 清空图片缓存
Image::clearCache();
// 关闭输入 // 关闭输入
Input::__uninit(); Input::__uninit();
// 恢复计时操作 // 恢复计时操作
Time::__uninit(); Time::__uninit();
// 清空图片缓存
Image::clearCache();
// 刷新内存池
ObjectManager::__clear();
// 删除渲染相关资源 // 删除渲染相关资源
Renderer::__discardResources(); Renderer::__discardResources();
// 销毁窗口 // 销毁窗口

View File

@ -2,6 +2,8 @@
#include "..\emanager.h" #include "..\emanager.h"
#include "..\enode.h" #include "..\enode.h"
static bool s_bShowFps = false;
static IDWriteTextFormat * s_pTextFormat = nullptr;
static ID2D1Factory * s_pDirect2dFactory = nullptr; static ID2D1Factory * s_pDirect2dFactory = nullptr;
static ID2D1HwndRenderTarget * s_pRenderTarget = nullptr; static ID2D1HwndRenderTarget * s_pRenderTarget = nullptr;
static ID2D1SolidColorBrush * s_pSolidBrush = nullptr; static ID2D1SolidColorBrush * s_pSolidBrush = nullptr;
@ -9,13 +11,6 @@ static IWICImagingFactory * s_pIWICFactory = nullptr;
static IDWriteFactory * s_pDWriteFactory = nullptr; static IDWriteFactory * s_pDWriteFactory = nullptr;
static D2D1_COLOR_F s_nClearColor = D2D1::ColorF(D2D1::ColorF::Black); static D2D1_COLOR_F s_nClearColor = D2D1::ColorF(D2D1::ColorF::Black);
static bool s_bShowFps = false;
static int s_nRenderTimes = 0;
static double s_fLastRenderTime = 0;
static e2d::String s_sFpsText = L"";
static IDWriteTextFormat * s_pTextFormat = nullptr;
bool e2d::Renderer::__createDeviceIndependentResources() bool e2d::Renderer::__createDeviceIndependentResources()
{ {
@ -64,6 +59,11 @@ bool e2d::Renderer::__createDeviceIndependentResources()
L"", L"",
&s_pTextFormat &s_pTextFormat
); );
if (s_pTextFormat)
{
s_pTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
}
} }
return SUCCEEDED(hr); return SUCCEEDED(hr);
@ -146,6 +146,10 @@ void e2d::Renderer::__render()
// äÖȾ FPS // äÖȾ FPS
if (s_bShowFps) if (s_bShowFps)
{ {
static int s_nRenderTimes = 0;
static double s_fLastRenderTime = 0;
static e2d::String s_sFpsText = L"";
s_nRenderTimes++; s_nRenderTimes++;
double fDelay = Time::getTotalTime() - s_fLastRenderTime; double fDelay = Time::getTotalTime() - s_fLastRenderTime;
@ -156,12 +160,9 @@ void e2d::Renderer::__render()
s_nRenderTimes = 0; s_nRenderTimes = 0;
} }
D2D1_SIZE_F renderTargetSize = s_pRenderTarget->GetSize();
D2D1_RECT_F rect = D2D1::RectF(0, 0, renderTargetSize.width, renderTargetSize.height);
s_pSolidBrush->SetColor(D2D1::ColorF(D2D1::ColorF::White)); s_pSolidBrush->SetColor(D2D1::ColorF(D2D1::ColorF::White));
s_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); s_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
s_pRenderTarget->DrawTextW(s_sFpsText, (UINT32)s_sFpsText.getLength(), s_pTextFormat, rect, s_pSolidBrush); s_pRenderTarget->DrawTextW(s_sFpsText, (UINT32)s_sFpsText.getLength(), s_pTextFormat, D2D1::RectF(), s_pSolidBrush);
} }
// ÖÕÖ¹äÖȾ // ÖÕÖ¹äÖȾ

View File

@ -3,9 +3,8 @@
e2d::Object::Object() e2d::Object::Object()
: m_nRefCount(0) : m_nRefCount(0)
, m_bManaged(false)
{ {
ObjectManager::add(this); // 将该对象放入释放池中 ObjectManager::__add(this);
} }
e2d::Object::~Object() e2d::Object::~Object()
@ -26,7 +25,7 @@ void e2d::Object::release()
ObjectManager::flush(); ObjectManager::flush();
} }
int e2d::Object::getReferenceCount() const int e2d::Object::getRefCount() const
{ {
return m_nRefCount; return m_nRefCount;
} }

View File

@ -16,7 +16,6 @@ e2d::Scene::Scene()
e2d::Scene::~Scene() e2d::Scene::~Scene()
{ {
SafeRelease(&m_pRoot);
} }
void e2d::Scene::_render() void e2d::Scene::_render()
@ -77,3 +76,8 @@ void e2d::Scene::showCollider(bool visiable)
{ {
m_bColliderVisiable = visiable; m_bColliderVisiable = visiable;
} }
void e2d::Scene::destroy()
{
SafeRelease(&m_pRoot);
}

View File

@ -2,14 +2,13 @@
#include "..\ebase.h" #include "..\ebase.h"
// ObjectManager 释放池的实现机制: // ObjectManager 释放池的实现机制:
// Object 类中的引用计数m_nRefCount保证了指针的使用安全 // Object 类中的引用计数m_nRefCount在一定程度上保证了指针的使用安全
// 它记录了对象被使用的次数,当计数为 0 时ObjectManager 会自动释放这个对象 // 它记录了对象被使用的次数,当计数为 0 时ObjectManager 会自动释放这个对象
// 所有的 Object 对象都应在被使用时(例如 Text 添加到了场景中) // 所有的 Object 对象都应在被使用时(例如 Text 添加到了场景中)
// 调用 retain 函数保证该对象不被删除,并在不再使用时调用 release 函数 // 调用 retain 函数保证该对象不被删除,并在不再使用时调用 release 函数
// 让其自动释放
// 对象管理池 // 对象管理池
static std::vector<e2d::Object*> s_vObjectPool; static std::set<e2d::Object*> s_vObjectPool;
// 标志释放池执行状态 // 标志释放池执行状态
static bool s_bNotifyed = false; static bool s_bNotifyed = false;
@ -18,14 +17,13 @@ void e2d::ObjectManager::__update()
if (!s_bNotifyed) return; if (!s_bNotifyed) return;
s_bNotifyed = false; s_bNotifyed = false;
// 创建迭代器
static std::vector<e2d::Object*>::iterator iter;
// 循环遍历容器中的所有对象 // 循环遍历容器中的所有对象
for (iter = s_vObjectPool.begin(); iter != s_vObjectPool.end();) for (auto iter = s_vObjectPool.begin(); iter != s_vObjectPool.end();)
{ {
if ((*iter)->getReferenceCount() <= 0) if ((*iter)->getRefCount() <= 0)
{ {
// 若对象的引用的计数小于等于 0, 释放该对象 // 若对象的引用的计数小于等于 0, 释放该对象
(*iter)->destroy();
delete (*iter); delete (*iter);
// 从释放池中删除该对象 // 从释放池中删除该对象
iter = s_vObjectPool.erase(iter); iter = s_vObjectPool.erase(iter);
@ -39,19 +37,18 @@ void e2d::ObjectManager::__update()
void e2d::ObjectManager::__clear() void e2d::ObjectManager::__clear()
{ {
if (s_vObjectPool.size() != 0) FOR_LOOP(pObj, s_vObjectPool)
{ {
s_bNotifyed = true; delete pObj;
ObjectManager::__update();
} }
s_vObjectPool.clear();
} }
void e2d::ObjectManager::add(e2d::Object * nptr) void e2d::ObjectManager::__add(e2d::Object * pObject)
{ {
if (!nptr->m_bManaged) if (pObject)
{ {
nptr->m_bManaged = true; s_vObjectPool.insert(pObject);
s_vObjectPool.push_back(nptr); // 将一个对象放入释放池中
} }
} }

View File

@ -170,7 +170,7 @@ void e2d::TimerManager::__uninit()
{ {
FOR_LOOP(timer, s_vTimers) FOR_LOOP(timer, s_vTimers)
{ {
timer->release(); SafeRelease(&timer);
} }
s_vTimers.clear(); s_vTimers.clear();
} }

View File

@ -46,12 +46,6 @@ e2d::Node::Node()
e2d::Node::~Node() e2d::Node::~Node()
{ {
ActionManager::__clearAllBindedWith(this);
ColliderManager::__removeCollider(m_pCollider);
FOR_LOOP(child, m_vChildren)
{
SafeRelease(&child);
}
} }
void e2d::Node::_update() void e2d::Node::_update()
@ -1014,6 +1008,16 @@ void e2d::Node::setDefaultColliderEnable(bool bEnable)
s_fDefaultColliderEnabled = bEnable; s_fDefaultColliderEnabled = bEnable;
} }
void e2d::Node::destroy()
{
ActionManager::__clearAllBindedWith(this);
ColliderManager::__removeCollider(m_pCollider);
FOR_LOOP(child, m_vChildren)
{
SafeRelease(&child);
}
}
void e2d::Node::resumeAllActions() void e2d::Node::resumeAllActions()
{ {
ActionManager::__resumeAllBindedWith(this); ActionManager::__resumeAllBindedWith(this);

View File

@ -27,7 +27,6 @@ e2d::Sprite::Sprite(String imageFileName, double x, double y, double width, doub
e2d::Sprite::~Sprite() e2d::Sprite::~Sprite()
{ {
SafeRelease(&m_pImage);
} }
void e2d::Sprite::open(Image * image) void e2d::Sprite::open(Image * image)
@ -83,3 +82,9 @@ void e2d::Sprite::onRender()
); );
} }
} }
void e2d::Sprite::destroy()
{
Node::destroy();
SafeRelease(&m_pImage);
}

View File

@ -18,8 +18,6 @@ e2d::Transition::Transition(double duration)
e2d::Transition::~Transition() e2d::Transition::~Transition()
{ {
SafeRelease(&m_pPrevScene);
SafeRelease(&m_pNextScene);
SafeReleaseInterface(&m_pPrevLayer); SafeReleaseInterface(&m_pPrevLayer);
SafeReleaseInterface(&m_pNextLayer); SafeReleaseInterface(&m_pNextLayer);
} }
@ -29,6 +27,12 @@ bool e2d::Transition::isEnding()
return m_bEnd; return m_bEnd;
} }
void e2d::Transition::destroy()
{
SafeRelease(&m_pPrevScene);
SafeRelease(&m_pNextScene);
}
void e2d::Transition::_init(Scene * prev, Scene * next) void e2d::Transition::_init(Scene * prev, Scene * next)
{ {
// ´´½¨Í¼²ã // ´´½¨Í¼²ã

View File

@ -63,6 +63,9 @@ public:
// 获取该动作的执行目标 // 获取该动作的执行目标
virtual Node * getTarget(); virtual Node * getTarget();
// 销毁对象
virtual void destroy() override;
protected: protected:
// 初始化动作 // 初始化动作
virtual void _init(); virtual void _init();
@ -376,6 +379,9 @@ public:
// 重置动作 // 重置动作
virtual void reset() override; virtual void reset() override;
// 销毁对象
virtual void destroy() override;
protected: protected:
// 初始化动作 // 初始化动作
virtual void _init() override; virtual void _init() override;
@ -446,6 +452,9 @@ public:
// 重置动作 // 重置动作
virtual void reset() override; virtual void reset() override;
// 销毁对象
virtual void destroy() override;
protected: protected:
// 初始化动作 // 初始化动作
virtual void _init() override; virtual void _init() override;
@ -504,6 +513,9 @@ public:
// 重置动作 // 重置动作
virtual void reset() override; virtual void reset() override;
// 销毁对象
virtual void destroy() override;
protected: protected:
// 初始化动作 // 初始化动作
virtual void _init() override; virtual void _init() override;
@ -596,6 +608,9 @@ public:
// 重置动作 // 重置动作
virtual void reset() override; virtual void reset() override;
// 销毁对象
virtual void destroy() override;
protected: protected:
// 初始化动作 // 初始化动作
virtual void _init() override; virtual void _init() override;

View File

@ -464,13 +464,9 @@ struct Font
}; };
class ObjectManager;
// 基础对象 // 基础对象
class Object class Object
{ {
friend ObjectManager;
public: public:
Object(); Object();
@ -483,11 +479,13 @@ public:
void release(); void release();
// 获取引用计数 // 获取引用计数
int getReferenceCount() const; int getRefCount() const;
// 销毁对象
virtual void destroy() {}
private: private:
int m_nRefCount; int m_nRefCount;
bool m_bManaged;
}; };
@ -641,6 +639,9 @@ public:
bool visiable = true bool visiable = true
); );
// 销毁对象
virtual void destroy() override;
protected: protected:
// 渲染场景画面 // 渲染场景画面
void _render(); void _render();

View File

@ -21,17 +21,18 @@ class CollisionListener;
class ObjectManager class ObjectManager
{ {
friend Game; friend Game;
friend Object;
public: public:
// 将一个对象放入内存池
static void add(
Object * nptr
);
// 释放垃圾对象的内存空间 // 释放垃圾对象的内存空间
static void flush(); static void flush();
private: private:
// 将对象放入内存池进行管理
static void __add(
Object * pObject
);
// 更新对象管理器 // 更新对象管理器
static void __update(); static void __update();

View File

@ -402,6 +402,9 @@ public:
bool bEnable bool bEnable
); );
// 销毁对象
virtual void destroy() override;
protected: protected:
// 更新节点 // 更新节点
void _update(); void _update();
@ -522,6 +525,9 @@ public:
// 渲染精灵 // 渲染精灵
virtual void onRender() override; virtual void onRender() override;
// 销毁对象
virtual void destroy() override;
protected: protected:
Image * m_pImage; Image * m_pImage;
}; };

View File

@ -20,6 +20,9 @@ public:
// 场景切换动画是否结束 // 场景切换动画是否结束
bool isEnding(); bool isEnding();
// 销毁对象
virtual void destroy() override;
protected: protected:
// 初始化场景动画 // 初始化场景动画
virtual void _init( virtual void _init(