mirror of https://github.com/KLayout/klayout.git
Merge remote-tracking branch 'origin/master' into master-mac-qt6
This commit is contained in:
commit
83551af9e4
|
|
@ -1261,13 +1261,20 @@ template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, d
|
|||
template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, db::Edge, db::Polygon>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, db::Edge, db::Edge>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::TextRef, db::TextRef>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::TextRef, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::TextRef, db::PolygonRef, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::TextRef, db::PolygonRef, db::TextRef>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::Edge, db::PolygonRef>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::Edge, db::Edge>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::PolygonRef, db::Edge>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::PolygonRef, db::PolygonRef, db::EdgePair>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, db::Polygon, db::EdgePair>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::Polygon, db::Polygon, db::Edge>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::Edge, db::Edge, db::Edge>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::Edge, db::PolygonRef, db::Edge>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::Edge, db::Edge, db::EdgePair>;
|
||||
template class DB_PUBLIC local_processor_context_computation_task<db::Edge, db::PolygonRef, db::PolygonRef>;
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// LocalProcessorResultComputationTask implementation
|
||||
|
|
|
|||
|
|
@ -1466,9 +1466,6 @@ PartialService::transform_selection (const db::DTrans &move_trans)
|
|||
|
||||
// then move all instances.
|
||||
|
||||
// TODO: DTrans should have a ctor that takes a vector
|
||||
db::DTrans move_trans_inst = db::DTrans (db::DVector () + lay::snap_angle (m_current - m_start, move_ac ()));
|
||||
|
||||
// sort the selected objects (the instances) by the cell they are in
|
||||
// The key is a pair: cell_index, cv_index
|
||||
std::map <std::pair <db::cell_index_type, unsigned int>, std::vector <partial_objects::const_iterator> > insts_by_cell;
|
||||
|
|
@ -1494,7 +1491,7 @@ PartialService::transform_selection (const db::DTrans &move_trans)
|
|||
if (tv_list && ! tv_list->empty ()) {
|
||||
|
||||
db::CplxTrans tt = (*tv_list) [0] * db::CplxTrans (cv->layout ().dbu ()) * cv.context_trans ();
|
||||
db::ICplxTrans move_trans_dbu (tt.inverted () * db::DCplxTrans (move_trans_inst) * tt);
|
||||
db::ICplxTrans move_trans_dbu (tt.inverted () * db::DCplxTrans (move_trans) * tt);
|
||||
|
||||
std::sort (insts_to_transform.begin (), insts_to_transform.end ());
|
||||
std::vector <std::pair <db::Instance, db::ICplxTrans> >::const_iterator unique_end = std::unique (insts_to_transform.begin (), insts_to_transform.end ());
|
||||
|
|
|
|||
|
|
@ -49,9 +49,11 @@ namespace {
|
|||
|
||||
// TODO: thread-safe? Unlikely that multiple threads access this member -
|
||||
// we do a initial scan and after this no more write access here.
|
||||
typedef std::map<const std::type_info *, const ClassBase *, type_info_compare> ti_to_class_map_t;
|
||||
static ti_to_class_map_t *sp_ti_to_class = 0;
|
||||
// NOTE: MacOS/clang seems to have some issue with RTTI across shared objects. This map provides a name-based fallback
|
||||
static std::vector<const ClassBase *> *sp_classes = 0;
|
||||
typedef std::map<const ClassBase *, size_t> class_to_index_map_t;
|
||||
static class_to_index_map_t *sp_class_to_index = 0;
|
||||
typedef std::map<const std::type_info *, size_t> ti_to_class_map_t;
|
||||
static ti_to_class_map_t *sp_ti_to_class_index = 0;
|
||||
typedef std::map<std::string, const ClassBase *> tname_to_class_map_t;
|
||||
static tname_to_class_map_t *sp_tname_to_class = 0;
|
||||
|
||||
|
|
@ -67,9 +69,17 @@ ClassBase::ClassBase (const std::string &doc, const Methods &mm, bool do_registe
|
|||
mp_new_class_collection->push_back (this);
|
||||
|
||||
// invalidate the "typeinfo to class" map
|
||||
if (sp_ti_to_class) {
|
||||
delete sp_ti_to_class;
|
||||
sp_ti_to_class = 0;
|
||||
if (sp_classes) {
|
||||
delete sp_classes;
|
||||
sp_classes = 0;
|
||||
}
|
||||
if (sp_class_to_index) {
|
||||
delete sp_class_to_index;
|
||||
sp_class_to_index = 0;
|
||||
}
|
||||
if (sp_ti_to_class_index) {
|
||||
delete sp_ti_to_class_index;
|
||||
sp_ti_to_class_index = 0;
|
||||
}
|
||||
if (sp_tname_to_class) {
|
||||
delete sp_tname_to_class;
|
||||
|
|
@ -826,14 +836,25 @@ static void add_class_to_map (const gsi::ClassBase *c)
|
|||
ti = &c->type ();
|
||||
}
|
||||
|
||||
if (! sp_ti_to_class) {
|
||||
sp_ti_to_class = new ti_to_class_map_t ();
|
||||
if (! sp_classes) {
|
||||
sp_classes = new std::vector<const ClassBase *> ();
|
||||
}
|
||||
if (! sp_class_to_index) {
|
||||
sp_class_to_index = new class_to_index_map_t ();
|
||||
}
|
||||
if (! sp_ti_to_class_index) {
|
||||
sp_ti_to_class_index = new ti_to_class_map_t ();
|
||||
}
|
||||
if (! sp_tname_to_class) {
|
||||
sp_tname_to_class = new tname_to_class_map_t ();
|
||||
}
|
||||
|
||||
if (!sp_ti_to_class->insert (std::make_pair (ti, c)).second) {
|
||||
auto c2i = sp_class_to_index->insert (std::make_pair (c, sp_classes->size ())).first;
|
||||
if (c2i->second >= sp_classes->size ()) {
|
||||
sp_classes->push_back (c);
|
||||
}
|
||||
|
||||
if (!sp_ti_to_class_index->insert (std::make_pair (ti, c2i->second)).second) {
|
||||
// Duplicate registration of this class
|
||||
tl::error << "Duplicate registration of class " << c->name () << " (type " << ti->name () << ")";
|
||||
tl_assert (false);
|
||||
|
|
@ -844,27 +865,27 @@ static void add_class_to_map (const gsi::ClassBase *c)
|
|||
|
||||
const ClassBase *class_by_typeinfo_no_assert (const std::type_info &ti)
|
||||
{
|
||||
if (! sp_ti_to_class || sp_ti_to_class->empty ()) {
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
if (! sp_ti_to_class_index || sp_ti_to_class_index->empty ()) {
|
||||
for (auto c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
add_class_to_map (c.operator-> ());
|
||||
}
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_new_classes (); c != gsi::ClassBase::end_new_classes (); ++c) {
|
||||
for (auto c = gsi::ClassBase::begin_new_classes (); c != gsi::ClassBase::end_new_classes (); ++c) {
|
||||
add_class_to_map (c.operator-> ());
|
||||
}
|
||||
}
|
||||
|
||||
if (! sp_ti_to_class) {
|
||||
if (! sp_ti_to_class_index) {
|
||||
return 0;
|
||||
} else {
|
||||
ti_to_class_map_t::const_iterator c = sp_ti_to_class->find (&ti);
|
||||
if (c != sp_ti_to_class->end ()) {
|
||||
return c->second;
|
||||
auto c = sp_ti_to_class_index->find (&ti);
|
||||
if (c != sp_ti_to_class_index->end ()) {
|
||||
return sp_classes->operator[] (c->second);
|
||||
} else {
|
||||
// try name lookup
|
||||
tname_to_class_map_t::const_iterator cn = sp_tname_to_class->find (std::string (ti.name ()));
|
||||
auto cn = sp_tname_to_class->find (std::string (ti.name ()));
|
||||
if (cn != sp_tname_to_class->end ()) {
|
||||
// we can use this typeinfo as alias
|
||||
sp_ti_to_class->insert (std::make_pair (&ti, cn->second));
|
||||
sp_ti_to_class_index->insert (std::make_pair (&ti, sp_class_to_index->operator[] (cn->second)));
|
||||
return cn->second;
|
||||
} else {
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -674,16 +674,24 @@ BrowserPanel::loadResource (int type, const QUrl &url)
|
|||
{
|
||||
if (type == QTextDocument::ImageResource) {
|
||||
|
||||
BEGIN_PROTECTED
|
||||
return QVariant (mp_source->get_image (tl::to_string (url.toString ())));
|
||||
END_PROTECTED
|
||||
try {
|
||||
return QVariant (mp_source->get_image (tl::to_string (url.toString ())));
|
||||
} catch (tl::Exception &ex) {
|
||||
tl::error << ex.msg ();
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
return QVariant ();
|
||||
|
||||
} else if (type == QTextDocument::StyleSheetResource) {
|
||||
|
||||
BEGIN_PROTECTED
|
||||
return QVariant (tl::to_qstring (mp_source->get_css (tl::to_string (url.toString ()))));
|
||||
END_PROTECTED
|
||||
try {
|
||||
return QVariant (tl::to_qstring (mp_source->get_css (tl::to_string (url.toString ()))));
|
||||
} catch (tl::Exception &ex) {
|
||||
tl::error << ex.msg ();
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
return QVariant ();
|
||||
|
||||
} else if (type != QTextDocument::HtmlResource) {
|
||||
|
|
@ -707,7 +715,7 @@ BrowserPanel::loadResource (int type, const QUrl &url)
|
|||
// (normal) override cursor.
|
||||
QApplication::setOverrideCursor (QCursor (Qt::ArrowCursor));
|
||||
|
||||
BEGIN_PROTECTED
|
||||
try {
|
||||
|
||||
std::string u = tl::to_string (url.toString ());
|
||||
std::string s;
|
||||
|
|
@ -756,7 +764,10 @@ BrowserPanel::loadResource (int type, const QUrl &url)
|
|||
// push the outline
|
||||
set_outline (ol);
|
||||
|
||||
END_PROTECTED
|
||||
} catch (tl::Exception &ex) {
|
||||
tl::error << ex.msg ();
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
QApplication::restoreOverrideCursor ();
|
||||
|
||||
|
|
|
|||
|
|
@ -144,22 +144,25 @@ struct VariantUserClassTableKey
|
|||
if (is_const != k.is_const) {
|
||||
return is_const < k.is_const;
|
||||
}
|
||||
if (*type != *k.type) {
|
||||
return type->before (*k.type);
|
||||
if (type != k.type) {
|
||||
return type < k.type;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator== (const VariantUserClassTableKey &k) const
|
||||
{
|
||||
return is_const == k.is_const && *type == *k.type;
|
||||
return is_const == k.is_const && type == k.type;
|
||||
}
|
||||
|
||||
const std::type_info *type;
|
||||
bool is_const;
|
||||
};
|
||||
|
||||
static std::map<VariantUserClassTableKey, const tl::VariantUserClassBase *> *sp_class_table = 0;
|
||||
static std::vector<const VariantUserClassBase *> *sp_classes = 0;
|
||||
static std::map<const VariantUserClassBase *, size_t> *sp_class_to_index = 0;
|
||||
static std::map<std::pair<std::string, bool>, size_t> *sp_class_index_by_name = 0;
|
||||
static std::map<VariantUserClassTableKey, size_t> *sp_class_table = 0;
|
||||
static std::map <std::string, const VariantUserClassBase *> s_user_type_by_name;
|
||||
|
||||
void
|
||||
|
|
@ -191,7 +194,7 @@ VariantUserClassBase::find_cls_by_name (const std::string &name)
|
|||
{
|
||||
tl_assert (! s_user_type_by_name.empty ());
|
||||
|
||||
std::map <std::string, const VariantUserClassBase *>::const_iterator s = s_user_type_by_name.find (tl::to_lower_case (name));
|
||||
auto s = s_user_type_by_name.find (tl::to_lower_case (name));
|
||||
if (s == s_user_type_by_name.end ()) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -199,34 +202,100 @@ VariantUserClassBase::find_cls_by_name (const std::string &name)
|
|||
return s->second;
|
||||
}
|
||||
|
||||
// type-info based interface
|
||||
|
||||
const tl::VariantUserClassBase *VariantUserClassBase::instance (const std::type_info &type, bool is_const)
|
||||
{
|
||||
tl_assert (sp_class_table != 0);
|
||||
std::map<VariantUserClassTableKey, const tl::VariantUserClassBase *>::const_iterator c = sp_class_table->find (VariantUserClassTableKey (type, is_const));
|
||||
tl_assert (c != sp_class_table->end ());
|
||||
return c->second;
|
||||
|
||||
const tl::VariantUserClassBase *inst = 0;
|
||||
|
||||
auto c = sp_class_table->find (VariantUserClassTableKey (type, is_const));
|
||||
if (c == sp_class_table->end ()) {
|
||||
|
||||
// fallback: lookup by name and update if required - sometimes, there may be two different type info objects for the same thing
|
||||
auto c2i = sp_class_index_by_name->find (std::make_pair (std::string (type.name ()), is_const));
|
||||
tl_assert (c2i != sp_class_index_by_name->end ());
|
||||
sp_class_table->insert (std::make_pair (VariantUserClassTableKey (type, is_const), c2i->second));
|
||||
inst = sp_classes->operator[] (c2i->second);
|
||||
|
||||
} else {
|
||||
inst = sp_classes->operator[] (c->second);
|
||||
}
|
||||
|
||||
tl_assert (inst != 0);
|
||||
return inst;
|
||||
}
|
||||
|
||||
void VariantUserClassBase::register_instance (const tl::VariantUserClassBase *inst, const std::type_info &type, bool is_const)
|
||||
{
|
||||
if (! sp_class_table) {
|
||||
sp_class_table = new std::map<VariantUserClassTableKey, const tl::VariantUserClassBase *> ();
|
||||
sp_class_table = new std::map<VariantUserClassTableKey, size_t> ();
|
||||
}
|
||||
(*sp_class_table)[VariantUserClassTableKey (type, is_const)] = inst;
|
||||
if (! sp_classes) {
|
||||
sp_classes = new std::vector<const tl::VariantUserClassBase *> ();
|
||||
}
|
||||
if (! sp_class_index_by_name) {
|
||||
sp_class_index_by_name = new std::map<std::pair<std::string, bool>, size_t> ();
|
||||
}
|
||||
if (! sp_class_to_index) {
|
||||
sp_class_to_index = new std::map<const VariantUserClassBase *, size_t> ();
|
||||
}
|
||||
|
||||
size_t index = sp_class_to_index->insert (std::make_pair (inst, sp_classes->size ())).first->second;
|
||||
if (index == sp_classes->size ()) {
|
||||
sp_classes->push_back (inst);
|
||||
}
|
||||
|
||||
(*sp_class_table)[VariantUserClassTableKey (type, is_const)] = index;
|
||||
(*sp_class_index_by_name) [std::make_pair (std::string (type.name ()), is_const)] = index;
|
||||
}
|
||||
|
||||
void VariantUserClassBase::unregister_instance (const tl::VariantUserClassBase *inst, const std::type_info &type, bool is_const)
|
||||
{
|
||||
if (sp_class_table) {
|
||||
std::map<VariantUserClassTableKey, const tl::VariantUserClassBase *>::iterator c = sp_class_table->find (VariantUserClassTableKey (type, is_const));
|
||||
if (c != sp_class_table->end () && c->second == inst) {
|
||||
auto c = sp_class_table->find (VariantUserClassTableKey (type, is_const));
|
||||
if (c != sp_class_table->end ()) {
|
||||
sp_class_table->erase (c);
|
||||
if (sp_classes) {
|
||||
sp_classes->operator[] (c->second) = 0;
|
||||
while (!sp_classes->empty () && sp_classes->back () == 0) {
|
||||
sp_classes->pop_back ();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sp_class_table->empty ()) {
|
||||
delete sp_class_table;
|
||||
sp_class_table = 0;
|
||||
}
|
||||
|
||||
if (sp_class_index_by_name) {
|
||||
auto cn = sp_class_index_by_name->find (std::make_pair (std::string (type.name ()), is_const));
|
||||
if (cn != sp_class_index_by_name->end ()) {
|
||||
sp_class_index_by_name->erase (cn);
|
||||
}
|
||||
}
|
||||
|
||||
if (sp_class_to_index) {
|
||||
sp_class_to_index->erase (inst);
|
||||
}
|
||||
|
||||
if (sp_class_table && sp_class_table->empty ()) {
|
||||
delete sp_class_table;
|
||||
sp_class_table = 0;
|
||||
}
|
||||
|
||||
if (sp_classes && sp_classes->empty ()) {
|
||||
delete sp_classes;
|
||||
sp_classes = 0;
|
||||
}
|
||||
|
||||
if (sp_class_index_by_name && sp_class_index_by_name->empty ()) {
|
||||
delete sp_class_index_by_name;
|
||||
sp_class_index_by_name = 0;
|
||||
}
|
||||
|
||||
if (sp_class_to_index && sp_class_to_index->empty ()) {
|
||||
delete sp_class_to_index;
|
||||
sp_class_to_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in New Issue