/* KLayout Layout Viewer Copyright (C) 2006-2017 Matthias Koefferlein This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "dbLibraryManager.h" #include "dbLibrary.h" #include "dbCommon.h" #include "tlAssert.h" #include "tlStaticObjects.h" #include "tlClassRegistry.h" #include namespace tl { template<> DB_PUBLIC tl::Registrar *tl::Registrar::instance = 0; } namespace db { static LibraryManager *sp_instance (0); LibraryManager & LibraryManager::instance () { if (sp_instance == 0) { sp_instance = new LibraryManager (); tl::StaticObjects::reg (&sp_instance); } return *sp_instance; } bool LibraryManager::initialized () { return sp_instance != 0; } LibraryManager::LibraryManager () { // handle auto-registered libraries: for (tl::Registrar::iterator l = tl::Registrar::begin (); l != tl::Registrar::end (); ++l) { // take library - no other one will need it register_lib (l.take ()); } } LibraryManager::~LibraryManager () { clear (); } std::pair LibraryManager::lib_by_name (const std::string &name) const { iterator l = m_lib_by_name.find (name); if (l == m_lib_by_name.end ()) { return std::make_pair (false, lib_id_type (0)); } else { return std::make_pair (true, l->second); } } void LibraryManager::delete_lib (Library *library) { if (!library) { return; } m_lib_by_name.erase (library->get_name ()); for (lib_id_type id = 0; id < m_libs.size (); ++id) { if (m_libs [id] == library) { library->remap_to (0); delete library; m_libs [id] = 0; } } } lib_id_type LibraryManager::register_lib (Library *library) { library->keep (); // marks the library owned by the C++ side of GSI lib_id_type id; for (id = 0; id < m_libs.size (); ++id) { if (m_libs [id] == 0) { break; } } if (id == m_libs.size ()) { m_libs.push_back (library); } else { m_libs [id] = library; } library->set_id (id); // if the new library replaces the old one, remap existing library proxies before deleting the library lib_name_map::iterator ln = m_lib_by_name.find (library->get_name ()); if (ln != m_lib_by_name.end () && m_libs [ln->second]) { m_libs [ln->second]->remap_to (library); delete m_libs [ln->second]; m_libs [ln->second] = 0; } m_lib_by_name.insert (std::make_pair (library->get_name (), id)).first->second = id; changed_event (); return id; } Library * LibraryManager::lib (lib_id_type id) const { if (id >= m_libs.size ()) { return 0; } else { return m_libs [id]; } } void LibraryManager::clear () { if (m_libs.empty ()) { return; } // empty the library table before we delete them - this avoid accesses to invalid libraries while doing so. std::vector libs; libs.swap (m_libs); m_lib_by_name.clear (); for (std::vector::iterator l = libs.begin (); l != libs.end (); ++l) { if (*l) { delete *l; } } changed_event (); } }