You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
1.9 KiB
79 lines
1.9 KiB
package nova.monadic_sfx.util
|
|
import com.softwaremill.quicklens._
|
|
|
|
final class MutHistory[T](initValue: T) {
|
|
private var _values = Vector(initValue)
|
|
def values = _values
|
|
private var _sp = 0
|
|
def sp = _sp
|
|
|
|
// def current = if (ints.isEmpty) None else Some(ints(sp))
|
|
def current = _values(_sp)
|
|
|
|
def push(v: T) = {
|
|
if (_sp < _values.length - 1) {
|
|
_values = _values.splitAt(_sp)._1
|
|
_values = _values :+ v
|
|
} else {
|
|
_values = _values :+ v
|
|
_sp = _values.length - 1
|
|
}
|
|
}
|
|
|
|
def forward() = {
|
|
if (!_values.isEmpty && _sp < _values.length - 1) _sp += 1
|
|
}
|
|
|
|
def backward() = {
|
|
if (_sp > 0) {
|
|
_sp -= 1
|
|
}
|
|
}
|
|
}
|
|
|
|
final class History[T] private (val state: History.State[T]) {
|
|
def current = state.values(state.sp)
|
|
def push(v: T) = {
|
|
val nextState =
|
|
// state.copy(state.values.splitAt(state.sp)._1 :+ v, state.sp + 1)
|
|
if (state.sp < state.values.length - 1) {
|
|
state.modify(_.values).using(_.splitAt(state.sp)._1 :+ v)
|
|
} else {
|
|
val s1 = state
|
|
.modify(_.values)
|
|
.using(_ :+ v)
|
|
s1.modify(_.sp)
|
|
.setTo(s1.values.length - 1)
|
|
}
|
|
new History(nextState)
|
|
}
|
|
def forward = {
|
|
// val nextState =
|
|
if (!state.values.isEmpty && state.sp < state.values.length - 1)
|
|
new History(state.modify(_.sp).using(_ + 1))
|
|
else this
|
|
// new History(nextState)
|
|
}
|
|
def backward = {
|
|
// val nextState =
|
|
if (state.sp > 0) new History(state.modify(_.sp).using(_ - 1)) else this
|
|
// new History(nextState)
|
|
}
|
|
}
|
|
|
|
// final class HistoryImpl()
|
|
|
|
object History {
|
|
case class State[T](values: Vector[T], sp: Int)
|
|
|
|
def apply[T](intialValue: T) =
|
|
new History(State(Vector(intialValue), 0))
|
|
|
|
// val history = new History(History.State(Vector.empty, 0))
|
|
|
|
implicit class HistoryOps[T](private val h: History[T]) extends AnyVal {
|
|
def :+(v: T) = h.push(v)
|
|
}
|
|
|
|
}
|
|
// History.history.push(1).forward
|