{"id":20355907,"url":"https://github.com/hedzr/undo-cxx","last_synced_at":"2025-04-12T02:51:11.229Z","repository":{"id":96618411,"uuid":"417999009","full_name":"hedzr/undo-cxx","owner":"hedzr","description":"a c++17 undo/redo subsystem (linear or restricted non-linear)","archived":false,"fork":false,"pushed_at":"2024-12-18T23:30:43.000Z","size":323,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-25T22:35:32.880Z","etag":null,"topics":["cmake","cpp","cpp17","cxx17","cxx17-library","history-management","memento-pattern","non-linear","state-machine","undo","undo-framework","undo-library","undo-redo","undoable","undomanager"],"latest_commit_sha":null,"homepage":"https://hedzr.com/c++/algorithm/cxx17-memento-pattern/","language":"CMake","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hedzr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":"https://paypal.me/hezr/5"}},"created_at":"2021-10-17T02:26:59.000Z","updated_at":"2025-01-10T20:42:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"740abba2-f012-4f84-95fb-73a354fd7f77","html_url":"https://github.com/hedzr/undo-cxx","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hedzr%2Fundo-cxx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hedzr%2Fundo-cxx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hedzr%2Fundo-cxx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hedzr%2Fundo-cxx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hedzr","download_url":"https://codeload.github.com/hedzr/undo-cxx/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248509255,"owners_count":21115970,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cmake","cpp","cpp17","cxx17","cxx17-library","history-management","memento-pattern","non-linear","state-machine","undo","undo-framework","undo-library","undo-redo","undoable","undomanager"],"created_at":"2024-11-14T23:14:26.664Z","updated_at":"2025-04-12T02:51:11.209Z","avatar_url":"https://github.com/hedzr.png","language":"CMake","funding_links":["https://paypal.me/hezr/5"],"categories":[],"sub_categories":[],"readme":"# undo-cxx\n\n![CMake Build Matrix](https://github.com/hedzr/undo-cxx/workflows/CMake%20Build%20Matrix/badge.svg) \u003c!--\n![CMake Build Matrix](https://github.com/hedzr/undo-cxx/workflows/CMake%20Build%20Matrix/badge.svg?event=release)\n--\u003e [![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/hedzr/undo-cxx.svg?label=release)](https://github.com/hedzr/undo-cxx/releases)\n\n`undo-cxx` C++17/20 library provides a undo/redo subsystem (linear or restricted non-linear).\n\n## Newest\n\n- v0.3.2, security patch for github workflow; fix arch detections in dummy project - affect generating undo-cxx_config.hh\n- v0.3.1, added `newest_item()` for #1\n- v0.3.0, build passed for c++20\n- v0.2.5, upgrade undo-log.hh, undo-util.hh, undo-zcore.hh, and cxx-macros.cmake\n- v0.2.3, upgrade cmake scripts\n- _v0.2.2_, fixes around the project files\n- v0.2.1, first implementation of Undoable/Redoable\n\n## Features\n\n- Highly configurable/customizable\n- Undo/Redo subsystem\n  - restricted non-linear undo (batch undo+erase+redo)\n  - todo: full-functional non-linear\n  - limitless undo/redo levels, or limited with `max_size(n)`\n- Bundled with Command subsystem\n  - undoable/redoable\n  - Composite command (`undo_cxx::composite_cmd_t\u003c\u003e`): composite multi-commands as one (groupable)\n  - Composite memento (`undo_cxx::state_t\u003c\u003e`) for composite-command\n\n## Examples\n\nThe following code is a part of a word-processor:\n\n```cpp\n#include \u003cundo_cxx.hh\u003e\n\nnamespace dp { namespace undo { namespace test {\n\n    template\u003ctypename State\u003e\n    class FontStyleCmd : public undo_cxx::cmd_t\u003cState\u003e {\n    public:\n        ~FontStyleCmd() {}\n        FontStyleCmd() {}\n        FontStyleCmd(std::string const \u0026default_state_info)\n            : _info(default_state_info) {}\n        UNDO_CXX_DEFINE_DEFAULT_CMD_TYPES(FontStyleCmd, undo_cxx::cmd_t);\n\n    protected:\n        void do_execute(CmdSP \u0026sender, ContextT \u0026) override {\n            UNUSED(sender);\n            // ... do sth to add/remove font style to/from\n            // current selection in current editor ...\n            std::cout \u003c\u003c \"\u003c\u003c\" \u003c\u003c _info \u003c\u003c \"\u003e\u003e\" \u003c\u003c '\\n';\n        }\n        MementoPtr save_state_impl(CmdSP \u0026sender, ContextT \u0026) override {\n            return std::make_unique\u003cMemento\u003e(sender, _info);\n        }\n        void undo_impl(CmdSP \u0026sender, ContextT \u0026, Memento \u0026memento) override {\n            memento = _info;\n            memento.command(sender);\n        }\n        void redo_impl(CmdSP \u0026sender, ContextT \u0026, Memento \u0026memento) override {\n            memento = _info;\n            memento.command(sender);\n        }\n\n    private:\n        std::string _info{\"make italic\"};\n    };\n\n    template\u003ctypename State\u003e\n    class UndoCmd : public undo_cxx::base_undo_cmd_t\u003cState\u003e {\n    public:\n        ~UndoCmd() {}\n        using undo_cxx::base_undo_cmd_t\u003cState\u003e::base_undo_cmd_t;\n        UndoCmd(std::string const \u0026default_state_info)\n            : _info(default_state_info) {}\n        UNDO_CXX_DEFINE_DEFAULT_CMD_TYPES(UndoCmd, undo_cxx::base_undo_cmd_t);\n\n    protected:\n        void do_execute(CmdSP \u0026sender, ContextT \u0026ctx) override {\n            std::cout \u003c\u003c \"\u003c\u003c\" \u003c\u003c _info \u003c\u003c \"\u003e\u003e\" \u003c\u003c '\\n';\n            Base::do_execute(sender, ctx);\n        }\n        MementoPtr save_state_impl(CmdSP \u0026sender, ContextT \u0026) override {\n            return std::make_unique\u003cMemento\u003e(sender, _info);\n        }\n        void undo_impl(CmdSP \u0026sender, ContextT \u0026, Memento \u0026memento) override {\n            memento = \"do 'undo'\";\n            // auto sp = typename Memento::CmdSP(this);\n            memento.command(sender);\n        }\n        void redo_impl(CmdSP \u0026sender, ContextT \u0026, Memento \u0026memento) override {\n            memento = \"do 'un-undo' again\";\n            memento.command(sender);\n        }\n\n    private:\n        std::string _info{\"do 'undo'\"};\n    };\n\n    template\u003ctypename State\u003e\n    class RedoCmd : public undo_cxx::base_redo_cmd_t\u003cState\u003e {\n    public:\n        ~RedoCmd() {}\n        using undo_cxx::base_redo_cmd_t\u003cState\u003e::base_redo_cmd_t;\n        RedoCmd(std::string const \u0026default_state_info)\n            : _info(default_state_info) {}\n        UNDO_CXX_DEFINE_DEFAULT_CMD_TYPES(RedoCmd, undo_cxx::base_redo_cmd_t);\n\n    protected:\n        void do_execute(CmdSP \u0026sender, ContextT \u0026ctx) override {\n            std::cout \u003c\u003c \"\u003c\u003c\" \u003c\u003c _info \u003c\u003c \"\u003e\u003e\" \u003c\u003c '\\n';\n            Base::do_execute(sender, ctx);\n        }\n        MementoPtr save_state_impl(CmdSP \u0026sender, ContextT \u0026) override {\n            return std::make_unique\u003cMemento\u003e(sender, _info);\n        }\n        void undo_impl(CmdSP \u0026sender, ContextT \u0026, Memento \u0026memento) override {\n            memento = \"do 'redo'\";\n            memento.command(sender);\n        }\n        void redo_impl(CmdSP \u0026sender, ContextT \u0026, Memento \u0026memento) override {\n            memento = \"do 'un-redo' again\";\n            memento.command(sender);\n        }\n\n    private:\n        std::string _info{\"do 'redo'\"};\n    };\n\n}}} // namespace dp::undo::test\n\nvoid test_undo_sys() {\n    using namespace dp::undo::test;\n    using namespace dp::undo::bugs;\n\n    using State = std::string;\n    using M = undo_cxx::undoable_cmd_system_t\u003cState\u003e;\n    using UndoCmdT = UndoCmd\u003cState\u003e;\n    using RedoCmdT = RedoCmd\u003cState\u003e;\n    using FontStyleCmdT = FontStyleCmd\u003cState\u003e;\n\n    M undoable_cmd_system;\n\n    // do some stuffs\n\n    undoable_cmd_system.invoke\u003cFontStyleCmdT\u003e(\"italic state1\");\n    undoable_cmd_system.invoke\u003cFontStyleCmdT\u003e(\"italic-bold state2\");\n    undoable_cmd_system.invoke\u003cFontStyleCmdT\u003e(\"underline state3\");\n    undoable_cmd_system.invoke\u003cFontStyleCmdT\u003e(\"italic state4\");\n\n    // and try to undo or redo\n\n    undoable_cmd_system.invoke\u003cUndoCmdT\u003e(\"undo 1\");\n    undoable_cmd_system.invoke\u003cUndoCmdT\u003e(\"undo 2\");\n    undoable_cmd_system.invoke\u003cRedoCmdT\u003e(\"redo 1\");\n    undoable_cmd_system.invoke\u003cUndoCmdT\u003e(\"undo 3\");\n    undoable_cmd_system.invoke\u003cUndoCmdT\u003e(\"undo 4\");\n}\n\nint main() {\n    test_undo_sys();\n    return 0;\n}\n```\n\n## Build Options\n\n### Build with CMake\n\n\u003e 1. gcc 10+: passed\n\u003e 2. clang 12+: passed\n\u003e 3. msvc build tool 16.7.2, 16.8.5 (VS2019 or Build Tool) passed\n\nninja is optional for faster building.\n\n```bash\n# configure\ncmake -S . -B build/ -G Ninja\n# build\ncmake --build build/\n# install\ncmake --install build/\n# Or:cmake --build build/ --target install\n#\n# Sometimes sudo it:\n#   sudo cmake --build build/ --target install\n# Or manually:\n#   cmake --install build/ --prefix ./install --strip\n#   sudo cp -R ./install/include/* /usr/local/include/\n#   sudo cp -R ./install/lib/cmake/undo_cxx /usr/local/lib/cmake/\n```\n\n### Other CMake Options\n\n1. `UNDO_CXX_BUILD_TESTS_EXAMPLES`=OFF\n2. `UNDO_CXX_BUILD_DOCS`=OFF\n3. ...\n\n## Thanks to JODL\n\nThanks to [JetBrains](https://www.jetbrains.com/?from=undo-cxx) for donating product licenses to help develop **undo-cxx** [![jetbrains](https://gist.githubusercontent.com/hedzr/447849cb44138885e75fe46f1e35b4a0/raw/bedfe6923510405ade4c034c5c5085487532dee4/jetbrains-variant-4.svg)](https://www.jetbrains.com/?from=hedzr/undo-cxx)\n\n## LICENSE\n\nApache 2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhedzr%2Fundo-cxx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhedzr%2Fundo-cxx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhedzr%2Fundo-cxx/lists"}