重做GC引用计数方式

This commit is contained in:
Nomango 2018-07-07 01:43:41 +08:00
parent a2d173800b
commit c8771231b4
34 changed files with 256 additions and 282 deletions

View File

@ -52,10 +52,6 @@ e2d::Node * e2d::Action::getTarget()
return _target; return _target;
} }
void e2d::Action::onDestroy()
{
}
void e2d::Action::reset() void e2d::Action::reset()
{ {
_initialized = false; _initialized = false;

View File

@ -16,6 +16,7 @@ e2d::Animate::Animate(Animation * animation)
e2d::Animate::~Animate() e2d::Animate::~Animate()
{ {
GC::safeRelease(_animation);
} }
e2d::Animation * e2d::Animate::getAnimation() const e2d::Animation * e2d::Animate::getAnimation() const
@ -29,7 +30,7 @@ void e2d::Animate::setAnimation(Animation * animation)
{ {
GC::safeRelease(_animation); GC::safeRelease(_animation);
_animation = animation; _animation = animation;
_animation->retain(); GC::retain(_animation);
} }
} }
@ -88,12 +89,6 @@ void e2d::Animate::reset()
_frameIndex = 0; _frameIndex = 0;
} }
void e2d::Animate::onDestroy()
{
Action::onDestroy();
GC::safeRelease(_animation);
}
e2d::Animate * e2d::Animate::clone() const e2d::Animate * e2d::Animate::clone() const
{ {
if (_animation) if (_animation)

View File

@ -24,6 +24,10 @@ e2d::Animation::Animation(double interval, const std::vector<Image*>& frames)
e2d::Animation::~Animation() e2d::Animation::~Animation()
{ {
for (auto frame : _frames)
{
GC::safeRelease(frame);
}
} }
void e2d::Animation::setInterval(double interval) void e2d::Animation::setInterval(double interval)
@ -31,20 +35,12 @@ void e2d::Animation::setInterval(double interval)
_interval = std::max(interval, 0.0); _interval = std::max(interval, 0.0);
} }
void e2d::Animation::onDestroy()
{
for (auto frame : _frames)
{
GC::safeRelease(frame);
}
}
void e2d::Animation::add(Image * frame) void e2d::Animation::add(Image * frame)
{ {
if (frame) if (frame)
{ {
_frames.push_back(frame); _frames.push_back(frame);
frame->retain(); GC::retain(frame);
} }
} }

View File

@ -11,12 +11,13 @@ e2d::Loop::Loop(Action * action, int times /* = -1 */)
if (action) if (action)
{ {
_action = action; _action = action;
_action->retain(); GC::retain(_action);
} }
} }
e2d::Loop::~Loop() e2d::Loop::~Loop()
{ {
GC::safeRelease(_action);
} }
e2d::Loop * e2d::Loop::clone() const e2d::Loop * e2d::Loop::clone() const
@ -90,12 +91,6 @@ void e2d::Loop::reset()
_times = 0; _times = 0;
} }
void e2d::Loop::onDestroy()
{
Action::onDestroy();
GC::safeRelease(_action);
}
void e2d::Loop::_resetTime() void e2d::Loop::_resetTime()
{ {
if (_action) _action->_resetTime(); if (_action) _action->_resetTime();

View File

@ -13,6 +13,10 @@ e2d::Sequence::Sequence(const std::vector<Action*>& actions)
e2d::Sequence::~Sequence() e2d::Sequence::~Sequence()
{ {
for (auto action : _actions)
{
GC::safeRelease(action);
}
} }
void e2d::Sequence::_init() void e2d::Sequence::_init()
@ -30,15 +34,6 @@ void e2d::Sequence::_init()
_actions[0]->_init(); _actions[0]->_init();
} }
void e2d::Sequence::onDestroy()
{
Action::onDestroy();
for (auto action : _actions)
{
GC::safeRelease(action);
}
}
void e2d::Sequence::_update() void e2d::Sequence::_update()
{ {
Action::_update(); Action::_update();
@ -83,7 +78,7 @@ void e2d::Sequence::add(Action * action)
if (action) if (action)
{ {
_actions.push_back(action); _actions.push_back(action);
action->retain(); GC::retain(action);
} }
} }

View File

