Refactor out function for updating FPS.

Co-authored-by: Daniel Garcia <pel_daniel@hotmail.com>
This commit is contained in:
Robbie Gleichman 2020-08-09 16:08:09 -07:00
parent 648891aded
commit b715173710

View File

@ -51,6 +51,7 @@ data Element = Element
data Inputs = Inputs data Inputs = Inputs
{ _asMouseXandY :: !(Double, Double) { _asMouseXandY :: !(Double, Double)
, _asTime :: SystemTime , _asTime :: SystemTime
, _asPrevTime :: SystemTime
} }
data AppState = AppState data AppState = AppState
@ -72,6 +73,7 @@ emptyInputs :: Inputs
emptyInputs = Inputs emptyInputs = Inputs
{ _asMouseXandY = (0, 0) { _asMouseXandY = (0, 0)
, _asTime = MkSystemTime 0 0 , _asTime = MkSystemTime 0 0
, _asPrevTime = MkSystemTime 0 0
} }
renderCairo :: Coercible a (ManagedPtr ()) => a -> Render c -> IO c renderCairo :: Coercible a (ManagedPtr ()) => a -> Render c -> IO c
@ -145,11 +147,26 @@ findElementByPosition elements (mouseX, mouseY) =
in in
fst <$> find mouseInElement (IntMap.toList elements) fst <$> find mouseInElement (IntMap.toList elements)
getFps :: Inputs -> Double
getFps inputs =
let
(MkSystemTime seconds nanoseconds) = _asTime inputs
(MkSystemTime oldSeconds oldNanoseconds) = _asPrevTime inputs
secondsDiff = seconds - oldSeconds
nanosecondDiff = nanoseconds - oldNanoseconds
fps = if secondsDiff == 0
then fromIntegral (div (10^(9 :: Int)) nanosecondDiff)
else 1 / fromIntegral secondsDiff
in
if fps >= 200
then fromIntegral $ div (truncate fps) 100 * (100 :: Int)
else fps
-- Update the state based on the old state and the mouse -- Update the state based on the old state and the mouse
-- position. Consider moving inputs like mouse position into a -- position. Consider moving inputs like mouse position into a
-- separate input struct. -- separate input struct.
updateState :: Inputs -> AppState -> AppState updateState :: Inputs -> AppState -> AppState
updateState Inputs{_asMouseXandY} oldState@AppState{_asElements, _asMovingNode} = updateState inputs@Inputs{_asMouseXandY} oldState@AppState{_asElements, _asMovingNode} =
let let
-- Move the asMovingNode to MouseXandY -- Move the asMovingNode to MouseXandY
newElements = case _asMovingNode of newElements = case _asMovingNode of
@ -163,7 +180,10 @@ updateState Inputs{_asMouseXandY} oldState@AppState{_asElements, _asMovingNode}
oldNode{_elPosition=(newX, newY)}) oldNode{_elPosition=(newX, newY)})
nodeId nodeId
_asElements _asElements
newState = oldState{_asElements=newElements} newState = oldState
{ _asElements=newElements
, _asFPSr=getFps inputs
}
in in
newState newState
@ -175,24 +195,16 @@ timeoutCallback ::
-> Gtk.DrawingArea -> Gtk.DrawingArea
-> IO Bool -> IO Bool
timeoutCallback inputsRef stateRef gdkWindow device backgroundArea = do timeoutCallback inputsRef stateRef gdkWindow device backgroundArea = do
newTime@(MkSystemTime seconds nanoseconds) <- getSystemTime newTime <- getSystemTime
oldInputs <- readIORef inputsRef
let
(MkSystemTime oldSeconds oldNanoseconds) = _asTime oldInputs
secondsDiff = seconds - oldSeconds
nanosecondDiff = nanoseconds - oldNanoseconds
fps = if secondsDiff == 0
then fromIntegral (div (10^(9 :: Int)) nanosecondDiff)
else 1 / fromIntegral secondsDiff
truncatedFps = if fps >= 200
then fromIntegral $ div (truncate fps) 100 * (100 :: Int)
else fps
gdkDevicePosition <- Gdk.windowGetDevicePositionDouble gdkWindow device gdkDevicePosition <- Gdk.windowGetDevicePositionDouble gdkWindow device
let (_, x, y, _) = gdkDevicePosition let (_, x, y, _) = gdkDevicePosition
modifyIORef' inputsRef (\inputs -> inputs{_asMouseXandY=(x, y), _asTime=newTime}) modifyIORef' inputsRef
(\inputs@Inputs{_asTime}
modifyIORef' stateRef (\state -> state{_asFPSr=truncatedFps}) -> inputs{_asMouseXandY=(x, y)
, _asTime=newTime
, _asPrevTime=_asTime
})
inputs <- readIORef inputsRef inputs <- readIORef inputsRef
modifyIORef' stateRef (updateState inputs) modifyIORef' stateRef (updateState inputs)