Save saves a new action as next action to be undone, with given action data and current full state of the system (either of which are optional). The state must be available for saving -- we do not copy in case we save the full raw copy.
(action, data string, state []string)
| 114 | // The state must be available for saving -- we do not copy in case we save the |
| 115 | // full raw copy. |
| 116 | func (us *Stack) Save(action, data string, state []string) { |
| 117 | us.Mu.Lock() // we start lock |
| 118 | if us.Records == nil { |
| 119 | if us.RawInterval == 0 { |
| 120 | us.RawInterval = DefaultRawInterval |
| 121 | } |
| 122 | us.Records = make([]*Record, 1) |
| 123 | us.Index = 0 |
| 124 | nr := &Record{Action: action, Data: data, Raw: state} |
| 125 | us.Records[0] = nr |
| 126 | us.Mu.Unlock() |
| 127 | return |
| 128 | } |
| 129 | // recs will be [old..., Index] after this |
| 130 | us.Index++ |
| 131 | var nr *Record |
| 132 | if len(us.Records) > us.Index { |
| 133 | us.Records = us.Records[:us.Index+1] |
| 134 | nr = us.Records[us.Index] |
| 135 | } else if len(us.Records) == us.Index { |
| 136 | nr = &Record{} |
| 137 | us.Records = append(us.Records, nr) |
| 138 | } else { |
| 139 | log.Printf("undo.Stack error: index: %d > len(um.Recs): %d\n", us.Index, len(us.Records)) |
| 140 | us.Index = len(us.Records) |
| 141 | nr = &Record{} |
| 142 | us.Records = append(us.Records, nr) |
| 143 | } |
| 144 | nr.Init(action, data) |
| 145 | if state == nil { |
| 146 | us.Mu.Unlock() |
| 147 | return |
| 148 | } |
| 149 | go us.SaveState(nr, us.Index, state) // fork off save -- it will unlock when done |
| 150 | // now we return straight away, with lock still held |
| 151 | } |
| 152 | |
| 153 | // MustSaveUndoStart returns true if the current state must be saved as the start of |
| 154 | // the first Undo action when at the end of the stack. If this returns true, then |