@ -11,6 +11,10 @@ e2d::Spawn::Spawn(const std::vector<Action*>& actions)
e2d::Spawn::~Spawn() e2d::Spawn::~Spawn()
{ {
for (auto action : _actions)
{
GC::safeRelease(action);
}
} }
void e2d::Spawn::_init() 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() void e2d::Spawn::_update()
{ {
Action::_update(); Action::_update();
@ -81,7 +76,7 @@ void e2d::Spawn::add(Action * action)
if (action) if (action)
{ {
_actions.push_back(action); _actions.push_back(action);
action->retain(); GC::retain(action);
} }
} }

View File

@ -2,8 +2,43 @@
#include "..\e2dtool.h" #include "..\e2dtool.h"
#include "..\e2dmanager.h" #include "..\e2dmanager.h"
// GC 机制,用于自动销毁单例 using namespace e2d;
e2d::GC e2d::GC::_instance;
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<Ref*>(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<Ref*>(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() e2d::GC::GC()
: _notifyed(false) : _notifyed(false)
@ -26,24 +61,25 @@ e2d::GC::~GC()
} }
// GC 释放池的实现机制:
// Object 类中的引用计数_refCount在一定程度上防止了内存泄漏
// 它记录了对象被使用的次数,当计数为 0 时GC 会自动释放这个对象
// 所有的 Object 对象都应在被使用时(例如 Text 添加到了场景中)
// 调用 retain 函数保证该对象不被删除,并在不再使用时调用 release 函数
void e2d::GC::update() void e2d::GC::update()
{ {
if (!_notifyed) if (!_instance._notifyed)
return; return;
_notifyed = false; _instance._notifyed = false;
for (auto iter = _pool.begin(); iter != _pool.end();) for (auto iter = _instance._pool.begin(); iter != _instance._pool.end();)
{ {
if ((*iter)->getRefCount() <= 0) if ((*iter).first->getRefCount() <= 0)
{ {
(*iter)->onDestroy(); if ((*iter).second)
delete (*iter); {
iter = _pool.erase(iter); delete[] (*iter).first;
}
else
{
delete (*iter).first;
}
iter = _instance._pool.erase(iter);
} }
else else
{ {
@ -54,27 +90,58 @@ void e2d::GC::update()
void e2d::GC::clear() 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;
}
}
} }

View File

@ -37,7 +37,6 @@ void e2d::Game::destroyInstance()
void e2d::Game::start(bool cleanup) void e2d::Game::start(bool cleanup)
{ {
auto gc = GC::getInstance();
auto input = Input::getInstance(); auto input = Input::getInstance();
auto window = Window::getInstance(); auto window = Window::getInstance();
auto renderer = Renderer::getInstance(); auto renderer = Renderer::getInstance();
@ -77,7 +76,7 @@ void e2d::Game::start(bool cleanup)
actionManager->update(); // 更新动作管理器 actionManager->update(); // 更新动作管理器
sceneManager->update(); // 更新场景内容 sceneManager->update(); // 更新场景内容
renderer->render(); // 渲染游戏画面 renderer->render(); // 渲染游戏画面
gc->update(); // 刷新内存池 GC::update(); // 刷新内存池
Time::__updateLast(); // 刷新时间信息 Time::__updateLast(); // 刷新时间信息
} }
@ -151,5 +150,5 @@ void e2d::Game::cleanup()
// 清空音乐缓存 // 清空音乐缓存
Player::getInstance()->clearCache(); Player::getInstance()->clearCache();
// 删除所有对象 // 删除所有对象
GC::getInstance()->clear(); GC::clear();
} }

View File

@ -237,7 +237,7 @@ double e2d::Input::getMouseDeltaZ()
e2d::Listener * e2d::Input::addListener(const Function& func, const String& name, bool paused) e2d::Listener * e2d::Input::addListener(const Function& func, const String& name, bool paused)
{ {
auto listener = new (e2d::autorelease) Listener(func, name, paused); auto listener = new (e2d::autorelease) Listener(func, name, paused);
listener->retain(); GC::retain(listener);
s_vListeners.push_back(listener); s_vListeners.push_back(listener);
return listener; return listener;
} }
@ -249,7 +249,7 @@ void e2d::Input::addListener(Listener * listener)
auto iter = std::find(s_vListeners.begin(), s_vListeners.end(), listener); auto iter = std::find(s_vListeners.begin(), s_vListeners.end(), listener);
if (iter == s_vListeners.end()) if (iter == s_vListeners.end())
{ {
listener->retain(); GC::retain(listener);
s_vListeners.push_back(listener); s_vListeners.push_back(listener);
} }
} }
@ -338,7 +338,7 @@ void e2d::Input::clearAllListeners()
{ {
for (auto listener : s_vListeners) for (auto listener : s_vListeners)
{ {
listener->release(); GC::release(listener);
} }
s_vListeners.clear(); s_vListeners.clear();
} }

