mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
ddb261d708
commit
062567f206
|
|
@ -26,6 +26,7 @@
|
|||
#include "dbPCellDeclaration.h"
|
||||
#include "dbPCellVariant.h"
|
||||
#include "dbLibraryManager.h"
|
||||
#include "tlTimer.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
|
|
@ -166,14 +167,36 @@ Library::rename (const std::string &name)
|
|||
void
|
||||
Library::refresh ()
|
||||
{
|
||||
// save a copy of the layout, so we can refer to it
|
||||
std::unique_ptr<db::Layout> org_layout (new db::Layout (layout ()));
|
||||
refresh_without_restore ();
|
||||
|
||||
std::string name = reload ();
|
||||
rename (name);
|
||||
// proxies need to be restored in a special case when a library has a proxy to itself.
|
||||
// The layout readers will not be able to create library references in this case.
|
||||
layout ().restore_proxies ();
|
||||
}
|
||||
|
||||
void
|
||||
Library::refresh_without_restore ()
|
||||
{
|
||||
db::LibraryManager::instance ().unregister_lib (this);
|
||||
|
||||
try {
|
||||
|
||||
m_name = reload ();
|
||||
|
||||
} catch (...) {
|
||||
|
||||
// fallback - leave the library, but with empty layout
|
||||
layout ().clear ();
|
||||
db::LibraryManager::instance ().register_lib (this);
|
||||
|
||||
throw;
|
||||
|
||||
}
|
||||
|
||||
layout ().refresh ();
|
||||
remap_to (this, org_layout.get ());
|
||||
|
||||
// re-register, potentially under the new name
|
||||
db::LibraryManager::instance ().register_lib (this);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -198,9 +221,9 @@ Library::remap_to (db::Library *other, db::Layout *original_layout)
|
|||
std::vector<std::pair<db::LibraryProxy *, db::PCellVariant *> > pcells_to_map;
|
||||
std::vector<db::LibraryProxy *> lib_cells_to_map;
|
||||
|
||||
for (auto ci = r->first->begin_top_down (); ci != r->first->end_top_down (); ++ci) {
|
||||
for (auto c = r->first->begin (); c != r->first->end (); ++c) {
|
||||
|
||||
db::LibraryProxy *lib_proxy = dynamic_cast<db::LibraryProxy *> (&r->first->cell (*ci));
|
||||
db::LibraryProxy *lib_proxy = dynamic_cast<db::LibraryProxy *> (c.operator-> ());
|
||||
if (lib_proxy && lib_proxy->lib_id () == get_id ()) {
|
||||
|
||||
db::Cell *lib_cell = &original_layout->cell (lib_proxy->library_cell_index ());
|
||||
|
|
@ -217,7 +240,7 @@ Library::remap_to (db::Library *other, db::Layout *original_layout)
|
|||
|
||||
}
|
||||
|
||||
// We do PCell resolution before the library proxy resolution. The reason is that
|
||||
// We do PCell resolution before the library proxy resolution. The reason is that
|
||||
// PCells may generate library proxies in their instantiation. Hence we must instantiate
|
||||
// the PCells before we can resolve them.
|
||||
for (std::vector<std::pair<db::LibraryProxy *, db::PCellVariant *> >::const_iterator lp = pcells_to_map.begin (); lp != pcells_to_map.end (); ++lp) {
|
||||
|
|
|
|||
|
|
@ -225,6 +225,13 @@ public:
|
|||
*/
|
||||
void refresh ();
|
||||
|
||||
/**
|
||||
* @brief Refreshes the library on all clients without restoring proxies
|
||||
*
|
||||
* This method is intended to be used internally for bulk refreshes.
|
||||
*/
|
||||
void refresh_without_restore ();
|
||||
|
||||
/**
|
||||
* @brief Renames the library
|
||||
*
|
||||
|
|
|
|||
|
|
@ -284,9 +284,27 @@ LibraryManager::lib_internal (lib_id_type id) const
|
|||
void
|
||||
LibraryManager::refresh_all ()
|
||||
{
|
||||
// NOTE: libraries may get deleted during the refresh, so better use weak pointers here
|
||||
// to track lifetime. Libraries appearing are not considered.
|
||||
|
||||
std::vector<tl::weak_ptr<Library> > libs;
|
||||
libs.reserve (m_libs.size ());
|
||||
for (auto l = m_libs.begin (); l != m_libs.end (); ++l) {
|
||||
libs.push_back (tl::weak_ptr<Library> (*l));
|
||||
}
|
||||
|
||||
for (auto l = libs.begin (); l != libs.end (); ++l) {
|
||||
if (l->get ()) {
|
||||
(*l)->refresh_without_restore ();
|
||||
}
|
||||
}
|
||||
|
||||
// restore proxies on all libraries - as the refresh happens in random order, dependencies
|
||||
// are not necessarily resolved. This is done here.
|
||||
|
||||
for (std::vector<Library *>::iterator l = m_libs.begin (); l != m_libs.end (); ++l) {
|
||||
if (*l) {
|
||||
(*l)->refresh ();
|
||||
(*l)->layout ().restore_proxies ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
|
||||
#include "dbLibraryProxy.h"
|
||||
#include "dbColdProxy.h"
|
||||
#include "dbLibraryManager.h"
|
||||
#include "dbLibrary.h"
|
||||
#include "dbLayout.h"
|
||||
|
|
@ -187,25 +188,6 @@ LibraryProxy::get_layer_indices (db::Layout &layout, db::ImportLayerMapping *lay
|
|||
return m_layer_indices;
|
||||
}
|
||||
|
||||
class LibraryCellIndexMapper
|
||||
{
|
||||
public:
|
||||
LibraryCellIndexMapper (Layout &layout, Library *lib)
|
||||
: mp_lib (lib), mp_layout (&layout)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
cell_index_type operator() (cell_index_type cell_index_in_lib)
|
||||
{
|
||||
return mp_layout->get_lib_proxy (mp_lib, cell_index_in_lib);
|
||||
}
|
||||
|
||||
private:
|
||||
Library *mp_lib;
|
||||
Layout *mp_layout;
|
||||
};
|
||||
|
||||
void
|
||||
LibraryProxy::update (db::ImportLayerMapping *layer_mapping)
|
||||
{
|
||||
|
|
@ -215,29 +197,44 @@ LibraryProxy::update (db::ImportLayerMapping *layer_mapping)
|
|||
Library *lib = LibraryManager::instance ().lib (lib_id ());
|
||||
const db::Cell &source_cell = lib->layout ().cell (library_cell_index ());
|
||||
|
||||
db::ICplxTrans tr;
|
||||
bool need_transform = false;
|
||||
if (fabs (layout ()->dbu () - lib->layout ().dbu ()) > 1e-6) {
|
||||
need_transform = true;
|
||||
tr = db::ICplxTrans (lib->layout ().dbu () / layout ()->dbu ());
|
||||
}
|
||||
|
||||
clear_shapes ();
|
||||
clear_insts ();
|
||||
|
||||
for (unsigned int l = 0; l < lib->layout ().layers (); ++l) {
|
||||
if (layer_indices [l] >= 0) {
|
||||
shapes ((unsigned int) layer_indices [l]).assign_transformed (source_cell.shapes (l), tr);
|
||||
shapes ((unsigned int) layer_indices [l]).assign_transformed (source_cell.shapes (l), db::ICplxTrans (lib->layout ().dbu () / layout ()->dbu ()));
|
||||
}
|
||||
}
|
||||
|
||||
LibraryCellIndexMapper cell_index_mapper (*layout (), lib);
|
||||
for (Cell::const_iterator i = source_cell.begin (); ! i.at_end (); ++i) {
|
||||
|
||||
for (Cell::const_iterator inst = source_cell.begin (); !inst.at_end (); ++inst) {
|
||||
db::Instance new_inst = insert (*inst, cell_index_mapper);
|
||||
if (need_transform) {
|
||||
replace (new_inst, new_inst.cell_inst ().transformed_into (tr));
|
||||
db::CellInstArray inst = i->cell_inst ();
|
||||
|
||||
Library *real_lib = lib;
|
||||
cell_index_type real_cil = inst.object ().cell_index ();
|
||||
|
||||
// use the "final lib", so we refer to the actual lib instead
|
||||
// of building chains of lib references
|
||||
LibraryProxy *lp;
|
||||
while ((lp = dynamic_cast<LibraryProxy *> (&real_lib->layout ().cell (real_cil))) != 0) {
|
||||
real_cil = lp->library_cell_index ();
|
||||
real_lib = db::LibraryManager::instance ().lib (lp->lib_id ());
|
||||
}
|
||||
|
||||
inst.object ().cell_index (layout ()->get_lib_proxy (real_lib, real_cil));
|
||||
|
||||
ColdProxy *cp = dynamic_cast<ColdProxy *> (&real_lib->layout ().cell (real_cil));
|
||||
if (cp) {
|
||||
// The final item is a cold proxy ("<defunct>" cell) - treat it like
|
||||
// a library proxy as it may become one in the future, but replace it
|
||||
// by a cold proxy now.
|
||||
layout ()->create_cold_proxy_as (cp->context_info (), inst.object ().cell_index ());
|
||||
}
|
||||
|
||||
inst.transform_into (db::ICplxTrans (lib->layout ().dbu () / layout ()->dbu ()));
|
||||
|
||||
insert (inst);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue