Added tracking of requesting assets to prevent multiple requests

This commit is contained in:
Mitchell McCaffrey 2021-01-25 08:38:50 +11:00
parent dc3827b6a9
commit 99502bc878

View File

@ -1,4 +1,4 @@
import React, { useState, useContext, useEffect } from "react"; import React, { useState, useContext, useEffect, useRef } from "react";
import TokenDataContext from "../contexts/TokenDataContext"; import TokenDataContext from "../contexts/TokenDataContext";
import MapDataContext from "../contexts/MapDataContext"; import MapDataContext from "../contexts/MapDataContext";
@ -35,16 +35,12 @@ function NetworkedMapAndTokens({ session }) {
isLoading, isLoading,
} = useContext(MapLoadingContext); } = useContext(MapLoadingContext);
const { putToken, getToken, updateToken, getTokenFromDB } = useContext( const { putToken, updateToken, getTokenFromDB } = useContext(
TokenDataContext TokenDataContext
); );
const { const { putMap, updateMap, getMapFromDB, updateMapState } = useContext(
putMap, MapDataContext
updateMap, );
getMap,
getMapFromDB,
updateMapState,
} = useContext(MapDataContext);
const [currentMap, setCurrentMap] = useState(null); const [currentMap, setCurrentMap] = useState(null);
const [currentMapState, setCurrentMapState] = useNetworkedState( const [currentMapState, setCurrentMapState] = useNetworkedState(
@ -63,7 +59,7 @@ function NetworkedMapAndTokens({ session }) {
false false
); );
function loadAssetManifestFromMap(map, mapState) { async function loadAssetManifestFromMap(map, mapState) {
const assets = []; const assets = [];
if (map.type === "file") { if (map.type === "file") {
const { id, lastModified, owner } = map; const { id, lastModified, owner } = map;
@ -71,7 +67,7 @@ function NetworkedMapAndTokens({ session }) {
} }
let processedTokens = new Set(); let processedTokens = new Set();
for (let tokenState of Object.values(mapState.tokens)) { for (let tokenState of Object.values(mapState.tokens)) {
const token = getToken(tokenState.tokenId); const token = await getTokenFromDB(tokenState.tokenId);
if ( if (
token && token &&
token.type === "file" && token.type === "file" &&
@ -116,6 +112,9 @@ function NetworkedMapAndTokens({ session }) {
} }
} }
// Keep track of assets we are already requesting to prevent from loading them multiple times
const requestingAssetsRef = useRef(new Set());
useEffect(() => { useEffect(() => {
if (!assetManifest) { if (!assetManifest) {
return; return;
@ -123,7 +122,10 @@ function NetworkedMapAndTokens({ session }) {
async function requestAssetsIfNeeded() { async function requestAssetsIfNeeded() {
for (let asset of assetManifest) { for (let asset of assetManifest) {
if (asset.owner === userId) { if (
asset.owner === userId ||
requestingAssetsRef.current.has(asset.id)
) {
continue; continue;
} }
@ -135,7 +137,7 @@ function NetworkedMapAndTokens({ session }) {
} }
if (asset.type === "map") { if (asset.type === "map") {
const cachedMap = getMap(asset.id); const cachedMap = await getMapFromDB(asset.id);
if (cachedMap && cachedMap.lastModified === asset.lastModified) { if (cachedMap && cachedMap.lastModified === asset.lastModified) {
continue; continue;
} else if (cachedMap && cachedMap.lastModified > asset.lastModified) { } else if (cachedMap && cachedMap.lastModified > asset.lastModified) {
@ -144,10 +146,11 @@ function NetworkedMapAndTokens({ session }) {
await updateMap(cachedMap.id, { lastUsed }); await updateMap(cachedMap.id, { lastUsed });
setCurrentMap({ ...cachedMap, lastUsed }); setCurrentMap({ ...cachedMap, lastUsed });
} else { } else {
requestingAssetsRef.current.add(asset.id);
session.sendTo(owner.sessionId, "mapRequest", asset.id); session.sendTo(owner.sessionId, "mapRequest", asset.id);
} }
} else if (asset.type === "token") { } else if (asset.type === "token") {
const cachedToken = getToken(asset.id); const cachedToken = await getTokenFromDB(asset.id);
if (cachedToken && cachedToken.lastModified === asset.lastModified) { if (cachedToken && cachedToken.lastModified === asset.lastModified) {
continue; continue;
} else if ( } else if (
@ -158,6 +161,7 @@ function NetworkedMapAndTokens({ session }) {
const lastUsed = Date.now(); const lastUsed = Date.now();
await updateToken(cachedToken.id, { lastUsed }); await updateToken(cachedToken.id, { lastUsed });
} else { } else {
requestingAssetsRef.current.add(asset.id);
session.sendTo(owner.sessionId, "tokenRequest", asset.id); session.sendTo(owner.sessionId, "tokenRequest", asset.id);
} }
} }
@ -169,8 +173,8 @@ function NetworkedMapAndTokens({ session }) {
assetManifest, assetManifest,
partyState, partyState,
session, session,
getMap, getMapFromDB,
getToken, getTokenFromDB,
updateMap, updateMap,
updateToken, updateToken,
userId, userId,
@ -299,7 +303,7 @@ function NetworkedMapAndTokens({ session }) {
return; return;
} }
// If file type token send the token to the other peers // If file type token send the token to the other peers
const token = getToken(tokenState.tokenId); const token = await getTokenFromDB(tokenState.tokenId);
if (token && token.type === "file") { if (token && token.type === "file") {
const { id, lastModified, owner } = token; const { id, lastModified, owner } = token;
addAssetIfNeeded({ type: "token", id, lastModified, owner }); addAssetIfNeeded({ type: "token", id, lastModified, owner });
@ -397,6 +401,10 @@ function NetworkedMapAndTokens({ session }) {
if (newMap?.id) { if (newMap?.id) {
setCurrentMap(newMap); setCurrentMap(newMap);
await putMap(newMap); await putMap(newMap);
// If we have the final map resolution
if (newMap.lastModified > 0) {
requestingAssetsRef.current.delete(newMap.id);
}
} }
assetLoadFinish(); assetLoadFinish();
} }