123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- #include <string.h>
- #include "state.h"
- static void
- past_dispose(void *dat, void *extra)
- {
- Branch_act *b_act = dat;
- State *state = extra;
- if (state->act_dispose)
- state->act_dispose(&b_act->act, state->extra);
- else
- free(b_act->act.key);
- free(b_act);
- }
- Nit_error
- state_init(State *state, Acts *acts, uint64_t branch,
- Act_dispose dispose, void *extra)
- {
- Nit_error error;
- Branch_act *root_act;
- state->act_dispose = dispose;
- state->disposer.dispose = past_dispose;
- state->disposer.extra = state;
- if (!(root_act = malloc(sizeof(*root_act))))
- return NIT_ERROR_MEMORY;
- root_act->branch = branch;
- root_act->act.key = NULL;
- root_act->act.real = 1;
- root_act->real_next = NULL;
- if ((error = trie_init(&state->past, &state->disposer,
- root_act))) {
- free(root_act);
- return error;
- }
- state->end = state->past.root;
- state->acts = acts;
- state->extra = extra;
- state->undoing = 0;
- state->branch = branch;
- return NIT_ERROR_FINE;
- }
- void
- state_dispose(State *state)
- {
- trie_dispose(&state->past);
- }
- Nit_error
- state_do(State *state, uint32_t key_len, const void *key,
- void *dat, void *args, int real)
- {
- Trie_entry *tmp;
- Branch_act *b_act = malloc(sizeof(*b_act));
- Nit_error error;
- if (real && !((Branch_act *) state->end->dat)->act.real)
- return NIT_ERROR_ROI;
- if (!b_act)
- return NIT_ERROR_MEMORY;
- if (!(b_act->act.key = malloc(key_len))) {
- free(b_act);
- return NIT_ERROR_MEMORY;
- }
- memcpy(b_act->act.key, key, (b_act->act.key_len = key_len));
- b_act->act.real = real;
- b_act->act.type = ACT_DO;
- b_act->act.dat = dat;
- b_act->act.args = args;
- b_act->branch = state->branch + (state->undoing ? 1 : 0);
- if ((error = acts_act(state->acts, &b_act->act, state->extra))) {
- free(b_act->act.key);
- free(b_act);
- return error;
- }
- if (!(tmp = trie_add(&state->past, state->end, sizeof(state->branch),
- &state->branch, b_act))) {
- free(b_act->act.key);
- free(b_act);
- return NIT_ERROR_MEMORY;
- }
- if (b_act->act.real)
- ((Branch_act *) state->end->dat)->real_next = tmp;
- state->end = tmp;
- if (state->undoing) {
- state->undoing = 0;
- ++state->branch;
- }
- return NIT_ERROR_FINE;
- }
- Nit_error
- state_undo(State *state)
- {
- Branch_act *b_act = state->end->dat;
- Act act = b_act->act;
- Nit_error error;
- if (!state->end->prev)
- return NIT_ERROR_NOT_UNDOABLE;
- act.type = ACT_UNDO;
- if ((error = acts_act(state->acts, &act, state->extra)))
- return error;
- state->undoing = 1;
- state->end = state->end->prev;
- return NIT_ERROR_FINE;
- }
- Nit_error
- state_redo(State *state, uint64_t branch, int real)
- {
- Trie_entry *entry;
- Branch_act *b_act;
- Act act;
- Nit_error error;
- if (real) {
- b_act = state->end->dat;
- if (!b_act->act.real)
- return NIT_ERROR_ROI;
- if (b_act->real_next)
- return NIT_ERROR_REDO_PAST;
- }
- if (!(entry = trie_get(state->end, sizeof(branch), &branch)))
- return NIT_ERROR_NOT_FOUND;
- b_act = entry->dat;
- act = b_act->act;
- act.type = ACT_REDO;
- act.real = 1;
- if ((error = acts_act(state->acts, &act, state->extra)))
- return error;
- b_act->act.real = real;
- state->end = entry;
- return NIT_ERROR_FINE;
- }
|