From 1a65375d31b613a31cb8df0be701047059618fff Mon Sep 17 00:00:00 2001 From: Alexander Drozdov Date: Mon, 4 Oct 2021 15:53:07 +0300 Subject: [PATCH] reduce GC objects --- src/assets/data/index.ts | 69 +++++++++++++++++++++++++++++---- src/parser/advanced-mod-desc.ts | 11 +++--- src/parser/stat-translations.ts | 5 ++- src/web/settings/maps.vue | 25 +++++++----- vue.config.js | 6 +++ 5 files changed, 92 insertions(+), 24 deletions(-) diff --git a/src/assets/data/index.ts b/src/assets/data/index.ts index 6215485d..d2155821 100644 --- a/src/assets/data/index.ts +++ b/src/assets/data/index.ts @@ -13,10 +13,47 @@ export let CLIENTLOG_STRINGS: ClientLogDict export let ITEM_NAME_REF_BY_TRANSLATED: Map export let TRANSLATED_ITEM_NAME_BY_REF: Map -export let STATS: Stat[] +class MapNDJSON { + #data: string + #mapFn?: (key: K, value: unknown) => V + #map = new Map() -export const STAT_BY_MATCH_STR = new Map() -export const STAT_BY_REF = new Map() + constructor ( + data: string, + mapFn?: (key: K, value: unknown) => V + ) { + this.#data = data + this.#mapFn = mapFn + } + + set (key: K, line: number): void { + this.#map.set(key, line) + } + + get (key: K): V | undefined { + const start = this.#map.get(key) + if (start !== undefined) { + const end = this.#data.indexOf('\n', start) + const entry = JSON.parse(this.#data.slice(start, end)) + if (this.#mapFn) { + return this.#mapFn(key, entry) + } else { + return entry + } + } + } + + has (key: K): boolean { + return this.#map.has(key) + } + + keys () { + return this.#map.keys() + } +} + +export let STAT_BY_MATCH_STR: MapNDJSON +export let STAT_BY_REF: MapNDJSON export let BASE_TYPES: Map @@ -43,15 +80,31 @@ export const ITEM_DROP = new Map() } { - STATS = (require(`./${language}/stats.json`)) - for (const entry of STATS) { + const STATS_RAW: string = (require(`./${language}/stats.ndjson?raw`)) + STAT_BY_REF = new MapNDJSON(STATS_RAW) + STAT_BY_MATCH_STR = new MapNDJSON(STATS_RAW, (matchStr, stat) => { + return { + stat: (stat as Stat), + matcher: (stat as Stat).stat.matchers.find(m => + m.string === matchStr || + m.advanced === matchStr)! + } + }) + + let start = 0 + while (start !== STATS_RAW.length) { + const end = STATS_RAW.indexOf('\n', start) + const entry: Stat = JSON.parse(STATS_RAW.slice(start, end)) + for (const condition of entry.stat.matchers) { - STAT_BY_MATCH_STR.set(condition.string, { matcher: condition, stat: entry }) + STAT_BY_MATCH_STR.set(condition.string, start) if (condition.advanced) { - STAT_BY_MATCH_STR.set(condition.advanced, { matcher: condition, stat: entry }) + STAT_BY_MATCH_STR.set(condition.advanced, start) } } - STAT_BY_REF.set(entry.stat.ref, entry) + STAT_BY_REF.set(entry.stat.ref, start) + + start = end + 1 } } diff --git a/src/parser/advanced-mod-desc.ts b/src/parser/advanced-mod-desc.ts index 068725ca..9751116f 100644 --- a/src/parser/advanced-mod-desc.ts +++ b/src/parser/advanced-mod-desc.ts @@ -1,4 +1,4 @@ -import { CLIENT_STRINGS as _$, STAT_BY_MATCH_STR } from '@/assets/data' +import { CLIENT_STRINGS as _$ } from '@/assets/data' import * as C from './constants' import { percentRoll } from '@/web/price-check/filters/util' import type { ParsedStat } from './stat-translations' @@ -123,16 +123,17 @@ export function parseModType (lines: string[]): { modType: ModifierType, lines: // this is the most common formatter const DIV_BY_100 = 2 -function applyIncr (mod: ModifierInfo, stat: ParsedStat): ParsedStat | null { +function applyIncr (mod: ModifierInfo, parsed: ParsedStat): ParsedStat | null { const { rollIncr } = mod - const { roll } = stat + const { roll } = parsed if (!rollIncr || !roll || roll.unscalable) { return null } return { - translation: stat.translation, + stat: parsed.stat, + translation: parsed.translation, roll: { unscalable: roll.unscalable, dp: roll.dp, @@ -161,7 +162,7 @@ export function sumStatsFromMods (mods: readonly ParsedModifier[]): LegacyItemMo continue } - const dbStatA = STAT_BY_MATCH_STR.get(statA.translation.string)!.stat + const dbStatA = statA.stat const toMerge = mods .reduce((filtered, modB) => { diff --git a/src/parser/stat-translations.ts b/src/parser/stat-translations.ts index bfe22faf..54ab28e6 100644 --- a/src/parser/stat-translations.ts +++ b/src/parser/stat-translations.ts @@ -1,10 +1,12 @@ -import { CLIENT_STRINGS as _$, STAT_BY_MATCH_STR, StatMatcher } from '@/assets/data' +import { CLIENT_STRINGS as _$, STAT_BY_MATCH_STR } from '@/assets/data' +import type { StatMatcher, Stat } from '@/assets/data' import type { ModifierType } from './modifiers' // This file is a little messy and scary, // but that's how stats translations are parsed :-D export interface ParsedStat { + readonly stat: Stat readonly translation: StatMatcher roll?: { unscalable: boolean @@ -150,6 +152,7 @@ export function tryParseTranslation (stat: StatString, modType: ModifierType): P } return { + stat: found.stat, translation: found.matcher, roll: combination.values.length ? { diff --git a/src/web/settings/maps.vue b/src/web/settings/maps.vue index 8c35e68a..61296617 100644 --- a/src/web/settings/maps.vue +++ b/src/web/settings/maps.vue @@ -37,19 +37,10 @@ import { computed, defineComponent, ref } from 'vue' import { useI18n } from 'vue-i18n' import { configProp, findWidget } from './utils' import type { ItemCheckWidget } from '@/web/overlay/interfaces' -import { STATS, STAT_BY_MATCH_STR } from '@/assets/data' +import { STAT_BY_REF, STAT_BY_MATCH_STR } from '@/assets/data' import MapsStatEntry from './MapsStatEntry.vue' import VirtualScroll from '../ui/VirtualScroll.vue' -const statList = computed(() => { - return STATS.flatMap(({ stat }) => - stat.matchers.map(c => ({ - matchStr: c.string, - searchStr: c.string.toLowerCase() - })) - ) -}) - export default defineComponent({ components: { MapsStatEntry, VirtualScroll }, props: configProp(), @@ -59,6 +50,20 @@ export default defineComponent({ const widget = computed(() => findWidget('item-check', props.config)!) + const statList = computed(() => { + const out: Array<{ matchStr: string, searchStr: string }> = [] + for (const statRef of STAT_BY_REF.keys()) { + const { stat } = STAT_BY_REF.get(statRef)! + for (const c of stat.matchers) { + out.push({ + matchStr: c.string, + searchStr: c.string.toLowerCase() + }) + } + } + return out + }) + const selectedMatchers = computed(() => { return new Set( widget.value.maps.selectedStats diff --git a/vue.config.js b/vue.config.js index e9f4f59c..a65a8d65 100644 --- a/vue.config.js +++ b/vue.config.js @@ -36,5 +36,11 @@ module.exports = { .use('i18n') .loader('@intlify/vue-i18n-loader') .end() + + config.module + .rule('raw') + .resourceQuery(/raw/) + .type('asset/source') + .end() } }