bool Object::destroyRenderer(qlib::uid_t uid) { // get renderer ptr/check consistency rendtab_t::iterator i = m_rendtab.find(uid); if (i==m_rendtab.end()) return false; RendererPtr pRend = i->second; ScenePtr pScene = getScene(); if (pScene.isnull() || pRend.isnull()) { LOG_DPRINTLN("Object::destroyRenderer> fatal error pScene or pRend is NULL!"); return false; } // detach renderer from the view-related resources (DL, VBO, etc) pRend->unloading(); // Detach the parent scene from the renderer event source pRend->removeListener(pScene.get()); // Fire the SCE_REND_REMOVING Event, before removing the renderer { MB_DPRINTLN("Object> Firing SCE_REND_REMOVING event..."); SceneEvent ev; ev.setType(SceneEvent::SCE_REND_REMOVING); ev.setSource(getSceneID()); ev.setTarget(pRend->getUID()); pScene->fireSceneEvent(ev); } // remove the rend from the scene's cache list pScene->removeRendCache(pRend); // 2012/9/30 // Detach the rend from obj HERE is very important!! // (This call remove the rend from object's event listener list. // Otherwise, deleted ptr will remain in the listener list, and thus cause crash!!) qlib::uid_t objid = pRend->detachObj(); // MB_ASSERT(objid==this->m_uid); // 2012/9/30 // Setting scene ID to null will cause removing pRend from the scene's listener list // (Without this, deleted ptr will remain in scene's listener list, after clearing the UNDO data!!) pRend->setSceneID(qlib::invalid_uid); // Remove from the renderer table m_rendtab.erase(i); // Record undo/redo info UndoManager *pUM = pScene->getUndoMgr(); if (pUM->isOK()) { ObjLoadEditInfo *pPEI = MB_NEW ObjLoadEditInfo; pPEI->setupRendDestroy(getUID(), pRend); pUM->addEditInfo(pPEI); } return true; }
bool Object::registerRendererImpl(RendererPtr rrend) { bool res = m_rendtab.insert(rendtab_t::value_type(rrend->getUID(), rrend)).second; if (!res) return false; rrend->setSceneID(getSceneID()); rrend->attachObj(this->m_uid); ScenePtr pScene = getScene(); if (pScene.isnull()) return true; // add the new rend to the scene's cache list pScene->addRendCache(rrend); // The scene observes events from the new renderer //rrend->addPropListener(pScene.get()); rrend->addListener(pScene.get()); // Fire the SCE_REND_ADDED Event { MB_DPRINTLN("Object> Firing SCE_REND_ADDED event..."); SceneEvent ev; ev.setType(SceneEvent::SCE_REND_ADDED); ev.setSource(getSceneID()); ev.setTarget(rrend->getUID()); pScene->fireSceneEvent(ev); } // Record undo/redo info UndoManager *pUM = pScene->getUndoMgr(); if (pUM->isOK()) { ObjLoadEditInfo *pPEI = MB_NEW ObjLoadEditInfo; pPEI->setupRendCreate(getUID(), rrend); pUM->addEditInfo(pPEI); } return true; }