module Octane.Type.Frame
( Frame(..)
) where
import Data.Aeson ((.=))
import Data.Function ((&))
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 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, Show)
$(OverloadedRecords.overloadedRecord Default.def ''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