2018-04-21 21:24:46 +08:00
|
|
|
|
#include "..\e2dbase.h"
|
2018-07-03 20:19:00 +08:00
|
|
|
|
#include "..\e2dtool.h"
|
2018-07-05 01:09:54 +08:00
|
|
|
|
#include "..\e2dmanager.h"
|
2018-07-03 18:16:26 +08:00
|
|
|
|
|
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-03 18:16:26 +08:00
|
|
|
|
|
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()
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-03 18:16:26 +08:00
|
|
|
|
e2d::GC::~GC()
|
|
|
|
|
|
{
|
|
|
|
|
|
// ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD>
|
|
|
|
|
|
Game::destroyInstance();
|
|
|
|
|
|
Renderer::destroyInstance();
|
2018-07-04 15:34:16 +08:00
|
|
|
|
Input::destroyInstance();
|
2018-07-03 18:16:26 +08:00
|
|
|
|
Window::destroyInstance();
|
2018-07-05 22:05:23 +08:00
|
|
|
|
Timer::destroyInstance();
|
2018-07-03 20:19:00 +08:00
|
|
|
|
Player::destroyInstance();
|
2018-07-05 16:34:53 +08:00
|
|
|
|
SceneManager::destroyInstance();
|
2018-07-05 01:09:54 +08:00
|
|
|
|
ActionManager::destroyInstance();
|
2018-07-08 16:57:12 +08:00
|
|
|
|
CollisionManager::destroyInstance();
|
2018-07-03 18:16:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-07-07 11:03:03 +08:00
|
|
|
|
void e2d::GC::flush()
|
2017-10-12 23:34:13 +08:00
|
|
|
|
{
|
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();)
|
2017-10-12 23:34:13 +08:00
|
|
|
|
{
|
2018-07-07 01:43:41 +08:00
|
|
|
|
if ((*iter).first->getRefCount() <= 0)
|
2017-10-12 23:34:13 +08:00
|
|
|
|
{
|
2018-07-07 01:43:41 +08:00
|
|
|
|
if ((*iter).second)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[] (*iter).first;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
delete (*iter).first;
|
|
|
|
|
|
}
|
|
|
|
|
|
iter = _instance._pool.erase(iter);
|
2017-10-12 23:34:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2018-05-14 22:51:40 +08:00
|
|
|
|
++iter;
|
2017-10-12 23:34:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-03 18:16:26 +08:00
|
|
|
|
void e2d::GC::clear()
|
2018-03-03 17:02:08 +08:00
|
|
|
|
{
|
2018-07-13 01:12:22 +08:00
|
|
|
|
_instance._cleanup = true;
|
2018-07-07 01:43:41 +08:00
|
|
|
|
for (auto pair : _instance._pool)
|
2018-04-21 00:46:26 +08:00
|
|
|
|
{
|
2018-07-13 01:12:22 +08:00
|
|
|
|
if (pair.second)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete[] pair.first;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
delete pair.first;
|
|
|
|
|
|
}
|
2018-04-21 00:46:26 +08:00
|
|
|
|
}
|
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)
|
2017-10-12 23:34:13 +08:00
|
|
|
|
{
|
2018-07-07 01:43:41 +08:00
|
|
|
|
if (ref)
|
2017-10-12 23:34:13 +08:00
|
|
|
|
{
|
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));
|
|
|
|
|
|
}
|
2017-10-12 23:34:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-07 01:43:41 +08:00
|
|
|
|
void e2d::GC::retain(Ref * ref)
|
2018-07-03 18:16:26 +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->retain();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-07-03 18:16:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
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
|
|
|
|
}
|