From 632da10acaf93ddb2a3192a0895230df0b024969 Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Tue, 18 Apr 2023 20:48:34 -0500 Subject: [PATCH] Make lazy proxies and options funcs pass along base object --- src/features/achievements/achievement.tsx | 6 ++++-- src/features/action.tsx | 6 ++++-- src/features/bars/bar.ts | 4 ++-- src/features/boards/board.ts | 4 ++-- src/features/challenges/challenge.tsx | 4 ++-- src/features/clickables/clickable.ts | 6 ++++-- src/features/conversion.ts | 8 +++---- src/features/feature.ts | 4 +--- src/features/grids/grid.ts | 4 ++-- src/features/hotkey.tsx | 4 ++-- src/features/infoboxes/infobox.ts | 4 ++-- src/features/links/links.ts | 4 ++-- src/features/particles/particles.tsx | 6 ++++-- src/features/repeatable.tsx | 4 ++-- src/features/reset.ts | 4 ++-- src/features/tabs/tab.ts | 4 ++-- src/features/tabs/tabFamily.ts | 6 ++++-- src/features/trees/tree.ts | 10 +++++---- src/features/upgrades/upgrade.ts | 4 ++-- src/game/layers.tsx | 2 +- src/game/modifiers.tsx | 26 ++++++++++++++--------- src/game/requirements.tsx | 7 +++--- src/util/proxies.ts | 6 +++--- 23 files changed, 77 insertions(+), 60 deletions(-) diff --git a/src/features/achievements/achievement.tsx b/src/features/achievements/achievement.tsx index 3f2a7f3..ccbbc37 100644 --- a/src/features/achievements/achievement.tsx +++ b/src/features/achievements/achievement.tsx @@ -140,8 +140,10 @@ export function createAchievement( optionsFunc?: OptionsFunc ): Achievement { const earned = persistent(false, false); - return createLazyProxy(() => { - const achievement = optionsFunc?.() ?? ({} as ReturnType>); + return createLazyProxy(feature => { + const achievement = + optionsFunc?.call(feature, feature) ?? + ({} as ReturnType>); achievement.id = getUniqueID("achievement-"); achievement.type = AchievementType; achievement[Component] = AchievementComponent as GenericComponent; diff --git a/src/features/action.tsx b/src/features/action.tsx index 46f0e72..31dd6a1 100644 --- a/src/features/action.tsx +++ b/src/features/action.tsx @@ -105,8 +105,10 @@ export function createAction( optionsFunc?: OptionsFunc ): Action { const progress = persistent(0); - return createLazyProxy(() => { - const action = optionsFunc?.() ?? ({} as ReturnType>); + return createLazyProxy(feature => { + const action = + optionsFunc?.call(feature, feature) ?? + ({} as ReturnType>); action.id = getUniqueID("action-"); action.type = ActionType; action[Component] = ClickableComponent as GenericComponent; diff --git a/src/features/bars/bar.ts b/src/features/bars/bar.ts index 0a6433c..82718eb 100644 --- a/src/features/bars/bar.ts +++ b/src/features/bars/bar.ts @@ -103,8 +103,8 @@ export type GenericBar = Replace< export function createBar( optionsFunc: OptionsFunc ): Bar { - return createLazyProxy(() => { - const bar = optionsFunc(); + return createLazyProxy(feature => { + const bar = optionsFunc.call(feature, feature); bar.id = getUniqueID("bar-"); bar.type = BarType; bar[Component] = BarComponent as GenericComponent; diff --git a/src/features/boards/board.ts b/src/features/boards/board.ts index b8f66b4..e10bf67 100644 --- a/src/features/boards/board.ts +++ b/src/features/boards/board.ts @@ -297,8 +297,8 @@ export function createBoard( false ); - return createLazyProxy(() => { - const board = optionsFunc(); + return createLazyProxy(feature => { + const board = optionsFunc.call(feature, feature); board.id = getUniqueID("board-"); board.type = BoardType; board[Component] = BoardComponent as GenericComponent; diff --git a/src/features/challenges/challenge.tsx b/src/features/challenges/challenge.tsx index 5b6231d..a180139 100644 --- a/src/features/challenges/challenge.tsx +++ b/src/features/challenges/challenge.tsx @@ -152,8 +152,8 @@ export function createChallenge( ): Challenge { const completions = persistent(0); const active = persistent(false, false); - return createLazyProxy(() => { - const challenge = optionsFunc(); + return createLazyProxy(feature => { + const challenge = optionsFunc.call(feature, feature); challenge.id = getUniqueID("challenge-"); challenge.type = ChallengeType; diff --git a/src/features/clickables/clickable.ts b/src/features/clickables/clickable.ts index d369603..1516965 100644 --- a/src/features/clickables/clickable.ts +++ b/src/features/clickables/clickable.ts @@ -97,8 +97,10 @@ export type GenericClickable = Replace< export function createClickable( optionsFunc?: OptionsFunc ): Clickable { - return createLazyProxy(() => { - const clickable = optionsFunc?.() ?? ({} as ReturnType>); + return createLazyProxy(feature => { + const clickable = + optionsFunc?.call(feature, feature) ?? + ({} as ReturnType>); clickable.id = getUniqueID("clickable-"); clickable.type = ClickableType; clickable[Component] = ClickableComponent as GenericComponent; diff --git a/src/features/conversion.ts b/src/features/conversion.ts index a184de0..6ea498f 100644 --- a/src/features/conversion.ts +++ b/src/features/conversion.ts @@ -125,8 +125,8 @@ export type GenericConversion = Replace< export function createConversion( optionsFunc: OptionsFunc ): Conversion { - return createLazyProxy(() => { - const conversion = optionsFunc(); + return createLazyProxy(feature => { + const conversion = optionsFunc.call(feature, feature); (conversion as GenericConversion).formula = conversion.formula( Formula.variable(conversion.baseResource) @@ -211,8 +211,8 @@ export function createCumulativeConversion( export function createIndependentConversion( optionsFunc: OptionsFunc ): Conversion { - return createConversion(() => { - const conversion: S = optionsFunc(); + return createConversion(feature => { + const conversion: S = optionsFunc.call(feature, feature); setDefault(conversion, "buyMax", false); diff --git a/src/features/feature.ts b/src/features/feature.ts index d234997..db0af40 100644 --- a/src/features/feature.ts +++ b/src/features/feature.ts @@ -42,9 +42,7 @@ export type Replace = S & Omit; * with "this" bound to what the type will eventually be processed into. * Intended for making lazily evaluated objects. */ -export type OptionsFunc, S = R> = () => T & - Partial & - ThisType; +export type OptionsFunc = (obj: R) => T & Partial & ThisType; let id = 0; /** diff --git a/src/features/grids/grid.ts b/src/features/grids/grid.ts index 57eb399..454bbfc 100644 --- a/src/features/grids/grid.ts +++ b/src/features/grids/grid.ts @@ -307,8 +307,8 @@ export function createGrid( optionsFunc: OptionsFunc ): Grid { const cellState = persistent>({}, false); - return createLazyProxy(() => { - const grid = optionsFunc(); + return createLazyProxy(feature => { + const grid = optionsFunc.call(feature, feature); grid.id = getUniqueID("grid-"); grid[Component] = GridComponent as GenericComponent; diff --git a/src/features/hotkey.tsx b/src/features/hotkey.tsx index dcfdade..51fafbb 100644 --- a/src/features/hotkey.tsx +++ b/src/features/hotkey.tsx @@ -68,8 +68,8 @@ const uppercaseNumbers = [")", "!", "@", "#", "$", "%", "^", "&", "*", "("]; export function createHotkey( optionsFunc: OptionsFunc ): Hotkey { - return createLazyProxy(() => { - const hotkey = optionsFunc(); + return createLazyProxy(feature => { + const hotkey = optionsFunc.call(feature, feature); hotkey.type = HotkeyType; processComputable(hotkey as T, "enabled"); diff --git a/src/features/infoboxes/infobox.ts b/src/features/infoboxes/infobox.ts index f5c7a2f..551d86c 100644 --- a/src/features/infoboxes/infobox.ts +++ b/src/features/infoboxes/infobox.ts @@ -91,8 +91,8 @@ export function createInfobox( optionsFunc: OptionsFunc ): Infobox { const collapsed = persistent(false, false); - return createLazyProxy(() => { - const infobox = optionsFunc(); + return createLazyProxy(feature => { + const infobox = optionsFunc.call(feature, feature); infobox.id = getUniqueID("infobox-"); infobox.type = InfoboxType; infobox[Component] = InfoboxComponent as GenericComponent; diff --git a/src/features/links/links.ts b/src/features/links/links.ts index 5b28c46..c5603c5 100644 --- a/src/features/links/links.ts +++ b/src/features/links/links.ts @@ -59,8 +59,8 @@ export type GenericLinks = Replace< export function createLinks( optionsFunc: OptionsFunc ): Links { - return createLazyProxy(() => { - const links = optionsFunc(); + return createLazyProxy(feature => { + const links = optionsFunc.call(feature, feature); links.type = LinksType; links[Component] = LinksComponent as GenericComponent; diff --git a/src/features/particles/particles.tsx b/src/features/particles/particles.tsx index 8edaab1..d2797d5 100644 --- a/src/features/particles/particles.tsx +++ b/src/features/particles/particles.tsx @@ -69,8 +69,10 @@ export type GenericParticles = Particles; export function createParticles( optionsFunc?: OptionsFunc ): Particles { - return createLazyProxy(() => { - const particles = optionsFunc?.() ?? ({} as ReturnType>); + return createLazyProxy(feature => { + const particles = + optionsFunc?.call(feature, feature) ?? + ({} as ReturnType>); particles.id = getUniqueID("particles-"); particles.type = ParticlesType; particles[Component] = ParticlesComponent as GenericComponent; diff --git a/src/features/repeatable.tsx b/src/features/repeatable.tsx index 2598c19..098b637 100644 --- a/src/features/repeatable.tsx +++ b/src/features/repeatable.tsx @@ -132,8 +132,8 @@ export function createRepeatable( optionsFunc: OptionsFunc ): Repeatable { const amount = persistent(0); - return createLazyProxy(() => { - const repeatable = optionsFunc(); + return createLazyProxy(feature => { + const repeatable = optionsFunc.call(feature, feature); repeatable.id = getUniqueID("repeatable-"); repeatable.type = RepeatableType; diff --git a/src/features/reset.ts b/src/features/reset.ts index 0bba943..b7c40ed 100644 --- a/src/features/reset.ts +++ b/src/features/reset.ts @@ -54,8 +54,8 @@ export type GenericReset = Reset; export function createReset( optionsFunc: OptionsFunc ): Reset { - return createLazyProxy(() => { - const reset = optionsFunc(); + return createLazyProxy(feature => { + const reset = optionsFunc.call(feature, feature); reset.id = getUniqueID("reset-"); reset.type = ResetType; diff --git a/src/features/tabs/tab.ts b/src/features/tabs/tab.ts index d19dfdd..111f954 100644 --- a/src/features/tabs/tab.ts +++ b/src/features/tabs/tab.ts @@ -62,8 +62,8 @@ export type GenericTab = Tab; export function createTab( optionsFunc: OptionsFunc ): Tab { - return createLazyProxy(() => { - const tab = optionsFunc(); + return createLazyProxy(feature => { + const tab = optionsFunc.call(feature, feature); tab.id = getUniqueID("tab-"); tab.type = TabType; tab[Component] = TabComponent as GenericComponent; diff --git a/src/features/tabs/tabFamily.ts b/src/features/tabs/tabFamily.ts index 316b309..2ca544b 100644 --- a/src/features/tabs/tabFamily.ts +++ b/src/features/tabs/tabFamily.ts @@ -156,8 +156,10 @@ export function createTabFamily( } const selected = persistent(Object.keys(tabs)[0], false); - return createLazyProxy(() => { - const tabFamily = optionsFunc?.() ?? ({} as ReturnType>); + return createLazyProxy(feature => { + const tabFamily = + optionsFunc?.call(feature, feature) ?? + ({} as ReturnType>); tabFamily.id = getUniqueID("tabFamily-"); tabFamily.type = TabFamilyType; diff --git a/src/features/trees/tree.ts b/src/features/trees/tree.ts index 8bd1f7a..67c6892 100644 --- a/src/features/trees/tree.ts +++ b/src/features/trees/tree.ts @@ -103,8 +103,10 @@ export type GenericTreeNode = Replace< export function createTreeNode( optionsFunc?: OptionsFunc ): TreeNode { - return createLazyProxy(() => { - const treeNode = optionsFunc?.() ?? ({} as ReturnType>); + return createLazyProxy(feature => { + const treeNode = + optionsFunc?.call(feature, feature) ?? + ({} as ReturnType>); treeNode.id = getUniqueID("treeNode-"); treeNode.type = TreeNodeType; treeNode[Component] = TreeNodeComponent as GenericComponent; @@ -242,8 +244,8 @@ export type GenericTree = Replace< export function createTree( optionsFunc: OptionsFunc ): Tree { - return createLazyProxy(() => { - const tree = optionsFunc(); + return createLazyProxy(feature => { + const tree = optionsFunc.call(feature, feature); tree.id = getUniqueID("tree-"); tree.type = TreeType; tree[Component] = TreeComponent as GenericComponent; diff --git a/src/features/upgrades/upgrade.ts b/src/features/upgrades/upgrade.ts index 14a64e7..5eebfc6 100644 --- a/src/features/upgrades/upgrade.ts +++ b/src/features/upgrades/upgrade.ts @@ -118,8 +118,8 @@ export function createUpgrade( optionsFunc: OptionsFunc ): Upgrade { const bought = persistent(false, false); - return createLazyProxy(() => { - const upgrade = optionsFunc(); + return createLazyProxy(feature => { + const upgrade = optionsFunc.call(feature, feature); upgrade.id = getUniqueID("upgrade-"); upgrade.type = UpgradeType; upgrade[Component] = UpgradeComponent as GenericComponent; diff --git a/src/game/layers.tsx b/src/game/layers.tsx index 532daba..6294592 100644 --- a/src/game/layers.tsx +++ b/src/game/layers.tsx @@ -220,7 +220,7 @@ export function createLayer( addingLayers.push(id); persistentRefs[id] = new Set(); layer.minimized = persistent(false, false); - Object.assign(layer, optionsFunc.call(layer as BaseLayer)); + Object.assign(layer, optionsFunc.call(layer, layer as BaseLayer)); if ( addingLayers[addingLayers.length - 1] == null || addingLayers[addingLayers.length - 1] !== id diff --git a/src/game/modifiers.tsx b/src/game/modifiers.tsx index 74692b0..cceacd8 100644 --- a/src/game/modifiers.tsx +++ b/src/game/modifiers.tsx @@ -1,5 +1,5 @@ import "components/common/modifiers.css"; -import type { CoercableComponent } from "features/feature"; +import type { CoercableComponent, OptionsFunc } from "features/feature"; import { jsx } from "features/feature"; import settings from "game/settings"; import type { DecimalSource } from "util/bignum"; @@ -66,10 +66,13 @@ export interface AdditiveModifierOptions { * @param optionsFunc Additive modifier options. */ export function createAdditiveModifier( - optionsFunc: () => T + optionsFunc: OptionsFunc ): ModifierFromOptionalParams { - return createLazyProxy(() => { - const { addend, description, enabled, smallerIsBetter } = optionsFunc(); + return createLazyProxy(feature => { + const { addend, description, enabled, smallerIsBetter } = optionsFunc.call( + feature, + feature + ); const processedAddend = convertComputable(addend); const processedDescription = convertComputable(description); @@ -128,10 +131,13 @@ export interface MultiplicativeModifierOptions { * @param optionsFunc Multiplicative modifier options. */ export function createMultiplicativeModifier( - optionsFunc: () => T + optionsFunc: OptionsFunc ): ModifierFromOptionalParams { - return createLazyProxy(() => { - const { multiplier, description, enabled, smallerIsBetter } = optionsFunc(); + return createLazyProxy(feature => { + const { multiplier, description, enabled, smallerIsBetter } = optionsFunc.call( + feature, + feature + ); const processedMultiplier = convertComputable(multiplier); const processedDescription = convertComputable(description); @@ -191,11 +197,11 @@ export interface ExponentialModifierOptions { * @param optionsFunc Exponential modifier options. */ export function createExponentialModifier( - optionsFunc: () => T + optionsFunc: OptionsFunc ): ModifierFromOptionalParams { - return createLazyProxy(() => { + return createLazyProxy(feature => { const { exponent, description, enabled, supportLowNumbers, smallerIsBetter } = - optionsFunc(); + optionsFunc.call(feature, feature); const processedExponent = convertComputable(exponent); const processedDescription = convertComputable(description); diff --git a/src/game/requirements.tsx b/src/game/requirements.tsx index acb7f7b..35504b6 100644 --- a/src/game/requirements.tsx +++ b/src/game/requirements.tsx @@ -3,6 +3,7 @@ import { CoercableComponent, isVisible, jsx, + OptionsFunc, Replace, setDefault, Visibility @@ -108,10 +109,10 @@ export type CostRequirement = Replace< * @param optionsFunc Cost requirement options. */ export function createCostRequirement( - optionsFunc: () => T + optionsFunc: OptionsFunc ): CostRequirement { - return createLazyProxy(() => { - const req = optionsFunc() as T & Partial; + return createLazyProxy(feature => { + const req = optionsFunc.call(feature, feature) as T & Partial; req.partialDisplay = amount => ( = NonNullable extends Record // Takes a function that returns an object and pretends to be that object // Note that the object is lazily calculated export function createLazyProxy( - objectFunc: (baseObject: S) => T & S, + objectFunc: (this: S, baseObject: S) => T & S, baseObject: S = {} as S ): T { const obj: S & Partial = baseObject; let calculated = false; function calculateObj(): T { if (!calculated) { - Object.assign(obj, objectFunc(obj)); + Object.assign(obj, objectFunc.call(obj, obj)); calculated = true; } return obj as S & T; @@ -73,7 +73,7 @@ export function createLazyProxy( }, getOwnPropertyDescriptor(target, key) { if (!calculated) { - Object.assign(obj, objectFunc(obj)); + Object.assign(obj, objectFunc.call(obj, obj)); calculated = true; } return Object.getOwnPropertyDescriptor(target, key);