Open splintersuidman opened 6 years ago
In 06213a8 I began implementing this idea. For easier exchange of metadata such as the name, description, and author we might want to introduce a new Metadata
struct. We might also consider using generics and having several ways of representing alive cells, this could be extremely useful; for example when outputting in Life 1.05 format.
I'd rather have the serialiser in a different module than parser
— probably serialise
. I'll create the file structure.
I hope to explain myself somewhat clearer here.
My idea was to first export the board (Vec<Vec<CellState>>
) to a Pattern
and then export the Pattern
into the desired filetype (placing the functions probably in the respective filetype parser file). This way we keep a nice structure where it's clear what does what and the higher-level GameOfLife
struct stays clearly separated from the lower-level parsing and serialising.
What do you mean by this?
I meant having the Pattern
have several ways of storing the data and introducing traits for usability, i.e.
pub struct Pattern<T>
where
T: Into<CellList> + Into<CellTable>
{
cells: T,
metadata: Metadata,
}
pub struct CellList {
cells: Vec<(isize, isize)>
}
pub struct CellTable {
cells: Vec<Vec<CellState>>
}
impl From<CellTable> for CellList {}
impl From<CellList> for CellTable {}
When this is implemented we can easily switch from a Vec<(isize, isize)>
to a Vec<Vec<CellState>>
or even something else (I don't know what that could sensibly be) depending on which format we are reading or writing.
NOTE: These different representation methods should only be used by parsers && Pattern
, NOT by GameOfLife
since we should choose one efficient method (like Vec<Vec<CellState>>
) and optimise it. Things like Vec<(isize, isize)>
are needed for Life 1.06 but absolutely destroy any kind of speed when used by GameOfLife
.
NOTE: Displayed suggestion was improved by @splintah's feedback and code.
NOTE: The structure we eventually implemented differs from the one displayed here.
Yeah, I just got what you meant. It might be an idea to implement update
as a trait on those different ways of representing the board, which gets called inside GameOfLife::update
.
By the way: CellList
should probably contain a HashSet<Coordinate>
(type Coordinate = (isize, isize);
?) — the lookup of neighbours will be much faster.
I'm now (drastically) redesigning the file parsing/serialising system.
It might be an idea to implement update as a trait on those different ways of representing the board, which gets called inside GameOfLife::update.
I didn't want to change GameOfLife.board
, only Pattern.cells
. I think Vec<Vec<CellState>>
is much better once loaded into RAM but for reading and writing files it will be necessary to switch between Vec<Vec<CellState>>
and Vec<(isize, isize)>
.
the lookup of neighbours will be much faster.
This shouldn't be used for updating anyway since we should convert to the optimal representation method for updating for GameOfLife
, this should solely be used for easier reading and writing of different file formats.
I think Vec<Vec
> is much better once loaded into RAM
This might not be true. HashSet
lookup and insert are O(1). It will probably require more memory, though (perhaps this can be solved by using with_capacity
?).
We can try it, but it's not necessary, and might be too much a hassle.
Add support for serialisation: writing the current state to a file. To make this more convenient, perhaps a pause function (key P?) can be added.
trait Parse
andtrait Serialise
.Pattern
to store aT: Into<CellList> + Into<CellTable>
Cells
, an enum ofList(CellList), Table(CellTable)
.impl Serialise
:impl Serialise for Life105
.impl Serialise for Life106
.impl Serialise for Plaintext
.impl Serialise for RLE
.src/lib/file/mod.rs
:Cells
-relatedstruct
s andimpl
s tocells.rs
.Maybe: