Add PieceTable::apply_change() and an initial undo

This commit is contained in:
Josh Holtrop 2016-09-26 22:54:19 -04:00
parent 5b662b63e0
commit fe9747390a
3 changed files with 43 additions and 31 deletions

View File

@ -345,10 +345,10 @@ void PieceTable::insertion_test(Cursor & c)
m_append_buffer[m_append_buffer_index++] = 'z'; m_append_buffer[m_append_buffer_index++] = 'z';
Change * change = &m_changes_buffer[m_changes_buffer_index++]; Change * change = &m_changes_buffer[m_changes_buffer_index++];
change->prior_link[0][0] = c.iterator.piece->prev; change->links[0][0][0] = c.iterator.piece->prev;
change->prior_link[0][1] = c.iterator.piece; change->links[0][0][1] = c.iterator.piece;
change->prior_link[1][0] = c.iterator.piece; change->links[0][1][0] = c.iterator.piece;
change->prior_link[1][1] = c.iterator.piece->next; change->links[0][1][1] = c.iterator.piece->next;
if (c.iterator.valid()) if (c.iterator.valid())
{ {
@ -369,49 +369,56 @@ void PieceTable::insertion_test(Cursor & c)
piece->next = piece3; piece->next = piece3;
piece3->prev = piece; piece3->prev = piece;
change->new_link[0][0] = c.iterator.piece->prev; change->links[1][0][0] = c.iterator.piece->prev;
change->new_link[0][1] = piece2; change->links[1][0][1] = piece2;
change->new_link[1][0] = piece3; change->links[1][1][0] = piece3;
change->new_link[1][1] = c.iterator.piece->next; change->links[1][1][1] = c.iterator.piece->next;
} }
else else
{ {
if (c.iterator.piece->length == 0u) if (c.iterator.piece->length == 0u)
{ {
piece->flags = c.iterator.piece->flags; piece->flags = c.iterator.piece->flags;
change->new_link[0][0] = c.iterator.piece->prev; change->links[1][0][0] = c.iterator.piece->prev;
change->new_link[0][1] = piece; change->links[1][0][1] = piece;
change->new_link[1][0] = piece; change->links[1][1][0] = piece;
change->new_link[1][1] = c.iterator.piece->next; change->links[1][1][1] = c.iterator.piece->next;
} }
else else
{ {
change->new_link[0][0] = c.iterator.piece->prev; change->links[1][0][0] = c.iterator.piece->prev;
change->new_link[0][1] = piece; change->links[1][0][1] = piece;
change->new_link[1][0] = piece; change->links[1][1][0] = piece;
change->new_link[1][1] = c.iterator.piece; change->links[1][1][1] = c.iterator.piece;
} }
} }
} }
else else
{ {
change->new_link[0][0] = start_piece; change->links[1][0][0] = start_piece;
change->new_link[0][1] = piece; change->links[1][0][1] = piece;
change->new_link[1][0] = piece; change->links[1][1][0] = piece;
change->new_link[1][1] = end_piece; change->links[1][1][1] = end_piece;
} }
apply_change(change, 0u); apply_change(change, 1u);
c.warp_to_inserted_piece(piece); c.warp_to_inserted_piece(piece);
} }
void PieceTable::apply_change(Change * change, uint8_t reverse) void PieceTable::undo()
{ {
uint8_t i1 = reverse; if (m_changes_buffer_index > 0u)
uint8_t i2 = reverse ^ 1u; {
change->new_link[i1][i1]->next = change->new_link[i1][i2]; m_changes_buffer_index--;
change->new_link[i1][i2]->prev = change->new_link[i1][i1]; apply_change(&m_changes_buffer[m_changes_buffer_index], 0u);
change->new_link[i2][i1]->next = change->new_link[i2][i2]; }
change->new_link[i2][i2]->prev = change->new_link[i2][i1]; }
void PieceTable::apply_change(Change * change, uint8_t forward)
{
change->links[forward][0][0]->next = change->links[forward][0][1];
change->links[forward][0][1]->prev = change->links[forward][0][0];
change->links[forward][1][0]->next = change->links[forward][1][1];
change->links[forward][1][1]->prev = change->links[forward][1][0];
} }

View File

@ -134,8 +134,7 @@ public:
struct Change struct Change
{ {
Piece * prior_link[2][2]; Piece * links[2][2][2];
Piece * new_link[2][2];
bool insert; bool insert;
}; };
@ -164,7 +163,9 @@ public:
void insertion_test(Cursor & c); void insertion_test(Cursor & c);
void apply_change(Change * change, uint8_t reverse); void undo();
void apply_change(Change * change, uint8_t forward);
protected: protected:
const uint8_t * m_file_buffer; const uint8_t * m_file_buffer;

View File

@ -270,6 +270,10 @@ void Window::handle_key(uint32_t scancode, uint32_t mod)
case SDL_SCANCODE_P: case SDL_SCANCODE_P:
insertion_test(); insertion_test();
break; break;
case SDL_SCANCODE_U:
m_buffer->piece_table->undo();
redraw();
break;
} }
} }