Skip to content

Commit

Permalink
+ make RecoveryWriter more robust
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Sep 18, 2015
1 parent bb05d17 commit 8db1280
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 24 deletions.
4 changes: 2 additions & 2 deletions src/Base/Writer.cpp
Expand Up @@ -264,7 +264,7 @@ void FileWriter::putNextEntry(const char* file)
this->FileStream.open(fileName.c_str(), std::ios::out);
}

bool FileWriter::shouldWrite(const Base::Persistence *) const
bool FileWriter::shouldWrite(const std::string& , const Base::Persistence *) const
{
return true;
}
Expand All @@ -278,7 +278,7 @@ void FileWriter::writeFiles(void)
while (index < FileList.size()) {
FileEntry entry = FileList.begin()[index];

if (shouldWrite(entry.Object)) {
if (shouldWrite(entry.FileName, entry.Object)) {
std::string filePath = entry.FileName;
std::string::size_type pos = 0;
while ((pos = filePath.find("/", pos)) != std::string::npos) {
Expand Down
4 changes: 2 additions & 2 deletions src/Base/Writer.h
Expand Up @@ -165,7 +165,7 @@ class BaseExport StringWriter : public Writer
std::stringstream StrStream;
};

/*! The FileWriter class
/*! The FileWriter class
This class writes out the data into files into a given directory name.
\see Base::Persistence
\author Werner Mayer
Expand All @@ -185,7 +185,7 @@ class BaseExport FileWriter : public Writer
to write out certain objects. The default implementation
always returns true.
*/
virtual bool shouldWrite(const Base::Persistence *Object) const;
virtual bool shouldWrite(const std::string& name, const Base::Persistence *Object) const;

private:
std::string DirName;
Expand Down
62 changes: 49 additions & 13 deletions src/Gui/AutoSaver.cpp
Expand Up @@ -33,11 +33,13 @@

#include "AutoSaver.h"
#include <Base/Console.h>
#include <Base/FileInfo.h>
#include <Base/Stream.h>
#include <Base/Tools.h>
#include <Base/Writer.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/DocumentObject.h>

#include "Document.h"
#include "WaitCursor.h"
Expand Down Expand Up @@ -86,6 +88,11 @@ void AutoSaver::slotCreateDocument(const App::Document& Doc)
int id = timeout > 0 ? startTimer(timeout) : 0;
AutoSaveProperty* as = new AutoSaveProperty(&Doc);
as->timerId = id;
std::string dirName = Doc.TransientDir.getValue();
dirName += "/fc_recovery_files";
Base::FileInfo fi(dirName);
fi.createDirectory();
as->dirName = dirName;
saverMap.insert(std::make_pair(name, as));
}

Expand All @@ -101,7 +108,7 @@ void AutoSaver::slotDeleteDocument(const App::Document& Doc)
}
}

