Skip to content

[WIP] Save undo history in .aseprite-undo file - #6022

Draft
dacap wants to merge 1 commit into
betafrom
save-undo-history
Draft

dacap wants to merge 1 commit into
betafrom
save-undo-history

Conversation

@dacap

@dacap dacap commented Sep 4, 2026

Copy link
Copy Markdown
Member

This is a work-in-progress draft to implement #3718. There is a lot of work to be done yet, a lot of PRINTARGS for debugging purposes, etc.

The idea behind .aseprite-undo files is to create a text format (as it's right now, for debugging purposes), and a binary format (to reduce the size). Then we should be able to embed the binary format in a .aseprite chunk in a future.

Don't expect compatibility/stability with these .aseprite-undo files at the moment (right now there are crashes, a lot).

@dacap dacap self-assigned this Sep 4, 2026
@dacap dacap added this to the v1.4-beta1 milestone Sep 4, 2026
@dacap dacap linked an issue Sep 4, 2026 that may be closed by this pull request

@aseprite-bot aseprite-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

Comment thread src/app/cmd_decode.cpp
break;

Cmd* cmd = nullptr;
switch (t) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: switching on non-enum value without default case may not cover all cases [bugprone-switch-missing-default-case]

  switch (t) {
  ^

Comment thread src/app/cmd_serial.cpp
void TextDecCmdSerial::cmdtype(cmdtype_t& t)
{
auto tok = nextToken();
t = make_cmdtype(tok.size() > 0 ? tok[0] : ' ',

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]

Suggested change
t = make_cmdtype(tok.size() > 0 ? tok[0] : ' ',
t = make_cmdtype(!tok.empty() ? tok[0] : ' ',
Additional context

/usr/include/c++/15/bits/basic_string.h:1330: method 'basic_string'::empty() defined here

      empty() const _GLIBCXX_NOEXCEPT
      ^

Comment thread src/app/cmd_serial.h Outdated

class CmdSerial : public doc::SubObjectsIO {
public:
enum Coding { Decoding = 0, Encoding = 1 };

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: enum 'Coding' uses a larger base type ('unsigned int', size: 4 bytes) than necessary for its value set, consider using 'std::uint8_t' (1 byte) as the base type to reduce its size [performance-enum-size]

  enum Coding { Decoding = 0, Encoding = 1 };
       ^

Comment thread src/app/cmd_serial.h
doc::CelDataRef getCelDataRef(doc::ObjectId celdataId) override;

protected:
doc::Sprite* m_sprite = nullptr;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member variable 'm_sprite' has protected visibility [misc-non-private-member-variables-in-classes]

  doc::Sprite* m_sprite = nullptr;
               ^

Comment thread src/app/cmd_serial.h

protected:
doc::Sprite* m_sprite = nullptr;
dio::FileInterface* m_f = nullptr;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member variable 'm_f' has protected visibility [misc-non-private-member-variables-in-classes]

  dio::FileInterface* m_f = nullptr;
                      ^

Comment thread src/doc/object_io.h
}

template<>
inline void write_object(std::ostream& os, Cel* cel)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: function template specialization 'doc::write_object<doc::Cel *>' has a primary template declaration with different parameter names [readability-inconsistent-declaration-parameter-name]

inline void write_object(std::ostream& os, Cel* cel)
            ^
Additional context

src/doc/object_io.h:18: the primary template declaration seen here

void write_object(std::ostream& os, T obj)
     ^

src/doc/object_io.h:30: differing parameters are named here: ('cel'), in primary template declaration: ('obj')

inline void write_object(std::ostream& os, Cel* cel)
            ^

Comment thread src/doc/object_io.h
}

template<>
inline void write_object(std::ostream& os, Layer* layer)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: function template specialization 'doc::write_object<doc::Layer *>' has a primary template declaration with different parameter names [readability-inconsistent-declaration-parameter-name]

inline void write_object(std::ostream& os, Layer* layer)
            ^
Additional context

src/doc/object_io.h:18: the primary template declaration seen here

void write_object(std::ostream& os, T obj)
     ^

src/doc/object_io.h:42: differing parameters are named here: ('layer'), in primary template declaration: ('obj')

inline void write_object(std::ostream& os, Layer* layer)
            ^

Comment thread src/doc/object_io.h
}

template<>
inline void write_object(std::ostream& os, ImageRef image)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: function template specialization 'doc::write_object<std::shared_ptrdoc::Image>' has a primary template declaration with different parameter names [readability-inconsistent-declaration-parameter-name]

inline void write_object(std::ostream& os, ImageRef image)
            ^
Additional context

src/doc/object_io.h:18: the primary template declaration seen here

void write_object(std::ostream& os, T obj)
     ^

src/doc/object_io.h:48: differing parameters are named here: ('image'), in primary template declaration: ('obj')

inline void write_object(std::ostream& os, ImageRef image)
            ^

Comment thread src/doc/object_io.h
}

template<>
inline void write_object(std::ostream& os, ImageRef image)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: the parameter 'image' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param]

inline void write_object(std::ostream& os, ImageRef image)
                                                    ^

Comment thread src/doc/object_io.h
}

