diff --git a/core/Action/Animate.cpp b/core/Action/Animate.cpp index fbb562d8..5eead2b9 100644 --- a/core/Action/Animate.cpp +++ b/core/Action/Animate.cpp @@ -27,7 +27,7 @@ void e2d::Animate::setAnimation(Animation * animation) { if (animation && animation != _animation) { - GC::release(_animation); + GC::safeRelease(_animation); _animation = animation; _animation->retain(); } @@ -91,14 +91,14 @@ void e2d::Animate::reset() void e2d::Animate::onDestroy() { Action::onDestroy(); - GC::release(_animation); + GC::safeRelease(_animation); } e2d::Animate * e2d::Animate::clone() const { if (_animation) { - return Create(_animation); + return new (std::nothrow) Animate(_animation); } return nullptr; } @@ -110,7 +110,7 @@ e2d::Animate * e2d::Animate::reverse() const auto animation = _animation->reverse(); if (animation) { - return Create(animation); + return new (std::nothrow) Animate(animation); } } return nullptr; diff --git a/core/Action/Animation.cpp b/core/Action/Animation.cpp index 9fe04c71..4fbad033 100644 --- a/core/Action/Animation.cpp +++ b/core/Action/Animation.cpp @@ -35,7 +35,7 @@ void e2d::Animation::onDestroy() { for (auto frame : _frames) { - GC::release(frame); + GC::safeRelease(frame); } } @@ -68,7 +68,7 @@ const std::vector& e2d::Animation::getFrames() const e2d::Animation * e2d::Animation::clone() const { - auto animation = Create(_interval); + auto animation = new (std::nothrow) Animation(_interval); if (animation) { for (auto frame : _frames) @@ -99,5 +99,5 @@ e2d::Animation * e2d::Animation::reverse() const } } - return Create(this->getInterval(), frames); + return new (std::nothrow) Animation(this->getInterval(), frames); } diff --git a/core/Action/CallFunc.cpp b/core/Action/CallFunc.cpp index ea739cf2..d13c3ca5 100644 --- a/core/Action/CallFunc.cpp +++ b/core/Action/CallFunc.cpp @@ -7,12 +7,12 @@ e2d::CallFunc::CallFunc(const Function& func) : e2d::CallFunc * e2d::CallFunc::clone() const { - return Create(_func); + return new (std::nothrow) CallFunc(_func); } e2d::CallFunc * e2d::CallFunc::reverse() const { - return Create(_func); + return new (std::nothrow) CallFunc(_func); } void e2d::CallFunc::_init() diff --git a/core/Action/Delay.cpp b/core/Action/Delay.cpp index 396bdfd5..8c0da9d5 100644 --- a/core/Action/Delay.cpp +++ b/core/Action/Delay.cpp @@ -8,12 +8,12 @@ e2d::Delay::Delay(double duration) e2d::Delay * e2d::Delay::clone() const { - return Create(_delay); + return new (std::nothrow) Delay(_delay); } e2d::Delay * e2d::Delay::reverse() const { - return Create(_delay); + return new (std::nothrow) Delay(_delay); } void e2d::Delay::reset() diff --git a/core/Action/JumpBy.cpp b/core/Action/JumpBy.cpp index 4898fad1..537d56a4 100644 --- a/core/Action/JumpBy.cpp +++ b/core/Action/JumpBy.cpp @@ -11,12 +11,12 @@ e2d::JumpBy::JumpBy(double duration, const Vector2 & vec, double height, int jum e2d::JumpBy * e2d::JumpBy::clone() const { - return Create(_duration, _deltaPos, _height, _jumps); + return new (std::nothrow) JumpBy(_duration, _deltaPos, _height, _jumps); } e2d::JumpBy * e2d::JumpBy::reverse() const { - return Create(_duration, -_deltaPos, _height, _jumps); + return new (std::nothrow) JumpBy(_duration, -_deltaPos, _height, _jumps); } void e2d::JumpBy::_init() diff --git a/core/Action/JumpTo.cpp b/core/Action/JumpTo.cpp index e2426bbf..cb8f36f5 100644 --- a/core/Action/JumpTo.cpp +++ b/core/Action/JumpTo.cpp @@ -9,7 +9,7 @@ e2d::JumpTo::JumpTo(double duration, const Point & pos, double height, int jumps e2d::JumpTo * e2d::JumpTo::clone() const { - return Create(_duration, _endPos, _height, _jumps); + return new (std::nothrow) JumpTo(_duration, _endPos, _height, _jumps); } void e2d::JumpTo::_init() diff --git a/core/Action/Loop.cpp b/core/Action/Loop.cpp index 341bfef5..49953a5d 100644 --- a/core/Action/Loop.cpp +++ b/core/Action/Loop.cpp @@ -23,7 +23,7 @@ e2d::Loop * e2d::Loop::clone() const { if (_action) { - return Create(_action->clone()); + return new (std::nothrow) Loop(_action->clone()); } else { @@ -35,7 +35,7 @@ e2d::Loop * e2d::Loop::reverse() const { if (_action) { - return Create(_action->clone()); + return new (std::nothrow) Loop(_action->clone()); } else { @@ -93,7 +93,7 @@ void e2d::Loop::reset() void e2d::Loop::onDestroy() { Action::onDestroy(); - GC::release(_action); + GC::safeRelease(_action); } void e2d::Loop::_resetTime() diff --git a/core/Action/MoveBy.cpp b/core/Action/MoveBy.cpp index 20328a44..5c855445 100644 --- a/core/Action/MoveBy.cpp +++ b/core/Action/MoveBy.cpp @@ -37,10 +37,10 @@ void e2d::MoveBy::_update() e2d::MoveBy * e2d::MoveBy::clone() const { - return Create(_duration, _deltaPos); + return new (std::nothrow) MoveBy(_duration, _deltaPos); } e2d::MoveBy * e2d::MoveBy::reverse() const { - return Create(_duration, -_deltaPos); + return new (std::nothrow) MoveBy(_duration, -_deltaPos); } \ No newline at end of file diff --git a/core/Action/MoveTo.cpp b/core/Action/MoveTo.cpp index 7691d19e..dee2429c 100644 --- a/core/Action/MoveTo.cpp +++ b/core/Action/MoveTo.cpp @@ -9,7 +9,7 @@ e2d::MoveTo::MoveTo(double duration, Point pos) e2d::MoveTo * e2d::MoveTo::clone() const { - return Create(_duration, _endPos); + return new (std::nothrow) MoveTo(_duration, _endPos); } void e2d::MoveTo::_init() diff --git a/core/Action/OpacityBy.cpp b/core/Action/OpacityBy.cpp index 8726bcb0..3b5454b3 100644 --- a/core/Action/OpacityBy.cpp +++ b/core/Action/OpacityBy.cpp @@ -30,10 +30,10 @@ void e2d::OpacityBy::_update() e2d::OpacityBy * e2d::OpacityBy::clone() const { - return Create(_duration, _deltaVal); + return new (std::nothrow) OpacityBy(_duration, _deltaVal); } e2d::OpacityBy * e2d::OpacityBy::reverse() const { - return Create(_duration, -_deltaVal); + return new (std::nothrow) OpacityBy(_duration, -_deltaVal); } \ No newline at end of file diff --git a/core/Action/OpacityTo.cpp b/core/Action/OpacityTo.cpp index bf4df219..11d3f4a5 100644 --- a/core/Action/OpacityTo.cpp +++ b/core/Action/OpacityTo.cpp @@ -10,7 +10,7 @@ e2d::OpacityTo::OpacityTo(double duration, double opacity) e2d::OpacityTo * e2d::OpacityTo::clone() const { - return Create(_duration, _endVal); + return new (std::nothrow) OpacityTo(_duration, _endVal); } void e2d::OpacityTo::_init() diff --git a/core/Action/RotateBy.cpp b/core/Action/RotateBy.cpp index bdcafb1c..50d520af 100644 --- a/core/Action/RotateBy.cpp +++ b/core/Action/RotateBy.cpp @@ -30,10 +30,10 @@ void e2d::RotateBy::_update() e2d::RotateBy * e2d::RotateBy::clone() const { - return Create(_duration, _deltaVal); + return new (std::nothrow) RotateBy(_duration, _deltaVal); } e2d::RotateBy * e2d::RotateBy::reverse() const { - return Create(_duration, -_deltaVal); + return new (std::nothrow) RotateBy(_duration, -_deltaVal); } \ No newline at end of file diff --git a/core/Action/RotateTo.cpp b/core/Action/RotateTo.cpp index 25a766d3..eeff6caa 100644 --- a/core/Action/RotateTo.cpp +++ b/core/Action/RotateTo.cpp @@ -10,7 +10,7 @@ e2d::RotateTo::RotateTo(double duration, double rotation) e2d::RotateTo * e2d::RotateTo::clone() const { - return Create(_duration, _endVal); + return new (std::nothrow) RotateTo(_duration, _endVal); } void e2d::RotateTo::_init() diff --git a/core/Action/ScaleBy.cpp b/core/Action/ScaleBy.cpp index 8c56472c..894e5057 100644 --- a/core/Action/ScaleBy.cpp +++ b/core/Action/ScaleBy.cpp @@ -39,10 +39,10 @@ void e2d::ScaleBy::_update() e2d::ScaleBy * e2d::ScaleBy::clone() const { - return Create(_duration, _deltaX, _deltaY); + return new (std::nothrow) ScaleBy(_duration, _deltaX, _deltaY); } e2d::ScaleBy * e2d::ScaleBy::reverse() const { - return Create(_duration, -_deltaX, -_deltaY); + return new (std::nothrow) ScaleBy(_duration, -_deltaX, -_deltaY); } \ No newline at end of file diff --git a/core/Action/ScaleTo.cpp b/core/Action/ScaleTo.cpp index 3dcba0e9..3306de8c 100644 --- a/core/Action/ScaleTo.cpp +++ b/core/Action/ScaleTo.cpp @@ -17,7 +17,7 @@ e2d::ScaleTo::ScaleTo(double duration, double scaleX, double scaleY) e2d::ScaleTo * e2d::ScaleTo::clone() const { - return Create(_duration, _endScaleX, _endScaleY); + return new (std::nothrow) ScaleTo(_duration, _endScaleX, _endScaleY); } void e2d::ScaleTo::_init() diff --git a/core/Action/Sequence.cpp b/core/Action/Sequence.cpp index 01b1f957..f28b71ae 100644 --- a/core/Action/Sequence.cpp +++ b/core/Action/Sequence.cpp @@ -35,7 +35,7 @@ void e2d::Sequence::onDestroy() Action::onDestroy(); for (auto action : _actions) { - GC::release(action); + GC::safeRelease(action); } } @@ -97,7 +97,7 @@ void e2d::Sequence::add(const std::vector& actions) e2d::Sequence * e2d::Sequence::clone() const { - auto sequence = Create(); + auto sequence = new (std::nothrow) Sequence(); for (const auto& action : _actions) { if (action) @@ -110,7 +110,7 @@ e2d::Sequence * e2d::Sequence::clone() const e2d::Sequence * e2d::Sequence::reverse() const { - auto sequence = Create(); + auto sequence = new (std::nothrow) Sequence(); if (sequence && !_actions.empty()) { std::vector newActions(_actions.size()); diff --git a/core/Action/Spawn.cpp b/core/Action/Spawn.cpp index eb9138a3..841b38bb 100644 --- a/core/Action/Spawn.cpp +++ b/core/Action/Spawn.cpp @@ -32,7 +32,7 @@ void e2d::Spawn::onDestroy() Action::onDestroy(); for (auto action : _actions) { - GC::release(action); + GC::safeRelease(action); } } @@ -95,7 +95,7 @@ void e2d::Spawn::add(const std::vector& actions) e2d::Spawn * e2d::Spawn::clone() const { - auto spawn = Create(); + auto spawn = new (std::nothrow) Spawn(); for (const auto& action : _actions) { if (action) @@ -108,7 +108,7 @@ e2d::Spawn * e2d::Spawn::clone() const e2d::Spawn * e2d::Spawn::reverse() const { - auto spawn = Create(); + auto spawn = new (std::nothrow) Spawn(); if (spawn && !_actions.empty()) { std::vector newActions(_actions.size()); diff --git a/core/Base/GC.cpp b/core/Base/GC.cpp index 80ac7dd7..3f523c03 100644 --- a/core/Base/GC.cpp +++ b/core/Base/GC.cpp @@ -5,6 +5,12 @@ // GC 机制,用于自动销毁单例 e2d::GC e2d::GC::_instance; +e2d::GC::GC() + : _notifyed(false) + , _pool() +{ +} + e2d::GC::~GC() { // 删除所有单例 @@ -27,7 +33,8 @@ e2d::GC::~GC() // 调用 retain 函数保证该对象不被删除,并在不再使用时调用 release 函数 void e2d::GC::update() { - if (!_notifyed) return; + if (!_notifyed) + return; _notifyed = false; for (auto iter = _pool.begin(); iter != _pool.end();) diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index 16a7be8c..317a0967 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -9,15 +9,13 @@ e2d::Game * e2d::Game::_instance = nullptr; e2d::Game::Game() : _ended(false) , _paused(false) - , _config(nullptr) + , _config() { CoInitialize(nullptr); } e2d::Game::~Game() { - GC::release(_config); - CoUninitialize(); } @@ -69,9 +67,9 @@ void e2d::Game::start(bool cleanup) if (Time::__isReady()) { // 更新配置 - if (_config && _config->_unconfigured) + if (_config._unconfigured) { - _config->_update(); + _config._update(); } input->update(); // 获取用户输入 @@ -79,13 +77,13 @@ void e2d::Game::start(bool cleanup) actionManager->update(); // 更新动作管理器 sceneManager->update(); // 更新场景内容 renderer->render(); // 渲染游戏画面 + gc->update(); // 刷新内存池 Time::__updateLast(); // 刷新时间信息 } else { Time::__sleep(); // 挂起线程 - gc->update(); // 刷新内存池 } } @@ -118,24 +116,14 @@ bool e2d::Game::isPaused() return _paused; } -void e2d::Game::setConfig(Config * config) +void e2d::Game::setConfig(const Config& config) { - if (_config != config && config) - { - GC::release(_config); - _config = config; - _config->_unconfigured = true; - GC::retain(_config); - } + _config = config; + _config._unconfigured = true; } -e2d::Config * e2d::Game::getConfig() +e2d::Config e2d::Game::getConfig() const { - if (!_config) - { - _config = Create(); - GC::retain(_config); - } return _config; } diff --git a/core/Base/Input.cpp b/core/Base/Input.cpp index e4987b88..d042e8ae 100644 --- a/core/Base/Input.cpp +++ b/core/Base/Input.cpp @@ -236,8 +236,9 @@ double e2d::Input::getMouseDeltaZ() e2d::Listener * e2d::Input::addListener(const Function& func, const String& name, bool paused) { - auto listener = Create(func, name, paused); - GC::retain(listener); + auto listener = new (std::nothrow) Listener(func, name, paused); + listener->autorelease(); + listener->retain(); s_vListeners.push_back(listener); return listener; } @@ -249,7 +250,7 @@ void e2d::Input::addListener(Listener * listener) auto iter = std::find(s_vListeners.begin(), s_vListeners.end(), listener); if (iter == s_vListeners.end()) { - GC::retain(listener); + listener->retain(); s_vListeners.push_back(listener); } } @@ -262,7 +263,7 @@ void e2d::Input::removeListener(Listener * listener) auto iter = std::find(s_vListeners.begin(), s_vListeners.end(), listener); if (iter != s_vListeners.end()) { - GC::release(listener); + GC::safeRelease(listener); s_vListeners.erase(iter); } } @@ -354,7 +355,7 @@ void e2d::Input::__updateListeners() // 清除已停止的监听器 if (listener->_stopped) { - GC::release(listener); + GC::safeRelease(listener); s_vListeners.erase(s_vListeners.begin() + i); } else diff --git a/core/Collider/Collision.cpp b/core/Collider/Collision.cpp index 86fb15b0..02c11853 100644 --- a/core/Collider/Collision.cpp +++ b/core/Collider/Collision.cpp @@ -104,7 +104,7 @@ void e2d::Collision::__update(Node * active, Node * passive) // 清除已停止的监听器 if (listener->_stopped) { - GC::release(listener); + GC::safeRelease(listener); s_vListeners.erase(s_vListeners.begin() + i); } else @@ -121,8 +121,9 @@ void e2d::Collision::__update(Node * active, Node * passive) e2d::Listener * e2d::Collision::addListener(const Function& func, const String& name, bool paused) { - auto listener = Create(func, name, paused); - GC::retain(listener); + auto listener = new (std::nothrow) Listener(func, name, paused); + listener->autorelease(); + listener->retain(); s_vListeners.push_back(listener); return listener; } @@ -134,7 +135,7 @@ void e2d::Collision::addListener(Listener * listener) auto iter = std::find(s_vListeners.begin(), s_vListeners.end(), listener); if (iter == s_vListeners.end()) { - GC::retain(listener); + listener->retain(); s_vListeners.push_back(listener); } } @@ -147,7 +148,7 @@ void e2d::Collision::removeListener(Listener * listener) auto iter = std::find(s_vListeners.begin(), s_vListeners.end(), listener); if (iter != s_vListeners.end()) { - GC::release(listener); + GC::safeRelease(listener); s_vListeners.erase(iter); } } diff --git a/core/Common/Config.cpp b/core/Common/Config.cpp index 572cc1af..7f60fe84 100644 --- a/core/Common/Config.cpp +++ b/core/Common/Config.cpp @@ -7,6 +7,7 @@ e2d::Config::Config() , _soundEnabled(true) , _collisionEnabled(false) , _colliderVisiable(false) + , _objectsAutoRelease(false) , _nodeDefColliderType(Collider::Type::None) , _unconfigured(true) { @@ -30,6 +31,11 @@ void e2d::Config::setSoundEnabled(bool enabled) } } +void e2d::Config::setObjectsAutoReleaseEnabled(bool enabled) +{ + _objectsAutoRelease = enabled; +} + void e2d::Config::setCollisionEnabled(bool enabled) { _collisionEnabled = enabled; @@ -63,6 +69,11 @@ bool e2d::Config::isSoundEnabled() const return _soundEnabled; } +bool e2d::Config::isObjectsAutoReleaseEnabled() const +{ + return _objectsAutoRelease; +} + bool e2d::Config::isCollisionEnabled() const { return _collisionEnabled; diff --git a/core/Common/Object.cpp b/core/Common/Object.cpp index 1fd2ddf3..c2c0fead 100644 --- a/core/Common/Object.cpp +++ b/core/Common/Object.cpp @@ -5,6 +5,10 @@ e2d::Object::Object() : _refCount(0) { + if (Game::getInstance()->getConfig().isObjectsAutoReleaseEnabled()) + { + this->autorelease(); + } } e2d::Object::~Object() diff --git a/core/Common/Scene.cpp b/core/Common/Scene.cpp index 9148bff2..2655d4a0 100644 --- a/core/Common/Scene.cpp +++ b/core/Common/Scene.cpp @@ -6,16 +6,10 @@ e2d::Scene::Scene() : _autoUpdate(true) , _root(nullptr) { - _root = Create(); - if (_root) - { - _root->retain(); - _root->_setParentScene(this); - } - else - { - throw Exception(L"场景根节点构造失败"); - } + _root = new (std::nothrow) Node(); + _root->autorelease(); + _root->retain(); + _root->_setParentScene(this); } e2d::Scene::~Scene() @@ -26,7 +20,7 @@ void e2d::Scene::_render() { _root->_render(); - if (Game::getInstance()->getConfig()->isColliderVisiable()) + if (Game::getInstance()->getConfig().isColliderVisiable()) { // 恢复矩阵转换 Renderer::getInstance()->getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); @@ -91,5 +85,5 @@ e2d::Node * e2d::Scene::getRoot() const void e2d::Scene::onDestroy() { - GC::release(_root); + GC::safeRelease(_root); } diff --git a/core/Manager/ActionManager.cpp b/core/Manager/ActionManager.cpp index 9dc31991..03bc5040 100644 --- a/core/Manager/ActionManager.cpp +++ b/core/Manager/ActionManager.cpp @@ -200,7 +200,7 @@ void e2d::ActionManager::clearAllBindedWith(Node * target) auto a = _runningActions[i]; if (a->getTarget() == target) { - GC::release(a); + GC::safeRelease(a); _runningActions.erase(_runningActions.begin() + i); } else diff --git a/core/Manager/ColliderManager.cpp b/core/Manager/ColliderManager.cpp index f8206f0b..91d08a74 100644 --- a/core/Manager/ColliderManager.cpp +++ b/core/Manager/ColliderManager.cpp @@ -43,7 +43,7 @@ void e2d::ColliderManager::clearAll() void e2d::ColliderManager::__updateCollider(e2d::Collider * pActiveCollider) { // 判断碰撞监听是否打开 - if (!Game::getInstance()->getConfig()->isCollisionEnabled()) + if (!Game::getInstance()->getConfig().isCollisionEnabled()) return; Node* pActiveNode = pActiveCollider->_parentNode; @@ -100,7 +100,7 @@ void e2d::ColliderManager::__remove(Collider * pCollider) { if (_colliders[i] == pCollider) { - GC::release(pCollider); + GC::safeRelease(pCollider); _colliders.erase(_colliders.begin() + i); return; } diff --git a/core/Manager/SceneManager.cpp b/core/Manager/SceneManager.cpp index dda827e4..8b29dce3 100644 --- a/core/Manager/SceneManager.cpp +++ b/core/Manager/SceneManager.cpp @@ -95,7 +95,7 @@ void e2d::SceneManager::clear() while (_scenes.size()) { auto temp = _scenes.top(); - GC::release(temp); + GC::safeRelease(temp); _scenes.pop(); } } diff --git a/core/Node/Node.cpp b/core/Node/Node.cpp index c9b83463..3573d4e6 100644 --- a/core/Node/Node.cpp +++ b/core/Node/Node.cpp @@ -32,13 +32,13 @@ e2d::Node::Node() , _positionFixed(false) , _colliderType(Collider::Type::None) { - auto config = Game::getInstance()->getConfig(); + auto& config = Game::getInstance()->getConfig(); // 设置默认中心点位置 - Point defPivot = config->getNodeDefaultPivot(); + Point defPivot = config.getNodeDefaultPivot(); this->_pivotX = float(defPivot.x); this->_pivotY = float(defPivot.y); // 设置默认碰撞体类型 - this->setColliderType(config->getDefaultColliderType()); + this->setColliderType(config.getDefaultColliderType()); } e2d::Node::~Node() @@ -573,11 +573,12 @@ void e2d::Node::setColliderType(Collider::Type type) case Collider::Type::Circle: case Collider::Type::Ellipse: { - this->_collider = Create(); - this->_collider->_parentNode = this; - this->_collider->_recreate(type); + _collider = new (std::nothrow) Collider(); + _collider->autorelease(); + _collider->_parentNode = this; + _collider->_recreate(type); // 添加新的碰撞体 - ColliderManager::getInstance()->__add(this->_collider); + ColliderManager::getInstance()->__add(_collider); } break; @@ -914,7 +915,7 @@ void e2d::Node::onDestroy() ColliderManager::getInstance()->__remove(_collider); for (auto child : _children) { - GC::release(child); + GC::safeRelease(child); } } diff --git a/core/Node/Sprite.cpp b/core/Node/Sprite.cpp index c2130a81..f27da298 100644 --- a/core/Node/Sprite.cpp +++ b/core/Node/Sprite.cpp @@ -46,7 +46,7 @@ bool e2d::Sprite::open(Image * image) { if (image) { - GC::release(_image); + GC::safeRelease(_image); _image = image; _image->retain(); @@ -60,7 +60,8 @@ bool e2d::Sprite::open(const String& filePath) { if (!_image) { - _image = Create(); + _image = new (std::nothrow) Image(); + _image->autorelease(); _image->retain(); } @@ -76,7 +77,8 @@ bool e2d::Sprite::open(int resNameId, const String& resType) { if (!_image) { - _image = Create(); + _image = new (std::nothrow) Image(); + _image->autorelease(); _image->retain(); } @@ -128,5 +130,5 @@ void e2d::Sprite::onRender() void e2d::Sprite::onDestroy() { Node::onDestroy(); - GC::release(_image); + GC::safeRelease(_image); } diff --git a/core/Tool/Path.cpp b/core/Tool/Path.cpp index f352359a..1e328c26 100644 --- a/core/Tool/Path.cpp +++ b/core/Tool/Path.cpp @@ -33,7 +33,7 @@ e2d::String e2d::Path::getDataPath() { // 设置数据的保存路径 String localAppDataPath = Path::getLocalAppDataPath(); - String gameName = Game::getInstance()->getConfig()->getGameName(); + String gameName = Game::getInstance()->getConfig().getGameName(); if (!localAppDataPath.isEmpty() && !gameName.isEmpty()) { _dataPath = localAppDataPath + L"\\Easy2DGameData\\" << gameName << L"\\"; @@ -54,7 +54,7 @@ e2d::String e2d::Path::getTempPath() { // 设置临时文件保存路径 wchar_t path[_MAX_PATH]; - String gameName = Game::getInstance()->getConfig()->getGameName(); + String gameName = Game::getInstance()->getConfig().getGameName(); if (0 != ::GetTempPath(_MAX_PATH, path) && !gameName.isEmpty()) { diff --git a/core/Tool/Player.cpp b/core/Tool/Player.cpp index e9e43a48..28d8f556 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) - delete pair.second; + pair.second->release(); _fileList.clear(); for (auto pair : _resList) - delete pair.second; + pair.second->release(); _resList.clear(); if (_masteringVoice) @@ -70,18 +70,15 @@ bool e2d::Player::preload(const String& filePath) else { Music * music = new (std::nothrow) Music(); + music->autorelease(); if (music->open(filePath)) { + music->retain(); music->setVolume(_volume); _fileList.insert(std::pair(hash, music)); return true; } - else - { - delete music; - music = nullptr; - } } return false; } @@ -95,18 +92,15 @@ bool e2d::Player::preload(int resNameId, const String& resType) else { Music * music = new (std::nothrow) Music(); + music->autorelease(); if (music->open(resNameId, resType)) { + music->retain(); music->setVolume(_volume); _resList.insert(std::pair(resNameId, music)); return true; } - else - { - delete music; - music = nullptr; - } } return false; } @@ -271,13 +265,13 @@ void e2d::Player::clearCache() { for (auto pair : _fileList) { - delete pair.second; + pair.second->release(); } _fileList.clear(); for (auto pair : _resList) { - delete pair.second; + pair.second->release(); } _resList.clear(); } diff --git a/core/Transition/Transition.cpp b/core/Transition/Transition.cpp index c614686c..c1dc4361 100644 --- a/core/Transition/Transition.cpp +++ b/core/Transition/Transition.cpp @@ -29,8 +29,8 @@ bool e2d::Transition::isDone() void e2d::Transition::onDestroy() { - GC::release(_outScene); - GC::release(_inScene); + GC::safeRelease(_outScene); + GC::safeRelease(_inScene); } void e2d::Transition::_init(Scene * prev, Scene * next) diff --git a/core/e2dbase.h b/core/e2dbase.h index 245ce58a..a069e98a 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -42,11 +42,11 @@ public: // 修改游戏配置 void setConfig( - Config * config + const Config& config ); // 获取游戏配置 - Config * getConfig(); + Config getConfig() const; private: Game(); @@ -58,7 +58,7 @@ private: private: bool _ended; bool _paused; - Config* _config; + Config _config; static Game * _instance; }; @@ -521,19 +521,9 @@ public: // 获取 GC 实例 static GC* getInstance(); - // 保留对象 - template - static inline void retain(Type*& p) - { - if (p != nullptr) - { - p->retain(); - } - } - // 释放对象 template - static inline void release(Type*& p) + static inline void safeRelease(Type*& p) { if (p != nullptr) { @@ -557,7 +547,7 @@ public: void clear(); private: - GC() {} + GC(); ~GC(); diff --git a/core/e2dcommon.h b/core/e2dcommon.h index 1f8b9896..f4c3972e 100644 --- a/core/e2dcommon.h +++ b/core/e2dcommon.h @@ -743,8 +743,7 @@ protected: class Game; // 游戏配置 -class Config : - public Object +class Config { friend class Game; @@ -765,6 +764,12 @@ public: bool enabled ); + // 打开或关闭自动回收 Easy2D 对象功能 + // 默认:关闭 + void setObjectsAutoReleaseEnabled( + bool enabled + ); + // 打开或关闭碰撞监听 // 默认:关闭 void setCollisionEnabled( @@ -795,6 +800,9 @@ public: // 获取声音打开状态 bool isSoundEnabled() const; + // 获取 Easy2D 对象自动释放状态 + bool isObjectsAutoReleaseEnabled() const; + // 获取碰撞监听状态 bool isCollisionEnabled() const; @@ -812,6 +820,7 @@ protected: protected: bool _unconfigured; + bool _objectsAutoRelease; bool _soundEnabled; bool _collisionEnabled; bool _colliderVisiable; @@ -821,150 +830,4 @@ protected: }; -#if _MSC_VER > 1700 - -// 创建可自动回收内存的对象 -template -inline Type * Create(Args&&... args) -{ - auto newObj = new (std::nothrow) Type(std::forward(args)...); - if (newObj) - { - newObj->autorelease(); - return newObj; - } - return nullptr; -} - -#else - -template -inline Type * Create() -{ - auto newObj = new (std::nothrow) Type(); - if (newObj) { newObj->autorelease(); return newObj; } - return nullptr; -} - -template -inline Type * Create(Arg1&& arg1) -{ - auto newObj = new (std::nothrow) Type(std::forward(arg1)); - if (newObj) { newObj->autorelease(); return newObj; } - return nullptr; -} - -template - inline Type * Create( - Arg1&& arg1, - Arg2&& arg2 - ) -{ - auto newObj = new (std::nothrow) Type( - std::forward(arg1), - std::forward(arg2) - ); - if (newObj) { newObj->autorelease(); return newObj; } - return nullptr; -} - -template - inline Type * Create( - Arg1&& arg1, - Arg2&& arg2, - Arg3&& arg3 - ) -{ - auto newObj = new (std::nothrow) Type( - std::forward(arg1), - std::forward(arg2), - std::forward(arg3) - ); - if (newObj) { newObj->autorelease(); return newObj; } - return nullptr; -} - -template - inline Type * Create( - Arg1&& arg1, - Arg2&& arg2, - Arg3&& arg3, - Arg4&& arg4 - ) -{ - auto newObj = new (std::nothrow) Type( - std::forward(arg1), - std::forward(arg2), - std::forward(arg3), - std::forward(arg4) - ); - if (newObj) { newObj->autorelease(); return newObj; } - return nullptr; -} - -template - inline Type * Create( - Arg1&& arg1, - Arg2&& arg2, - Arg3&& arg3, - Arg4&& arg4, - Arg5&& arg5 - ) -{ - auto newObj = new (std::nothrow) Type( - std::forward(arg1), - std::forward(arg2), - std::forward(arg3), - std::forward(arg4), - std::forward(arg5) - ); - if (newObj) { newObj->autorelease(); return newObj; } - return nullptr; -} - -template - inline Type * Create( - Arg1&& arg1, - Arg2&& arg2, - Arg3&& arg3, - Arg4&& arg4, - Arg5&& arg5, - Arg6&& arg6 - ) -{ - auto newObj = new (std::nothrow) Type( - std::forward(arg1), - std::forward(arg2), - std::forward(arg3), - std::forward(arg4), - std::forward(arg5), - std::forward(arg6) - ); - if (newObj) { newObj->autorelease(); return newObj; } - return nullptr; -} - -#endif - - } \ No newline at end of file diff --git a/project/vs2012/Easy2D.vcxproj b/project/vs2012/Easy2D.vcxproj index 7b55a143..715233c5 100644 --- a/project/vs2012/Easy2D.vcxproj +++ b/project/vs2012/Easy2D.vcxproj @@ -95,6 +95,7 @@ + diff --git a/project/vs2012/Easy2D.vcxproj.filters b/project/vs2012/Easy2D.vcxproj.filters index 8cdfbf25..a1011e88 100644 --- a/project/vs2012/Easy2D.vcxproj.filters +++ b/project/vs2012/Easy2D.vcxproj.filters @@ -236,6 +236,9 @@ Tool + + Tool + Transition diff --git a/project/vs2013/Easy2D.vcxproj b/project/vs2013/Easy2D.vcxproj index a0a4085e..e1f36b9d 100644 --- a/project/vs2013/Easy2D.vcxproj +++ b/project/vs2013/Easy2D.vcxproj @@ -239,6 +239,7 @@ + diff --git a/project/vs2013/Easy2D.vcxproj.filters b/project/vs2013/Easy2D.vcxproj.filters index 21464d94..3e2a679d 100644 --- a/project/vs2013/Easy2D.vcxproj.filters +++ b/project/vs2013/Easy2D.vcxproj.filters @@ -236,6 +236,9 @@ Tool + + Tool + Transition