PUParticleSystem3D::~PUParticleSystem3D()
{
    stopParticleSystem();
    unPrepared();

    _particlePool.removeAllDatas();

    for (auto iter : _emittedEmitterParticlePool){
        auto pool = iter.second;
        auto lockedList = pool.getUnActiveDataList();
        for (auto iter2 : lockedList){
            static_cast<PUParticle3D *>(iter2)->particleEntityPtr->release();
        }
        iter.second.removeAllDatas();
    }

    for (auto iter : _emittedSystemParticlePool){
        auto pool = iter.second;
        auto lockedList = pool.getUnActiveDataList();
        for (auto iter2 : lockedList){
            static_cast<PUParticle3D *>(iter2)->particleEntityPtr->release();
        }
        iter.second.removeAllDatas();
    }

    //release all emitters
    for (auto it : _emitters) {
        it->release();
    }
    _emitters.clear();

    for (auto it : _observers){
        it->release();
    }

    for (auto it : _behaviourTemplates) {
        it->release();
    }

    _observers.clear();
}
void PUParticleSystem3D::forceStopParticleSystem()
{
    if (_render)
        _render->notifyStop();

    for (auto &it : _observers){
        it->notifyStop();
    }

    for (auto& it : _emitters) {
        auto emitter = static_cast<PUEmitter*>(it);
        emitter->notifyStop();
    }

    for (auto& it : _affectors) {
        auto affector = static_cast<PUAffector*>(it);
        affector->notifyStop();
    }
    unscheduleUpdate();
    unPrepared();
}