UNPKG

pixi-fusion

Version:

This module offers a set of common components needed for playing games.

125 lines (124 loc) 3.99 kB
import React, { createContext, useMemo, useRef, useState } from "react"; import { GameStatus } from "../types"; export const GameContext = createContext({ reset: () => { }, pause: () => { }, start: () => { }, stop: () => { }, timeout: 0, status: GameStatus.READY, startTime: null, pauseTime: 0, endTime: null }); export const GameContextProvider = ({ children, timeout: inputTimeout = 0, events }) => { const timerRef = useRef(null); const timeout = Math.max(0, inputTimeout); const [status, setStatus] = useState(GameStatus.READY); const [startTime, setStartTime] = useState(null); const [endTime, setEndTime] = useState(null); const [pauseTime, setPauseTime] = useState(0); const [pausedAtTime, setPausedAtTime] = useState(null); const onTimedOut = () => { const newEndTime = +new Date(); const newStatus = GameStatus.TIMEDOUT; setEndTime(newEndTime); setStatus(GameStatus.TIMEDOUT); events?.onTimedOut?.({ startTime, endTime: newEndTime, status: newStatus, pausedAtTime: null, pauseTime }); }; const start = () => { const newStartTime = startTime || +new Date(); const newStatus = GameStatus.IN_PROGRESS; const newEndTime = null; const newPauseTime = pausedAtTime ? pauseTime + +new Date() - (pausedAtTime || 0) : 0; setStatus(newStatus); setStartTime((currentStartTime) => currentStartTime || newStartTime); setPauseTime(newPauseTime); setPausedAtTime(null); setEndTime(newEndTime); if (timeout !== 0) { timerRef.current = setTimeout(() => { onTimedOut(); }, timeout * 1000); } events?.onStart?.({ startTime: newStartTime, endTime: newEndTime, status: newStatus, pausedAtTime: null, pauseTime: newPauseTime }); }; const reset = () => { const newStartTime = null; const newStatus = GameStatus.READY; const newEndTime = null; const newPausedAtTime = null; const newPauseTime = 0; setStatus(newStatus); setStartTime(newStartTime); setEndTime(newEndTime); setPauseTime(newPauseTime); setPausedAtTime(newPausedAtTime); if (timerRef.current) { clearTimeout(timerRef.current); } events?.onReset?.({ startTime: newStartTime, endTime: newEndTime, status: newStatus, pausedAtTime: newPausedAtTime, pauseTime: newPauseTime }); }; const stop = () => { const newStatus = GameStatus.COMPLETED; const newEndTime = +new Date(); if (timerRef.current) { clearTimeout(timerRef.current); } setEndTime(+new Date()); setStatus(GameStatus.COMPLETED); events?.onStop?.({ startTime, endTime: newEndTime, status: newStatus, pausedAtTime, pauseTime }); }; const pause = () => { const newStatus = GameStatus.PAUSED; const newPausedAtTime = +new Date(); if (timerRef.current) { clearTimeout(timerRef.current); } setStatus(GameStatus.PAUSED); setPausedAtTime(newPausedAtTime); events?.onPause?.({ startTime, endTime: null, pausedAtTime: newPausedAtTime, status: newStatus, pauseTime }); }; const contextValue = useMemo(() => ({ status, startTime, endTime, pauseTime, timeout, stop, start, reset, pause }), [timeout, status, startTime, endTime, pauseTime, pausedAtTime]); return React.createElement(GameContext.Provider, { value: contextValue }, children); };