mirror of https://github.com/KLayout/klayout.git
WIP: dynamic definition of macro categories (currently: drc, lvs)
This commit is contained in:
parent
ff3bc38aea
commit
30f774f055
|
|
@ -158,6 +158,11 @@ module DRC
|
|||
# Register the new interpreters
|
||||
DRCInterpreter::new(drc_recipe)
|
||||
DRCPlainTextInterpreter::new(drc_recipe)
|
||||
|
||||
# Creates a new macro category
|
||||
if RBA::Application::instance
|
||||
RBA::Application::instance.add_macro_category("drc", "DRC", [ "drc" ])
|
||||
end
|
||||
|
||||
end
|
||||
</text>
|
||||
|
|
|
|||
|
|
@ -87,6 +87,12 @@ static std::string version (C *)
|
|||
return C::version ();
|
||||
}
|
||||
|
||||
template <class C>
|
||||
static void add_macro_category (C *c, const std::string &name, const std::string &description, const std::vector<std::string> &folders)
|
||||
{
|
||||
c->add_macro_category (name, description, folders);
|
||||
}
|
||||
|
||||
template <class C>
|
||||
static gsi::Methods application_methods ()
|
||||
{
|
||||
|
|
@ -226,6 +232,12 @@ static gsi::Methods application_methods ()
|
|||
"@brief Returns the architecture string\n"
|
||||
"This method has been introduced in version 0.25."
|
||||
) +
|
||||
method_ext<C, const std::string &, const std::string &, const std::vector<std::string> &> ("add_macro_category", &add_macro_category<C>, gsi::arg ("name"), gsi::arg ("description"), gsi::arg ("folders"),
|
||||
"@brief Creates a new macro category\n"
|
||||
"Creating a new macro category is only possible during the autorun_early stage. "
|
||||
"The new macro category must correspond to an interpreter registered at the same stage.\n"
|
||||
"This method has been introduced in version 0.28."
|
||||
) +
|
||||
method<C *> ("instance", &C::instance,
|
||||
"@brief Return the singleton instance of the application\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -686,6 +686,22 @@ ApplicationBase::init_app ()
|
|||
|
||||
if (mc) {
|
||||
|
||||
// create the basic macro categories
|
||||
|
||||
if (ruby_interpreter ().available ()) {
|
||||
std::vector<std::string> folders;
|
||||
folders.push_back ("macros");
|
||||
folders.push_back ("ruby");
|
||||
mc->add_macro_category ("macros", "Ruby", folders);
|
||||
}
|
||||
|
||||
if (python_interpreter ().available ()) {
|
||||
std::vector<std::string> folders;
|
||||
folders.push_back ("pymacros");
|
||||
folders.push_back ("python");
|
||||
mc->add_macro_category ("pymacros", "Python", folders);
|
||||
}
|
||||
|
||||
mc->enable_implicit_macros (! m_no_macros);
|
||||
|
||||
// Add the global ruby modules as the first ones.
|
||||
|
|
@ -741,13 +757,29 @@ ApplicationBase::init_app ()
|
|||
}
|
||||
}
|
||||
|
||||
std::set<std::string> already_executed;
|
||||
|
||||
// run all early autorun macros
|
||||
lym::MacroCollection::root ().autorun_early ();
|
||||
lym::MacroCollection::root ().autorun_early (&already_executed);
|
||||
|
||||
// autorun_early may have added macro categories, so we need to call finish() again
|
||||
if (mc) {
|
||||
|
||||
mc->finish ();
|
||||
|
||||
// as this regenerates the macro collection, autorun_early is required again
|
||||
// note: this does no re-execute macros that have been executed already
|
||||
lym::MacroCollection::root ().autorun_early (&already_executed);
|
||||
|
||||
}
|
||||
|
||||
// rescan the folders because early autorun macros might have added
|
||||
// suffixes through the MacroInterpreter interface.
|
||||
lym::MacroCollection::root ().rescan ();
|
||||
|
||||
// and yet another autorun_early pass ..
|
||||
lym::MacroCollection::root ().autorun_early (&already_executed);
|
||||
|
||||
// creates the main window or plugin root as required
|
||||
setup ();
|
||||
|
||||
|
|
@ -785,6 +817,15 @@ ApplicationBase::init_app ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ApplicationBase::add_macro_category (const std::string &name, const std::string &description, const std::vector<std::string> &folders)
|
||||
{
|
||||
lay::MacroController *mc = lay::MacroController::instance ();
|
||||
if (mc) {
|
||||
mc->add_macro_category (name, description, folders);
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationBase::~ApplicationBase ()
|
||||
{
|
||||
tl::set_ui_exception_handlers (0, 0, 0);
|
||||
|
|
|
|||
|
|
@ -214,6 +214,13 @@ public:
|
|||
return *mp_python_interpreter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a new macro category
|
||||
*
|
||||
* This method is only effective when called during the autorun_early stage
|
||||
*/
|
||||
void add_macro_category (const std::string &name, const std::string &description, const std::vector<std::string> &folders);
|
||||
|
||||
/**
|
||||
* @brief Return true, if undo buffering is enabled
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -49,62 +49,27 @@ MacroController::MacroController ()
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
static lay::MacroController::MacroCategory ruby_cat ()
|
||||
void
|
||||
MacroController::add_macro_category (const std::string &name, const std::string &description, const std::vector<std::string> &folders)
|
||||
{
|
||||
lay::MacroController::MacroCategory cat;
|
||||
cat.name = "macros";
|
||||
cat.description = tl::to_string (QObject::tr ("Ruby"));
|
||||
cat.folders.push_back ("macros");
|
||||
cat.folders.push_back ("ruby");
|
||||
return cat;
|
||||
}
|
||||
|
||||
static lay::MacroController::MacroCategory python_cat ()
|
||||
{
|
||||
lay::MacroController::MacroCategory cat;
|
||||
cat.name = "pymacros";
|
||||
cat.description = tl::to_string (QObject::tr ("Python"));
|
||||
cat.folders.push_back ("pymacros");
|
||||
cat.folders.push_back ("python");
|
||||
return cat;
|
||||
}
|
||||
|
||||
static lay::MacroController::MacroCategory drc_cat ()
|
||||
{
|
||||
lay::MacroController::MacroCategory cat;
|
||||
cat.name = "drc";
|
||||
cat.description = tl::to_string (QObject::tr ("DRC"));
|
||||
cat.folders.push_back ("drc");
|
||||
return cat;
|
||||
}
|
||||
|
||||
static lay::MacroController::MacroCategory lvs_cat ()
|
||||
{
|
||||
lay::MacroController::MacroCategory cat;
|
||||
cat.name = "lvs";
|
||||
cat.description = tl::to_string (QObject::tr ("LVS"));
|
||||
cat.folders.push_back ("lvs");
|
||||
return cat;
|
||||
cat.name = name;
|
||||
cat.description = description;
|
||||
cat.folders = folders;
|
||||
m_macro_categories.push_back (cat);
|
||||
}
|
||||
|
||||
void
|
||||
MacroController::finish ()
|
||||
{
|
||||
lym::MacroCollection::root ().clear ();
|
||||
|
||||
// Scan built-in macros
|
||||
// These macros are always taken, even if there are no macros requested (they are required to
|
||||
// fully form the API).
|
||||
lym::MacroCollection::root ().add_folder (tl::to_string (QObject::tr ("Built-In")), ":/built-in-macros", "macros", true);
|
||||
lym::MacroCollection::root ().add_folder (tl::to_string (QObject::tr ("Built-In")), ":/built-in-pymacros", "pymacros", true);
|
||||
|
||||
// TODO: consider adding "drc" and "lvs" dynamically and allow more dynamic categories
|
||||
// We can do so if we first load the macros with the initial interpreters, then do autorun (which creates DSL interpreters) and then
|
||||
// register the remaining categories.
|
||||
|
||||
m_macro_categories.push_back (ruby_cat ());
|
||||
m_macro_categories.push_back (python_cat ());
|
||||
m_macro_categories.push_back (drc_cat ());
|
||||
m_macro_categories.push_back (lvs_cat ());
|
||||
|
||||
// scans the macros from techs and packages (this will allow autorun-early on them)
|
||||
// and updates m_external_paths
|
||||
sync_macro_sources ();
|
||||
|
|
|
|||
|
|
@ -147,10 +147,16 @@ public:
|
|||
|
||||
/**
|
||||
* @brief Loads the macros from the predefined paths and establishes the search paths
|
||||
* This method will also establish the macro categories.
|
||||
* This method can be called multiple times.
|
||||
*/
|
||||
void finish ();
|
||||
|
||||
/**
|
||||
* @brief Adds a new macro category
|
||||
* finish() needs to be called after adding a new category.
|
||||
*/
|
||||
void add_macro_category (const std::string &name, const std::string &description, const std::vector<std::string> &folders);
|
||||
|
||||
/**
|
||||
* @brief Adds a temporary macro
|
||||
*
|
||||
|
|
|
|||
|
|
@ -159,6 +159,11 @@ module LVS
|
|||
LVSInterpreter::new(lvs_recipe)
|
||||
LVSPlainTextInterpreter::new(lvs_recipe)
|
||||
|
||||
# Creates a new macro category
|
||||
if RBA::Application::instance
|
||||
RBA::Application::instance.add_macro_category("lvs", "LVS", [ "lvs" ])
|
||||
end
|
||||
|
||||
end
|
||||
</text>
|
||||
</klayout-macro>
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@
|
|||
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
namespace lym
|
||||
{
|
||||
|
|
@ -1065,6 +1067,11 @@ MacroCollection::MacroCollection ()
|
|||
}
|
||||
|
||||
MacroCollection::~MacroCollection ()
|
||||
{
|
||||
do_clear ();
|
||||
}
|
||||
|
||||
void MacroCollection::do_clear ()
|
||||
{
|
||||
for (iterator m = begin (); m != end (); ++m) {
|
||||
delete m->second;
|
||||
|
|
@ -1513,6 +1520,13 @@ void MacroCollection::scan (const std::string &path)
|
|||
}
|
||||
}
|
||||
|
||||
void MacroCollection::clear ()
|
||||
{
|
||||
begin_changes ();
|
||||
do_clear ();
|
||||
on_changed ();
|
||||
}
|
||||
|
||||
void MacroCollection::erase (lym::Macro *mp)
|
||||
{
|
||||
for (iterator m = m_macros.begin (); m != m_macros.end (); ++m) {
|
||||
|
|
@ -1861,30 +1875,42 @@ bool MacroCollection::has_autorun_early () const
|
|||
return has_autorun_for (*this, true);
|
||||
}
|
||||
|
||||
static void autorun_for (lym::MacroCollection &collection, bool early)
|
||||
static void autorun_for (lym::MacroCollection &collection, bool early, std::set<std::string> *executed_already)
|
||||
{
|
||||
for (lym::MacroCollection::child_iterator c = collection.begin_children (); c != collection.end_children (); ++c) {
|
||||
autorun_for (*c->second, early);
|
||||
autorun_for (*c->second, early, executed_already);
|
||||
}
|
||||
|
||||
for (lym::MacroCollection::iterator c = collection.begin (); c != collection.end (); ++c) {
|
||||
|
||||
if (c->second->can_run () && ((early && c->second->is_autorun_early ()) || (!early && c->second->is_autorun () && !c->second->is_autorun_early ()))) {
|
||||
BEGIN_PROTECTED_SILENT
|
||||
c->second->run ();
|
||||
c->second->install_doc ();
|
||||
END_PROTECTED_SILENT
|
||||
|
||||
if (!executed_already || executed_already->find (c->second->path ()) == executed_already->end ()) {
|
||||
|
||||
BEGIN_PROTECTED_SILENT
|
||||
c->second->run ();
|
||||
c->second->install_doc ();
|
||||
END_PROTECTED_SILENT
|
||||
|
||||
if (executed_already) {
|
||||
executed_already->insert (c->second->path ());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void MacroCollection::autorun ()
|
||||
void MacroCollection::autorun (std::set<std::string> *already_executed)
|
||||
{
|
||||
autorun_for (*this, false);
|
||||
autorun_for (*this, false, already_executed);
|
||||
}
|
||||
|
||||
void MacroCollection::autorun_early ()
|
||||
void MacroCollection::autorun_early (std::set<std::string> *already_executed)
|
||||
{
|
||||
autorun_for (*this, true);
|
||||
autorun_for (*this, true, already_executed);
|
||||
}
|
||||
|
||||
void MacroCollection::dump (int l)
|
||||
|
|
|
|||
|
|
@ -845,6 +845,12 @@ public:
|
|||
*/
|
||||
void add_unspecific (lym::Macro *m);
|
||||
|
||||
/**
|
||||
* @brief Empties the collection
|
||||
* Note: only the unspecific on_changed event is generated.
|
||||
*/
|
||||
void clear ();
|
||||
|
||||
/**
|
||||
* @brief Erases the given macro from the list
|
||||
*
|
||||
|
|
@ -995,7 +1001,7 @@ public:
|
|||
/**
|
||||
* @brief Runs all macros marked with auto-run
|
||||
*/
|
||||
void autorun ();
|
||||
void autorun (std::set<std::string> *already_executed = 0);
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the collection has an early autorun macro
|
||||
|
|
@ -1005,7 +1011,7 @@ public:
|
|||
/**
|
||||
* @brief Runs all macros marked with early auto-run
|
||||
*/
|
||||
void autorun_early ();
|
||||
void autorun_early (std::set<std::string> *already_executed = 0);
|
||||
|
||||
/**
|
||||
* @brief Redo the scan (will add new files or folders)
|
||||
|
|
@ -1129,6 +1135,8 @@ private:
|
|||
m_readonly = f;
|
||||
}
|
||||
|
||||
void do_clear ();
|
||||
|
||||
// no copying
|
||||
MacroCollection (const MacroCollection &d);
|
||||
MacroCollection &operator= (const MacroCollection &d);
|
||||
|
|
|
|||
Loading…
Reference in New Issue