summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AppleEvents.cc2
-rw-r--r--src/CSGTermEvaluator.cc3
-rw-r--r--src/MainWindow.h20
-rw-r--r--src/ModuleCache.cc1
-rw-r--r--src/lexer.l2
-rw-r--r--src/mainwin.cc252
-rw-r--r--src/module.cc7
-rw-r--r--src/module.h1
-rw-r--r--src/parsersettings.cc8
9 files changed, 191 insertions, 105 deletions
diff --git a/src/AppleEvents.cc b/src/AppleEvents.cc
index 1fb4f99..3102792 100644
--- a/src/AppleEvents.cc
+++ b/src/AppleEvents.cc
@@ -15,7 +15,7 @@ OSErr eventHandler(const AppleEvent *, AppleEvent *, SRefCon )
if (mainwin) break;
}
if (mainwin) {
- mainwin->actionReloadCompile();
+ mainwin->actionReloadRenderCSG();
}
return noErr;
}
diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc
index a6b654c..71cf149 100644
--- a/src/CSGTermEvaluator.cc
+++ b/src/CSGTermEvaluator.cc
@@ -115,6 +115,7 @@ Response CSGTermEvaluator::visit(State &state, const AbstractPolyNode &node)
if (ps) {
t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background,
ps, node.modinst, node);
+ node.progress_report();
}
}
this->stored_term[node.index()] = t1;
@@ -178,6 +179,7 @@ Response CSGTermEvaluator::visit(State &state, const RenderNode &node)
shared_ptr<PolySet> ps;
if (this->psevaluator) {
ps = this->psevaluator->getPolySet(node, true);
+ node.progress_report();
}
if (ps) {
t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background,
@@ -201,6 +203,7 @@ Response CSGTermEvaluator::visit(State &state, const CgaladvNode &node)
if (ps) {
t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background,
ps, node.modinst, node);
+ node.progress_report();
}
this->stored_term[node.index()] = t1;
addToParent(state, node);
diff --git a/src/MainWindow.h b/src/MainWindow.h
index 1dcffeb..79e2080 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -28,6 +28,7 @@ public:
QTimer *autoReloadTimer;
std::string autoReloadId;
+ QTimer *waitAfterReloadTimer;
ModuleContext top_ctx;
FileModule *root_module; // Result of parsing
@@ -76,8 +77,8 @@ private:
void refreshDocument();
void updateTemporalVariables();
bool fileChangedOnDisk();
- bool compileTopLevelDocument(bool reload);
- bool compile(bool reload, bool procevents);
+ void compileTopLevelDocument();
+ void compile(bool reload, bool forcedone = false);
void compileCSG(bool procevents);
bool maybeSave();
bool checkEditorModified();
@@ -102,6 +103,10 @@ private slots:
void actionReload();
void actionShowLibraryFolder();
+ void instantiateRoot();
+ void compileDone(bool didchange);
+ void compileEnded();
+
private slots:
void pasteViewportTranslation();
void pasteViewportRotation();
@@ -109,10 +114,13 @@ private slots:
void preferences();
private slots:
- void actionCompile();
+ void actionRenderCSG();
+ void csgRender();
+ void csgReloadRender();
#ifdef ENABLE_CGAL
void actionRenderCGAL();
void actionRenderCGALDone(class CGAL_Nef_polyhedron *);
+ void cgalRender();
#endif
void actionDisplayAST();
void actionDisplayCSGTree();
@@ -131,6 +139,7 @@ public:
void clearCurrentOutput();
public slots:
+ void actionReloadRenderCSG();
#ifdef ENABLE_OPENCSG
void viewModeOpenCSG();
#endif
@@ -163,13 +172,16 @@ public slots:
void helpManual();
void helpLibrary();
void quit();
- void actionReloadCompile();
void checkAutoReload();
+ void waitAfterReload();
void autoReloadSet(bool);
private:
static void report_func(const class AbstractNode*, void *vp, int mark);
+ char const * afterCompileSlot;
+ bool procevents;
+
class ProgressWidget *progresswidget;
class CGALWorker *cgalworker;
QMutex consolemutex;
diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc
index 99c0b20..de9af01 100644
--- a/src/ModuleCache.cc
+++ b/src/ModuleCache.cc
@@ -53,7 +53,6 @@ FileModule *ModuleCache::evaluate(const std::string &filename)
if (lib_mod) {
if (this->entries[filename].cache_id == cache_id) {
shouldCompile = false;
-
if (lib_mod->includesChanged()) {
lib_mod = NULL;
shouldCompile = true;
diff --git a/src/lexer.l b/src/lexer.l
index 0b8048f..3dd3b6b 100644
--- a/src/lexer.l
+++ b/src/lexer.l
@@ -100,7 +100,7 @@ E [Ee][+-]?{D}+
%%
-include[ \t\r\n>]*"<" { BEGIN(cond_include); filepath = filename = "";}
+include[ \t\r\n>]*"<" { BEGIN(cond_include); filepath = filename = ""; }
<cond_include>{
[^\t\r\n>]*"/" { filepath = yytext; }
[^\t\r\n>/]+ { filename = yytext; }
diff --git a/src/mainwin.cc b/src/mainwin.cc
index 95f7242..3d50d6f 100644
--- a/src/mainwin.cc
+++ b/src/mainwin.cc
@@ -206,9 +206,15 @@ MainWindow::MainWindow(const QString &filename)
autoReloadTimer = new QTimer(this);
autoReloadTimer->setSingleShot(false);
+ autoReloadTimer->setInterval(200);
connect(autoReloadTimer, SIGNAL(timeout()), this, SLOT(checkAutoReload()));
- connect(this->e_tval, SIGNAL(textChanged(QString)), this, SLOT(actionCompile()));
+ waitAfterReloadTimer = new QTimer(this);
+ waitAfterReloadTimer->setSingleShot(true);
+ waitAfterReloadTimer->setInterval(200);
+ connect(waitAfterReloadTimer, SIGNAL(timeout()), this, SLOT(waitAfterReload()));
+
+ connect(this->e_tval, SIGNAL(textChanged(QString)), this, SLOT(actionRenderCSG()));
connect(this->e_fps, SIGNAL(textChanged(QString)), this, SLOT(updatedFps()));
animate_panel->hide();
@@ -288,8 +294,8 @@ MainWindow::MainWindow(const QString &filename)
// Design menu
connect(this->designActionAutoReload, SIGNAL(toggled(bool)), this, SLOT(autoReloadSet(bool)));
- connect(this->designActionReloadAndCompile, SIGNAL(triggered()), this, SLOT(actionReloadCompile()));
- connect(this->designActionCompile, SIGNAL(triggered()), this, SLOT(actionCompile()));
+ connect(this->designActionReloadAndCompile, SIGNAL(triggered()), this, SLOT(actionReloadRenderCSG()));
+ connect(this->designActionCompile, SIGNAL(triggered()), this, SLOT(actionRenderCSG()));
#ifdef ENABLE_CGAL
connect(this->designActionCompileAndRender, SIGNAL(triggered()), this, SLOT(actionRenderCGAL()));
#else
@@ -580,7 +586,7 @@ void MainWindow::updateTVal()
double fps = this->e_fps->text().toDouble(&fps_ok);
if (fps_ok) {
if (fps <= 0) {
- actionCompile();
+ actionRenderCSG();
} else {
double s = this->e_fsteps->text().toDouble();
double t = this->e_tval->text().toDouble() + 1/s;
@@ -612,14 +618,96 @@ void MainWindow::refreshDocument()
}
/*!
- Parse and evaluate the design => this->root_node
-
- Returns true if something was compiled, false if nothing was changed
- and the root_node was left untouched.
+ compiles the design. Calls compileDone() if anything was compiled
*/
-bool MainWindow::compile(bool reload, bool procevents)
+void MainWindow::compile(bool reload, bool forcedone)
+{
+ bool shouldcompiletoplevel = false;
+ bool didcompile = false;
+
+ // Reload checks the timestamp of the toplevel file and refreshes if necessary,
+ if (reload) {
+ // Refresh files if it has changed on disk
+ if (fileChangedOnDisk() && checkEditorModified()) {
+ shouldcompiletoplevel = true;
+ refreshDocument();
+ }
+ // If the file hasn't changed, we might still need to compile it
+ // if we haven't yet compiled the current text.
+ else {
+ QString current_doc = editor->toPlainText();
+ if (current_doc != last_compiled_doc) shouldcompiletoplevel = true;
+ }
+ }
+ else {
+ shouldcompiletoplevel = true;
+ }
+
+ if (!shouldcompiletoplevel && this->root_module && this->root_module->includesChanged()) {
+ shouldcompiletoplevel = true;
+ }
+
+ if (shouldcompiletoplevel) {
+ console->clear();
+ compileTopLevelDocument();
+ didcompile = true;
+ }
+
+ if (this->root_module) {
+ if (this->root_module->handleDependencies()) {
+ PRINTB("Module cache size: %d modules", ModuleCache::instance()->size());
+ didcompile = true;
+ }
+ }
+
+ // 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->hasIncludes() ||
+ this->root_module->usesLibraries()) {
+ this->waitAfterReloadTimer->start();
+ return;
+ }
+ }
+ compileDone(didcompile | forcedone);
+}
+
+void MainWindow::waitAfterReload()
+{
+ if (this->root_module->handleDependencies()) {
+ this->waitAfterReloadTimer->start();
+ return;
+ }
+ else {
+ compile(true, true); // In case file itself or top-level includes changed during dependency updates
+ }
+}
+
+void MainWindow::compileDone(bool didchange)
+{
+ const char *callslot;
+ if (didchange) {
+ instantiateRoot();
+ callslot = afterCompileSlot;
+ }
+ else {
+ callslot = "compileEnded";
+ }
+
+ this->procevents = false;
+ QMetaObject::invokeMethod(this, callslot);
+}
+
+void MainWindow::compileEnded()
+{
+ clearCurrentOutput();
+ GuiLocker::unlock();
+ if (designActionAutoReload->isChecked()) autoReloadTimer->start();
+}
+
+void MainWindow::instantiateRoot()
{
- if (!compileTopLevelDocument(reload)) return false;
+ // Go on and instantiate root_node, then call the continuation slot
// Invalidate renderers before we kill the CSG tree
this->qglview->setRenderer(NULL);
@@ -652,7 +740,7 @@ bool MainWindow::compile(bool reload, bool procevents)
if (this->root_module) {
// Evaluate CSG tree
PRINT("Compiling design (CSG Tree generation)...");
- if (procevents) QApplication::processEvents();
+ if (this->procevents) QApplication::processEvents();
AbstractNode::resetIndexCounter();
@@ -681,10 +769,8 @@ bool MainWindow::compile(bool reload, bool procevents)
} else {
PRINT("ERROR: Compilation failed!");
}
- if (procevents) QApplication::processEvents();
+ if (this->procevents) QApplication::processEvents();
}
-
- return true;
}
/*!
@@ -1043,77 +1129,42 @@ bool MainWindow::fileChangedOnDisk()
}
/*!
- If reload is true, does a timestamp check on the document and tries to reload it.
- Otherwise, just reparses the current document and any dependencies, updates the
- GUI accordingly and populates this->root_module.
-
Returns true if anything was compiled.
*/
-bool MainWindow::compileTopLevelDocument(bool reload)
+void MainWindow::compileTopLevelDocument()
{
- bool shouldcompiletoplevel = !reload;
-
- if (this->root_module && this->root_module->includesChanged()) {
- shouldcompiletoplevel = true;
- }
-
- if (reload) {
- // Refresh file if it has changed on disk
- if (fileChangedOnDisk() && checkEditorModified()) {
- shouldcompiletoplevel = true;
- refreshDocument();
- }
- // If the file hasn't changed, we might still need to compile it
- // if we haven't yet compiled the current text.
- else if (!editor->isContentModified()) {
- QString current_doc = editor->toPlainText();
- if (current_doc != last_compiled_doc) shouldcompiletoplevel = true;
- }
- }
+ updateTemporalVariables();
- if (shouldcompiletoplevel) {
- console->clear();
-
- updateTemporalVariables();
-
- this->last_compiled_doc = editor->toPlainText();
- std::string fulltext =
- std::string(this->last_compiled_doc.toLocal8Bit().constData()) +
- "\n" + commandline_commands;
-
- delete this->root_module;
- this->root_module = NULL;
-
- this->root_module = parse(fulltext.c_str(),
- this->fileName.isEmpty() ?
- "" :
- QFileInfo(this->fileName).absolutePath().toLocal8Bit(),
- false);
-
- if (!animate_panel->isVisible()) {
- highlighter->unhighlightLastError();
- if (!this->root_module) {
- QTextCursor cursor = editor->textCursor();
- cursor.setPosition(parser_error_pos);
- editor->setTextCursor(cursor);
- highlighter->highlightError( parser_error_pos );
- }
+ this->last_compiled_doc = editor->toPlainText();
+ std::string fulltext =
+ std::string(this->last_compiled_doc.toLocal8Bit().constData()) +
+ "\n" + commandline_commands;
+
+ delete this->root_module;
+ this->root_module = NULL;
+
+ this->root_module = parse(fulltext.c_str(),
+ this->fileName.isEmpty() ?
+ "" :
+ QFileInfo(this->fileName).absolutePath().toLocal8Bit(),
+ false);
+
+ if (!animate_panel->isVisible()) {
+ highlighter->unhighlightLastError();
+ if (!this->root_module) {
+ QTextCursor cursor = editor->textCursor();
+ cursor.setPosition(parser_error_pos);
+ editor->setTextCursor(cursor);
+ highlighter->highlightError( parser_error_pos );
}
-
- }
-
- bool changed = shouldcompiletoplevel;
- if (this->root_module) {
- changed |= this->root_module->handleDependencies();
- if (changed) PRINTB("Module cache size: %d modules", ModuleCache::instance()->size());
}
-
- return changed;
}
void MainWindow::checkAutoReload()
{
- if (!this->fileName.isEmpty()) actionReloadCompile();
+ if (!this->fileName.isEmpty()) {
+ actionReloadRenderCSG();
+ }
}
void MainWindow::autoReloadSet(bool on)
@@ -1143,15 +1194,22 @@ bool MainWindow::checkEditorModified()
return true;
}
-void MainWindow::actionReloadCompile()
+void MainWindow::actionReloadRenderCSG()
{
if (GuiLocker::isLocked()) return;
- GuiLocker lock;
+ GuiLocker::lock();
+ autoReloadTimer->stop();
setCurrentOutput();
// PRINT("Parsing design (AST generation)...");
// QApplication::processEvents();
- if (!compile(true, true)) return;
+ this->afterCompileSlot = "csgReloadRender";
+ this->procevents = true;
+ compile(true);
+}
+
+void MainWindow::csgReloadRender()
+{
if (this->root_node) compileCSG(true);
// Go to non-CGAL view mode
@@ -1165,20 +1223,25 @@ void MainWindow::actionReloadCompile()
viewModeThrownTogether();
#endif
}
-
- clearCurrentOutput();
+ compileEnded();
}
-void MainWindow::actionCompile()
+void MainWindow::actionRenderCSG()
{
if (GuiLocker::isLocked()) return;
- GuiLocker lock;
+ GuiLocker::lock();
+ autoReloadTimer->stop();
setCurrentOutput();
- console->clear();
PRINT("Parsing design (AST generation)...");
QApplication::processEvents();
- compile(false, !viewActionAnimate->isChecked());
+ this->afterCompileSlot = "csgRender";
+ this->procevents = !viewActionAnimate->isChecked();
+ compile(false);
+}
+
+void MainWindow::csgRender()
+{
if (this->root_node) compileCSG(!viewActionAnimate->isChecked());
// Go to non-CGAL view mode
@@ -1202,7 +1265,7 @@ void MainWindow::actionCompile()
img.save(filename, "PNG");
}
- clearCurrentOutput();
+ compileEnded();
}
#ifdef ENABLE_CGAL
@@ -1210,15 +1273,19 @@ void MainWindow::actionCompile()
void MainWindow::actionRenderCGAL()
{
if (GuiLocker::isLocked()) return;
- GuiLocker lock;
-
+ GuiLocker::lock();
+ autoReloadTimer->stop();
setCurrentOutput();
- console->clear();
PRINT("Parsing design (AST generation)...");
QApplication::processEvents();
- compile(false, true);
+ this->afterCompileSlot = "cgalRender";
+ this->procevents = true;
+ compile(false);
+}
+void MainWindow::cgalRender()
+{
if (!this->root_module || !this->root_node) {
return;
}
@@ -1238,7 +1305,6 @@ void MainWindow::actionRenderCGAL()
progress_report_prep(this->root_node, report_func, this);
- GuiLocker::lock(); // Will be unlocked in actionRenderCGALDone()
this->cgalworker->start(this->tree);
}
@@ -1301,9 +1367,7 @@ void MainWindow::actionRenderCGALDone(CGAL_Nef_polyhedron *root_N)
this->statusBar()->removeWidget(this->progresswidget);
delete this->progresswidget;
this->progresswidget = NULL;
- clearCurrentOutput();
-
- GuiLocker::unlock();
+ compileEnded();
}
#endif /* ENABLE_CGAL */
@@ -1616,7 +1680,7 @@ void MainWindow::viewModeAnimate()
{
if (viewActionAnimate->isChecked()) {
animate_panel->show();
- actionCompile();
+ actionRenderCSG();
updatedFps();
} else {
animate_panel->hide();
diff --git a/src/module.cc b/src/module.cc
index 8fb8506..9c0272d 100644
--- a/src/module.cc
+++ b/src/module.cc
@@ -264,6 +264,10 @@ bool FileModule::handleDependencies()
// as it will have a relative path.
// Iterating manually since we want to modify the container while iterating
+<<<<<<< HEAD
+=======
+ std::vector<std::pair<std::string, FileModule*> > modified_modules;
+>>>>>>> origin/issue181
FileModule::ModuleContainer::iterator iter = this->usedlibs.begin();
while (iter != this->usedlibs.end()) {
FileModule::ModuleContainer::iterator curr = iter++;
@@ -293,6 +297,9 @@ bool FileModule::handleDependencies()
}
}
}
+ BOOST_FOREACH(const FileModule::ModuleContainer::value_type &mod, modified_modules) {
+ this->usedlibs[mod.first] = mod.second;
+ }
this->is_handling_dependencies = false;
return changed;
diff --git a/src/module.h b/src/module.h
index 6027fe6..b5c58af 100644
--- a/src/module.h
+++ b/src/module.h
@@ -107,6 +107,7 @@ private:
};
bool include_modified(const IncludeFile &inc) const;
+
typedef boost::unordered_map<std::string, struct IncludeFile> IncludeContainer;
IncludeContainer includes;
bool is_handling_dependencies;
diff --git a/src/parsersettings.cc b/src/parsersettings.cc
index ab93b78..5ad30e1 100644
--- a/src/parsersettings.cc
+++ b/src/parsersettings.cc
@@ -35,19 +35,19 @@ fs::path search_libs(const fs::path &localpath)
static bool check_valid(const fs::path &p, const std::vector<std::string> *openfilenames)
{
if (p.empty()) {
-// PRINTB("WARNING: File path is blank: %s",p);
+ //PRINTB("WARNING: File path is blank: %s",p);
return false;
}
if (!p.has_parent_path()) {
-// PRINTB("WARNING: No parent path: %s",p);
+ //PRINTB("WARNING: No parent path: %s",p);
return false;
}
if (!fs::exists(p)) {
-// PRINTB("WARNING: File not found: %s",p);
+ //PRINTB("WARNING: File not found: %s",p);
return false;
}
if (fs::is_directory(p)) {
-// PRINTB("WARNING: %s invalid - points to a directory",p);
+ //PRINTB("WARNING: %s invalid - points to a directory",p);
return false;
}
std::string fullname = boosty::stringy(p);
contact: Jan Huwald // Impressum