From c8771231b4d82d9202182adf96585fa53332b250 Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Sat, 7 Jul 2018 01:43:41 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=81=9AGC=E5=BC=95=E7=94=A8=E8=AE=A1?= =?UTF-8?q?=E6=95=B0=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Action/Action.cpp | 4 - core/Action/Animate.cpp | 9 +- core/Action/Animation.cpp | 14 ++-- core/Action/Loop.cpp | 9 +- core/Action/Sequence.cpp | 15 ++-- core/Action/Spawn.cpp | 15 ++-- core/Base/GC.cpp | 115 ++++++++++++++++++++------ core/Base/Game.cpp | 5 +- core/Base/Input.cpp | 6 +- core/Collider/Collision.cpp | 6 +- core/Common/Object.cpp | 51 ------------ core/Common/Ref.cpp | 25 ++++++ core/Common/Scene.cpp | 8 +- core/Custom/VoiceCallback.cpp | 4 +- core/Manager/ActionManager.cpp | 8 +- core/Manager/ColliderManager.cpp | 18 ++-- core/Manager/SceneManager.cpp | 12 +-- core/Node/Node.cpp | 28 +++---- core/Node/Sprite.cpp | 15 ++-- core/Tool/Player.cpp | 12 +-- core/Tool/Timer.cpp | 6 +- core/Transition/Transition.cpp | 12 +-- core/e2daction.h | 22 +---- core/e2dbase.h | 41 +++++---- core/e2dcommon.h | 41 ++++----- core/e2dnode.h | 8 +- core/e2dtool.h | 8 +- core/e2dtransition.h | 5 +- project/vs2012/Easy2D.vcxproj | 2 +- project/vs2012/Easy2D.vcxproj.filters | 2 +- project/vs2013/Easy2D.vcxproj | 2 +- project/vs2013/Easy2D.vcxproj.filters | 2 +- project/vs2017/Easy2D.vcxproj | 2 +- project/vs2017/Easy2D.vcxproj.filters | 6 +- 34 files changed, 256 insertions(+), 282 deletions(-) delete mode 100644 core/Common/Object.cpp create mode 100644 core/Common/Ref.cpp diff --git a/core/Action/Action.cpp b/core/Action/Action.cpp index 0ac66222..d998ca9e 100644 --- a/core/Action/Action.cpp +++ b/core/Action/Action.cpp @@ -52,10 +52,6 @@ e2d::Node * e2d::Action::getTarget() return _target; } -void e2d::Action::onDestroy() -{ -} - void e2d::Action::reset() { _initialized = false; diff --git a/core/Action/Animate.cpp b/core/Action/Animate.cpp index fdde44db..69eadd0d 100644 --- a/core/Action/Animate.cpp +++ b/core/Action/Animate.cpp @@ -16,6 +16,7 @@ e2d::Animate::Animate(Animation * animation) e2d::Animate::~Animate() { + GC::safeRelease(_animation); } e2d::Animation * e2d::Animate::getAnimation() const @@ -29,7 +30,7 @@ void e2d::Animate::setAnimation(Animation * animation) { GC::safeRelease(_animation); _animation = animation; - _animation->retain(); + GC::retain(_animation); } } @@ -88,12 +89,6 @@ void e2d::Animate::reset() _frameIndex = 0; } -void e2d::Animate::onDestroy() -{ - Action::onDestroy(); - GC::safeRelease(_animation); -} - e2d::Animate * e2d::Animate::clone() const { if (_animation) diff --git a/core/Action/Animation.cpp b/core/Action/Animation.cpp index 75d06a82..23f13d2f 100644 --- a/core/Action/Animation.cpp +++ b/core/Action/Animation.cpp @@ -24,6 +24,10 @@ e2d::Animation::Animation(double interval, const std::vector& frames) e2d::Animation::~Animation() { + for (auto frame : _frames) + { + GC::safeRelease(frame); + } } void e2d::Animation::setInterval(double interval) @@ -31,20 +35,12 @@ void e2d::Animation::setInterval(double interval) _interval = std::max(interval, 0.0); } -void e2d::Animation::onDestroy() -{ - for (auto frame : _frames) - { - GC::safeRelease(frame); - } -} - void e2d::Animation::add(Image * frame) { if (frame) { _frames.push_back(frame); - frame->retain(); + GC::retain(frame); } } diff --git a/core/Action/Loop.cpp b/core/Action/Loop.cpp index 76587c7b..4966ef8b 100644 --- a/core/Action/Loop.cpp +++ b/core/Action/Loop.cpp @@ -11,12 +11,13 @@ e2d::Loop::Loop(Action * action, int times /* = -1 */) if (action) { _action = action; - _action->retain(); + GC::retain(_action); } } e2d::Loop::~Loop() { + GC::safeRelease(_action); } e2d::Loop * e2d::Loop::clone() const @@ -90,12 +91,6 @@ void e2d::Loop::reset() _times = 0; } -void e2d::Loop::onDestroy() -{ - Action::onDestroy(); - GC::safeRelease(_action); -} - void e2d::Loop::_resetTime() { if (_action) _action->_resetTime(); diff --git a/core/Action/Sequence.cpp b/core/Action/Sequence.cpp index 81207e08..152eb05e 100644 --- a/core/Action/Sequence.cpp +++ b/core/Action/Sequence.cpp @@ -13,6 +13,10 @@ e2d::Sequence::Sequence(const std::vector& actions) e2d::Sequence::~Sequence() { + for (auto action : _actions) + { + GC::safeRelease(action); + } } void e2d::Sequence::_init() @@ -30,15 +34,6 @@ void e2d::Sequence::_init() _actions[0]->_init(); } -void e2d::Sequence::onDestroy() -{ - Action::onDestroy(); - for (auto action : _actions) - { - GC::safeRelease(action); - } -} - void e2d::Sequence::_update() { Action::_update(); @@ -83,7 +78,7 @@ void e2d::Sequence::add(Action * action) if (action) { _actions.push_back(action); - action->retain(); + GC::retain(action); } } diff --git a/core/Action/Spawn.cpp b/core/Action/Spawn.cpp index 5c80d490..50f954cc 100644 --- a/core/Action/Spawn.cpp +++ b/core/Action/Spawn.cpp @@ -11,6 +11,10 @@ e2d::Spawn::Spawn(const std::vector& actions) e2d::Spawn::~Spawn() { + for (auto action : _actions) + { + GC::safeRelease(action); + } } void e2d::Spawn::_init() @@ -27,15 +31,6 @@ void e2d::Spawn::_init() } } -void e2d::Spawn::onDestroy() -{ - Action::onDestroy(); - for (auto action : _actions) - { - GC::safeRelease(action); - } -} - void e2d::Spawn::_update() { Action::_update(); @@ -81,7 +76,7 @@ void e2d::Spawn::add(Action * action) if (action) { _actions.push_back(action); - action->retain(); + GC::retain(action); } } diff --git a/core/Base/GC.cpp b/core/Base/GC.cpp index 3f523c03..b1b66989 100644 --- a/core/Base/GC.cpp +++ b/core/Base/GC.cpp @@ -2,8 +2,43 @@ #include "..\e2dtool.h" #include "..\e2dmanager.h" -// GC 机制,用于自动销毁单例 -e2d::GC e2d::GC::_instance; +using namespace e2d; + +e2d::autorelease_t const e2d::autorelease = e2d::autorelease_t(); + +void * operator new(size_t size, e2d::autorelease_t const &) E2D_NOEXCEPT +{ + void* p = ::operator new(size, std::nothrow); + if (p) + { + GC::autorelease(static_cast(p)); + } + return p; +} + +void* operator new[](size_t size, e2d::autorelease_t const&) E2D_NOEXCEPT +{ + void* p = ::operator new[](size, std::nothrow); + if (p) + { + GC::autoreleaseArray(static_cast(p)); + } + return p; +} + +void operator delete(void * block, e2d::autorelease_t const &) E2D_NOEXCEPT +{ + ::operator delete (block, std::nothrow); +} + +void operator delete[](void* block, e2d::autorelease_t const&) E2D_NOEXCEPT +{ + ::operator delete[](block, std::nothrow); +} + + +// GC 机制,用于销毁所有单例 +GC GC::_instance; e2d::GC::GC() : _notifyed(false) @@ -26,24 +61,25 @@ e2d::GC::~GC() } -// GC 释放池的实现机制: -// Object 类中的引用计数(_refCount)在一定程度上防止了内存泄漏 -// 它记录了对象被使用的次数,当计数为 0 时,GC 会自动释放这个对象 -// 所有的 Object 对象都应在被使用时(例如 Text 添加到了场景中) -// 调用 retain 函数保证该对象不被删除,并在不再使用时调用 release 函数 void e2d::GC::update() { - if (!_notifyed) + if (!_instance._notifyed) return; - _notifyed = false; - for (auto iter = _pool.begin(); iter != _pool.end();) + _instance._notifyed = false; + for (auto iter = _instance._pool.begin(); iter != _instance._pool.end();) { - if ((*iter)->getRefCount() <= 0) + if ((*iter).first->getRefCount() <= 0) { - (*iter)->onDestroy(); - delete (*iter); - iter = _pool.erase(iter); + if ((*iter).second) + { + delete[] (*iter).first; + } + else + { + delete (*iter).first; + } + iter = _instance._pool.erase(iter); } else { @@ -54,27 +90,58 @@ void e2d::GC::update() void e2d::GC::clear() { - for (auto pObj : _pool) + for (auto pair : _instance._pool) { - delete pObj; + delete pair.first; } - _pool.clear(); + _instance._pool.clear(); } -void e2d::GC::addObject(e2d::Object * object) +void e2d::GC::autorelease(Ref * ref) { - if (object) + if (ref) { - _pool.insert(object); + auto iter = _instance._pool.find(ref); + if (iter == _instance._pool.end()) + { + _instance._pool.insert(std::make_pair(ref, false)); + } } } -e2d::GC * e2d::GC::getInstance() +void e2d::GC::autoreleaseArray(Ref * ref) { - return &_instance; + if (ref) + { + auto iter = _instance._pool.find(ref); + if (iter == _instance._pool.end()) + { + _instance._pool.insert(std::make_pair(ref, true)); + } + } } -void e2d::GC::notify() +void e2d::GC::retain(Ref * ref) { - _notifyed = true; + if (ref) + { + auto iter = _instance._pool.find(ref); + if (iter != _instance._pool.end()) + { + (*iter).first->retain(); + } + } +} + +void e2d::GC::release(Ref * ref) +{ + if (ref) + { + auto iter = _instance._pool.find(ref); + if (iter != _instance._pool.end()) + { + (*iter).first->release(); + _instance._notifyed = true; + } + } } diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index 317a0967..67e9998b 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -37,7 +37,6 @@ void e2d::Game::destroyInstance() void e2d::Game::start(bool cleanup) { - auto gc = GC::getInstance(); auto input = Input::getInstance(); auto window = Window::getInstance(); auto renderer = Renderer::getInstance(); @@ -77,7 +76,7 @@ void e2d::Game::start(bool cleanup) actionManager->update(); // 更新动作管理器 sceneManager->update(); // 更新场景内容 renderer->render(); // 渲染游戏画面 - gc->update(); // 刷新内存池 + GC::update(); // 刷新内存池 Time::__updateLast(); // 刷新时间信息 } @@ -151,5 +150,5 @@ void e2d::Game::cleanup() // 清空音乐缓存 Player::getInstance()->clearCache(); // 删除所有对象 - GC::getInstance()->clear(); + GC::clear(); } diff --git a/core/Base/Input.cpp b/core/Base/Input.cpp index b1abacec..54ae286e 100644 --- a/core/Base/Input.cpp +++ b/core/Base/Input.cpp @@ -237,7 +237,7 @@ double e2d::Input::getMouseDeltaZ() e2d::Listener * e2d::Input::addListener(const Function& func, const String& name, bool paused) { auto listener = new (e2d::autorelease) Listener(func, name, paused); - listener->retain(); + GC::retain(listener); s_vListeners.push_back(listener); return listener; } @@ -249,7 +249,7 @@ void e2d::Input::addListener(Listener * listener) auto iter = std::find(s_vListeners.begin(), s_vListeners.end(), listener); if (iter == s_vListeners.end()) { - listener->retain(); + GC::retain(listener); s_vListeners.push_back(listener); } } @@ -338,7 +338,7 @@ void e2d::Input::clearAllListeners() { for (auto listener : s_vListeners) { - listener->release(); + GC::release(listener); } s_vListeners.clear(); } diff --git a/core/Collider/Collision.cpp b/core/Collider/Collision.cpp index 7adbf852..70909c6f 100644 --- a/core/Collider/Collision.cpp +++ b/core/Collider/Collision.cpp @@ -122,7 +122,7 @@ void e2d::Collision::__update(Node * active, Node * passive) e2d::Listener * e2d::Collision::addListener(const Function& func, const String& name, bool paused) { auto listener = new (e2d::autorelease) Listener(func, name, paused); - listener->retain(); + GC::retain(listener); s_vListeners.push_back(listener); return listener; } @@ -134,7 +134,7 @@ void e2d::Collision::addListener(Listener * listener) auto iter = std::find(s_vListeners.begin(), s_vListeners.end(), listener); if (iter == s_vListeners.end()) { - listener->retain(); + GC::retain(listener); s_vListeners.push_back(listener); } } @@ -223,7 +223,7 @@ void e2d::Collision::clearAllListeners() { for (auto listener : s_vListeners) { - listener->release(); + GC::release(listener); } s_vListeners.clear(); } diff --git a/core/Common/Object.cpp b/core/Common/Object.cpp deleted file mode 100644 index 4b92495f..00000000 --- a/core/Common/Object.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "..\e2dbase.h" -#include "..\e2dmanager.h" - -e2d::autorelease_t const e2d::autorelease = e2d::autorelease_t(); - -void * operator new(size_t _Size, e2d::autorelease_t const &) E2D_NOEXCEPT -{ - void* p = ::operator new (_Size, std::nothrow); - e2d::Object * newObject = static_cast(p); - if (newObject) - { - newObject->autorelease(); - } - return p; -} - -void operator delete(void * _Block, e2d::autorelease_t const &) E2D_NOEXCEPT -{ - ::operator delete (_Block, std::nothrow); -} - - -e2d::Object::Object() - : _refCount(0) -{ -} - -e2d::Object::~Object() -{ -} - -void e2d::Object::autorelease() -{ - GC::getInstance()->addObject(this); -} - -void e2d::Object::retain() -{ - ++_refCount; -} - -void e2d::Object::release() -{ - _refCount--; - GC::getInstance()->notify(); -} - -int e2d::Object::getRefCount() const -{ - return _refCount; -} \ No newline at end of file diff --git a/core/Common/Ref.cpp b/core/Common/Ref.cpp new file mode 100644 index 00000000..fcd18fe5 --- /dev/null +++ b/core/Common/Ref.cpp @@ -0,0 +1,25 @@ +#include "..\e2dcommon.h" + +e2d::Ref::Ref() + : _refCount(0) +{ +} + +e2d::Ref::~Ref() +{ +} + +void e2d::Ref::retain() +{ + _refCount++; +} + +void e2d::Ref::release() +{ + _refCount--; +} + +int e2d::Ref::getRefCount() const +{ + return _refCount; +} diff --git a/core/Common/Scene.cpp b/core/Common/Scene.cpp index 83195738..357664c2 100644 --- a/core/Common/Scene.cpp +++ b/core/Common/Scene.cpp @@ -7,12 +7,13 @@ e2d::Scene::Scene() , _root(nullptr) { _root = new (e2d::autorelease) Node(); - _root->retain(); + GC::retain(_root); _root->_setParentScene(this); } e2d::Scene::~Scene() { + GC::safeRelease(_root); } void e2d::Scene::_render() @@ -81,8 +82,3 @@ e2d::Node * e2d::Scene::getRoot() const { return _root; } - -void e2d::Scene::onDestroy() -{ - GC::safeRelease(_root); -} diff --git a/core/Custom/VoiceCallback.cpp b/core/Custom/VoiceCallback.cpp index c5ececc8..3fc3223c 100644 --- a/core/Custom/VoiceCallback.cpp +++ b/core/Custom/VoiceCallback.cpp @@ -41,7 +41,7 @@ void e2d::VoiceCallback::OnBufferEnd(void * pBufferContext) if (_music) { - _music->release(); + GC::release(_music); } } @@ -49,7 +49,7 @@ void e2d::VoiceCallback::OnBufferStart(void * pBufferContext) { if (_music) { - _music->retain(); + GC::retain(_music); } } diff --git a/core/Manager/ActionManager.cpp b/core/Manager/ActionManager.cpp index 03bc5040..edfaaa7a 100644 --- a/core/Manager/ActionManager.cpp +++ b/core/Manager/ActionManager.cpp @@ -41,9 +41,9 @@ void e2d::ActionManager::update() { auto action = _runningActions[i]; // 获取动作运行状态 - if (action->_isDone() || action->_target->getRefCount() == 0) + if (action->_isDone()) { - action->release(); + GC::release(action); action->_target = nullptr; _runningActions.erase(_runningActions.begin() + i); } @@ -136,8 +136,8 @@ void e2d::ActionManager::start(Action * action, Node * target, bool paused) auto iter = std::find(_runningActions.begin(), _runningActions.end(), action); if (iter == _runningActions.end()) { + GC::retain(action); action->_startWithTarget(target); - action->retain(); action->_running = !paused; _runningActions.push_back(action); } @@ -215,7 +215,7 @@ void e2d::ActionManager::clearAll() { for (auto action : _runningActions) { - action->release(); + GC::release(action); } _actions.clear(); _runningActions.clear(); diff --git a/core/Manager/ColliderManager.cpp b/core/Manager/ColliderManager.cpp index 91d08a74..e6940626 100644 --- a/core/Manager/ColliderManager.cpp +++ b/core/Manager/ColliderManager.cpp @@ -35,7 +35,7 @@ void e2d::ColliderManager::clearAll() { for (auto collder : _colliders) { - collder->release(); + GC::release(collder); } _colliders.clear(); } @@ -83,24 +83,24 @@ void e2d::ColliderManager::__updateCollider(e2d::Collider * pActiveCollider) } } -void e2d::ColliderManager::__add(Collider * pCollider) +void e2d::ColliderManager::__add(Collider * collider) { - if (pCollider) + if (collider) { - pCollider->retain(); - _colliders.push_back(pCollider); + GC::retain(collider); + _colliders.push_back(collider); } } -void e2d::ColliderManager::__remove(Collider * pCollider) +void e2d::ColliderManager::__remove(Collider * collider) { - if (pCollider) + if (collider) { for (size_t i = 0; i < _colliders.size(); ++i) { - if (_colliders[i] == pCollider) + if (_colliders[i] == collider) { - GC::safeRelease(pCollider); + GC::release(collider); _colliders.erase(_colliders.begin() + i); return; } diff --git a/core/Manager/SceneManager.cpp b/core/Manager/SceneManager.cpp index 8b29dce3..7f7d2e05 100644 --- a/core/Manager/SceneManager.cpp +++ b/core/Manager/SceneManager.cpp @@ -41,7 +41,7 @@ void e2d::SceneManager::enter(Scene * scene, Transition * transition /* = nullpt // 保存下一场景的指针 _nextScene = scene; - _nextScene->retain(); + GC::retain(_nextScene); // 设置切换场景动作 if (transition) @@ -49,10 +49,10 @@ void e2d::SceneManager::enter(Scene * scene, Transition * transition /* = nullpt if (_transition) { _transition->_stop(); - _transition->release(); + GC::release(_transition); } _transition = transition; - transition->retain(); + GC::retain(transition); transition->_init(_currScene, _nextScene); transition->_update(); } @@ -83,7 +83,7 @@ void e2d::SceneManager::back(Transition * transition /* = nullptr */) if (transition) { _transition = transition; - transition->retain(); + GC::retain(transition); transition->_init(_currScene, _nextScene); transition->_update(); } @@ -132,7 +132,7 @@ void e2d::SceneManager::update() if (_transition->isDone()) { - _transition->release(); + GC::release(_transition); _transition = nullptr; } else @@ -156,7 +156,7 @@ void e2d::SceneManager::update() } else { - _currScene->release(); + GC::release(_currScene); } } diff --git a/core/Node/Node.cpp b/core/Node/Node.cpp index 2dedcaed..8769f410 100644 --- a/core/Node/Node.cpp +++ b/core/Node/Node.cpp @@ -43,6 +43,12 @@ e2d::Node::Node() e2d::Node::~Node() { + ActionManager::getInstance()->clearAllBindedWith(this); + ColliderManager::getInstance()->__remove(_collider); + for (auto child : _children) + { + GC::release(child); + } } void e2d::Node::_update() @@ -606,14 +612,10 @@ void e2d::Node::addChild(Node * child, int order /* = 0 */) } } + GC::retain(child); _children.push_back(child); - child->setOrder(order); - - child->retain(); - child->_parent = this; - if (this->_parentScene) { child->_setParentScene(this->_parentScene); @@ -717,7 +719,7 @@ bool e2d::Node::removeChild(Node * child) child->_setParentScene(nullptr); } - child->release(); + GC::release(child); return true; } } @@ -748,7 +750,7 @@ void e2d::Node::removeChildren(const String& childName) { child->_setParentScene(nullptr); } - child->release(); + GC::release(child); } } } @@ -758,7 +760,7 @@ void e2d::Node::clearAllChildren() // 所有节点的引用计数减一 for (auto child : _children) { - child->release(); + GC::release(child); } // 清空储存节点的容器 _children.clear(); @@ -908,16 +910,6 @@ void e2d::Node::setAutoUpdate(bool bAutoUpdate) _autoUpdate = bAutoUpdate; } -void e2d::Node::onDestroy() -{ - ActionManager::getInstance()->clearAllBindedWith(this); - ColliderManager::getInstance()->__remove(_collider); - for (auto child : _children) - { - GC::safeRelease(child); - } -} - void e2d::Node::resumeAllActions() { ActionManager::getInstance()->resumeAllBindedWith(this); diff --git a/core/Node/Sprite.cpp b/core/Node/Sprite.cpp index 2f2abd9d..1aff8252 100644 --- a/core/Node/Sprite.cpp +++ b/core/Node/Sprite.cpp @@ -40,15 +40,16 @@ e2d::Sprite::Sprite(int resNameId, const String& resType, const Rect& cropRect) e2d::Sprite::~Sprite() { + GC::safeRelease(_image); } bool e2d::Sprite::open(Image * image) { if (image) { - GC::safeRelease(_image); + GC::release(_image); _image = image; - _image->retain(); + GC::retain(_image); Node::setSize(_image->getWidth(), _image->getHeight()); return true; @@ -61,7 +62,7 @@ bool e2d::Sprite::open(const String& filePath) if (!_image) { _image = new (e2d::autorelease) Image(); - _image->retain(); + GC::retain(_image); } if (_image->open(filePath)) @@ -77,7 +78,7 @@ bool e2d::Sprite::open(int resNameId, const String& resType) if (!_image) { _image = new (e2d::autorelease) Image(); - _image->retain(); + GC::retain(_image); } if (_image->open(resNameId, resType)) @@ -124,9 +125,3 @@ void e2d::Sprite::onRender() ); } } - -void e2d::Sprite::onDestroy() -{ - Node::onDestroy(); - GC::safeRelease(_image); -} diff --git a/core/Tool/Player.cpp b/core/Tool/Player.cpp index 6271de3e..dc807d48 100644 --- a/core/Tool/Player.cpp +++ b/core/Tool/Player.cpp @@ -14,11 +14,11 @@ e2d::Player::Player() e2d::Player::~Player() { for (auto pair : _fileList) - pair.second->release(); + GC::release(pair.second); _fileList.clear(); for (auto pair : _resList) - pair.second->release(); + GC::release(pair.second); _resList.clear(); if (_masteringVoice) @@ -73,7 +73,7 @@ bool e2d::Player::preload(const String& filePath) if (music->open(filePath)) { - music->retain(); + GC::retain(music); music->setVolume(_volume); _fileList.insert(std::pair(hash, music)); return true; @@ -94,7 +94,7 @@ bool e2d::Player::preload(int resNameId, const String& resType) if (music->open(resNameId, resType)) { - music->retain(); + GC::retain(music); music->setVolume(_volume); _resList.insert(std::pair(resNameId, music)); return true; @@ -263,13 +263,13 @@ void e2d::Player::clearCache() { for (auto pair : _fileList) { - pair.second->release(); + GC::release(pair.second); } _fileList.clear(); for (auto pair : _resList) { - pair.second->release(); + GC::release(pair.second); } _resList.clear(); } diff --git a/core/Tool/Timer.cpp b/core/Tool/Timer.cpp index f526f6df..8a8c4699 100644 --- a/core/Tool/Timer.cpp +++ b/core/Tool/Timer.cpp @@ -34,7 +34,7 @@ void e2d::Timer::addTask(Task * task) auto iter = std::find(_tasks.begin(), _tasks.end(), task); if (iter == _tasks.end()) { - task->retain(); + GC::retain(task); task->updateTime(); _tasks.push_back(task); } @@ -102,7 +102,7 @@ void e2d::Timer::clearAllTasks() { for (auto task : _tasks) { - task->release(); + GC::release(task); } _tasks.clear(); } @@ -118,7 +118,7 @@ void e2d::Timer::update() // 清除已停止的任务 if (task->_stopped) { - task->release(); + GC::release(task); _tasks.erase(_tasks.begin() + i); } else diff --git a/core/Transition/Transition.cpp b/core/Transition/Transition.cpp index c1dc4361..5072b3dc 100644 --- a/core/Transition/Transition.cpp +++ b/core/Transition/Transition.cpp @@ -20,6 +20,8 @@ e2d::Transition::~Transition() { SafeRelease(_outLayer); SafeRelease(_inLayer); + GC::safeRelease(_outScene); + GC::safeRelease(_inScene); } bool e2d::Transition::isDone() @@ -27,12 +29,6 @@ bool e2d::Transition::isDone() return _end; } -void e2d::Transition::onDestroy() -{ - GC::safeRelease(_outScene); - GC::safeRelease(_inScene); -} - void e2d::Transition::_init(Scene * prev, Scene * next) { auto renderer = Renderer::getInstance(); @@ -52,8 +48,8 @@ void e2d::Transition::_init(Scene * prev, Scene * next) _last = Time::getTotalTime(); _outScene = prev; _inScene = next; - if (_outScene) _outScene->retain(); - if (_inScene) _inScene->retain(); + GC::retain(_outScene); + GC::retain(_inScene); _windowSize = Window::getInstance()->getSize(); _outLayerParam = _inLayerParam = D2D1::LayerParameters(); diff --git a/core/e2daction.h b/core/e2daction.h index c0d92928..8b3b585d 100644 --- a/core/e2daction.h +++ b/core/e2daction.h @@ -15,7 +15,7 @@ class ActionManager; // 基础动作 class Action : - public Object + public Ref { friend class ActionManager; friend class Loop; @@ -59,9 +59,6 @@ public: // 获取该动作的执行目标 virtual Node * getTarget(); - // 销毁对象 - virtual void onDestroy() override; - protected: // 初始化动作 virtual void _init(); @@ -517,9 +514,6 @@ public: // 重置动作 virtual void reset() override; - // 销毁对象 - virtual void onDestroy() override; - protected: // 初始化动作 virtual void _init() override; @@ -596,9 +590,6 @@ public: // 重置动作 virtual void reset() override; - // 销毁对象 - virtual void onDestroy() override; - protected: // 初始化动作 virtual void _init() override; @@ -647,9 +638,6 @@ public: // 重置动作 virtual void reset() override; - // 销毁对象 - virtual void onDestroy() override; - protected: // 初始化动作 virtual void _init() override; @@ -667,7 +655,7 @@ protected: // 帧动画 class Animation : - public Object + public Ref { public: Animation(); @@ -714,9 +702,6 @@ public: // 获取帧动画的倒转 Animation * reverse() const; - // 销毁对象 - virtual void onDestroy() override; - protected: double _interval; std::vector _frames; @@ -753,9 +738,6 @@ public: // 重置动作 virtual void reset() override; - // 销毁对象 - virtual void onDestroy() override; - protected: // 初始化动作 virtual void _init() override; diff --git a/core/e2dbase.h b/core/e2dbase.h index a069e98a..1dab00b2 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -518,33 +518,42 @@ class GC friend class Game; public: - // 获取 GC 实例 - static GC* getInstance(); + // 自动释放 + static void autorelease( + Ref* ref + ); - // 释放对象 + // 自动释放数组 + static void autoreleaseArray( + Ref* ref + ); + + // 保留 + static void retain( + Ref* ref + ); + + // 释放 + static void release( + Ref* ref + ); + + // 安全地释放对象 template static inline void safeRelease(Type*& p) { if (p != nullptr) { - p->release(); + GC::release(p); p = nullptr; } } - // 通知 GC 回收垃圾内存 - void notify(); - - // 将对象放入释放池 - void addObject( - Object * object - ); - // 更新垃圾回收器状态 - void update(); + static void update(); // 清空所有对象 - void clear(); + static void clear(); private: GC(); @@ -554,8 +563,8 @@ private: E2D_DISABLE_COPY(GC); private: - bool _notifyed; - std::set _pool; + bool _notifyed; + std::map _pool; static GC _instance; }; diff --git a/core/e2dcommon.h b/core/e2dcommon.h index 5156b50d..651025c5 100644 --- a/core/e2dcommon.h +++ b/core/e2dcommon.h @@ -440,29 +440,23 @@ public: }; -// 基础对象 -class Object +// 引用计数对象 +class Ref { public: - Object(); + Ref(); - virtual ~Object(); + virtual ~Ref(); - // 自动释放 - void autorelease(); - - // 引用计数加一 + // 增加引用计数 void retain(); - // 引用计数减一 + // 减少引用计数 void release(); // 获取引用计数 int getRefCount() const; - // 销毁对象 - virtual void onDestroy() {} - private: int _refCount; }; @@ -470,7 +464,7 @@ private: // 图片 class Image : - public Object + public Ref { public: Image(); @@ -575,7 +569,7 @@ class Transition; // 场景 class Scene : - public Object + public Ref { friend class SceneManager; friend class Transition; @@ -635,9 +629,6 @@ public: // 获取根节点 Node * getRoot() const; - // 销毁对象 - virtual void onDestroy() override; - protected: // 渲染场景画面 void _render(); @@ -655,7 +646,7 @@ class ColliderManager; // 碰撞体 class Collider : - public Object + public Ref { friend class Node; friend class ColliderManager; @@ -833,12 +824,22 @@ namespace e2d } void* operator new( - size_t _Size, + size_t size, + e2d::autorelease_t const& + ) E2D_NOEXCEPT; + +void* operator new[]( + size_t size, e2d::autorelease_t const& ) E2D_NOEXCEPT; void operator delete( - void* _Block, + void* block, + e2d::autorelease_t const& + ) E2D_NOEXCEPT; + +void operator delete[]( + void* block, e2d::autorelease_t const& ) E2D_NOEXCEPT; #endif diff --git a/core/e2dnode.h b/core/e2dnode.h index 1006ed7b..51c6f6c5 100644 --- a/core/e2dnode.h +++ b/core/e2dnode.h @@ -9,7 +9,7 @@ class Action; class Transition; class Node : - public Object + public Ref { friend class Scene; friend class Collider; @@ -377,9 +377,6 @@ public: // 停止所有动作 virtual void stopAllActions(); - // 销毁对象 - virtual void onDestroy() override; - protected: // 更新节点 void _update(); @@ -498,9 +495,6 @@ public: // 渲染精灵 virtual void onRender() override; - // 销毁对象 - virtual void onDestroy() override; - protected: Image * _image; }; diff --git a/core/e2dtool.h b/core/e2dtool.h index 5e41a830..6bf3fb13 100644 --- a/core/e2dtool.h +++ b/core/e2dtool.h @@ -50,7 +50,7 @@ private: // 音乐 class Music : - public Object + public Ref { friend class VoiceCallback; @@ -274,7 +274,7 @@ class Timer; // 定时任务 class Task : - public Object + public Ref { friend class Timer; @@ -389,8 +389,8 @@ private: class Collision; // 监听器 -class Listener - : public Object +class Listener : + public Ref { friend class Input; friend class Collision; diff --git a/core/e2dtransition.h b/core/e2dtransition.h index 63dd0ec2..22a8d5a0 100644 --- a/core/e2dtransition.h +++ b/core/e2dtransition.h @@ -10,7 +10,7 @@ class SceneManager; // 场景过渡 class Transition : - public Object + public Ref { friend class SceneManager; @@ -22,9 +22,6 @@ public: // 场景过渡动画是否结束 bool isDone(); - // 销毁对象 - virtual void onDestroy() override; - protected: // 初始化场景过渡动画 virtual void _init( diff --git a/project/vs2012/Easy2D.vcxproj b/project/vs2012/Easy2D.vcxproj index 715233c5..13a4d696 100644 --- a/project/vs2012/Easy2D.vcxproj +++ b/project/vs2012/Easy2D.vcxproj @@ -65,7 +65,7 @@ - + diff --git a/project/vs2012/Easy2D.vcxproj.filters b/project/vs2012/Easy2D.vcxproj.filters index a1011e88..8bcf6970 100644 --- a/project/vs2012/Easy2D.vcxproj.filters +++ b/project/vs2012/Easy2D.vcxproj.filters @@ -143,7 +143,7 @@ Common - + Common diff --git a/project/vs2013/Easy2D.vcxproj b/project/vs2013/Easy2D.vcxproj index e1f36b9d..6f374e92 100644 --- a/project/vs2013/Easy2D.vcxproj +++ b/project/vs2013/Easy2D.vcxproj @@ -209,7 +209,7 @@ - + diff --git a/project/vs2013/Easy2D.vcxproj.filters b/project/vs2013/Easy2D.vcxproj.filters index 3e2a679d..409819a9 100644 --- a/project/vs2013/Easy2D.vcxproj.filters +++ b/project/vs2013/Easy2D.vcxproj.filters @@ -143,7 +143,7 @@ Common - + Common diff --git a/project/vs2017/Easy2D.vcxproj b/project/vs2017/Easy2D.vcxproj index 1422e230..10f9a185 100644 --- a/project/vs2017/Easy2D.vcxproj +++ b/project/vs2017/Easy2D.vcxproj @@ -227,9 +227,9 @@ - + diff --git a/project/vs2017/Easy2D.vcxproj.filters b/project/vs2017/Easy2D.vcxproj.filters index 8081ffab..e610a2a0 100644 --- a/project/vs2017/Easy2D.vcxproj.filters +++ b/project/vs2017/Easy2D.vcxproj.filters @@ -39,9 +39,6 @@ Common - - Common - Common @@ -240,6 +237,9 @@ Tool + + Common +