template<>
inline ImageRef read_object(std::istream& is, SubObjectsIO* subObjects)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: parameter 'subObjects' is unused [misc-unused-parameters]

Suggested change
inline ImageRef read_object(std::istream& is, SubObjectsIO* subObjects)
inline ImageRef read_object(std::istream& is, SubObjectsIO* /*subObjects*/)

@dacap
dacap force-pushed the save-undo-history branch 2 times, most recently from 9cf130a to a649d53 Compare September 7, 2026 18:12
Base automatically changed from refactor-cmd-ctx to beta September 7, 2026 18:36

@aseprite-bot aseprite-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

Comment thread src/app/cmd_serial.h
doc::Sprite* m_sprite = nullptr;
dio::FileInterface* m_f = nullptr;
IdsMap m_idsMap;
Coding m_coding = Coding::Decoding;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member variable 'm_idsMap' has protected visibility [misc-non-private-member-variables-in-classes]

  IdsMap m_idsMap;
         ^

@aseprite-bot aseprite-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

Comment thread src/app/cmd_serial.h
doc::Sprite* m_sprite = nullptr;
dio::FileInterface* m_f = nullptr;
IdsMap m_idsMap;
Coding m_coding = Coding::Decoding;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member variable 'm_coding' has protected visibility [misc-non-private-member-variables-in-classes]

  Coding m_coding = Coding::Decoding;
         ^

@dacap
dacap force-pushed the save-undo-history branch from a649d53 to 57a330a Compare September 8, 2026 22:02

@aseprite-bot aseprite-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

Comment thread src/app/cmd_serial.h
dio::FileInterface* m_f = nullptr;
IdsMap m_idsMap;
Coding m_coding = Coding::Decoding;
bool m_beforeCurState = true;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member variable 'm_beforeCurState' has protected visibility [misc-non-private-member-variables-in-classes]

  bool m_beforeCurState = true;
       ^

Comment thread src/app/cmd_serial.h
void operator()(gfx::Point& pt) override;
void operator()(gfx::Rect& rc) override;
void operator()(gfx::Region& rg) override;
void operator()(serial_span& buf) override;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: function 'app::TextDecCmdSerial::operator()' has a definition with different parameter names [readability-inconsistent-declaration-parameter-name]

  void operator()(serial_span& buf) override;
       ^
Additional context

src/app/cmd_serial.cpp:352: the definition seen here

void TextDecCmdSerial::operator()(serial_span& span)
                       ^

src/app/cmd_serial.h:126: differing parameters are named here: ('buf'), in definition: ('span')

  void operator()(serial_span& buf) override;
       ^

@aseprite-bot aseprite-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

Comment thread src/app/cmd/patch_cel.h

const doc::Image* m_patch;
const gfx::Region& m_region;
const doc::Image* m_patch = nullptr;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member variable 'm_patch' has protected visibility [misc-non-private-member-variables-in-classes]

  const doc::Image* m_patch = nullptr;
                    ^

Comment thread src/app/cmd/patch_cel.h
const doc::Image* m_patch;
const gfx::Region& m_region;
const doc::Image* m_patch = nullptr;
const gfx::Region* m_region = nullptr;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member variable 'm_region' has protected visibility [misc-non-private-member-variables-in-classes]

  const gfx::Region* m_region = nullptr;
                     ^

Comment thread src/app/cmd_serial.h
void operator()(gfx::Point& pt) override;
void operator()(gfx::Rect& rc) override;
void operator()(gfx::Region& rg) override;
void operator()(serial_span& buf) override;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: function 'app::TextDecCmdSerial::operator()' has a definition with different parameter names [readability-inconsistent-declaration-parameter-name]

  void operator()(serial_span& buf) override;
       ^
Additional context

src/app/cmd_serial.cpp:367: the definition seen here

void TextDecCmdSerial::operator()(serial_span& span)
                       ^

src/app/cmd_serial.h:128: differing parameters are named here: ('buf'), in definition: ('span')

  void operator()(serial_span& buf) override;
       ^

dacap added a commit to dacap/laf that referenced this pull request Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Saved Undo History

2 participants