diff --git a/core/Action/Animate.cpp b/core/Action/Animate.cpp index 02f27fe5..61075af6 100644 --- a/core/Action/Animate.cpp +++ b/core/Action/Animate.cpp @@ -16,7 +16,7 @@ e2d::Animate::Animate(Animation * animation) e2d::Animate::~Animate() { - GC::safeRelease(_animation); + GC::getInstance()->safeRelease(_animation); } e2d::Animation * e2d::Animate::getAnimation() const @@ -28,9 +28,9 @@ void e2d::Animate::setAnimation(Animation * animation) { if (animation && animation != _animation) { - GC::safeRelease(_animation); + if (_animation) _animation->release(); _animation = animation; - GC::retain(_animation); + _animation->retain(); } } diff --git a/core/Action/Animation.cpp b/core/Action/Animation.cpp index 23f13d2f..1c4f2665 100644 --- a/core/Action/Animation.cpp +++ b/core/Action/Animation.cpp @@ -26,7 +26,7 @@ e2d::Animation::~Animation() { for (auto frame : _frames) { - GC::safeRelease(frame); + GC::getInstance()->safeRelease(frame); } } @@ -40,7 +40,7 @@ void e2d::Animation::add(Image * frame) if (frame) { _frames.push_back(frame); - GC::retain(frame); + frame->retain(); } } diff --git a/core/Action/Loop.cpp b/core/Action/Loop.cpp index 4966ef8b..08892502 100644 --- a/core/Action/Loop.cpp +++ b/core/Action/Loop.cpp @@ -11,13 +11,13 @@ e2d::Loop::Loop(Action * action, int times /* = -1 */) if (action) { _action = action; - GC::retain(_action); + _action->retain(); } } e2d::Loop::~Loop() { - GC::safeRelease(_action); + GC::getInstance()->safeRelease(_action); } e2d::Loop * e2d::Loop::clone() const diff --git a/core/Action/Sequence.cpp b/core/Action/Sequence.cpp index 152eb05e..a2ced564 100644 --- a/core/Action/Sequence.cpp +++ b/core/Action/Sequence.cpp @@ -15,7 +15,7 @@ e2d::Sequence::~Sequence() { for (auto action : _actions) { - GC::safeRelease(action); + GC::getInstance()->safeRelease(action); } } @@ -78,7 +78,7 @@ void e2d::Sequence::add(Action * action) if (action) { _actions.push_back(action); - GC::retain(action); + action->retain(); } } diff --git a/core/Action/Spawn.cpp b/core/Action/Spawn.cpp index 50f954cc..697cba7e 100644 --- a/core/Action/Spawn.cpp +++ b/core/Action/Spawn.cpp @@ -13,7 +13,7 @@ e2d::Spawn::~Spawn() { for (auto action : _actions) { - GC::safeRelease(action); + GC::getInstance()->safeRelease(action); } } @@ -76,7 +76,7 @@ void e2d::Spawn::add(Action * action) if (action) { _actions.push_back(action); - GC::retain(action); + action->retain(); } } diff --git a/core/Base/GC.cpp b/core/Base/GC.cpp index c59ccc22..25470889 100644 --- a/core/Base/GC.cpp +++ b/core/Base/GC.cpp @@ -11,17 +11,7 @@ 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)); + GC::getInstance()->autorelease(static_cast(p)); } return p; } @@ -31,11 +21,6 @@ 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; @@ -50,7 +35,7 @@ e2d::GC::GC() e2d::GC::~GC() { // 删除所有对象 - GC::clear(); + this->clear(); // 清除图片缓存 Image::clearCache(); // 删除所有单例 @@ -68,23 +53,16 @@ e2d::GC::~GC() void e2d::GC::flush() { - if (!_instance._notifyed) + if (!_notifyed) return; - _instance._notifyed = false; - for (auto iter = _instance._pool.begin(); iter != _instance._pool.end();) + _notifyed = false; + for (auto iter = _pool.begin(); iter != _pool.end();) { - if ((*iter).first->getRefCount() <= 0) + if ((*iter)->getRefCount() <= 0) { - if ((*iter).second) - { - delete[] (*iter).first; - } - else - { - delete (*iter).first; - } - iter = _instance._pool.erase(iter); + delete (*iter); + iter = _pool.erase(iter); } else { @@ -95,72 +73,45 @@ void e2d::GC::flush() void e2d::GC::clear() { - _instance._cleanup = true; + _cleanup = true; SceneManager::getInstance()->clear(); Timer::getInstance()->clearAllTasks(); ActionManager::getInstance()->clearAll(); - for (auto pair : _instance._pool) + for (auto ref : _pool) { - if (pair.second) - { - delete[] pair.first; - } - else - { - delete pair.first; - } + delete ref; } - _instance._pool.clear(); - _instance._cleanup = false; + _pool.clear(); + _cleanup = false; +} + +e2d::GC * e2d::GC::getInstance() +{ + return &_instance; } void e2d::GC::autorelease(Ref * ref) { if (ref) { - auto iter = _instance._pool.find(ref); - if (iter == _instance._pool.end()) - { - _instance._pool.insert(std::make_pair(ref, false)); - } + _pool.insert(ref); } } -void e2d::GC::autoreleaseArray(Ref * ref) +void e2d::GC::safeRelease(Ref* ref) { + if (_cleanup) + return; + if (ref) { - auto iter = _instance._pool.find(ref); - if (iter == _instance._pool.end()) + auto iter = _pool.find(ref); + if (iter != _pool.end()) { - _instance._pool.insert(std::make_pair(ref, true)); - } - } -} - -void e2d::GC::retain(Ref * ref) -{ - if (ref && !_instance._cleanup) - { - auto iter = _instance._pool.find(ref); - if (iter != _instance._pool.end()) - { - (*iter).first->retain(); - } - } -} - -void e2d::GC::release(Ref * ref) -{ - if (ref && !_instance._cleanup) - { - auto iter = _instance._pool.find(ref); - if (iter != _instance._pool.end()) - { - (*iter).first->release(); - _instance._notifyed = true; + (*iter)->release(); + _notifyed = true; } } } diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index 4a13ac1f..b5ef413a 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -20,7 +20,7 @@ e2d::Game::Game() e2d::Game::~Game() { - GC::safeRelease(_config); + GC::getInstance()->safeRelease(_config); CoUninitialize(); } @@ -43,6 +43,7 @@ void e2d::Game::destroyInstance() void e2d::Game::start() { + auto gc = GC::getInstance(); auto input = Input::getInstance(); auto window = Window::getInstance(); auto renderer = Renderer::getInstance(); @@ -80,7 +81,7 @@ void e2d::Game::start() if (frameInterval < interval) { - _last = _now; + _last += interval; input->update(); timer->update(); @@ -89,7 +90,7 @@ void e2d::Game::start() _config->_update(); renderer->render(); window->poll(); - GC::flush(); + gc->flush(); } else { @@ -127,10 +128,10 @@ void e2d::Game::setConfig(Config* config) { if (config && _config != config) { - GC::release(_config); + if (_config) _config->release(); _config = config; _config->_unconfigured = true; - GC::retain(_config); + _config->retain(); } } @@ -153,7 +154,7 @@ void e2d::Game::quit() void e2d::Game::cleanup() { - GC::clear(); + GC::getInstance()->clear(); Image::clearCache(); Player::getInstance()->clearCache(); } diff --git a/core/Common/Scene.cpp b/core/Common/Scene.cpp index 865986ce..ae84ffef 100644 --- a/core/Common/Scene.cpp +++ b/core/Common/Scene.cpp @@ -7,13 +7,13 @@ e2d::Scene::Scene() , _root(nullptr) { _root = new (e2d::autorelease) Node(); - GC::retain(_root); + _root->retain(); _root->_setParentScene(this); } e2d::Scene::~Scene() { - GC::safeRelease(_root); + GC::getInstance()->safeRelease(_root); } void e2d::Scene::render() diff --git a/core/Common/Time.cpp b/core/Common/Time.cpp index 8ccbdc0f..14c9d27a 100644 --- a/core/Common/Time.cpp +++ b/core/Common/Time.cpp @@ -20,7 +20,13 @@ time_t e2d::Time::getTimeStamp() const e2d::Time e2d::Time::operator+(Duration const & other) const { - return std::move(Time(_timePoint - milliseconds(other.milliseconds()))); + return std::move(Time(_timePoint + milliseconds(other.milliseconds()))); +} + +e2d::Time & e2d::Time::operator+=(Duration const & other) +{ + _timePoint += milliseconds(other.milliseconds()); + return (*this); } e2d::Duration e2d::Time::operator-(Time const & other) const diff --git a/core/Custom/VoiceCallback.cpp b/core/Custom/VoiceCallback.cpp index 3fc3223c..c5ececc8 100644 --- a/core/Custom/VoiceCallback.cpp +++ b/core/Custom/VoiceCallback.cpp @@ -41,7 +41,7 @@ void e2d::VoiceCallback::OnBufferEnd(void * pBufferContext) if (_music) { - GC::release(_music); + _music->release(); } } @@ -49,7 +49,7 @@ void e2d::VoiceCallback::OnBufferStart(void * pBufferContext) { if (_music) { - GC::retain(_music); + _music->retain(); } } diff --git a/core/Manager/ActionManager.cpp b/core/Manager/ActionManager.cpp index fb321bce..8d924c2f 100644 --- a/core/Manager/ActionManager.cpp +++ b/core/Manager/ActionManager.cpp @@ -43,7 +43,7 @@ void e2d::ActionManager::update() // 获取动作运行状态 if (action->_isDone()) { - GC::release(action); + action->release(); action->_target = nullptr; _runningActions.erase(_runningActions.begin() + i); } @@ -136,7 +136,7 @@ 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->retain(); action->_startWithTarget(target); action->_running = !paused; _runningActions.push_back(action); @@ -197,10 +197,10 @@ void e2d::ActionManager::clearAllBindedWith(Node * target) { for (size_t i = 0; i < _runningActions.size();) { - auto a = _runningActions[i]; - if (a->getTarget() == target) + auto action = _runningActions[i]; + if (action->getTarget() == target) { - GC::safeRelease(a); + action->release(); _runningActions.erase(_runningActions.begin() + i); } else @@ -217,7 +217,7 @@ void e2d::ActionManager::clearAll() { for (auto action : _runningActions) { - GC::release(action); + action->release(); } _runningActions.clear(); } diff --git a/core/Manager/SceneManager.cpp b/core/Manager/SceneManager.cpp index f91eac14..b197451a 100644 --- a/core/Manager/SceneManager.cpp +++ b/core/Manager/SceneManager.cpp @@ -41,7 +41,7 @@ void e2d::SceneManager::push(Scene * scene, Transition * transition /* = nullptr // 保存下一场景的指针 _nextScene = scene; - GC::retain(_nextScene); + _nextScene->retain(); // 设置切换场景动作 if (transition) @@ -49,10 +49,10 @@ void e2d::SceneManager::push(Scene * scene, Transition * transition /* = nullptr if (_transition) { _transition->_stop(); - GC::release(_transition); + _transition->release(); } _transition = transition; - GC::retain(transition); + transition->retain(); transition->_init(_currScene, _nextScene); transition->_update(); } @@ -85,7 +85,7 @@ void e2d::SceneManager::pop(Transition * transition /* = nullptr */) // 设置切换场景动作 if (transition) { - GC::retain(transition); + transition->retain(); transition->_init(_currScene, _nextScene); transition->_update(); _transition = transition; @@ -134,7 +134,7 @@ void e2d::SceneManager::update() if (_transition->isDone()) { - GC::release(_transition); + _transition->release(); _transition = nullptr; } else @@ -158,15 +158,15 @@ void e2d::SceneManager::update() } else { - GC::release(_currScene); + _currScene->release(); } } // 执行下一场景的 onEnter 函数 _nextScene->onEnter(); - _currScene = _nextScene; // 切换场景 - _nextScene = nullptr; // 下一场景置空 + _currScene = _nextScene; + _nextScene = nullptr; } } diff --git a/core/Node/Node.cpp b/core/Node/Node.cpp index 29bed8c6..b56b1658 100644 --- a/core/Node/Node.cpp +++ b/core/Node/Node.cpp @@ -81,7 +81,7 @@ e2d::Node::~Node() ActionManager::getInstance()->clearAllBindedWith(this); for (auto child : _children) { - GC::release(child); + GC::getInstance()->safeRelease(child); } } @@ -713,7 +713,7 @@ void e2d::Node::addChild(Node * child, int order /* = 0 */) } } - GC::retain(child); + child->retain(); _children.push_back(child); child->setOrder(order); child->_parent = this; @@ -820,7 +820,7 @@ bool e2d::Node::removeChild(Node * child) child->_setParentScene(nullptr); } - GC::release(child); + child->release(); return true; } } @@ -851,7 +851,7 @@ void e2d::Node::removeChildren(const String& childName) { child->_setParentScene(nullptr); } - GC::release(child); + child->release(); } } } @@ -861,7 +861,7 @@ void e2d::Node::removeAllChildren() // 所有节点的引用计数减一 for (auto child : _children) { - GC::release(child); + child->release(); } // 清空储存节点的容器 _children.clear(); diff --git a/core/Node/Sprite.cpp b/core/Node/Sprite.cpp index 9fe36eca..d549d149 100644 --- a/core/Node/Sprite.cpp +++ b/core/Node/Sprite.cpp @@ -40,16 +40,16 @@ e2d::Sprite::Sprite(const String & fileName, const Rect & cropRect) e2d::Sprite::~Sprite() { - GC::safeRelease(_image); + GC::getInstance()->safeRelease(_image); } bool e2d::Sprite::open(Image * image) { if (image) { - GC::release(_image); + if (_image) _image->release(); _image = image; - GC::retain(_image); + _image->retain(); Node::setSize(_image->getWidth(), _image->getHeight()); return true; @@ -62,7 +62,7 @@ bool e2d::Sprite::open(const Resource& res) if (!_image) { _image = new (e2d::autorelease) Image(); - GC::retain(_image); + _image->retain(); } if (_image->open(res)) diff --git a/core/Tool/Timer.cpp b/core/Tool/Timer.cpp index 83462dcc..91beddc1 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()) { - GC::retain(task); + task->retain(); task->updateTime(); _tasks.push_back(task); } @@ -105,7 +105,7 @@ void e2d::Timer::clearAllTasks() for (auto task : _tasks) { - GC::release(task); + task->release(); } _tasks.clear(); } @@ -121,7 +121,7 @@ void e2d::Timer::update() // 清除已停止的任务 if (task->_stopped) { - GC::release(task); + task->release(); _tasks.erase(_tasks.begin() + i); } else diff --git a/core/Transition/Transition.cpp b/core/Transition/Transition.cpp index a4e50f58..a6919688 100644 --- a/core/Transition/Transition.cpp +++ b/core/Transition/Transition.cpp @@ -20,8 +20,8 @@ e2d::Transition::~Transition() { SafeRelease(_outLayer); SafeRelease(_inLayer); - GC::safeRelease(_outScene); - GC::safeRelease(_inScene); + GC::getInstance()->safeRelease(_outScene); + GC::getInstance()->safeRelease(_inScene); } bool e2d::Transition::isDone() @@ -48,8 +48,8 @@ void e2d::Transition::_init(Scene * prev, Scene * next) _last = Game::getInstance()->getTotalDuration(); _outScene = prev; _inScene = next; - GC::retain(_outScene); - GC::retain(_inScene); + if (_outScene) _outScene->retain(); + if (_inScene) _inScene->retain(); _windowSize = Window::getInstance()->getSize(); _outLayerParam = _inLayerParam = D2D1::LayerParameters(); diff --git a/core/e2dbase.h b/core/e2dbase.h index f076a327..54952a50 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -361,42 +361,24 @@ private: class GC { public: + // 获取 GC 实例 + static GC * getInstance(); + // 自动释放 - static void autorelease( - Ref* ref - ); - - // 自动释放数组 - static void autoreleaseArray( - Ref* ref - ); - - // 保留 - static void retain( - Ref* ref - ); - - // 释放 - static void release( + void autorelease( Ref* ref ); // 安全地释放对象 - template - static inline void safeRelease(Type*& p) - { - if (p != nullptr) - { - GC::release(p); - p = nullptr; - } - } + void safeRelease( + Ref* ref + ); // 刷新内存池 - static void flush(); + void flush(); // 回收内存池中的所有对象 - static void clear(); + void clear(); private: GC(); @@ -408,7 +390,7 @@ private: private: bool _notifyed; bool _cleanup; - std::map _pool; + std::set _pool; static GC _instance; }; diff --git a/core/e2dcommon.h b/core/e2dcommon.h index fb58e1a4..febde6b1 100644 --- a/core/e2dcommon.h +++ b/core/e2dcommon.h @@ -452,9 +452,9 @@ public: // 获取时间戳 time_t getTimeStamp() const; - // 计算时间间隔后的时间点 Time operator + (Duration const & other) const; - // 计算两时间点的时间间隔 + Time& operator += (Duration const &); + Duration operator - (Time const & other) const; // 获取当前时间 @@ -1161,17 +1161,7 @@ void* operator new( e2d::autorelease_t const& ) E2D_NOEXCEPT; -void* operator new[]( - size_t size, - e2d::autorelease_t const& - ) E2D_NOEXCEPT; - void operator delete( void* block, e2d::autorelease_t const& ) E2D_NOEXCEPT; - -void operator delete[]( - void* block, - e2d::autorelease_t const& - ) E2D_NOEXCEPT;