mirror of
https://github.com/KLayout/klayout.git
synced 2026-08-22 05:57:41 +02:00
WIP: some bug and performance fixes.
This commit is contained in:
@@ -51,16 +51,6 @@ initialize ()
|
|||||||
// merge the extensions to the main declaration
|
// merge the extensions to the main declaration
|
||||||
gsi::ClassBase::merge_declarations ();
|
gsi::ClassBase::merge_declarations ();
|
||||||
|
|
||||||
// do a full re-initialization - maybe merge_declarations modified existing classes too
|
|
||||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
|
||||||
// Initialize the method table once again after we have merged the declarations
|
|
||||||
// TODO: get rid of that const cast
|
|
||||||
(const_cast<gsi::ClassBase *> (&*c))->initialize ();
|
|
||||||
|
|
||||||
// there should be only main declarations since we merged
|
|
||||||
tl_assert (c->declaration () == &*c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// build or rebuild the variant user class table
|
// build or rebuild the variant user class table
|
||||||
// NOTE: as the variant classes are tied to the gsi::Class objects, we can rebuild the table
|
// NOTE: as the variant classes are tied to the gsi::Class objects, we can rebuild the table
|
||||||
// and will get the same pointers for the classes that have been there before
|
// and will get the same pointers for the classes that have been there before
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ namespace {
|
|||||||
static std::map<const std::type_info *, const ClassBase *, type_info_compare> s_ti_to_class;
|
static std::map<const std::type_info *, const ClassBase *, type_info_compare> s_ti_to_class;
|
||||||
|
|
||||||
ClassBase::ClassBase (const std::string &doc, const Methods &mm, bool do_register)
|
ClassBase::ClassBase (const std::string &doc, const Methods &mm, bool do_register)
|
||||||
: mp_base (0), mp_parent (0), m_doc (doc), m_methods (mm)
|
: m_initialized (false), mp_base (0), mp_parent (0), m_doc (doc), m_methods (mm)
|
||||||
{
|
{
|
||||||
if (do_register) {
|
if (do_register) {
|
||||||
|
|
||||||
@@ -79,13 +79,19 @@ ClassBase::~ClassBase ()
|
|||||||
void
|
void
|
||||||
ClassBase::set_parent (const ClassBase *p)
|
ClassBase::set_parent (const ClassBase *p)
|
||||||
{
|
{
|
||||||
mp_parent = p;
|
if (mp_parent != p) {
|
||||||
|
mp_parent = p;
|
||||||
|
m_initialized = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ClassBase::set_base (const ClassBase *b)
|
ClassBase::set_base (const ClassBase *b)
|
||||||
{
|
{
|
||||||
mp_base = b;
|
if (mp_base != b) {
|
||||||
|
mp_base = b;
|
||||||
|
m_initialized = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
@@ -100,6 +106,15 @@ ClassBase::qname () const
|
|||||||
return qn;
|
return qn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ClassBase::add_subclass (const ClassBase *cls)
|
||||||
|
{
|
||||||
|
// TODO: ugly const_cast hack
|
||||||
|
ClassBase *non_const_cls = const_cast<ClassBase *> (cls);
|
||||||
|
m_subclasses.push_back (non_const_cls);
|
||||||
|
m_initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ClassBase::add_child_class (const ClassBase *cls)
|
ClassBase::add_child_class (const ClassBase *cls)
|
||||||
{
|
{
|
||||||
@@ -109,6 +124,7 @@ ClassBase::add_child_class (const ClassBase *cls)
|
|||||||
// child classes inherit the module of their parent
|
// child classes inherit the module of their parent
|
||||||
non_const_cls->set_module (module ());
|
non_const_cls->set_module (module ());
|
||||||
m_child_classes.push_back (non_const_cls);
|
m_child_classes.push_back (non_const_cls);
|
||||||
|
m_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -395,7 +411,7 @@ ClassBase::merge_declarations ()
|
|||||||
|
|
||||||
// Consolidate the classes (merge, remove etc.)
|
// Consolidate the classes (merge, remove etc.)
|
||||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_new_classes (); c != gsi::ClassBase::end_new_classes (); ++c) {
|
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_new_classes (); c != gsi::ClassBase::end_new_classes (); ++c) {
|
||||||
if (! c->consolidate()) {
|
if (! c->consolidate ()) {
|
||||||
to_remove.push_back (&*c);
|
to_remove.push_back (&*c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -410,7 +426,7 @@ ClassBase::merge_declarations ()
|
|||||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_new_classes (); c != gsi::ClassBase::end_new_classes (); ++c) {
|
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_new_classes (); c != gsi::ClassBase::end_new_classes (); ++c) {
|
||||||
if (c->base ()) {
|
if (c->base ()) {
|
||||||
// TODO: ugly const_cast hack
|
// TODO: ugly const_cast hack
|
||||||
const_cast<gsi::ClassBase *> (c->base ())->m_subclasses.push_back (const_cast<gsi::ClassBase *> (c.operator-> ()));
|
const_cast<gsi::ClassBase *> (c->base ())->add_subclass (c.operator-> ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,11 +515,26 @@ ClassBase::merge_declarations ()
|
|||||||
mp_class_collection->push_back (non_const_decl);
|
mp_class_collection->push_back (non_const_decl);
|
||||||
}
|
}
|
||||||
mp_new_class_collection->clear ();
|
mp_new_class_collection->clear ();
|
||||||
|
|
||||||
|
// do a full re-initialization - maybe merge_declarations modified existing classes too
|
||||||
|
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||||
|
// Initialize the method table once again after we have merged the declarations
|
||||||
|
// TODO: get rid of that const cast
|
||||||
|
(const_cast<gsi::ClassBase *> (&*c))->initialize ();
|
||||||
|
|
||||||
|
// there should be only main declarations since we merged
|
||||||
|
tl_assert (c->declaration () == &*c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ClassBase::initialize ()
|
ClassBase::initialize ()
|
||||||
{
|
{
|
||||||
|
// don't initialize again
|
||||||
|
if (m_initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_methods.initialize ();
|
m_methods.initialize ();
|
||||||
|
|
||||||
m_constructors.clear ();
|
m_constructors.clear ();
|
||||||
@@ -519,11 +550,14 @@ ClassBase::initialize ()
|
|||||||
m_callbacks.push_back (*m);
|
m_callbacks.push_back (*m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ClassBase::add_method (MethodBase *method, bool /*base_class*/)
|
ClassBase::add_method (MethodBase *method, bool /*base_class*/)
|
||||||
{
|
{
|
||||||
|
m_initialized = false;
|
||||||
m_methods.add_method (method);
|
m_methods.add_method (method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -188,6 +188,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
void add_child_class (const ClassBase *cls);
|
void add_child_class (const ClassBase *cls);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Adds a subclass
|
||||||
|
* Subclasses are the ones that derive from us (opposite of base)
|
||||||
|
*/
|
||||||
|
void add_subclass (const ClassBase *cls);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Iterates all child classes (begin)
|
* @brief Iterates all child classes (begin)
|
||||||
*/
|
*/
|
||||||
@@ -595,6 +601,7 @@ protected:
|
|||||||
void set_base (const ClassBase *base);
|
void set_base (const ClassBase *base);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool m_initialized;
|
||||||
const ClassBase *mp_base, *mp_parent;
|
const ClassBase *mp_base, *mp_parent;
|
||||||
std::string m_doc;
|
std::string m_doc;
|
||||||
Methods m_methods;
|
Methods m_methods;
|
||||||
|
|||||||
+55
-24
@@ -2223,21 +2223,7 @@ PythonModule::PythonModule ()
|
|||||||
PythonModule::~PythonModule ()
|
PythonModule::~PythonModule ()
|
||||||
{
|
{
|
||||||
PYAObjectBase::clear_callbacks_cache ();
|
PYAObjectBase::clear_callbacks_cache ();
|
||||||
|
delete_module ();
|
||||||
while (!m_methods_heap.empty ()) {
|
|
||||||
delete m_methods_heap.back ();
|
|
||||||
m_methods_heap.pop_back ();
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!m_getseters_heap.empty ()) {
|
|
||||||
delete m_getseters_heap.back ();
|
|
||||||
m_getseters_heap.pop_back ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mp_mod_def) {
|
|
||||||
delete[] mp_mod_def;
|
|
||||||
mp_mod_def = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
@@ -2256,6 +2242,22 @@ void
|
|||||||
PythonModule::delete_module ()
|
PythonModule::delete_module ()
|
||||||
{
|
{
|
||||||
mp_module = PythonRef ();
|
mp_module = PythonRef ();
|
||||||
|
mp_base_class = PythonRef ();
|
||||||
|
|
||||||
|
while (!m_methods_heap.empty ()) {
|
||||||
|
delete m_methods_heap.back ();
|
||||||
|
m_methods_heap.pop_back ();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!m_getseters_heap.empty ()) {
|
||||||
|
delete m_getseters_heap.back ();
|
||||||
|
m_getseters_heap.pop_back ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mp_mod_def) {
|
||||||
|
delete[] mp_mod_def;
|
||||||
|
mp_mod_def = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2283,12 +2285,13 @@ PythonModule::init (const char *mod_name, const char *description)
|
|||||||
module_methods
|
module_methods
|
||||||
};
|
};
|
||||||
|
|
||||||
tl_assert (mp_mod_def == 0);
|
tl_assert (! mp_mod_def);
|
||||||
|
|
||||||
// prepare a persistent structure with the module definition
|
// prepare a persistent structure with the module definition
|
||||||
// and pass this one to PyModule_Create
|
// and pass this one to PyModule_Create
|
||||||
mp_mod_def = new char[sizeof (PyModuleDef)];
|
mp_mod_def = new char[sizeof (PyModuleDef)];
|
||||||
memcpy ((void *) mp_mod_def, (const void *) &mod_def, sizeof (PyModuleDef));
|
memcpy ((void *) mp_mod_def, (const void *) &mod_def, sizeof (PyModuleDef));
|
||||||
|
|
||||||
module = PyModule_Create ((PyModuleDef *) mp_mod_def);
|
module = PyModule_Create ((PyModuleDef *) mp_mod_def);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -2350,6 +2353,39 @@ PythonModule::python_doc (const gsi::MethodBase *method)
|
|||||||
void
|
void
|
||||||
PythonModule::make_classes (const char *mod_name)
|
PythonModule::make_classes (const char *mod_name)
|
||||||
{
|
{
|
||||||
|
// Check whether the new classes are self-contained within this module
|
||||||
|
if (mod_name) {
|
||||||
|
|
||||||
|
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||||
|
|
||||||
|
if (c->module () != mod_name) {
|
||||||
|
// don't handle classes outside this module
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_rev_cls_map.find (&*c) != m_rev_cls_map.end ()) {
|
||||||
|
// don't handle classes twice
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All child classes must originate from this module or be known already
|
||||||
|
for (tl::weak_collection<gsi::ClassBase>::const_iterator cc = c->begin_child_classes (); cc != c->end_child_classes (); ++cc) {
|
||||||
|
if (m_rev_cls_map.find (cc->declaration ()) == m_rev_cls_map.end ()
|
||||||
|
&& cc->module () != mod_name) {
|
||||||
|
throw tl::Exception (tl::sprintf (tl::to_string (QObject::tr ("Class %s from module %s depends on %s.%s (try 'import klayout.%s' before 'import klayout.%s')")), c->name (), mod_name, cc->module (), cc->name (), cc->module (), mod_name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same for base class
|
||||||
|
if (c->base () && m_rev_cls_map.find (c->base ()) == m_rev_cls_map.end ()
|
||||||
|
&& c->base ()->module () != mod_name) {
|
||||||
|
throw tl::Exception (tl::sprintf (tl::to_string (QObject::tr ("Class %s from module %s depends on %s.%s (try 'import klayout.%s' before 'import klayout.%s')")), c->name (), mod_name, c->base ()->module (), c->base ()->name (), c->base ()->module (), mod_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
PyObject *module = mp_module.get ();
|
PyObject *module = mp_module.get ();
|
||||||
|
|
||||||
// Prepare an __all__ index for the module
|
// Prepare an __all__ index for the module
|
||||||
@@ -2426,9 +2462,6 @@ PythonModule::make_classes (const char *mod_name)
|
|||||||
for (tl::weak_collection<gsi::ClassBase>::const_iterator cc = c->begin_child_classes (); cc != c->end_child_classes (); ++cc) {
|
for (tl::weak_collection<gsi::ClassBase>::const_iterator cc = c->begin_child_classes (); cc != c->end_child_classes (); ++cc) {
|
||||||
tl_assert (cc->declaration () != 0);
|
tl_assert (cc->declaration () != 0);
|
||||||
if (m_rev_cls_map.find (cc->declaration ()) == m_rev_cls_map.end ()) {
|
if (m_rev_cls_map.find (cc->declaration ()) == m_rev_cls_map.end ()) {
|
||||||
if (mod_name && cc->module () != mod_name) {
|
|
||||||
throw tl::Exception (tl::sprintf (tl::to_string (QObject::tr ("Class %s from module %s depends on %s.%s (try 'import klayout.%s' before 'import klayout.%s')")), c->name (), mod_name, cc->module (), cc->name (), cc->module (), mod_name));
|
|
||||||
}
|
|
||||||
all_children_available = false;
|
all_children_available = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2440,9 +2473,6 @@ PythonModule::make_classes (const char *mod_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (c->base () && m_rev_cls_map.find (c->base ()) == m_rev_cls_map.end ()) {
|
if (c->base () && m_rev_cls_map.find (c->base ()) == m_rev_cls_map.end ()) {
|
||||||
if (mod_name && c->base ()->module () != mod_name) {
|
|
||||||
throw tl::Exception (tl::sprintf (tl::to_string (QObject::tr ("Class %s from module %s depends on %s.%s (try 'import klayout.%s' before 'import klayout.%s')")), c->name (), mod_name, c->base ()->module (), c->base ()->name (), c->base ()->module (), mod_name));
|
|
||||||
}
|
|
||||||
// can't produce this class yet. The base class needs to be handled first.
|
// can't produce this class yet. The base class needs to be handled first.
|
||||||
more_classes = true;
|
more_classes = true;
|
||||||
continue;
|
continue;
|
||||||
@@ -2478,8 +2508,9 @@ PythonModule::make_classes (const char *mod_name)
|
|||||||
PyList_Append (all_list.get (), PythonRef (c2python (c->name ())).get ());
|
PyList_Append (all_list.get (), PythonRef (c2python (c->name ())).get ());
|
||||||
PyModule_AddObject (module, c->name ().c_str (), (PyObject *) type);
|
PyModule_AddObject (module, c->name ().c_str (), (PyObject *) type);
|
||||||
|
|
||||||
m_cls_map.insert (std::make_pair (type, &*c));
|
// NOTE: we force the new values as there may be value from a previous (failed) attempt
|
||||||
m_rev_cls_map.insert (std::make_pair (&*c, type));
|
m_cls_map[type] = c.operator-> ();
|
||||||
|
m_rev_cls_map[c.operator-> ()] = type;
|
||||||
|
|
||||||
// Create the sub-class attributes
|
// Create the sub-class attributes
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user