Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the "--max / -m" option for finite-length pipes #26

Merged
merged 10 commits into from
May 14, 2018

Conversation

StefansM
Copy link
Contributor

If the --max=N option is passed to cpipes, the tail of each pipe will be erased after each movement, fixing the length of the pipe at N characters.

Doing this well requires us to store a list of characters that have been drawn to each grid cell, so that if we erase the tail of a pipe we know what character to redraw, if any.

StefansM added 10 commits April 28, 2018 20:11
Switch away from my cobbled-together "ok" macro. We were reaching the
point of needing to split the TAP functions into a separate file, so we
may as well just use libtap, which works well.
As cpipes becomes more complex, it will become useful to separate this
information into an object, rather than passsing lots of parameters
around between funcitons.
The plan is to store the list of characters that have been drawn on each
grid cell of the canvas in a linked list. Then, we can erase a character
drawn by a particular pipe by looking backwards from the tail and
popping the first matching pipe cell from the list.

Then, if the list is empty we will erase that cell and if the list still
contains elements, make sure that if the head of the linked list has
changed, it is the character drawn to the terminal.

For example, we might have the following list for a particular cell:

        pipe    char    color
        0x1     ━       1      ← Head
        0x2     ┃       2
        0x3     ━       1
        0x1     ┓       3      ← Tail

If we remove pipe 0x1 from the list, the tail will point to 0x3, and the
head is unchanged so we will not need to change the character drawn at
this cell position. If we then remove 0x1 again, the head will point to
0x2 and a "┃" character must be drawn with color 1. If we remove all
pipes, that cell is erased.
A canvas contains a pipe_cell_list at each position, so we must realloc
the list of pipe_cell_lists when the canvas is resized, freeing any
pipe_cell_lists that are no longer needed.
The location_buffer struct will be used to store a list of locations for
a pipe in a circular buffer. When a pipe moves forwards, the buffer will
be updated so that the previous tail is replaced by the next location,
and the new head will be pushed.

For a buffer of length 4:

        buffer     pushed
        1               1
        21              2
        321             3
        4321            4
        5432            5
        6543            6

The implementation of this circular buffer is fairly standard. The
buffer itself is a fixed-size portion of memory, and a head index is
updated each time an element is pushed.
This commit integrates the previous few commits into cpipes.

The function "canvas_erase_tail" is added, which is repsonsible for
removing a pipe from a pipe_cell_list at the tail of a pipe, and then
drawing either a new pipe character, erasing that cell or leaving it
as-is if the uppermost pipe did not change.

The "-m" or "--max" parameter was added to the command line interface to
allow setting the maximum pipe length. This value is now also accepted
by the "init_pipe" function, which now initialises the location_buffer
struct in each pipe.
The pipe_cell_list is not really part of the canvas, so refactor it into
a separate file.
@StefansM StefansM merged commit 01787e2 into pipeseroni:master May 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant