pixi-fusion 1.0.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -96,7 +96,6 @@ This monorepo contains configuration for VSCode editor. It doesn't mean that you
96
96
  2. To build monorepo use: `npm run build`
97
97
  3. To lint monorepo use: `npm run lint`
98
98
  4. To initialize pre-commit hooks use: `npm run prepare`
99
- 5. To run storybook `npm run storybook`
100
99
 
101
100
  ## Workflow
102
101
 
@@ -1,35 +1,22 @@
1
1
  import React, { PropsWithChildren } from "react";
2
- import { GameStatus } from "../types";
2
+ import { GameStatus, GameStatusChangeEvent } from "../types";
3
3
  export type GameContextValue = {
4
4
  readonly reset: () => void;
5
5
  readonly start: () => void;
6
+ readonly pause: () => void;
6
7
  readonly stop: () => void;
7
8
  readonly timeout: number;
8
9
  readonly status: GameStatus;
9
10
  readonly startTime: number | null;
11
+ readonly pauseTime: number;
10
12
  readonly endTime: number | null;
11
13
  };
12
14
  export type GameContextProviderEvents = {
13
- onStart?: (event: {
14
- startTime: number | null;
15
- status: GameStatus;
16
- endTime: number | null;
17
- }) => unknown;
18
- onStop?: (event: {
19
- startTime: number | null;
20
- status: GameStatus;
21
- endTime: number | null;
22
- }) => unknown;
23
- onTimedOut?: (event: {
24
- startTime: number | null;
25
- status: GameStatus;
26
- endTime: number | null;
27
- }) => unknown;
28
- onReset?: (event: {
29
- startTime: number | null;
30
- status: GameStatus;
31
- endTime: number | null;
32
- }) => unknown;
15
+ onStart?: (event: GameStatusChangeEvent) => unknown;
16
+ onStop?: (event: GameStatusChangeEvent) => unknown;
17
+ onPause?: (event: GameStatusChangeEvent) => unknown;
18
+ onTimedOut?: (event: GameStatusChangeEvent) => unknown;
19
+ onReset?: (event: GameStatusChangeEvent) => unknown;
33
20
  };
34
21
  export declare const GameContext: React.Context<GameContextValue>;
