state.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include <string.h>
  2. #include "state.h"
  3. static void
  4. past_dispose(void *dat, void *extra)
  5. {
  6. Branch_act *b_act = dat;
  7. State *state = extra;
  8. if (state->act_dispose)
  9. state->act_dispose(&b_act->act, state->extra);
  10. else
  11. free(b_act->act.key);
  12. free(b_act);
  13. }
  14. Nit_error
  15. state_init(State *state, Acts *acts, uint64_t branch,
  16. Act_dispose dispose, void *extra)
  17. {
  18. Nit_error error;
  19. Branch_act *root_act;
  20. state->act_dispose = dispose;
  21. state->disposer.dispose = past_dispose;
  22. state->disposer.extra = state;
  23. if (!(root_act = malloc(sizeof(*root_act))))
  24. return NIT_ERROR_MEMORY;
  25. root_act->branch = branch;
  26. root_act->act.key = NULL;
  27. root_act->act.real = 1;
  28. root_act->real_next = NULL;
  29. if ((error = trie_init(&state->past, &state->disposer,
  30. root_act))) {
  31. free(root_act);
  32. return error;
  33. }
  34. state->end = state->past.root;
  35. state->acts = acts;
  36. state->extra = extra;
  37. state->undoing = 0;
  38. state->branch = branch;
  39. return NIT_ERROR_FINE;
  40. }
  41. void
  42. state_dispose(State *state)
  43. {
  44. trie_dispose(&state->past);
  45. }
  46. Nit_error
  47. state_do(State *state, uint32_t key_len, const void *key,
  48. void *dat, void *args, int real)
  49. {
  50. Trie_entry *tmp;
  51. Branch_act *b_act = malloc(sizeof(*b_act));
  52. Nit_error error;
  53. if (real && !((Branch_act *) state->end->dat)->act.real)
  54. return NIT_ERROR_ROI;
  55. if (!b_act)
  56. return NIT_ERROR_MEMORY;
  57. if (!(b_act->act.key = malloc(key_len))) {
  58. free(b_act);
  59. return NIT_ERROR_MEMORY;
  60. }
  61. memcpy(b_act->act.key, key, (b_act->act.key_len = key_len));
  62. b_act->act.real = real;
  63. b_act->act.type = ACT_DO;
  64. b_act->act.dat = dat;
  65. b_act->act.args = args;
  66. b_act->branch = state->branch + (state->undoing ? 1 : 0);
  67. if ((error = acts_act(state->acts, &b_act->act, state->extra))) {
  68. free(b_act->act.key);
  69. free(b_act);
  70. return error;
  71. }
  72. if (!(tmp = trie_add(&state->past, state->end, sizeof(state->branch),
  73. &state->branch, b_act))) {
  74. free(b_act->act.key);
  75. free(b_act);
  76. return NIT_ERROR_MEMORY;
  77. }
  78. if (b_act->act.real)
  79. ((Branch_act *) state->end->dat)->real_next = tmp;
  80. state->end = tmp;
  81. if (state->undoing) {
  82. state->undoing = 0;
  83. ++state->branch;
  84. }
  85. return NIT_ERROR_FINE;
  86. }
  87. Nit_error
  88. state_undo(State *state)
  89. {
  90. Branch_act *b_act = state->end->dat;
  91. Act act = b_act->act;
  92. Nit_error error;
  93. if (!state->end->prev)
  94. return NIT_ERROR_NOT_UNDOABLE;
  95. act.type = ACT_UNDO;
  96. if ((error = acts_act(state->acts, &act, state->extra)))
  97. return error;
  98. state->undoing = 1;
  99. state->end = state->end->prev;
  100. return NIT_ERROR_FINE;
  101. }
  102. Nit_error
  103. state_redo(State *state, uint64_t branch, int real)
  104. {
  105. Trie_entry *entry;
  106. Branch_act *b_act;
  107. Act act;
  108. Nit_error error;
  109. if (real) {
  110. b_act = state->end->dat;
  111. if (!b_act->act.real)
  112. return NIT_ERROR_ROI;
  113. if (b_act->real_next)
  114. return NIT_ERROR_REDO_PAST;
  115. }
  116. if (!(entry = trie_get(state->end, sizeof(branch), &branch)))
  117. return NIT_ERROR_NOT_FOUND;
  118. b_act = entry->dat;
  119. act = b_act->act;
  120. act.type = ACT_REDO;
  121. act.real = 1;
  122. if ((error = acts_act(state->acts, &act, state->extra)))
  123. return error;
  124. b_act->act.real = real;
  125. state->end = entry;
  126. return NIT_ERROR_FINE;
  127. }