Files
sanspie a46347e2c6
ci-platforms / darwin arm64 smoke (push) Skipped
ci / build (amd64, linux, ubuntu-24.04) (push) Failing after 12m19s
ci-platforms / darwin amd64 smoke (push) Skipped
ci-platforms / windows amd64 smoke (push) Skipped
github-native / gitea-pending (push) Skipped
github-native / darwin amd64 native (push) Skipped
github-native / linux amd64 native (push) Skipped
github-native / windows amd64 native (push) Skipped
github-native / darwin arm64 native (push) Skipped
github-native / gitea-result (push) Skipped
ci / checks (push) Failing after 23m57s
ci / release (push) Skipped
GitHub / windows amd64 native GitHub-hosted native CI: failure
GitHub / darwin arm64 native GitHub-hosted native CI: failure
GitHub / darwin amd64 native GitHub-hosted native CI: failure
GitHub / linux amd64 native GitHub-hosted native CI: success
editor: add art studio and stage 12.5 workflows
2026-11-08 18:47:57 +03:00

59 lines
1.4 KiB
Go

package history
// ByteCommand is optional: pixel commands report retained COW data while scene
// commands keep their established step-count limit. It is not another journal.
type ByteCommand interface{ HistoryBytes() int64 }
func entryBytes(e entry) int64 {
var n int64
for _, c := range e.cmds {
if b, ok := c.(ByteCommand); ok {
n += max(0, b.HistoryBytes())
}
}
return n
}
// TrimBytes releases oldest undo entries to enforce an authoring memory budget.
// Call after a completed Exec, never inside a transaction. The closest undo and
// redo steps are retained. A fresh backing slice releases discarded COW images.
func (h *History) TrimBytes(limit int64) {
if h.tx != nil || limit < 1 {
return
}
var used int64
for _, e := range h.undo {
used += entryBytes(e)
}
for _, e := range h.redo {
used += entryBytes(e)
}
drop := 0
for used > limit && drop < len(h.undo) {
used -= entryBytes(h.undo[drop])
h.base = h.undo[drop].seq
drop++
}
if drop > 0 {
h.undo = append([]entry(nil), h.undo[drop:]...)
}
// The front of redo is the most distant future step.
dropRedo := 0
for used > limit && dropRedo < len(h.redo) {
used -= entryBytes(h.redo[dropRedo])
if h.redo[dropRedo].seq == h.saved {
h.savedLost = true
}
dropRedo++
}
if dropRedo > 0 {
h.redo = append([]entry(nil), h.redo[dropRedo:]...)
}
if len(h.redo) == 0 {
h.redo = nil
}
if drop > 0 || dropRedo > 0 {
h.notify()
}
}