summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/MainWindow.h1
-rw-r--r--src/ModuleCache.cc12
-rw-r--r--src/mainwin.cc21
-rw-r--r--src/module.cc62
-rw-r--r--src/module.h23
5 files changed, 66 insertions, 53 deletions
diff --git a/src/MainWindow.h b/src/MainWindow.h
index fc64137..79e2080 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -77,7 +77,6 @@ private:
void refreshDocument();
void updateTemporalVariables();
bool fileChangedOnDisk();
- bool includesChanged();
void compileTopLevelDocument();
void compile(bool reload, bool forcedone = false);
void compileCSG(bool procevents);
diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc
index 0e443e8..5ebd549 100644
--- a/src/ModuleCache.cc
+++ b/src/ModuleCache.cc
@@ -38,6 +38,9 @@ FileModule *ModuleCache::evaluate(const std::string &filename)
memset(&st, 0, sizeof(struct stat));
bool valid = (stat(filename.c_str(), &st) == 0);
+ // If file isn't there, just return and let the cache retain the old module
+ if (!valid) return NULL;
+
std::string cache_id = str(boost::format("%x.%x") % st.st_mtime % st.st_size);
// Lookup in cache
@@ -46,12 +49,9 @@ FileModule *ModuleCache::evaluate(const std::string &filename)
if (this->entries[filename].cache_id == cache_id) {
shouldCompile = false;
- BOOST_FOREACH(const FileModule::IncludeContainer::value_type &include, lib_mod->includes) {
- if (lib_mod->include_modified(include.second)) {
- lib_mod = NULL;
- shouldCompile = true;
- break;
- }
+ if (lib_mod->includesChanged()) {
+ lib_mod = NULL;
+ shouldCompile = true;
}
}
}
diff --git a/src/mainwin.cc b/src/mainwin.cc
index 52b432c..9652d6c 100644
--- a/src/mainwin.cc
+++ b/src/mainwin.cc
@@ -636,11 +636,12 @@ void MainWindow::compile(bool reload, bool forcedone)
shouldcompiletoplevel = true;
}
- if (!shouldcompiletoplevel && includesChanged()) {
+ if (!shouldcompiletoplevel && this->root_module && this->root_module->includesChanged()) {
shouldcompiletoplevel = true;
}
if (shouldcompiletoplevel) {
+ console->clear();
compileTopLevelDocument();
didcompile = true;
}
@@ -655,8 +656,8 @@ void MainWindow::compile(bool reload, bool forcedone)
// If we're auto-reloading, listen for a cascade of changes by starting a timer
// if something changed _and_ there are any external dependencies
if (reload && didcompile && this->root_module) {
- if (this->root_module->includes.size() > 0 ||
- this->root_module->usedlibs.size() > 0) {
+ if (this->root_module->hasIncludes() ||
+ this->root_module->usesLibraries()) {
this->waitAfterReloadTimer->start();
return;
}
@@ -1116,23 +1117,11 @@ bool MainWindow::fileChangedOnDisk()
return false;
}
-bool MainWindow::includesChanged()
-{
- if (this->root_module) {
- BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, this->root_module->includes) {
- if (this->root_module->include_modified(item.second)) return true;
- }
- }
- return false;
-}
-
/*!
Returns true if anything was compiled.
*/
void MainWindow::compileTopLevelDocument()
{
- console->clear();
-
updateTemporalVariables();
this->last_compiled_doc = editor->toPlainText();
@@ -1233,7 +1222,6 @@ void MainWindow::actionRenderCSG()
GuiLocker::lock();
autoReloadTimer->stop();
setCurrentOutput();
- console->clear();
PRINT("Parsing design (AST generation)...");
QApplication::processEvents();
@@ -1278,7 +1266,6 @@ void MainWindow::actionRenderCGAL()
GuiLocker::lock();
autoReloadTimer->stop();
setCurrentOutput();
- console->clear();
PRINT("Parsing design (AST generation)...");
QApplication::processEvents();
diff --git a/src/module.cc b/src/module.cc
index 080a3dd..6cd8322 100644
--- a/src/module.cc
+++ b/src/module.cc
@@ -207,6 +207,28 @@ void FileModule::registerInclude(const std::string &localpath,
this->includes[localpath] = inc;
}
+bool FileModule::includesChanged() const
+{
+ BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, this->includes) {
+ if (include_modified(item.second)) return true;
+ }
+ return false;
+}
+
+bool FileModule::include_modified(const IncludeFile &inc) const
+{
+ struct stat st;
+ memset(&st, 0, sizeof(struct stat));
+
+ fs::path fullpath = find_valid_path(this->path, inc.filename);
+ bool valid = !fullpath.empty() ? (stat(boosty::stringy(fullpath).c_str(), &st) == 0) : false;
+
+ if (valid && !inc.valid) return true; // Detect appearance of file but not removal
+ if (valid && st.st_mtime > inc.mtime) return true;
+
+ return false;
+}
+
/*!
Check if any dependencies have been modified and recompile them.
Returns true if anything was recompiled.
@@ -217,12 +239,13 @@ bool FileModule::handleDependencies()
this->is_handling_dependencies = true;
bool changed = false;
- // Iterating manually since we want to modify the container while iterating
-
// If a lib in usedlibs was previously missing, we need to relocate it
// by searching the applicable paths. We can identify a previously missing module
// as it will have a relative path.
+
+ // Iterating manually since we want to modify the container while iterating
+ std::vector<std::pair<std::string, FileModule*> > modified_modules;
FileModule::ModuleContainer::iterator iter = this->usedlibs.begin();
while (iter != this->usedlibs.end()) {
FileModule::ModuleContainer::iterator curr = iter++;
@@ -237,16 +260,27 @@ bool FileModule::handleDependencies()
if (!fullpath.empty()) filename = boosty::stringy(fullpath);
}
- curr->second = ModuleCache::instance()->evaluate(filename);
- if (curr->second != oldmodule) {
+ FileModule *newmodule = ModuleCache::instance()->evaluate(filename);
+ // Detect appearance but not removal of files
+ if (newmodule && oldmodule != newmodule) {
changed = true;
#ifdef DEBUG
- PRINTB_NOCACHE(" %s: %p", filename % curr->second);
+ PRINTB_NOCACHE(" %s: %p", filename % newmodule);
#endif
}
- if (!curr->second && !wasmissing) {
- PRINTB_NOCACHE("WARNING: Failed to compile library '%s'.", filename);
+ if (newmodule) {
+ modified_modules.push_back(std::make_pair(filename, newmodule));
+ this->usedlibs.erase(curr);
}
+ else {
+ // Only print warning if we're not part of an automatic reload
+ if (!oldmodule && !wasmissing) {
+ PRINTB_NOCACHE("WARNING: Failed to compile library '%s'.", filename);
+ }
+ }
+ }
+ BOOST_FOREACH(const FileModule::ModuleContainer::value_type &mod, modified_modules) {
+ this->usedlibs[mod.first] = mod.second;
}
this->is_handling_dependencies = false;
@@ -269,17 +303,3 @@ AbstractNode *FileModule::instantiate(const Context *ctx, const ModuleInstantiat
return node;
}
-
-bool FileModule::include_modified(IncludeFile inc)
-{
- struct stat st;
- memset(&st, 0, sizeof(struct stat));
-
- fs::path fullpath = find_valid_path(this->path, inc.filename);
- bool valid = !fullpath.empty() ? (stat(boosty::stringy(fullpath).c_str(), &st) == 0) : false;
-
- if (valid != inc.valid) return true;
- if (valid && st.st_mtime > inc.mtime) return true;
-
- return false;
-}
diff --git a/src/module.h b/src/module.h
index 5dfb8c4..ad2a46c 100644
--- a/src/module.h
+++ b/src/module.h
@@ -77,12 +77,6 @@ public:
LocalScope scope;
};
-struct IncludeFile {
- std::string filename;
- bool valid;
- time_t mtime;
-};
-
// FIXME: A FileModule doesn't have definition arguments, so we shouldn't really
// inherit from a Module
class FileModule : public Module
@@ -94,15 +88,28 @@ public:
void setModulePath(const std::string &path) { this->path = path; }
const std::string &modulePath() const { return this->path; }
void registerInclude(const std::string &localpath, const std::string &fullpath);
+ bool includesChanged() const;
bool handleDependencies();
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx = NULL) const;
+ bool hasIncludes() const { return !this->includes.empty(); }
+ bool usesLibraries() const { return !this->usedlibs.empty(); }
+
+
typedef boost::unordered_map<std::string, class FileModule*> ModuleContainer;
ModuleContainer usedlibs;
+private:
+ struct IncludeFile {
+ std::string filename;
+ bool valid;
+ time_t mtime;
+ };
+
+ bool include_modified(const IncludeFile &inc) const;
+
typedef boost::unordered_map<std::string, struct IncludeFile> IncludeContainer;
IncludeContainer includes;
- bool include_modified(struct IncludeFile inc);
-private:
+
bool is_handling_dependencies;
std::string path;
};
contact: Jan Huwald // Impressum