View File

@ -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) e2d::Listener * e2d::Collision::addListener(const Function& func, const String& name, bool paused)
{ {
auto listener = new (e2d::autorelease) Listener(func, name, paused); auto listener = new (e2d::autorelease) Listener(func, name, paused);
listener->retain(); GC::retain(listener);
s_vListeners.push_back(listener); s_vListeners.push_back(listener);
return listener; return listener;
} }
@ -134,7 +134,7 @@ void e2d::Collision::addListener(Listener * listener)
auto iter = std::find(s_vListeners.begin(), s_vListeners.end(), listener); auto iter = std::find(s_vListeners.begin(), s_vListeners.end(), listener);
if (iter == s_vListeners.end()) if (iter == s_vListeners.end())
{ {
listener->retain(); GC::retain(listener);
s_vListeners.push_back(listener); s_vListeners.push_back(listener);
} }
} }
@ -223,7 +223,7 @@ void e2d::Collision::clearAllListeners()
{ {
for (auto listener : s_vListeners) for (auto listener : s_vListeners)
{ {
listener->release(); GC::release(listener);
} }
s_vListeners.clear(); s_vListeners.clear();
} }

View File

@ -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<e2d::Object*>(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;
}

25
core/Common/Ref.cpp Normal file
View File

@ -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;
}

View File

@ -7,12 +7,13 @@ e2d::Scene::Scene()
, _root(nullptr) , _root(nullptr)
{ {
_root = new (e2d::autorelease) Node(); _root = new (e2d::autorelease) Node();
_root->retain(); GC::retain(_root);
_root->_setParentScene(this); _root->_setParentScene(this);
} }
e2d::Scene::~Scene() e2d::Scene::~Scene()
{ {
GC::safeRelease(_root);
} }
void e2d::Scene::_render() void e2d::Scene::_render()
@ -81,8 +82,3 @@ e2d::Node * e2d::Scene::getRoot() const
{ {
return _root; return _root;
} }
void e2d::Scene::onDestroy()
{
GC::safeRelease(_root);
}

View File

@ -41,7 +41,7 @@ void e2d::VoiceCallback::OnBufferEnd(void * pBufferContext)
if (_music) if (_music)
{ {
_music->release(); GC::release(_music);
} }
} }
@ -49,7 +49,7 @@ void e2d::VoiceCallback::OnBufferStart(void * pBufferContext)
{ {
if (_music) if (_music)
{ {
_music->retain(); GC::retain(_music);
} }
} }

View File

