{-# LANGUAGE DeriveGeneric #-}
module Game.LambdaHack.Common.RingBuffer
( RingBuffer
, empty, cons, toList, length
) where
import Prelude ()
import Game.LambdaHack.Core.Prelude hiding (length, uncons)
import Data.Binary
import qualified Data.Foldable as Foldable
import qualified Data.Sequence as Seq
import GHC.Generics (Generic)
data RingBuffer a = RingBuffer
{ RingBuffer a -> Seq a
rbCarrier :: Seq.Seq a
, RingBuffer a -> Int
rbMaxSize :: Int
, RingBuffer a -> Int
rbNext :: Int
, RingBuffer a -> Int
rbLength :: Int
}
deriving (Int -> RingBuffer a -> ShowS
[RingBuffer a] -> ShowS
RingBuffer a -> String
(Int -> RingBuffer a -> ShowS)
-> (RingBuffer a -> String)
-> ([RingBuffer a] -> ShowS)
-> Show (RingBuffer a)
forall a. Show a => Int -> RingBuffer a -> ShowS
forall a. Show a => [RingBuffer a] -> ShowS
forall a. Show a => RingBuffer a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RingBuffer a] -> ShowS
$cshowList :: forall a. Show a => [RingBuffer a] -> ShowS
show :: RingBuffer a -> String
$cshow :: forall a. Show a => RingBuffer a -> String
showsPrec :: Int -> RingBuffer a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> RingBuffer a -> ShowS
Show, (forall x. RingBuffer a -> Rep (RingBuffer a) x)
-> (forall x. Rep (RingBuffer a) x -> RingBuffer a)
-> Generic (RingBuffer a)
forall x. Rep (RingBuffer a) x -> RingBuffer a
forall x. RingBuffer a -> Rep (RingBuffer a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (RingBuffer a) x -> RingBuffer a
forall a x. RingBuffer a -> Rep (RingBuffer a) x
$cto :: forall a x. Rep (RingBuffer a) x -> RingBuffer a
$cfrom :: forall a x. RingBuffer a -> Rep (RingBuffer a) x
Generic)
instance Binary a => Binary (RingBuffer a)
empty :: Int -> a -> RingBuffer a
empty :: Int -> a -> RingBuffer a
empty Int
size a
dummy =
let rbMaxSize :: Int
rbMaxSize = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
size
in Seq a -> Int -> Int -> Int -> RingBuffer a
forall a. Seq a -> Int -> Int -> Int -> RingBuffer a
RingBuffer (Int -> a -> Seq a
forall a. Int -> a -> Seq a
Seq.replicate Int
rbMaxSize a
dummy) Int
rbMaxSize Int
0 Int
0
cons :: a -> RingBuffer a -> RingBuffer a
cons :: a -> RingBuffer a -> RingBuffer a
cons a
a RingBuffer{Int
Seq a
rbLength :: Int
rbNext :: Int
rbMaxSize :: Int
rbCarrier :: Seq a
rbLength :: forall a. RingBuffer a -> Int
rbNext :: forall a. RingBuffer a -> Int
rbMaxSize :: forall a. RingBuffer a -> Int
rbCarrier :: forall a. RingBuffer a -> Seq a
..} =
let incNext :: Int
incNext = (Int
rbNext Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
rbMaxSize
incLength :: Int
incLength = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
rbMaxSize (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Int
rbLength Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
in Seq a -> Int -> Int -> Int -> RingBuffer a
forall a. Seq a -> Int -> Int -> Int -> RingBuffer a
RingBuffer (Int -> a -> Seq a -> Seq a
forall a. Int -> a -> Seq a -> Seq a
Seq.update Int
rbNext a
a Seq a
rbCarrier) Int
rbMaxSize Int
incNext Int
incLength
toList :: RingBuffer a -> [a]
toList :: RingBuffer a -> [a]
toList RingBuffer{Int
Seq a
rbLength :: Int
rbNext :: Int
rbMaxSize :: Int
rbCarrier :: Seq a
rbLength :: forall a. RingBuffer a -> Int
rbNext :: forall a. RingBuffer a -> Int
rbMaxSize :: forall a. RingBuffer a -> Int
rbCarrier :: forall a. RingBuffer a -> Seq a
..} =
let l :: [a]
l = Seq a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList Seq a
rbCarrier
start :: Int
start = (Int
rbNext Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
rbMaxSize Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
rbLength) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
rbMaxSize
in Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
rbLength ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop Int
start ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ [a]
l [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a]
l
length :: RingBuffer a -> Int
length :: RingBuffer a -> Int
length RingBuffer{Int
rbLength :: Int
rbLength :: forall a. RingBuffer a -> Int
rbLength} = Int
rbLength