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 "dbPCellDeclaration.h"
|
||||||
#include "dbPCellVariant.h"
|
#include "dbPCellVariant.h"
|
||||||
#include "dbLibraryManager.h"
|
#include "dbLibraryManager.h"
|
||||||
|
#include "tlTimer.h"
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
|
@ -166,14 +167,36 @@ Library::rename (const std::string &name)
|
||||||
void
|
void
|
||||||
Library::refresh ()
|
Library::refresh ()
|
||||||
{
|
{
|
||||||
// save a copy of the layout, so we can refer to it
|
refresh_without_restore ();
|
||||||
std::unique_ptr<db::Layout> org_layout (new db::Layout (layout ()));
|
|
||||||
|
|
||||||
std::string name = reload ();
|
// proxies need to be restored in a special case when a library has a proxy to itself.
|
||||||
rename (name);
|
// 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 ();
|
layout ().refresh ();
|
||||||
remap_to (this, org_layout.get ());
|
|
||||||
|
// re-register, potentially under the new name
|
||||||
|
db::LibraryManager::instance ().register_lib (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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<std::pair<db::LibraryProxy *, db::PCellVariant *> > pcells_to_map;
|
||||||
std::vector<db::LibraryProxy *> lib_cells_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 ()) {
|
if (lib_proxy && lib_proxy->lib_id () == get_id ()) {
|
||||||
|
|
||||||
db::Cell *lib_cell = &original_layout->cell (lib_proxy->library_cell_index ());
|
db::Cell *lib_cell = &original_layout->cell (lib_proxy->library_cell_index ());
|
||||||
|
|
|
||||||
|
|
@ -225,6 +225,13 @@ public:
|
||||||
*/
|
*/
|
||||||
void refresh ();
|
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
|
* @brief Renames the library
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -284,9 +284,27 @@ LibraryManager::lib_internal (lib_id_type id) const
|
||||||
void
|
void
|
||||||
LibraryManager::refresh_all ()
|
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) {
|
for (std::vector<Library *>::iterator l = m_libs.begin (); l != m_libs.end (); ++l) {
|
||||||
if (*l) {
|
if (*l) {
|
||||||
(*l)->refresh ();
|
(*l)->layout ().restore_proxies ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include "dbLibraryProxy.h"
|
#include "dbLibraryProxy.h"
|
||||||
|
#include "dbColdProxy.h"
|
||||||
#include "dbLibraryManager.h"
|
#include "dbLibraryManager.h"
|
||||||
#include "dbLibrary.h"
|
#include "dbLibrary.h"
|
||||||
#include "dbLayout.h"
|
#include "dbLayout.h"
|
||||||
|
|
@ -187,25 +188,6 @@ LibraryProxy::get_layer_indices (db::Layout &layout, db::ImportLayerMapping *lay
|
||||||
return m_layer_indices;
|
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
|
void
|
||||||
LibraryProxy::update (db::ImportLayerMapping *layer_mapping)
|
LibraryProxy::update (db::ImportLayerMapping *layer_mapping)
|
||||||
{
|
{
|
||||||
|
|
@ -215,29 +197,44 @@ LibraryProxy::update (db::ImportLayerMapping *layer_mapping)
|
||||||
Library *lib = LibraryManager::instance ().lib (lib_id ());
|
Library *lib = LibraryManager::instance ().lib (lib_id ());
|
||||||
const db::Cell &source_cell = lib->layout ().cell (library_cell_index ());
|
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_shapes ();
|
||||||
clear_insts ();
|
clear_insts ();
|
||||||
|
|
||||||
for (unsigned int l = 0; l < lib->layout ().layers (); ++l) {
|
for (unsigned int l = 0; l < lib->layout ().layers (); ++l) {
|
||||||
if (layer_indices [l] >= 0) {
|
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::CellInstArray inst = i->cell_inst ();
|
||||||
db::Instance new_inst = insert (*inst, cell_index_mapper);
|
|
||||||
if (need_transform) {
|
Library *real_lib = lib;
|
||||||
replace (new_inst, new_inst.cell_inst ().transformed_into (tr));
|
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