void AutoSaver::saveDocument(const std::string& name, const std::set<std::string>& data)
void AutoSaver::saveDocument(const std::string& name, AutoSaveProperty& saver)
{
Gui::WaitCursor wc;
App::Document* doc = App::GetApplication().getDocument(name.c_str());
Expand Down Expand Up @@ -145,6 +152,7 @@ void AutoSaver::saveDocument(const std::string& name, const std::set<std::string
Base::ofstream file(tmp, std::ios::out | std::ios::binary);
if (file.is_open()) {
Base::ZipWriter writer(file);
//RecoveryWriter writer(saver);
if (hGrp->GetBool("SaveBinaryBrep", true))
writer.setMode("BinaryBrep");

Expand Down Expand Up @@ -177,8 +185,8 @@ void AutoSaver::timerEvent(QTimerEvent * event)
for (std::map<std::string, AutoSaveProperty*>::iterator it = saverMap.begin(); it != saverMap.end(); ++it) {
if (it->second->timerId == id) {
try {
saveDocument(it->first, it->second->objects);
it->second->objects.clear();
saveDocument(it->first, *it->second);
it->second->touched.clear();
break;
}
catch (...) {
Expand All @@ -192,40 +200,60 @@ void AutoSaver::timerEvent(QTimerEvent * event)

AutoSaveProperty::AutoSaveProperty(const App::Document* doc) : timerId(-1)
{
document = const_cast<App::Document*>(doc)->signalChangedObject.connect
documentNew = const_cast<App::Document*>(doc)->signalNewObject.connect
(boost::bind(&AutoSaveProperty::slotNewObject, this, _1));
documentMod = const_cast<App::Document*>(doc)->signalChangedObject.connect
(boost::bind(&AutoSaveProperty::slotChangePropertyData, this, _2));
}

AutoSaveProperty::~AutoSaveProperty()
{
document.disconnect();
documentNew.disconnect();
documentMod.disconnect();
}

void AutoSaveProperty::slotNewObject(const App::DocumentObject& obj)
{
std::vector<App::Property*> props;
obj.getPropertyList(props);

// if an object was deleted and then restored by an undo then add all properties
// because this might be the data files which we may want to re-write
for (std::vector<App::Property*>::iterator it = props.begin(); it != props.end(); ++it) {
slotChangePropertyData(*(*it));
}
}

void AutoSaveProperty::slotChangePropertyData(const App::Property& prop)
{
std::stringstream str;
str << static_cast<const void *>(&prop) << std::ends;
std::string address = str.str();
this->objects.insert(address);
this->touched.insert(address);
}

// ----------------------------------------------------------------------------

RecoveryWriter::RecoveryWriter(const char* DirName)
: Base::FileWriter(DirName)
RecoveryWriter::RecoveryWriter(AutoSaveProperty& saver)
: Base::FileWriter(saver.dirName.c_str()), saver(saver)
{
}

RecoveryWriter::~RecoveryWriter()
{
}

void RecoveryWriter::setModifiedData(const std::set<std::string>& m)
void RecoveryWriter::setLevel(int)
{
data = m;
// not implemented
}

bool RecoveryWriter::shouldWrite(const Base::Persistence *object) const
void RecoveryWriter::setComment(const char*)
{
// not implemented
}

bool RecoveryWriter::shouldWrite(const std::string& name, const Base::Persistence *object) const
{
// Property files of a view provider can always be written because
// these are rather small files.
Expand All @@ -244,8 +272,16 @@ bool RecoveryWriter::shouldWrite(const Base::Persistence *object) const
str << static_cast<const void *>(object) << std::ends;
std::string address = str.str();

std::set<std::string>::const_iterator it = data.find(address);
return (it != data.end());
// Check if the property will be exported to the same file. If the file has changed or if the property hasn't been
// yet exported then (re-)write the file.
std::map<std::string, std::string>::iterator it = saver.fileMap.find(address);
if (it == saver.fileMap.end() || it->second != name) {
saver.fileMap[address] = name;
return true;
}

std::set<std::string>::const_iterator jt = saver.touched.find(address);
return (jt != saver.touched.end());
}


Expand Down
21 changes: 14 additions & 7 deletions src/Gui/AutoSaver.h
Expand Up @@ -33,6 +33,7 @@

namespace App {
class Document;
class DocumentObject;
class Property;
}

Expand All @@ -45,12 +46,16 @@ class AutoSaveProperty
AutoSaveProperty(const App::Document* doc);
~AutoSaveProperty();
int timerId;
std::set<std::string> objects;
std::set<std::string> touched;
std::string dirName;
std::map<std::string, std::string> fileMap;

private:
void slotNewObject(const App::DocumentObject&);
void slotChangePropertyData(const App::Property&);
typedef boost::BOOST_SIGNALS_NAMESPACE::connection Connection;
Connection document;
Connection documentNew;
Connection documentMod;
};

/*!
Expand All @@ -77,7 +82,7 @@ class AutoSaver : public QObject
void slotCreateDocument(const App::Document& Doc);
void slotDeleteDocument(const App::Document& Doc);
void timerEvent(QTimerEvent * event);
void saveDocument(const std::string&, const std::set<std::string>&);
void saveDocument(const std::string&, AutoSaveProperty&);

private:
int timeout; /*!< Timeout in milliseconds */
Expand All @@ -87,19 +92,21 @@ class AutoSaver : public QObject
class RecoveryWriter : public Base::FileWriter
{
public:
RecoveryWriter(const char* DirName);
RecoveryWriter(AutoSaveProperty&);
virtual ~RecoveryWriter();
void setModifiedData(const std::set<std::string> &);

void setLevel(int);
void setComment(const char*);

/*!
This method can be re-implemented in sub-classes to avoid
to write out certain objects. The default implementation
always returns true.
*/
virtual bool shouldWrite(const Base::Persistence *) const;
virtual bool shouldWrite(const std::string&, const Base::Persistence *) const;

private:
std::set<std::string> data;
AutoSaveProperty& saver;
};

} //namespace Gui
Expand Down

0 comments on commit 8db1280

Please sign in to comment.