重做GC引用计数方式
This commit is contained in:
parent
a2d173800b
commit
c8771231b4
|
|
@ -52,10 +52,6 @@ e2d::Node * e2d::Action::getTarget()
|
|||
return _target;
|
||||
}
|
||||
|
||||
void e2d::Action::onDestroy()
|
||||
{
|
||||
}
|
||||
|
||||
void e2d::Action::reset()
|
||||
{
|
||||
_initialized = false;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@ e2d::Animation::Animation(double interval, const std::vector<Image*>& 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@ e2d::Sequence::Sequence(const std::vector<Action*>& 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ e2d::Spawn::Spawn(const std::vector<Action*>& 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
115
core/Base/GC.cpp
115
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<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()
|
||||
: _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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<UINT, Music *>(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<UINT, Music *>(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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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<Image*> _frames;
|
||||
|
|
@ -753,9 +738,6 @@ public:
|
|||
// 重置动作
|
||||
virtual void reset() override;
|
||||
|
||||
// 销毁对象
|
||||
virtual void onDestroy() override;
|
||||
|
||||
protected:
|
||||
// 初始化动作
|
||||
virtual void _init() override;
|
||||
|
|
|
|||
|
|
@ -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 <typename Type>
|
||||
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<Object*> _pool;
|
||||
bool _notifyed;
|
||||
std::map<Ref*, bool> _pool;
|
||||
|
||||
static GC _instance;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
<ClCompile Include="..\..\core\Common\Font.cpp" />
|
||||
<ClCompile Include="..\..\core\Common\Function.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\Rect.cpp" />
|
||||
<ClCompile Include="..\..\core\Common\Scene.cpp" />
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@
|
|||
<ClCompile Include="..\..\core\Common\Image.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\Common\Object.cpp">
|
||||
<ClCompile Include="..\..\core\Common\Ref.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\Common\Point.cpp">
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@
|
|||
<ClCompile Include="..\..\core\Common\Font.cpp" />
|
||||
<ClCompile Include="..\..\core\Common\Function.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\Rect.cpp" />
|
||||
<ClCompile Include="..\..\core\Common\Scene.cpp" />
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@
|
|||
<ClCompile Include="..\..\core\Common\Image.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\Common\Object.cpp">
|
||||
<ClCompile Include="..\..\core\Common\Ref.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\Common\Point.cpp">
|
||||
|
|
|
|||
|
|
@ -227,9 +227,9 @@
|
|||
<ClCompile Include="..\..\core\Common\Config.cpp" />
|
||||
<ClCompile Include="..\..\core\Common\Font.cpp" />
|
||||
<ClCompile Include="..\..\core\Common\Function.cpp" />
|
||||
<ClCompile Include="..\..\core\Common\Object.cpp" />
|
||||
<ClCompile Include="..\..\core\Common\Point.cpp" />
|
||||
<ClCompile Include="..\..\core\Common\Rect.cpp" />
|
||||
<ClCompile Include="..\..\core\Common\Ref.cpp" />
|
||||
<ClCompile Include="..\..\core\Common\Scene.cpp" />
|
||||
<ClCompile Include="..\..\core\Common\Size.cpp" />
|
||||
<ClCompile Include="..\..\core\Common\String.cpp" />
|
||||
|
|
|
|||
|
|
@ -39,9 +39,6 @@
|
|||
<ClCompile Include="..\..\core\Common\Image.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\Common\Object.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\Common\String.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -240,6 +237,9 @@
|
|||
<ClCompile Include="..\..\core\Tool\Task.cpp">
|
||||
<Filter>Tool</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\core\Common\Ref.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\core\easy2d.h" />
|
||||
|
|
|
|||
Loading…
Reference in New Issue