Magic_Game/core/Base/GC.cpp

167 lines
2.8 KiB
C++
Raw Normal View History

2018-04-21 21:24:46 +08:00
#include "..\e2dbase.h"
#include "..\e2dtool.h"
2018-07-05 01:09:54 +08:00
#include "..\e2dmanager.h"
2018-07-07 01:43:41 +08:00
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 <20><><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD>
GC GC::_instance;
2018-07-06 00:47:50 +08:00
e2d::GC::GC()
: _notifyed(false)
2018-07-13 01:12:22 +08:00
, _cleanup(false)
2018-07-06 00:47:50 +08:00
, _pool()
{
}
e2d::GC::~GC()
{
// ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6><EFBFBD>
GC::clear();
// <20><><EFBFBD><EFBFBD>ͼƬ<CDBC><C6AC><EFBFBD><EFBFBD>
Image::clearCache();
// ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD>
Game::destroyInstance();
Renderer::destroyInstance();
2018-07-04 15:34:16 +08:00
Input::destroyInstance();
Window::destroyInstance();
Timer::destroyInstance();
Player::destroyInstance();
SceneManager::destroyInstance();
2018-07-05 01:09:54 +08:00
ActionManager::destroyInstance();
CollisionManager::destroyInstance();
}
2018-07-07 11:03:03 +08:00
void e2d::GC::flush()
{
2018-07-07 01:43:41 +08:00
if (!_instance._notifyed)
2018-07-06 00:47:50 +08:00
return;
2017-10-14 01:07:34 +08:00
2018-07-07 01:43:41 +08:00
_instance._notifyed = false;
for (auto iter = _instance._pool.begin(); iter != _instance._pool.end();)
{
2018-07-07 01:43:41 +08:00
if ((*iter).first->getRefCount() <= 0)
{
2018-07-07 01:43:41 +08:00
if ((*iter).second)
{
delete[] (*iter).first;
}
else
{
delete (*iter).first;
}
iter = _instance._pool.erase(iter);
}
else
{
2018-05-14 22:51:40 +08:00
++iter;
}
}
}
void e2d::GC::clear()
2018-03-03 17:02:08 +08:00
{
2018-07-13 01:12:22 +08:00
_instance._cleanup = true;
SceneManager::getInstance()->clear();
Timer::getInstance()->clearAllTasks();
ActionManager::getInstance()->clearAll();
2018-07-07 01:43:41 +08:00
for (auto pair : _instance._pool)
{
2018-07-13 01:12:22 +08:00
if (pair.second)
{
delete[] pair.first;
}
else
{
delete pair.first;
}
}
2018-07-07 01:43:41 +08:00
_instance._pool.clear();
2018-07-13 01:12:22 +08:00
_instance._cleanup = false;
2018-03-03 17:02:08 +08:00
}
2018-07-07 01:43:41 +08:00
void e2d::GC::autorelease(Ref * ref)
{
2018-07-07 01:43:41 +08:00
if (ref)
{
2018-07-07 01:43:41 +08:00
auto iter = _instance._pool.find(ref);
if (iter == _instance._pool.end())
{
_instance._pool.insert(std::make_pair(ref, false));
}
}
}
void e2d::GC::autoreleaseArray(Ref * ref)
{
if (ref)
{
auto iter = _instance._pool.find(ref);
if (iter == _instance._pool.end())
{
_instance._pool.insert(std::make_pair(ref, true));
}
}
}
2018-07-07 01:43:41 +08:00
void e2d::GC::retain(Ref * ref)
{
2018-07-13 01:12:22 +08:00
if (ref && !_instance._cleanup)
2018-07-07 01:43:41 +08:00
{
auto iter = _instance._pool.find(ref);
if (iter != _instance._pool.end())
{
(*iter).first->retain();
}
}
}
2018-07-07 01:43:41 +08:00
void e2d::GC::release(Ref * ref)
2017-10-14 01:07:34 +08:00
{
2018-07-13 01:12:22 +08:00
if (ref && !_instance._cleanup)
2018-07-07 01:43:41 +08:00
{
auto iter = _instance._pool.find(ref);
if (iter != _instance._pool.end())
{
(*iter).first->release();
_instance._notifyed = true;
}
}
2017-10-14 01:07:34 +08:00
}