35
22
  export type GameContextProviderProps = PropsWithChildren & {
@@ -2,19 +2,23 @@ import React, { createContext, useMemo, useRef, useState } from "react";
2
2
  import { GameStatus } from "../types";
3
3
  export const GameContext = createContext({
4
4
  reset: () => { },
5
+ pause: () => { },
5
6
  start: () => { },
6
7
  stop: () => { },
7
8
  timeout: 0,
8
9
  status: GameStatus.READY,
9
10
  startTime: null,
11
+ pauseTime: 0,
10
12
  endTime: null
11
13
  });
12
14
  export const GameContextProvider = ({ children, timeout: inputTimeout = 0, events }) => {
13
- const timerRef = useRef();
15
+ const timerRef = useRef(null);
14
16
  const timeout = Math.max(0, inputTimeout);
15
17
  const [status, setStatus] = useState(GameStatus.READY);
16
18
  const [startTime, setStartTime] = useState(null);
17
19
  const [endTime, setEndTime] = useState(null);
20
+ const [pauseTime, setPauseTime] = useState(0);
21
+ const [pausedAtTime, setPausedAtTime] = useState(null);
18
22
  const onTimedOut = () => {
19
23
  const newEndTime = +new Date();
20
24
  const newStatus = GameStatus.TIMEDOUT;
@@ -23,15 +27,20 @@ export const GameContextProvider = ({ children, timeout: inputTimeout = 0, event
23
27
  events?.onTimedOut?.({
24
28
  startTime,
25
29
  endTime: newEndTime,
26
- status: newStatus
30
+ status: newStatus,
31
+ pausedAtTime: null,
32
+ pauseTime
27
33
  });
28
34
  };
29
35
  const start = () => {
30
- const newStartTime = +new Date();
36
+ const newStartTime = startTime || +new Date();
31
37
  const newStatus = GameStatus.IN_PROGRESS;
32
38
  const newEndTime = null;
39
+ const newPauseTime = pausedAtTime ? pauseTime + +new Date() - (pausedAtTime || 0) : 0;
33
40
  setStatus(newStatus);
34
- setStartTime(newStartTime);
41
+ setStartTime((currentStartTime) => currentStartTime || newStartTime);
42
+ setPauseTime(newPauseTime);
43
+ setPausedAtTime(null);
35
44
  setEndTime(newEndTime);
36
45
  if (timeout !== 0) {
37
46
  timerRef.current = setTimeout(() => {
@@ -41,45 +50,75 @@ export const GameContextProvider = ({ children, timeout: inputTimeout = 0, event
41
50
  events?.onStart?.({
42
51
  startTime: newStartTime,
43
52
  endTime: newEndTime,
44
- status: newStatus
53
+ status: newStatus,
54
+ pausedAtTime: null,
55
+ pauseTime: newPauseTime
45
56
  });
46
57
  };
47
58
  const reset = () => {
48
59
  const newStartTime = null;
49
60
  const newStatus = GameStatus.READY;
50
61
  const newEndTime = null;
62
+ const newPausedAtTime = null;
63
+ const newPauseTime = 0;
51
64
  setStatus(newStatus);
52
65
  setStartTime(newStartTime);
53
66
  setEndTime(newEndTime);
67
+ setPauseTime(newPauseTime);
68
+ setPausedAtTime(newPausedAtTime);
54
69
  if (timerRef.current) {
55
70
  clearTimeout(timerRef.current);
56
71
  }
57
72
  events?.onReset?.({
58
73
  startTime: newStartTime,
59
74
  endTime: newEndTime,
60
- status: newStatus
75
+ status: newStatus,
76
+ pausedAtTime: newPausedAtTime,
77
+ pauseTime: newPauseTime
61
78
  });
62
79
  };
63
80
  const stop = () => {
64
81
  const newStatus = GameStatus.COMPLETED;
65
82
  const newEndTime = +new Date();
66
- clearTimeout(timerRef.current);
83
+ if (timerRef.current) {
84
+ clearTimeout(timerRef.current);
85
+ }
67
86
  setEndTime(+new Date());
68
87
  setStatus(GameStatus.COMPLETED);
69
88
  events?.onStop?.({
70
89
  startTime,
71
90
  endTime: newEndTime,
72
- status: newStatus
91
+ status: newStatus,
92
+ pausedAtTime,
93
+ pauseTime
94
+ });
95
+ };
96
+ const pause = () => {
97
+ const newStatus = GameStatus.PAUSED;
98
+ const newPausedAtTime = +new Date();
99
+ if (timerRef.current) {
100
+ clearTimeout(timerRef.current);
101
+ }
102
+ setStatus(GameStatus.PAUSED);
103
+ setPausedAtTime(newPausedAtTime);
104
+ events?.onPause?.({
105
+ startTime,
106
+ endTime: null,
107
+ pausedAtTime: newPausedAtTime,
108
+ status: newStatus,
109
+ pauseTime
73
110
  });
74
111
  };
75
112
  const contextValue = useMemo(() => ({
76
113
  status,
77
114
  startTime,
78
115
  endTime,
116
+ pauseTime,
79
117
  timeout,
80
118
  stop,
81
119
  start,
82
- reset
83
- }), [timeout, status, startTime, endTime]);
120
+ reset,
121
+ pause
122
+ }), [timeout, status, startTime, endTime, pauseTime, pausedAtTime]);
84
123
  return React.createElement(GameContext.Provider, { value: contextValue }, children);
85
124
  };
@@ -2,6 +2,14 @@ export declare enum GameStatus {
2
2
  READY = 0,
3
3
  IN_PROGRESS = 1,
4
4
  TIMEDOUT = 2,
5
- COMPLETED = 3
5
+ COMPLETED = 3,
6
+ PAUSED = 4
6
7
  }
7
8
  export type Nullable<T> = T | null;
9
+ export type GameStatusChangeEvent = {
10
+ startTime: number | null;
11
+ status: GameStatus;
12
+ endTime: number | null;
13
+ pausedAtTime: number | null;
14
+ pauseTime: number;
15
+ };
package/dist/src/types.js CHANGED
@@ -4,4 +4,5 @@ export var GameStatus;
4
4
  GameStatus[GameStatus["IN_PROGRESS"] = 1] = "IN_PROGRESS";
5
5
  GameStatus[GameStatus["TIMEDOUT"] = 2] = "TIMEDOUT";
6
6
  GameStatus[GameStatus["COMPLETED"] = 3] = "COMPLETED";
7
+ GameStatus[GameStatus["PAUSED"] = 4] = "PAUSED";
7
8
  })(GameStatus || (GameStatus = {}));
package/package.json CHANGED
@@ -5,13 +5,13 @@
5
5
  "url": "https://github.com/laverve/fusion/issues"
6
6
  },
7
7
  "dependencies": {
8
- "@types/matter-js": "^0.19.7",
8
+ "@types/matter-js": "^0.19.8",
9
9
  "matter-js": "^0.20.0",
10
- "pixi.js": "^8.4.1",
11
- "pixi-viewport": "^5.0.3"
10
+ "pixi.js": "^8.6.6",
11
+ "pixi-viewport": "^6.0.3"
12
12
  },
13
13
  "peerDependencies": {
14
- "react": "^18.2.0"
14
+ "react": "^19.0.0"
15
15
  },
16
16
  "description": "This module offers a set of common components needed for playing games.",
17
17
  "keywords": [
@@ -47,6 +47,6 @@
47
47
  "build": "tsc",
48
48
  "build:dev": "tsc -w"
49
49
  },
50
- "version": "1.0.2",
50
+ "version": "2.0.0",
51
51
  "webpack": "./src/index.ts"
52
52
  }
@@ -1,30 +1,35 @@
1
1
  import React, { PropsWithChildren, createContext, useMemo, useRef, useState } from "react";
2
- import { GameStatus } from "../types";
2
+ import { GameStatus, GameStatusChangeEvent } from "../types";
3
3
 
4
4
  export type GameContextValue = {
5
5
  readonly reset: () => void;
6
6
  readonly start: () => void;
7
+ readonly pause: () => void;
7
8
  readonly stop: () => void;
8
9
  readonly timeout: number;
9
10
  readonly status: GameStatus;
10
11
  readonly startTime: number | null;
12
+ readonly pauseTime: number;
11
13
  readonly endTime: number | null;
12
14
  };
13
15
 
14
16
  export type GameContextProviderEvents = {
15
- onStart?: (event: { startTime: number | null; status: GameStatus; endTime: number | null }) => unknown;
16
- onStop?: (event: { startTime: number | null; status: GameStatus; endTime: number | null }) => unknown;
17
- onTimedOut?: (event: { startTime: number | null; status: GameStatus; endTime: number | null }) => unknown;
18
- onReset?: (event: { startTime: number | null; status: GameStatus; endTime: number | null }) => unknown;
17
+ onStart?: (event: GameStatusChangeEvent) => unknown;
18
+ onStop?: (event: GameStatusChangeEvent) => unknown;
19
+ onPause?: (event: GameStatusChangeEvent) => unknown;
20
+ onTimedOut?: (event: GameStatusChangeEvent) => unknown;
21
+ onReset?: (event: GameStatusChangeEvent) => unknown;
19
22
  };
20
23
 
21
24
  export const GameContext = createContext<GameContextValue>({
22
25
  reset: () => {},
26
+ pause: () => {},
23
27
  start: () => {},
24
28
  stop: () => {},
25
29
  timeout: 0,
26
30
  status: GameStatus.READY,
27
31
  startTime: null,
32
+ pauseTime: 0,
28
33
  endTime: null
29
34
  });
30
35
 
@@ -38,12 +43,14 @@ export const GameContextProvider: React.FC<GameContextProviderProps> = ({
38
43
  timeout: inputTimeout = 0,
39
44
  events
40
45
  }) => {
41
- const timerRef = useRef<NodeJS.Timeout>();
46
+ const timerRef = useRef<NodeJS.Timeout>(null);
42
47
  const timeout = Math.max(0, inputTimeout);
43
48
 
44
49
  const [status, setStatus] = useState(GameStatus.READY);
45
50
  const [startTime, setStartTime] = useState<number | null>(null);
46
51
  const [endTime, setEndTime] = useState<number | null>(null);
52
+ const [pauseTime, setPauseTime] = useState<number>(0);
53
+ const [pausedAtTime, setPausedAtTime] = useState<number | null>(null);
47
54
 
48
55
  const onTimedOut = () => {
49
56
  const newEndTime = +new Date();
@@ -55,17 +62,22 @@ export const GameContextProvider: React.FC<GameContextProviderProps> = ({
55
62
  events?.onTimedOut?.({
56
63
  startTime,
57
64
  endTime: newEndTime,
58
- status: newStatus
65
+ status: newStatus,
66
+ pausedAtTime: null,
67
+ pauseTime
59
68
  });
60
69
  };
61
70
 
62
71
  const start = () => {
63
- const newStartTime = +new Date();
72
+ const newStartTime = startTime || +new Date();
64
73
  const newStatus = GameStatus.IN_PROGRESS;
65
74
  const newEndTime = null;
75
+ const newPauseTime = pausedAtTime ? pauseTime + +new Date() - (pausedAtTime || 0) : 0;
66
76
 
67
77
  setStatus(newStatus);
68
- setStartTime(newStartTime);
78
+ setStartTime((currentStartTime) => currentStartTime || newStartTime);
79
+ setPauseTime(newPauseTime);
80
+ setPausedAtTime(null);
69
81
  setEndTime(newEndTime);
70
82
 
71
83
  if (timeout !== 0) {
@@ -77,7 +89,9 @@ export const GameContextProvider: React.FC<GameContextProviderProps> = ({
77
89
  events?.onStart?.({
78
90
  startTime: newStartTime,
79
91
  endTime: newEndTime,
80
- status: newStatus
92
+ status: newStatus,
93
+ pausedAtTime: null,
94
+ pauseTime: newPauseTime
81
95
  });
82
96
  };
83
97
 
@@ -85,10 +99,14 @@ export const GameContextProvider: React.FC<GameContextProviderProps> = ({
85
99
  const newStartTime = null;
86
100
  const newStatus = GameStatus.READY;
87
101
  const newEndTime = null;
102
+ const newPausedAtTime = null;
103
+ const newPauseTime = 0;
88
104
 
89
105
  setStatus(newStatus);
90
106
  setStartTime(newStartTime);
91
107
  setEndTime(newEndTime);
108
+ setPauseTime(newPauseTime);
109
+ setPausedAtTime(newPausedAtTime);
92
110
 
93
111
  if (timerRef.current) {
94
112
  clearTimeout(timerRef.current);
@@ -97,7 +115,9 @@ export const GameContextProvider: React.FC<GameContextProviderProps> = ({
97
115
  events?.onReset?.({
98
116
  startTime: newStartTime,
99
117
  endTime: newEndTime,
100
- status: newStatus
118
+ status: newStatus,
119
+ pausedAtTime: newPausedAtTime,
120
+ pauseTime: newPauseTime
101
121
  });
102
122
  };
103
123
 
@@ -105,14 +125,37 @@ export const GameContextProvider: React.FC<GameContextProviderProps> = ({
105
125
  const newStatus = GameStatus.COMPLETED;
106
126
  const newEndTime = +new Date();
107
127
 
108
- clearTimeout(timerRef.current);
128
+ if (timerRef.current) {
129
+ clearTimeout(timerRef.current);
130
+ }
109
131
  setEndTime(+new Date());
110
132
  setStatus(GameStatus.COMPLETED);
111
133
 
112
134
  events?.onStop?.({
113
135
  startTime,
114
136
  endTime: newEndTime,
115
- status: newStatus
137
+ status: newStatus,
138
+ pausedAtTime,
139
+ pauseTime
140
+ });
141
+ };
142
+
143
+ const pause = () => {
144
+ const newStatus = GameStatus.PAUSED;
145
+ const newPausedAtTime = +new Date();
146
+
147
+ if (timerRef.current) {
148
+ clearTimeout(timerRef.current);
149
+ }
150
+ setStatus(GameStatus.PAUSED);
151
+ setPausedAtTime(newPausedAtTime);
152
+
153
+ events?.onPause?.({
154
+ startTime,
155
+ endTime: null,
156
+ pausedAtTime: newPausedAtTime,
157
+ status: newStatus,
158
+ pauseTime
116
159
  });
117
160
  };
118
161
 
@@ -121,12 +164,14 @@ export const GameContextProvider: React.FC<GameContextProviderProps> = ({
121
164
  status,
122
165
  startTime,
123
166
  endTime,
167
+ pauseTime,
124
168
  timeout,
125
169
  stop,
126
170
  start,
127
- reset
171
+ reset,
172
+ pause
128
173
  }),
129
- [timeout, status, startTime, endTime]
174
+ [timeout, status, startTime, endTime, pauseTime, pausedAtTime]
130
175
  );
131
176
 
132
177
  return <GameContext.Provider value={contextValue}>{children}</GameContext.Provider>;
package/src/types.ts CHANGED
@@ -2,7 +2,16 @@ export enum GameStatus {
2
2
  READY = 0,
3
3
  IN_PROGRESS = 1,
4
4
  TIMEDOUT = 2,
5
- COMPLETED = 3
5
+ COMPLETED = 3,
6
+ PAUSED = 4
6
7
  }
7
8
 
8
9
  export type Nullable<T> = T | null;
10
+
11
+ export type GameStatusChangeEvent = {
12
+ startTime: number | null;
13
+ status: GameStatus;
14
+ endTime: number | null;
15
+ pausedAtTime: number | null;
16
+ pauseTime: number;
17
+ };