{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
module Octane.Type.Frame
( Frame(..)
) where
import Data.Aeson ((.=))
import Data.Function ((&))
import qualified Control.DeepSeq as DeepSeq
import qualified Data.Aeson as Aeson
import qualified Data.Default.Class as Default
import qualified Data.Map.Strict as Map
import qualified Data.OverloadedRecords.TH as OverloadedRecords
import qualified Data.Text as StrictText
import qualified GHC.Generics as Generics
import qualified Octane.Type.Float32 as Float32
import qualified Octane.Type.Replication as Replication
import qualified Octane.Type.State as State
data Frame = Frame
{ frameNumber :: Word
, frameIsKeyFrame :: Bool
, frameTime :: Float32.Float32
, frameDelta :: Float32.Float32
, frameReplications :: [Replication.Replication]
} deriving (Eq, Generics.Generic, Show)
$(OverloadedRecords.overloadedRecord Default.def ''Frame)
instance DeepSeq.NFData Frame
instance Aeson.ToJSON Frame where
toJSON frame =
Aeson.object
[ "Number" .= #number frame
, "IsKeyFrame" .= #isKeyFrame frame
, "Time" .= #time frame
, "Delta" .= #delta frame
, "Spawned" .= (frame & #replications & getSpawned)
, "Updated" .= (frame & #replications & getUpdated)
, "Destroyed" .= (frame & #replications & getDestroyed)
]
newtype Spawned =
Spawned [Replication.Replication]
instance Aeson.ToJSON Spawned where
toJSON (Spawned xs) =
xs &
map
(\x -> do
let k = x & #actorId & #value & show & StrictText.pack
let v =
Aeson.object
[ "Name" .= #objectName x
, "Class" .= #className x
, "Position" .= (x & #initialization & fmap #location)
, "Rotation" .= (x & #initialization & fmap #rotation)
]
(k, v)) &
Map.fromList &
Aeson.toJSON
getSpawned :: [Replication.Replication] -> Spawned
getSpawned xs = xs & filter (\x -> x & #state & State.isOpening) & Spawned
newtype Updated =
Updated [Replication.Replication]
instance Aeson.ToJSON Updated where
toJSON (Updated xs) =
xs &
map
(\x -> do
let k = x & #actorId & #value & show & StrictText.pack
let v = x & #properties
(k, v)) &
Map.fromList &
Aeson.toJSON
getUpdated :: [Replication.Replication] -> Updated
getUpdated xs =
xs & filter (\x -> x & #state & State.isExisting) &
filter (\x -> x & #properties & null & not) &
Updated
newtype Destroyed =
Destroyed [Replication.Replication]
instance Aeson.ToJSON Destroyed where
toJSON (Destroyed xs) = xs & map #actorId & map #value & Aeson.toJSON
getDestroyed :: [Replication.Replication] -> Destroyed
getDestroyed xs = xs & filter (\x -> x & #state & State.isClosing) & Destroyed