Skip to content

Commit

Permalink
Fixed #21 (Autorun(-early) doesn't seem to run when lym files are ins…
Browse files Browse the repository at this point in the history
…ide a package)
  • Loading branch information
klayoutmatthias committed Dec 2, 2017
1 parent 54a3735 commit 1bb662b
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 95 deletions.
2 changes: 1 addition & 1 deletion src/lay/lay/layApplication.cc
Expand Up @@ -773,7 +773,7 @@ Application::Application (int &argc, char **argv, bool non_ui_mode)
}

// Actually load the macros and/or establish the search path
mc->finish (! m_no_macros);
mc->finish ();

}

Expand Down
207 changes: 116 additions & 91 deletions src/lay/lay/layMacroController.cc
Expand Up @@ -80,7 +80,7 @@ static lay::MacroController::MacroCategory drc_cat ()
}

void
MacroController::finish (bool load)
MacroController::finish ()
{
// Scan built-in macros
// These macros are always taken, even if there are no macros requested (they are required to
Expand All @@ -96,10 +96,14 @@ MacroController::finish (bool load)
m_macro_categories.push_back (python_cat ());
m_macro_categories.push_back (drc_cat ());

// scans the macros from techs and packages (this will allow autorun-early on them)
// and updates m_external_paths
sync_macro_sources ();

// Scan for macros and set interpreter path
for (std::vector <InternalPathDescriptor>::const_iterator p = m_internal_paths.begin (); p != m_internal_paths.end (); ++p) {

if (load) {
if (! m_no_implicit_macros) {

for (size_t c = 0; c < m_macro_categories.size (); ++c) {

Expand Down Expand Up @@ -137,6 +141,19 @@ MacroController::finish (bool load)
}

}


// Scan for macros in packages and techs

if (! m_no_implicit_macros) {
for (std::vector <ExternalPathDescriptor>::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) {
lym::MacroCollection::root ().add_folder (p->description, p->path, p->cat, p->readonly);
}
}

// Set the interpreter path to packages too

sync_package_paths ();
}

void
Expand Down Expand Up @@ -377,10 +394,106 @@ void
MacroController::sync_implicit_macros (bool ask_before_autorun)
{
if (m_no_implicit_macros) {

sync_macro_sources ();
sync_package_paths ();
return;

} else {

// determine the paths currently in use
std::map<std::string, const ExternalPathDescriptor *> prev_folders_by_path;
for (std::vector<ExternalPathDescriptor>::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) {
prev_folders_by_path.insert (std::make_pair (p->path, p.operator-> ()));
}

// gets the external paths (tech, packages) into m_external_paths
sync_macro_sources ();

// delete macro collections which are no longer required or update description

std::vector<lym::MacroCollection *> folders_to_delete;

// determine the paths that will be in use
std::map<std::string, const ExternalPathDescriptor *> new_folders_by_path;
for (std::vector<ExternalPathDescriptor>::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) {
new_folders_by_path.insert (std::make_pair (p->path, p.operator-> ()));
}

lym::MacroCollection *root = &lym::MacroCollection::root ();

for (lym::MacroCollection::child_iterator m = root->begin_children (); m != root->end_children (); ++m) {
if (m->second->virtual_mode () == lym::MacroCollection::TechFolder ||
m->second->virtual_mode () == lym::MacroCollection::SaltFolder) {
std::map<std::string, const ExternalPathDescriptor *>::const_iterator u = new_folders_by_path.find (m->second->path ());
if (u == new_folders_by_path.end ()) {
// no longer used
folders_to_delete.push_back (m->second);
} else {
m->second->set_description (u->second->description);
}
}
}

for (std::vector<lym::MacroCollection *>::iterator m = folders_to_delete.begin (); m != folders_to_delete.end (); ++m) {
if (tl::verbosity () >= 20) {
tl::info << "Removing macro folder " << (*m)->path () << ", category '" << (*m)->category () << "' because no longer in use";
}
root->erase (*m);
}

// sync the search paths with the packages
sync_package_paths ();

// add new folders
std::vector<lym::MacroCollection *> new_folders;

for (std::vector<ExternalPathDescriptor>::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) {

if (prev_folders_by_path.find (p->path) != prev_folders_by_path.end ()) {
continue;
}

if (tl::verbosity () >= 20) {
tl::info << "Adding macro folder " << p->path << ", category '" << p->cat << "' for '" << p->description << "'";
}

// Add the folder. Note: it may happen that a macro folder for the tech specific macros already exists in
// a non-tech context.
// In that case, the add_folder method will return 0.

// TODO: is it wise to make this writeable?
lym::MacroCollection *mc = lym::MacroCollection::root ().add_folder (p->description, p->path, p->cat, p->readonly);
if (mc) {
mc->set_virtual_mode (p->type);
new_folders.push_back (mc);
}

}

{
// This prevents the message dialog below to issue deferred methods
tl::NoDeferredMethods silent;

bool has_autorun = false;
for (std::vector<lym::MacroCollection *>::const_iterator m = new_folders.begin (); m != new_folders.end () && ! has_autorun; ++m) {
has_autorun = (*m)->has_autorun ();
}

if (has_autorun) {
if (! ask_before_autorun || QMessageBox::question (mp_mw, QObject::tr ("Run Macros"), QObject::tr ("Some macros associated with new items are configured to run automatically.\n\nChoose 'Yes' to run these macros now. Choose 'No' to not run them."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
for (std::vector<lym::MacroCollection *>::const_iterator m = new_folders.begin (); m != new_folders.end (); ++m) {
(*m)->autorun ();
}
}
}
}

}
}

void
MacroController::sync_macro_sources ()
{
std::vector<ExternalPathDescriptor> external_paths;

// Add additional places where the technologies define some macros
Expand Down Expand Up @@ -480,96 +593,8 @@ MacroController::sync_implicit_macros (bool ask_before_autorun)

}

// delete macro collections which are no longer required or update description

std::vector<lym::MacroCollection *> folders_to_delete;

// determine the paths that will be in use
std::map<std::string, const ExternalPathDescriptor *> new_folders_by_path;
for (std::vector<ExternalPathDescriptor>::const_iterator p = external_paths.begin (); p != external_paths.end (); ++p) {
new_folders_by_path.insert (std::make_pair (p->path, p.operator-> ()));
}

// determine the paths currently in use
std::map<std::string, const ExternalPathDescriptor *> prev_folders_by_path;
for (std::vector<ExternalPathDescriptor>::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) {
prev_folders_by_path.insert (std::make_pair (p->path, p.operator-> ()));
}

lym::MacroCollection *root = &lym::MacroCollection::root ();

for (lym::MacroCollection::child_iterator m = root->begin_children (); m != root->end_children (); ++m) {
if (m->second->virtual_mode () == lym::MacroCollection::TechFolder ||
m->second->virtual_mode () == lym::MacroCollection::SaltFolder) {
std::map<std::string, const ExternalPathDescriptor *>::const_iterator u = new_folders_by_path.find (m->second->path ());
if (u == new_folders_by_path.end ()) {
// no longer used
folders_to_delete.push_back (m->second);
} else {
m->second->set_description (u->second->description);
}
}
}

for (std::vector<lym::MacroCollection *>::iterator m = folders_to_delete.begin (); m != folders_to_delete.end (); ++m) {
if (tl::verbosity () >= 20) {
tl::info << "Removing macro folder " << (*m)->path () << ", category '" << (*m)->category () << "' because no longer in use";
}
root->erase (*m);
}

// sync the search paths with the packages
sync_package_paths ();

// store new paths
m_external_paths = external_paths;

// add new folders

std::vector<lym::MacroCollection *> new_folders;

for (std::vector<ExternalPathDescriptor>::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) {

if (prev_folders_by_path.find (p->path) != prev_folders_by_path.end ()) {
continue;
}

if (tl::verbosity () >= 20) {
tl::info << "Adding macro folder " << p->path << ", category '" << p->cat << "' for '" << p->description << "'";
}

// Add the folder. Note: it may happen that a macro folder for the tech specific macros already exists in
// a non-tech context.
// In that case, the add_folder method will return 0.

// TODO: is it wise to make this writeable?
lym::MacroCollection *mc = lym::MacroCollection::root ().add_folder (p->description, p->path, p->cat, p->readonly);
if (mc) {
mc->set_virtual_mode (p->type);
new_folders.push_back (mc);
}

}

{

// This prevents the message dialog below to issue deferred methods
tl::NoDeferredMethods silent;

bool has_autorun = false;
for (std::vector<lym::MacroCollection *>::const_iterator m = new_folders.begin (); m != new_folders.end () && ! has_autorun; ++m) {
has_autorun = (*m)->has_autorun ();
}

if (has_autorun) {
if (! ask_before_autorun || QMessageBox::question (mp_mw, QObject::tr ("Run Macros"), QObject::tr ("Some macros associated with new items are configured to run automatically.\n\nChoose 'Yes' to run these macros now. Choose 'No' to not run them."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
for (std::vector<lym::MacroCollection *>::const_iterator m = new_folders.begin (); m != new_folders.end (); ++m) {
(*m)->autorun ();
}
}
}

}
}

void
Expand Down
5 changes: 2 additions & 3 deletions src/lay/lay/layMacroController.h
Expand Up @@ -144,10 +144,8 @@ Q_OBJECT
/**
* @brief Loads the macros from the predefined paths and establishes the search paths
* This method will also establish the macro categories.
* If "load" is false, only the search path will be set. The macros themselves are not
* loaded into memory.
*/
void finish (bool load);
void finish ();

/**
* @brief Adds a temporary macro
Expand Down Expand Up @@ -256,6 +254,7 @@ private slots:
void sync_file_watcher ();
void sync_files ();
void sync_package_paths ();
void sync_macro_sources ();
};

}
Expand Down
5 changes: 5 additions & 0 deletions src/lym/lym/lymMacro.cc
Expand Up @@ -1789,6 +1789,11 @@ bool MacroCollection::has_autorun () const
return has_autorun_for (*this, false);
}

bool MacroCollection::has_autorun_early () const
{
return has_autorun_for (*this, true);
}

static void autorun_for (lym::MacroCollection &collection, bool early)
{
for (lym::MacroCollection::child_iterator c = collection.begin_children (); c != collection.end_children (); ++c) {
Expand Down
5 changes: 5 additions & 0 deletions src/lym/lym/lymMacro.h
Expand Up @@ -989,6 +989,11 @@ Q_OBJECT
*/
void autorun ();

/**
* @brief Returns true, if the collection has an early autorun macro
*/
bool has_autorun_early () const;

/**
* @brief Runs all macros marked with early auto-run
*/
Expand Down

0 comments on commit 1bb662b

Please sign in to comment.