Skip to content

Commit

Permalink
Fix auto-recovery (#363)
Browse files Browse the repository at this point in the history
  • Loading branch information
blackwarthog committed Aug 23, 2017
1 parent 6c807ce commit 0dde721
Show file tree
Hide file tree
Showing 22 changed files with 496 additions and 481 deletions.
6 changes: 6 additions & 0 deletions synfig-core/src/modules/lyr_std/import.cpp
Expand Up @@ -110,6 +110,12 @@ Import::set_param(const String & param, const ValueBase &value)
return true;
}

if (is_surface_modified())
{
error("Unable to load new file, already opened file is not saved");
return false;
}

String filename = value.get(String());
String fixed_filename = filename;

Expand Down
4 changes: 2 additions & 2 deletions synfig-core/src/modules/mod_imagemagick/mptr_imagemagick.cpp
Expand Up @@ -111,11 +111,11 @@ imagemagick_mptr::get_frame(synfig::Surface &surface, const synfig::RendDesc &re

bool is_temporary_file = false;
string filename=identifier.file_system->get_real_filename(identifier.filename);
string target_filename=FileSystemTemporary::generate_temporary_filename();
string target_filename=FileSystemTemporary::generate_system_temporary_filename("imagemagick");

if (filename.empty()) {
is_temporary_file = true;
filename = FileSystemTemporary::generate_temporary_filename();
filename = FileSystemTemporary::generate_system_temporary_filename("imagemagick");

// try to copy file to a temp file
if (!FileSystem::copy(identifier.file_system, identifier.filename, identifier.file_system, filename))
Expand Down
10 changes: 7 additions & 3 deletions synfig-core/src/synfig/filecontainerzip.cpp
Expand Up @@ -30,13 +30,17 @@
#endif

#include <cstring>
#include <stdint.h>
#include <cstdint>
#include <cstddef>
#include <ETL/stringf>

#include <libxml++/libxml++.h>
#include "filecontainerzip.h"

#include <ETL/stringf>

#include "zstreambuf.h"

#include "filecontainerzip.h"

#endif

/* === U S I N G =========================================================== */
Expand Down
3 changes: 1 addition & 2 deletions synfig-core/src/synfig/filesystem.cpp
Expand Up @@ -118,8 +118,7 @@ bool FileSystem::file_rename(const String &from_filename, const String &to_filen
}

bool FileSystem::directory_create_recursive(const String &dirname) {
return dirname.empty()
|| dirname == "."
return is_directory(dirname)
|| (directory_create_recursive(etl::dirname(dirname)) && directory_create(dirname));
}

Expand Down
89 changes: 67 additions & 22 deletions synfig-core/src/synfig/filesystemtemporary.cpp
Expand Up @@ -55,37 +55,65 @@ using namespace synfig;

/* === M E T H O D S ======================================================= */

FileSystemTemporary::FileSystemTemporary(const FileSystem::Handle &sub_file_system):
FileSystemTemporary::FileSystemTemporary(const String &tag, const String &temporary_directory, const FileSystem::Handle &sub_file_system):
file_system(FileSystemNative::instance()),
temporary_filename_base(generate_temporary_filename()),
tag(tag),
temporary_directory(temporary_directory.empty() ? get_system_temporary_directory() : temporary_directory),
temporary_filename_base(generate_temporary_filename_base(tag)),
autosave(true)
{
set_sub_file_system(sub_file_system);
}

FileSystemTemporary::~FileSystemTemporary() { }
FileSystemTemporary::~FileSystemTemporary()
{
discard_changes();
}

String
FileSystemTemporary::get_temporary_directory()
FileSystemTemporary::get_system_temporary_directory()
{
const char *tmpdir;
if ((tmpdir = getenv("TEMP")) == NULL)
if ((tmpdir = getenv("TMP")) == NULL)
if ((tmpdir = getenv("TMPDIR")) == NULL)
tmpdir = "/tmp";
return String(tmpdir) + ETL_DIRECTORY_SEPARATOR;
return String(tmpdir);
}

String
FileSystemTemporary::generate_temporary_filename_base()
FileSystemTemporary::generate_temporary_filename_base(const String &tag)
{
return "synfig_" + GUID().get_string();
return "synfig_" + tag + "_" + GUID().get_string();
}

bool
FileSystemTemporary::scan_temporary_directory(const String &tag, FileList &out_files, const String &dirname)
{
String tmpdir = dirname.empty() ? get_system_temporary_directory() : dirname;

FileList files;
if (!FileSystemNative::instance()->directory_scan(dirname, files))
return false;

String prefix = "synfig_" + tag + "_";
for(FileList::const_iterator i = files.begin(); i != files.end(); ++i)
if (i->substr(0, prefix.size()) == prefix)
if (FileSystemNative::instance()->is_file(tmpdir + ETL_DIRECTORY_SEPARATOR + *i))
out_files.push_back(*i);
return true;
}

String
FileSystemTemporary::generate_temporary_filename()
FileSystemTemporary::generate_system_temporary_filename(const String &tag)
{
return get_system_temporary_directory() + ETL_DIRECTORY_SEPARATOR + generate_temporary_filename_base(tag);
}

bool
FileSystemTemporary::create_temporary_directory() const
{
return get_temporary_directory() + generate_temporary_filename_base();
return file_system->directory_create_recursive(get_temporary_directory());
}

bool
Expand Down Expand Up @@ -239,9 +267,12 @@ FileSystemTemporary::get_write_stream(const String &filename)
if (i == files.end())
{
// create new file
create_temporary_directory();
FileInfo new_info;
new_info.name = fix_slashes(filename);
new_info.tmp_filename = generate_temporary_filename();
new_info.tmp_filename = get_temporary_directory()
+ ETL_DIRECTORY_SEPARATOR
+ generate_temporary_filename_base(tag + ".file");
stream = file_system->get_write_stream(new_info.tmp_filename);
if (stream)
{
Expand All @@ -252,8 +283,11 @@ FileSystemTemporary::get_write_stream(const String &filename)
else
if (!i->second.is_directory || i->second.is_removed)
{
create_temporary_directory();
String tmp_filename = i->second.tmp_filename.empty()
? generate_temporary_filename()
? get_temporary_directory()
+ ETL_DIRECTORY_SEPARATOR
+ generate_temporary_filename_base(tag + ".file")
: i->second.tmp_filename;
stream = file_system->get_write_stream(tmp_filename);
if (stream)
Expand Down Expand Up @@ -403,12 +437,14 @@ FileSystemTemporary::discard_changes()
}

void
FileSystemTemporary::reset_temporary_filename_base()
FileSystemTemporary::reset_temporary_filename_base(const String &tag, const String &temporary_directory)
{
// remove previous file
assert(empty());
save_temporary();
temporary_filename_base = generate_temporary_filename_base();
this->tag = tag;
this->temporary_directory = temporary_directory;
temporary_filename_base = generate_temporary_filename_base(this->tag);
}

String
Expand Down Expand Up @@ -454,7 +490,7 @@ FileSystemTemporary::save_temporary() const
{
if (empty())
{
file_system->file_remove(get_temporary_directory() + get_temporary_filename_base());
file_system->file_remove(get_temporary_directory() + ETL_DIRECTORY_SEPARATOR + get_temporary_filename_base());
return true;
}

Expand All @@ -479,9 +515,11 @@ FileSystemTemporary::save_temporary() const
entry->add_child("is-removed")->set_child_text(i->second.is_removed ? "true" : "false");
}

create_temporary_directory();
FileSystem::WriteStream::Handle stream =
file_system->get_write_stream(
get_temporary_directory()
+ ETL_DIRECTORY_SEPARATOR
+ get_temporary_filename_base() );
if (!stream) return false;

Expand Down Expand Up @@ -515,16 +553,21 @@ FileSystemTemporary::get_xml_node_text(xmlpp::Node *node)
}

bool
FileSystemTemporary::open_temporary(const String &filename_base)
FileSystemTemporary::open_temporary(const String &filename)
{
assert(empty());

discard_changes();

FileSystem::ReadStream::Handle stream =
file_system->get_read_stream(
get_temporary_directory()
+ filename_base);
String tag;
String temporary_directory = etl::dirname(filename);
String temporary_filename_base = etl::basename(filename);

size_t tag_begin = temporary_filename_base.find_first_of("_");
size_t tag_end = temporary_filename_base.find_last_of("_");
if (tag_begin != String::npos && tag_end != String::npos && tag_end - tag_begin > 1)
tag = temporary_filename_base.substr(tag_begin + 1, tag_end - tag_begin - 1);

FileSystem::ReadStream::Handle stream = file_system->get_read_stream(filename);
if (!stream) return false;
stream = new ZReadStream(stream);

Expand Down Expand Up @@ -581,14 +624,16 @@ FileSystemTemporary::open_temporary(const String &filename_base)
info.is_removed = get_xml_node_text(*k) == "true";
}
if (!info.tmp_filename.empty())
info.tmp_filename = get_temporary_directory() + info.tmp_filename;
info.tmp_filename = temporary_directory + ETL_DIRECTORY_SEPARATOR + info.tmp_filename;
files[info.name] = info;
}
}
}
}

