The LineCollection Class is an extension of the built-in Array Object. It adds methods that are vital to the functionality of the app.
See Source.
Shuffles this
(the instance of the LineCollection).
LineCollection.shuffle()
Generates rgb value based on i
.
LineCollection.calcColor(i)
Generates collection of Line Objects.
LineCollection._generateCollection()
Iterates over this
and updates the shuffledIdx property of each Line.
LineCollection._updateShuffleIdx()
The Line Class represents a single line.
See source.
Recalculates the height, width, x and y properties of this
(instance of Line).
Line.recalculate(i)
Sets the Line.isComparing
property to true
. When Line.isComparing === true
the line will render yellow. You must unmark the line to revert it to its original color.
Line.mark()
Sets the Line.isComparing
property to false
. When Line.isComparing === false
the line will render its original color.
Line.unmark()
The AlgoRunner Class is the mechanism that runs the sorting algorithm. It implements a "lazy sort" system (more on that later). It allows you to control the speed that the given sorting algorithm runs at.
See source.
First, let me explain a key piece of how the sorting algorithms are implemented*. Every sorting algorithm is implemented using Generator functions.
Before I explain why, I will explain what lead me to this implementation.
The original implementation would perform the sort and collect slices of the sorting proccess to later be rerendered. This, all before a single rerender occurred. The queued up slices would then be dequeued at an adjustable rate. This is where the rerendering would begin. This worked well for small collections but once the size increased it would appear to the user that the application was frozen. This was not acceptable.
Generator functions save the day! In short, a Generator is a function you can pause and come back to at anytime. This allowed me to implement a lazy sorting mechanism.
- Constructor:
- Run:
- Dispatch new slice to redux store. This kicks off the render.
- Subsequent next invokation to retrieve next slice of the sort. To be rerendered.
- Invoke
_continueCycle()
with delay ofthis.speed
. - Rinse and repeat.
Kicks off sorting cycle.
AlgoRunner.run()
Dispatches current slice, retrieves next slice and invokes this._continueCycle()
with a delay.
AlgoRunner._startCycle()
Invokes this._startCycle()
.
AlgoRunner._continueCyle()
- Every algorithm must be a Generator.
- Every yield value must be a
new LineCollection()
. Will rerender using yielded value. - Recursive algorithms may use yield*.
- Helper functions that perform swaps must also be Generators that yield
new LineCollections()
.
- Every yield value must be a
Q: Why did you make this?
A: I wanted to gain a deeper understanding of sorting algorithms. This project made it fun.
Q: How many algorithms are you going to implement?
A: I'm aiming for all of these.
** This step only occurs in the constructor