@ -41,9 +41,9 @@ void e2d::ActionManager::update()
{ {
auto action = _runningActions[i]; auto action = _runningActions[i];
// 获取动作运行状态 // 获取动作运行状态
if (action->_isDone() || action->_target->getRefCount() == 0) if (action->_isDone())
{ {
action->release(); GC::release(action);
action->_target = nullptr; action->_target = nullptr;
_runningActions.erase(_runningActions.begin() + i); _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); auto iter = std::find(_runningActions.begin(), _runningActions.end(), action);
if (iter == _runningActions.end()) if (iter == _runningActions.end())
{ {
GC::retain(action);
action->_startWithTarget(target); action->_startWithTarget(target);
action->retain();
action->_running = !paused; action->_running = !paused;
_runningActions.push_back(action); _runningActions.push_back(action);
} }
@ -215,7 +215,7 @@ void e2d::ActionManager::clearAll()
{ {
for (auto action : _runningActions) for (auto action : _runningActions)
{ {
action->release(); GC::release(action);
} }
_actions.clear(); _actions.clear();
_runningActions.clear(); _runningActions.clear();

View File

@ -35,7 +35,7 @@ void e2d::ColliderManager::clearAll()
{ {
for (auto collder : _colliders) for (auto collder : _colliders)
{ {
collder->release(); GC::release(collder);
} }
_colliders.clear(); _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(); GC::retain(collider);
_colliders.push_back(pCollider); _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) 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); _colliders.erase(_colliders.begin() + i);
return; return;
} }

View File

@ -41,7 +41,7 @@ void e2d::SceneManager::enter(Scene * scene, Transition * transition /* = nullpt
// 保存下一场景的指针 // 保存下一场景的指针
_nextScene = scene; _nextScene = scene;
_nextScene->retain(); GC::retain(_nextScene);
// 设置切换场景动作 // 设置切换场景动作
if (transition) if (transition)
@ -49,10 +49,10 @@ void e2d::SceneManager::enter(Scene * scene, Transition * transition /* = nullpt
if (_transition) if (_transition)
{ {
_transition->_stop(); _transition->_stop();
_transition->release(); GC::release(_transition);
} }
_transition = transition; _transition = transition;
transition->retain(); GC::retain(transition);
transition->_init(_currScene, _nextScene); transition->_init(_currScene, _nextScene);
transition->_update(); transition->_update();
} }
@ -83,7 +83,7 @@ void e2d::SceneManager::back(Transition * transition /* = nullptr */)
if (transition) if (transition)
{ {
_transition = transition; _transition = transition;
transition->retain(); GC::retain(transition);
transition->_init(_currScene, _nextScene); transition->_init(_currScene, _nextScene);
transition->_update(); transition->_update();
} }
@ -132,7 +132,7 @@ void e2d::SceneManager::update()
if (_transition->isDone()) if (_transition->isDone())
{ {
_transition->release(); GC::release(_transition);
_transition = nullptr; _transition = nullptr;
} }
else else
@ -156,7 +156,7 @@ void e2d::SceneManager::update()
} }
else else
{ {
_currScene->release(); GC::release(_currScene);
} }
} }

View File

@ -43,6 +43,12 @@ e2d::Node::Node()
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() void e2d::Node::_update()
@ -606,14 +612,10 @@ void e2d::Node::addChild(Node * child, int order /* = 0 */)
} }
} }
GC::retain(child);
_children.push_back(child); _children.push_back(child);
child->setOrder(order); child->setOrder(order);
child->retain();
child->_parent = this; child->_parent = this;
if (this->_parentScene) if (this->_parentScene)
{ {
child->_setParentScene(this->_parentScene); child->_setParentScene(this->_parentScene);
@ -717,7 +719,7 @@ bool e2d::Node::removeChild(Node * child)
child->_setParentScene(nullptr); child->_setParentScene(nullptr);
} }
child->release(); GC::release(child);
return true; return true;
} }
} }
@ -748,7 +750,7 @@ void e2d::Node::removeChildren(const String& childName)
{ {
child->_setParentScene(nullptr); child->_setParentScene(nullptr);
} }
child->release(); GC::release(child);
} }
} }
} }
@ -758,7 +760,7 @@ void e2d::Node::clearAllChildren()
// 所有节点的引用计数减一 // 所有节点的引用计数减一
for (auto child : _children) for (auto child : _children)
{ {
child->release(); GC::release(child);
} }
// 清空储存节点的容器 // 清空储存节点的容器
_children.clear(); _children.clear();
@ -908,16 +910,6 @@ void e2d::Node::setAutoUpdate(bool bAutoUpdate)
_autoUpdate = 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() void e2d::Node::resumeAllActions()
{ {
ActionManager::getInstance()->resumeAllBindedWith(this); ActionManager::getInstance()->resumeAllBindedWith(this);

View File

@ -40,15 +40,16 @@ e2d::Sprite::Sprite(int resNameId, const String& resType, const Rect& cropRect)
e2d::Sprite::~Sprite() e2d::Sprite::~Sprite()
{ {
GC::safeRelease(_image);
} }
bool e2d::Sprite::open(Image * image) bool e2d::Sprite::open(Image * image)
{ {
if (image) if (image)
{ {
GC::safeRelease(_image); GC::release(_image);
_image = image; _image = image;
_image->retain(); GC::retain(_image);
Node::setSize(_image->getWidth(), _image->getHeight()); Node::setSize(_image->getWidth(), _image->getHeight());
return true; return true;
@ -61,7 +62,7 @@ bool e2d::Sprite::open(const String& filePath)
if (!_image) if (!_image)
{ {
_image = new (e2d::autorelease) Image(); _image = new (e2d::autorelease) Image();
_image->retain(); GC::retain(_image);
} }
if (_image->open(filePath)) if (_image->open(filePath))
@ -77,7 +78,7 @@ bool e2d::Sprite::open(int resNameId, const String& resType)
if (!_image) if (!_image)
{ {
_image = new (e2d::autorelease) Image(); _image = new (e2d::autorelease) Image();
_image->retain(); GC::retain(_image);
} }
if (_image->open(resNameId, resType)) if (_image->open(resNameId, resType))
@ -124,9 +125,3 @@ void e2d::Sprite::onRender()
); );
} }
} }
void e2d::Sprite::onDestroy()
{
Node::onDestroy();
GC::safeRelease(_image);
}

View File

@ -14,11 +14,11 @@ e2d::Player::Player()
e2d::Player::~Player() e2d::Player::~Player()
{ {
for (auto pair : _fileList) for (auto pair : _fileList)
pair.second->release(); GC::release(pair.second);
_fileList.clear(); _fileList.clear();
for (auto pair : _resList) for (auto pair : _resList)
pair.second->release(); GC::release(pair.second);
_resList.clear(); _resList.clear();
if (_masteringVoice) if (_masteringVoice)
@ -73,7 +73,7 @@ bool e2d::Player::preload(const String& filePath)
if (music->open(filePath)) if (music->open(filePath))
{ {
music->retain(); GC::retain(music);
music->setVolume(_volume); music->setVolume(_volume);
_fileList.insert(std::pair<UINT, Music *>(hash, music)); _fileList.insert(std::pair<UINT, Music *>(hash, music));
return true; return true;
@ -94,7 +94,7 @@ bool e2d::Player::preload(int resNameId, const String& resType)
if (music->open(resNameId, resType)) if (music->open(resNameId, resType))
{ {
music->retain(); GC::retain(music);
music->setVolume(_volume); music->setVolume(_volume);
_resList.insert(std::pair<UINT, Music *>(resNameId, music)); _resList.insert(std::pair<UINT, Music *>(resNameId, music));
return true; return true;
@ -263,13 +263,13 @@ void e2d::Player::clearCache()
{ {
for (auto pair : _fileList) for (auto pair : _fileList)
{ {
pair.second->release(); GC::release(pair.second);
} }
_fileList.clear(); _fileList.clear();
for (auto pair : _resList) for (auto pair : _resList)
{ {
pair.second->release(); GC::release(pair.second);
} }
_resList.clear(); _resList.clear();
} }

View File

@ -34,7 +34,7 @@ void e2d::Timer::addTask(Task * task)
auto iter = std::find(_tasks.begin(), _tasks.end(), task); auto iter = std::find(_tasks.begin(), _tasks.end(), task);
if (iter == _tasks.end()) if (iter == _tasks.end())
{ {
task->retain(); GC::retain(task);
task->updateTime(); task->updateTime();
_tasks.push_back(task); _tasks.push_back(task);
} }
@ -102,7 +102,7 @@ void e2d::Timer::clearAllTasks()
{ {
for (auto task : _tasks) for (auto task : _tasks)
{ {
task->release(); GC::release(task);
} }
_tasks.clear(); _tasks.clear();
} }
@ -118,7 +118,7 @@ void e2d::Timer::update()
// 清除已停止的任务 // 清除已停止的任务
if (task->_stopped) if (task->_stopped)
{ {
task->release(); GC::release(task);
_tasks.erase(_tasks.begin() + i); _tasks.erase(_tasks.begin() + i);
} }
else else

View File

@ -20,6 +20,8 @@ e2d::Transition::~Transition()
{ {
SafeRelease(_outLayer); SafeRelease(_outLayer);
SafeRelease(_inLayer); SafeRelease(_inLayer);
GC::safeRelease(_outScene);
GC::safeRelease(_inScene);
} }
bool e2d::Transition::isDone() bool e2d::Transition::isDone()
@ -27,12 +29,6 @@ bool e2d::Transition::isDone()
return _end; return _end;
} }
void e2d::Transition::onDestroy()
{
GC::safeRelease(_outScene);
GC::safeRelease(_inScene);
}
void e2d::Transition::_init(Scene * prev, Scene * next) void e2d::Transition::_init(Scene * prev, Scene * next)
{ {
auto renderer = Renderer::getInstance(); auto renderer = Renderer::getInstance();
@ -52,8 +48,8 @@ void e2d::Transition::_init(Scene * prev, Scene * next)
_last = Time::getTotalTime(); _last = Time::getTotalTime();
_outScene = prev; _outScene = prev;
_inScene = next; _inScene = next;
if (_outScene) _outScene->retain(); GC::retain(_outScene);
if (_inScene) _inScene->retain(); GC::retain(_inScene);
_windowSize = Window::getInstance()->getSize(); _windowSize = Window::getInstance()->getSize();
_outLayerParam = _inLayerParam = D2D1::LayerParameters(); _outLayerParam = _inLayerParam = D2D1::LayerParameters();

View File

@ -15,7 +15,7 @@ class ActionManager;
// 基础动作 // 基础动作
class Action : class Action :
public Object public Ref
{ {
friend class ActionManager; friend class ActionManager;
friend class Loop; friend class Loop;
@ -59,9 +59,6 @@ public:
// 获取该动作的执行目标 // 获取该动作的执行目标
virtual Node * getTarget(); virtual Node * getTarget();
// 销毁对象
virtual void onDestroy() override;
protected: protected:
// 初始化动作 // 初始化动作
virtual void _init(); virtual void _init();
@ -517,9 +514,6 @@ public:
// 重置动作 // 重置动作
virtual void reset() override; virtual void reset() override;
// 销毁对象
virtual void onDestroy() override;
protected: protected:
// 初始化动作 // 初始化动作
virtual void _init() override; virtual void _init() override;
@ -596,9 +590,6 @@ public:
// 重置动作 // 重置动作
virtual void reset() override; virtual void reset() override;
// 销毁对象
virtual void onDestroy() override;
protected: protected:
// 初始化动作 // 初始化动作
virtual void _init() override; virtual void _init() override;
@ -647,9 +638,6 @@ public:
// 重置动作 // 重置动作
virtual void reset() override; virtual void reset() override;
// 销毁对象
virtual void onDestroy() override;
protected: protected:
// 初始化动作 // 初始化动作
virtual void _init() override; virtual void _init() override;
@ -667,7 +655,7 @@ protected:
// 帧动画 // 帧动画
class Animation : class Animation :
public Object public Ref
{ {
public: public:
Animation(); Animation();
@ -714,9 +702,6 @@ public:
// 获取帧动画的倒转 // 获取帧动画的倒转
Animation * reverse() const; Animation * reverse() const;
// 销毁对象
virtual void onDestroy() override;
protected: protected:
double _interval; double _interval;
std::vector<Image*> _frames; std::vector<Image*> _frames;
@ -753,9 +738,6 @@ public:
// 重置动作 // 重置动作
virtual void reset() override; virtual void reset() override;
// 销毁对象
virtual void onDestroy() override;
protected: protected:
// 初始化动作 // 初始化动作
virtual void _init() override; virtual void _init() override;

View File

@ -518,33 +518,42 @@ class GC
friend class Game; friend class Game;
public: 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 <typename Type> template <typename Type>
static inline void safeRelease(Type*& p) static inline void safeRelease(Type*& p)
{ {
if (p != nullptr) if (p != nullptr)
{ {
p->release(); GC::release(p);
p = nullptr; p = nullptr;
} }
} }
// 通知 GC 回收垃圾内存
void notify();
// 将对象放入释放池
void addObject(
Object * object
);
// 更新垃圾回收器状态 // 更新垃圾回收器状态
void update(); static void update();
// 清空所有对象 // 清空所有对象
void clear(); static void clear();
private: private:
GC(); GC();
@ -554,8 +563,8 @@ private:
E2D_DISABLE_COPY(GC); E2D_DISABLE_COPY(GC);
private: private:
bool _notifyed; bool _notifyed;
std::set<Object*> _pool; std::map<Ref*, bool> _pool;
static GC _instance; static GC _instance;
}; };

View File

@ -440,29 +440,23 @@ public:
}; };
// 基础对象 // 引用计数对象
class Object class Ref
{ {
public: public:
Object(); Ref();
virtual ~Object(); virtual ~Ref();
// 自动释放 // 增加引用计数
void autorelease();
// 引用计数加一
void retain(); void retain();
// 引用计数减一 // 减少引用计数
void release(); void release();
// 获取引用计数 // 获取引用计数
int getRefCount() const; int getRefCount() const;
// 销毁对象
virtual void onDestroy() {}
private: private:
int _refCount; int _refCount;
}; };
@ -470,7 +464,7 @@ private:
// 图片 // 图片
class Image : class Image :
public Object public Ref
{ {
public: public:
Image(); Image();
@ -575,7 +569,7 @@ class Transition;
// 场景 // 场景
class Scene : class Scene :
public Object public Ref
{ {
friend class SceneManager; friend class SceneManager;
friend class Transition; friend class Transition;
@ -635,9 +629,6 @@ public:
// 获取根节点 // 获取根节点
Node * getRoot() const; Node * getRoot() const;
// 销毁对象
virtual void onDestroy() override;
protected: protected:
// 渲染场景画面 // 渲染场景画面
void _render(); void _render();
@ -655,7 +646,7 @@ class ColliderManager;
// 碰撞体 // 碰撞体
class Collider : class Collider :
public Object public Ref
{ {
friend class Node; friend class Node;
friend class ColliderManager; friend class ColliderManager;
@ -833,12 +824,22 @@ namespace e2d
} }
void* operator new( 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::autorelease_t const&
) E2D_NOEXCEPT; ) E2D_NOEXCEPT;
void operator delete( void operator delete(
void* _Block, void* block,
e2d::autorelease_t const&
) E2D_NOEXCEPT;
void operator delete[](
void* block,
e2d::autorelease_t const& e2d::autorelease_t const&
) E2D_NOEXCEPT; ) E2D_NOEXCEPT;
#endif #endif

View File

@ -9,7 +9,7 @@ class Action;
class Transition; class Transition;
class Node : class Node :
public Object public Ref
{ {
friend class Scene; friend class Scene;
friend class Collider; friend class Collider;
@ -377,9 +377,6 @@ public:
// 停止所有动作 // 停止所有动作
virtual void stopAllActions(); virtual void stopAllActions();
// 销毁对象
virtual void onDestroy() override;
protected: protected:
// 更新节点 // 更新节点
void _update(); void _update();
@ -498,9 +495,6 @@ public:
// 渲染精灵 // 渲染精灵
virtual void onRender() override; virtual void onRender() override;
// 销毁对象
virtual void onDestroy() override;
protected: protected:
Image * _image; Image * _image;
}; };

View File

@ -50,7 +50,7 @@ private:
// 音乐 // 音乐
class Music : class Music :
public Object public Ref
{ {
friend class VoiceCallback; friend class VoiceCallback;
@ -274,7 +274,7 @@ class Timer;
// 定时任务 // 定时任务
class Task : class Task :
public Object public Ref
{ {
friend class Timer; friend class Timer;
@ -389,8 +389,8 @@ private:
class Collision; class Collision;
// 监听器 // 监听器
class Listener class Listener :
: public Object public Ref
{ {
friend class Input; friend class Input;
friend class Collision; friend class Collision;

View File

@ -10,7 +10,7 @@ class SceneManager;
// 场景过渡 // 场景过渡
class Transition : class Transition :
public Object public Ref
{ {
friend class SceneManager; friend class SceneManager;
@ -22,9 +22,6 @@ public:
// 场景过渡动画是否结束 // 场景过渡动画是否结束
bool isDone(); bool isDone();
// 销毁对象
virtual void onDestroy() override;
protected: protected:
// 初始化场景过渡动画 // 初始化场景过渡动画
virtual void _init( virtual void _init(

View File

@ -65,7 +65,7 @@
<ClCompile Include="..\..\core\Common\Font.cpp" /> <ClCompile Include="..\..\core\Common\Font.cpp" />
<ClCompile Include="..\..\core\Common\Function.cpp" /> <ClCompile Include="..\..\core\Common\Function.cpp" />
<ClCompile Include="..\..\core\Common\Image.cpp" /> <ClCompile Include="..\..\core\Common\Image.cpp" />
<ClCompile Include="..\..\core\Common\Object.cpp" /> <ClCompile Include="..\..\core\Common\Ref.cpp" />
<ClCompile Include="..\..\core\Common\Point.cpp" /> <ClCompile Include="..\..\core\Common\Point.cpp" />
<ClCompile Include="..\..\core\Common\Rect.cpp" /> <ClCompile Include="..\..\core\Common\Rect.cpp" />
<ClCompile Include="..\..\core\Common\Scene.cpp" /> <ClCompile Include="..\..\core\Common\Scene.cpp" />

View File

@ -143,7 +143,7 @@
<ClCompile Include="..\..\core\Common\Image.cpp"> <ClCompile Include="..\..\core\Common\Image.cpp">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\core\Common\Object.cpp"> <ClCompile Include="..\..\core\Common\Ref.cpp">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\core\Common\Point.cpp"> <ClCompile Include="..\..\core\Common\Point.cpp">

View File

@ -209,7 +209,7 @@
<ClCompile Include="..\..\core\Common\Font.cpp" /> <ClCompile Include="..\..\core\Common\Font.cpp" />
<ClCompile Include="..\..\core\Common\Function.cpp" /> <ClCompile Include="..\..\core\Common\Function.cpp" />
<ClCompile Include="..\..\core\Common\Image.cpp" /> <ClCompile Include="..\..\core\Common\Image.cpp" />
<ClCompile Include="..\..\core\Common\Object.cpp" /> <ClCompile Include="..\..\core\Common\Ref.cpp" />
<ClCompile Include="..\..\core\Common\Point.cpp" /> <ClCompile Include="..\..\core\Common\Point.cpp" />
<ClCompile Include="..\..\core\Common\Rect.cpp" /> <ClCompile Include="..\..\core\Common\Rect.cpp" />
<ClCompile Include="..\..\core\Common\Scene.cpp" /> <ClCompile Include="..\..\core\Common\Scene.cpp" />

View File

@ -143,7 +143,7 @@
<ClCompile Include="..\..\core\Common\Image.cpp"> <ClCompile Include="..\..\core\Common\Image.cpp">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\core\Common\Object.cpp"> <ClCompile Include="..\..\core\Common\Ref.cpp">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\core\Common\Point.cpp"> <ClCompile Include="..\..\core\Common\Point.cpp">

View File

@ -227,9 +227,9 @@
<ClCompile Include="..\..\core\Common\Config.cpp" /> <ClCompile Include="..\..\core\Common\Config.cpp" />
<ClCompile Include="..\..\core\Common\Font.cpp" /> <ClCompile Include="..\..\core\Common\Font.cpp" />
<ClCompile Include="..\..\core\Common\Function.cpp" /> <ClCompile Include="..\..\core\Common\Function.cpp" />
<ClCompile Include="..\..\core\Common\Object.cpp" />
<ClCompile Include="..\..\core\Common\Point.cpp" /> <ClCompile Include="..\..\core\Common\Point.cpp" />
<ClCompile Include="..\..\core\Common\Rect.cpp" /> <ClCompile Include="..\..\core\Common\Rect.cpp" />
<ClCompile Include="..\..\core\Common\Ref.cpp" />
<ClCompile Include="..\..\core\Common\Scene.cpp" /> <ClCompile Include="..\..\core\Common\Scene.cpp" />
<ClCompile Include="..\..\core\Common\Size.cpp" /> <ClCompile Include="..\..\core\Common\Size.cpp" />
<ClCompile Include="..\..\core\Common\String.cpp" /> <ClCompile Include="..\..\core\Common\String.cpp" />

View File

@ -39,9 +39,6 @@
<ClCompile Include="..\..\core\Common\Image.cpp"> <ClCompile Include="..\..\core\Common\Image.cpp">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\core\Common\Object.cpp">
<Filter>Common</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Common\String.cpp"> <ClCompile Include="..\..\core\Common\String.cpp">
<Filter>Common</Filter> <Filter>Common</Filter>
</ClCompile> </ClCompile>
@ -240,6 +237,9 @@
<ClCompile Include="..\..\core\Tool\Task.cpp"> <ClCompile Include="..\..\core\Tool\Task.cpp">
<Filter>Tool</Filter> <Filter>Tool</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\core\Common\Ref.cpp">
<Filter>Common</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\core\easy2d.h" /> <ClInclude Include="..\..\core\easy2d.h" />