temporary_filename_base = filename_base;
this->tag = tag;
this->temporary_directory = temporary_directory;
this->temporary_filename_base = temporary_filename_base;
return true;
}

Expand Down
22 changes: 14 additions & 8 deletions synfig-core/src/synfig/filesystemtemporary.h
Expand Up @@ -66,6 +66,8 @@ namespace synfig
FileSystemNative::Handle file_system;
FileSystem::Handle sub_file_system;

String tag;
String temporary_directory;
String temporary_filename_base;

std::map<String, String> meta;
Expand All @@ -78,12 +80,13 @@ namespace synfig
FileMap &files,
bool remove_files);

bool create_temporary_directory() const;
bool autosave_temporary() const;

static String get_xml_node_text(xmlpp::Node *node);

public:
explicit FileSystemTemporary(const FileSystem::Handle &sub_file_system = FileSystem::Handle());
explicit FileSystemTemporary(const String &tag, const String &temporary_directory = String(), const FileSystem::Handle &sub_file_system = FileSystem::Handle());
~FileSystemTemporary();

virtual bool is_file(const String &filename);
Expand All @@ -102,15 +105,18 @@ namespace synfig
void set_sub_file_system(const FileSystem::Handle &file_system)
{ this->sub_file_system = file_system; }

bool empty() const { return files.empty() && meta.empty(); }
bool empty() const { return files.empty(); }

