From 134dad8d5fc2530d0244806cede1e7b32fe2b8d8 Mon Sep 17 00:00:00 2001 From: David Capello Date: Tue, 21 Apr 2015 16:52:41 -0300 Subject: [PATCH] Use an object to implement crash::write_document() to avoid versions and dir params --- src/app/crash/write_document.cpp | 209 ++++++++++++++++++------------- 1 file changed, 123 insertions(+), 86 deletions(-) diff --git a/src/app/crash/write_document.cpp b/src/app/crash/write_document.cpp index 9dd1ccb47..37f247c84 100644 --- a/src/app/crash/write_document.cpp +++ b/src/app/crash/write_document.cpp @@ -55,75 +55,138 @@ namespace { typedef std::map Versions; static std::map g_documentObjects; -template -void save_object(const char* prefix, T* obj, WriteFunc write_func, Versions& versions, const std::string& dir) -{ - if (!obj->version()) - obj->incrementVersion(); - - if (versions[obj->id()] != obj->version()) { - OFSTREAM(dir, s, prefix ? prefix + base::convert_to(obj->id()): "doc"); - write_func(s, obj); - versions[obj->id()] = obj->version(); - - TRACE(" - %s %d saved with version %d\n", - prefix, obj->id(), obj->version()); +class Writer { +public: + Writer(const std::string& dir, app::Document* doc) + : m_dir(dir) + , m_doc(doc) + , m_versions(g_documentObjects[doc->id()]) { } - else { - TRACE(" - Ignoring %s %d (version %d already saved)\n", - prefix, obj->id(), obj->version()); - } -} -void write_document_file(std::ofstream& s, app::Document* doc) -{ - write32(s, doc->sprite()->id()); - write_string(s, doc->filename()); -} + void saveDocument() { + Sprite* spr = m_doc->sprite(); -void write_sprite(std::ofstream& s, Sprite* spr) -{ - write8(s, spr->pixelFormat()); - write16(s, spr->width()); - write16(s, spr->height()); - write32(s, spr->transparentColor()); + saveObject(nullptr, m_doc, &Writer::writeDocumentFile); + saveObject("spr", spr, &Writer::writeSprite); - // Frame durations - write32(s, spr->totalFrames()); - for (frame_t fr = 0; fr < spr->totalFrames(); ++fr) - write32(s, spr->frameDuration(fr)); + ////////////////////////////////////////////////////////////////////// + // Create one stream for each object - // IDs of all main layers - std::vector layers; - spr->getLayersList(layers); - write32(s, layers.size()); - for (Layer* lay : layers) - write32(s, lay->id()); + for (Palette* pal : spr->getPalettes()) + saveObject("pal", pal, &Writer::writePalette); - // IDs of all palettes - write32(s, spr->getPalettes().size()); - for (Palette* pal : spr->getPalettes()) - write32(s, pal->id()); -} + for (FrameTag* frtag : spr->frameTags()) + saveObject("frtag", frtag, &Writer::writeFrameTag); -void write_layer_structure(std::ofstream& s, Layer* lay) -{ - write32(s, static_cast(lay->flags())); // Flags - write16(s, static_cast(lay->type())); // Type - write_string(s, lay->name()); + std::vector layers; + spr->getLayersList(layers); + for (Layer* lay : layers) + saveObject("lay", lay, &Writer::writeLayerStructure); - if (lay->type() == ObjectType::LayerImage) { - CelConstIterator it, begin = static_cast(lay)->getCelBegin(); - CelConstIterator end = static_cast(lay)->getCelEnd(); + for (Cel* cel : spr->cels()) + saveObject("cel", cel, &Writer::writeCel); - // Cels - write32(s, static_cast(lay)->getCelsCount()); - for (it=begin; it != end; ++it) { - const Cel* cel = *it; - write32(s, cel->id()); + // Images (CelData) + for (Cel* cel : spr->uniqueCels()) { + saveObject("celdata", cel->data(), &Writer::writeCelData); + saveObject("img", cel->image(), &Writer::writeImage); } } -} + +private: + + void writeDocumentFile(std::ofstream& s, app::Document* doc) { + write32(s, doc->sprite()->id()); + write_string(s, doc->filename()); + } + + void writeSprite(std::ofstream& s, Sprite* spr) { + write8(s, spr->pixelFormat()); + write16(s, spr->width()); + write16(s, spr->height()); + write32(s, spr->transparentColor()); + + // Frame durations + write32(s, spr->totalFrames()); + for (frame_t fr = 0; fr < spr->totalFrames(); ++fr) + write32(s, spr->frameDuration(fr)); + + // IDs of all main layers + std::vector layers; + spr->getLayersList(layers); + write32(s, layers.size()); + for (Layer* lay : layers) + write32(s, lay->id()); + + // IDs of all palettes + write32(s, spr->getPalettes().size()); + for (Palette* pal : spr->getPalettes()) + write32(s, pal->id()); + } + + void writeLayerStructure(std::ofstream& s, Layer* lay) { + write32(s, static_cast(lay->flags())); // Flags + write16(s, static_cast(lay->type())); // Type + write_string(s, lay->name()); + + if (lay->type() == ObjectType::LayerImage) { + CelConstIterator it, begin = static_cast(lay)->getCelBegin(); + CelConstIterator end = static_cast(lay)->getCelEnd(); + + // Cels + write32(s, static_cast(lay)->getCelsCount()); + for (it=begin; it != end; ++it) { + const Cel* cel = *it; + write32(s, cel->id()); + } + } + } + + void writeCel(std::ofstream& s, Cel* cel) { + write_cel(s, cel); + } + + void writeCelData(std::ofstream& s, CelData* celdata) { + write_celdata(s, celdata); + } + + void writeImage(std::ofstream& s, Image* img) { + write_image(s, img); + } + + void writePalette(std::ofstream& s, Palette* pal) { + write_palette(s, pal); + } + + void writeFrameTag(std::ofstream& s, FrameTag* frameTag) { + write_frame_tag(s, frameTag); + } + + template + void saveObject(const char* prefix, T* obj, void (Writer::*writeMember)(std::ofstream&, T*)) { + if (!obj->version()) + obj->incrementVersion(); + + if (m_versions[obj->id()] != obj->version()) { + std::string fn = (prefix ? prefix + base::convert_to(obj->id()): "doc"); + + OFSTREAM(m_dir, s, fn); + (this->*writeMember)(s, obj); + m_versions[obj->id()] = obj->version(); + + TRACE(" - %s %d saved with version %d\n", + prefix, obj->id(), obj->version()); + } + else { + TRACE(" - Ignoring %s %d (version %d already saved)\n", + prefix, obj->id(), obj->version()); + } + } + + std::string m_dir; + app::Document* m_doc; + Versions& m_versions; +}; } // anonymous namespace @@ -132,34 +195,8 @@ void write_layer_structure(std::ofstream& s, Layer* lay) void write_document(const std::string& dir, app::Document* doc) { - Versions& versions = g_documentObjects[doc->id()]; - Sprite* spr = doc->sprite(); - - save_object(nullptr, doc, write_document_file, versions, dir); - save_object("spr", spr, write_sprite, versions, dir); - - ////////////////////////////////////////////////////////////////////// - // Create one stream for each object - - for (Palette* pal : spr->getPalettes()) - save_object("pal", pal, write_palette, versions, dir); - - for (FrameTag* frtag : spr->frameTags()) - save_object("frtag", frtag, write_frame_tag, versions, dir); - - std::vector layers; - spr->getLayersList(layers); - for (Layer* lay : layers) - save_object("lay", lay, write_layer_structure, versions, dir); - - for (Cel* cel : spr->cels()) - save_object("cel", cel, write_cel, versions, dir); - - // Images (CelData) - for (Cel* cel : spr->uniqueCels()) { - save_object("celdata", cel->data(), write_celdata, versions, dir); - save_object("img", cel->image(), write_image, versions, dir); - } + Writer writer(dir, doc); + writer.saveDocument(); } void delete_document_internals(app::Document* doc)