bool save_changes(const FileSystem::Handle &sub_file_system, bool as_copy);
bool save_changes_copy(const FileSystem::Handle &sub_file_system) const;
bool save_changes();
void discard_changes();

void reset_temporary_filename_base();
const String& get_tag() const { return tag; }
const String& get_temporary_directory() const { return temporary_directory; }
const String& get_temporary_filename_base() const { return temporary_filename_base; }
void reset_temporary_filename_base() { reset_temporary_filename_base(get_tag(), get_temporary_directory()); }
void reset_temporary_filename_base(const String &tag, const String &temporary_directory);

String get_meta(const String &key) const;
void set_meta(const String &key, const String &value);
Expand All @@ -125,13 +131,13 @@ namespace synfig
{ autosave = value; }

bool save_temporary() const;
bool open_temporary(const String &filename_base);

static String get_temporary_directory();
static String generate_temporary_filename_base();
static String generate_temporary_filename();
bool open_temporary(const String &filename);

static String get_system_temporary_directory();
static String generate_temporary_filename_base(const String &tag);
static String generate_system_temporary_filename(const String &tag);
static String generate_indexed_temporary_filename(const FileSystem::Handle &fs, const String &filename);
static bool scan_temporary_directory(const String &tag, FileList &out_files, const String &dirname = String());
};

}
Expand Down
13 changes: 7 additions & 6 deletions synfig-core/src/synfig/layers/layer_bitmap.cpp
Expand Up @@ -71,12 +71,13 @@ using namespace etl;

synfig::Layer_Bitmap::Layer_Bitmap():
Layer_Composite (1.0,Color::BLEND_COMPOSITE),
method (SOFTWARE),
param_tl (Point(-0.5,0.5)),
param_br (Point(0.5,-0.5)),
param_c (int(1)),
param_gamma_adjust (Real(1.0)),
trimmed (false)
method (SOFTWARE),
surface_modification_id (0),
param_tl (Point(-0.5,0.5)),
param_br (Point(0.5,-0.5)),
param_c (int(1)),
param_gamma_adjust (Real(1.0)),
trimmed (false)
{
SET_INTERPOLATION_DEFAULTS();
SET_STATIC_DEFAULTS();
Expand Down
12 changes: 12 additions & 0 deletions synfig-core/src/synfig/layers/layer_bitmap.h
Expand Up @@ -30,6 +30,7 @@

#include "layer_composite.h"
#include <synfig/surface.h>
#include <synfig/guid.h>
#include <synfig/target.h> // for RenderMethod

#include <synfig/rendering/surface.h>
Expand All @@ -51,6 +52,8 @@ class Layer_Bitmap : public Layer_Composite, public Layer_NoDeform
const Color& filter(Color& c)const;
const CairoColor& filter(CairoColor& c)const;
RenderMethod method;

GUID surface_modification_id;
public:
typedef etl::handle<Layer_Bitmap> Handle;

Expand All @@ -70,6 +73,15 @@ class Layer_Bitmap : public Layer_Composite, public Layer_NoDeform

synfig::Surface& get_surface() const;

GUID get_surface_modification_id() const
{ return surface_modification_id; }
bool is_surface_modified() const
{ return (bool)get_surface_modification_id(); }
void add_surface_modification_id(const GUID &modification_id)
{ surface_modification_id ^= modification_id; }
void reset_surface_modification_id()
{ surface_modification_id = GUID::zero(); }

virtual bool set_param(const String & param, const ValueBase & value);

virtual ValueBase get_param(const String & param)const;
Expand Down
3 changes: 3 additions & 0 deletions synfig-core/src/synfig/layers/layer_pastecanvas.h
Expand Up @@ -51,6 +51,9 @@ namespace synfig {
*/
class Layer_PasteCanvas : public Layer_Composite, public Layer_NoDeform
{
public:
typedef etl::handle<Layer_PasteCanvas> Handle;

private:
//! Parameter: (Origin) Position offset
ValueBase param_origin;
Expand Down
2 changes: 1 addition & 1 deletion synfig-studio/configure.ac
Expand Up @@ -301,7 +301,7 @@ AC_COMPILE_IFELSE([
# -- H E A D E R S --------------------------------------------

AC_CHECK_HEADERS([unistd.h signal.h fcntl.h])
AC_CHECK_HEADERS([sys/types.h sys/wait.h sys/stat.h sys/time.h sys/resource.h sys/errno.h])
AC_CHECK_HEADERS([sys/types.h sys/wait.h sys/stat.h sys/errno.h])

# -- T Y P E S & S T R U C T S --------------------------------

Expand Down

0 comments on commit 0dde721

Please sign in to comment.