From 64f1b460b06d2e0590d18571100fc448a67faf5f Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Sun, 10 Apr 2022 19:04:56 -0500 Subject: [PATCH] Added FeatureOptionsFunc to simplify features --- src/data/common.tsx | 6 +++--- src/features/achievements/achievement.tsx | 7 +++---- src/features/bars/bar.ts | 7 +++++-- src/features/boards/board.ts | 7 +++---- src/features/buyable.tsx | 7 +++---- src/features/challenges/challenge.tsx | 5 +++-- src/features/clickables/clickable.ts | 5 +++-- src/features/conversion.ts | 12 +++++------- src/features/feature.ts | 2 ++ src/features/grids/grid.ts | 7 +++---- src/features/hotkey.tsx | 6 +++--- src/features/infoboxes/infobox.ts | 7 +++---- src/features/links/links.ts | 6 +++--- src/features/milestones/milestone.tsx | 7 +++---- src/features/particles/particles.tsx | 13 ++++++++++--- src/features/reset.ts | 6 +++--- src/features/tabs/tab.ts | 7 +++++-- src/features/tabs/tabFamily.ts | 7 +++---- src/features/trees/tree.ts | 9 +++++---- src/features/upgrades/upgrade.ts | 7 +++---- src/game/layers.tsx | 3 ++- 21 files changed, 76 insertions(+), 67 deletions(-) diff --git a/src/data/common.tsx b/src/data/common.tsx index 5fd5547..50bcfe6 100644 --- a/src/data/common.tsx +++ b/src/data/common.tsx @@ -5,7 +5,7 @@ import { GenericClickable } from "features/clickables/clickable"; import { GenericConversion } from "features/conversion"; -import { CoercableComponent, jsx, Replace, setDefault } from "features/feature"; +import { CoercableComponent, OptionsFunc, jsx, Replace, setDefault } from "features/feature"; import { displayResource } from "features/resources/resource"; import { createTreeNode, @@ -57,7 +57,7 @@ export type GenericResetButton = Replace< >; export function createResetButton( - optionsFunc: () => T + optionsFunc: OptionsFunc ): ResetButton { return createClickable(() => { const resetButton = optionsFunc(); @@ -139,7 +139,7 @@ export type GenericLayerTreeNode = Replace< >; export function createLayerTreeNode( - optionsFunc: () => T + optionsFunc: OptionsFunc ): LayerTreeNode { return createTreeNode(() => { const options = optionsFunc(); diff --git a/src/features/achievements/achievement.tsx b/src/features/achievements/achievement.tsx index 31140ff..be97c1c 100644 --- a/src/features/achievements/achievement.tsx +++ b/src/features/achievements/achievement.tsx @@ -2,6 +2,7 @@ import AchievementComponent from "features/achievements/Achievement.vue"; import { CoercableComponent, Component, + OptionsFunc, GatherProps, getUniqueID, Replace, @@ -67,12 +68,10 @@ export type GenericAchievement = Replace< >; export function createAchievement( - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseAchievement> ): Achievement { return createLazyProxy(persistent => { - // Create temp literally just to avoid explicitly assigning types - const temp = Object.assign(persistent, optionsFunc()); - const achievement: Partial & typeof temp = temp; + const achievement = Object.assign(persistent, optionsFunc()); achievement.id = getUniqueID("achievement-"); achievement.type = AchievementType; achievement[Component] = AchievementComponent; diff --git a/src/features/bars/bar.ts b/src/features/bars/bar.ts index 0b39233..b732048 100644 --- a/src/features/bars/bar.ts +++ b/src/features/bars/bar.ts @@ -2,6 +2,7 @@ import BarComponent from "features/bars/Bar.vue"; import { CoercableComponent, Component, + OptionsFunc, GatherProps, getUniqueID, Replace, @@ -79,9 +80,11 @@ export type GenericBar = Replace< } >; -export function createBar(optionsFunc: () => T & ThisType>): Bar { +export function createBar( + optionsFunc: OptionsFunc, BaseBar> +): Bar { return createLazyProxy(() => { - const bar: T & Partial = optionsFunc(); + const bar = optionsFunc(); bar.id = getUniqueID("bar-"); bar.type = BarType; bar[Component] = BarComponent; diff --git a/src/features/boards/board.ts b/src/features/boards/board.ts index 0328c77..8eefca0 100644 --- a/src/features/boards/board.ts +++ b/src/features/boards/board.ts @@ -1,6 +1,7 @@ import BoardComponent from "features/boards/Board.vue"; import { Component, + OptionsFunc, findFeatures, GatherProps, getUniqueID, @@ -197,13 +198,11 @@ export type GenericBoard = Replace< >; export function createBoard( - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseBoard> ): Board { return createLazyProxy( persistent => { - // Create temp literally just to avoid explicitly assigning types - const temp = Object.assign(persistent, optionsFunc()); - const board: Partial & typeof temp = temp; + const board = Object.assign(persistent, optionsFunc()); board.id = getUniqueID("board-"); board.type = BoardType; board[Component] = BoardComponent; diff --git a/src/features/buyable.tsx b/src/features/buyable.tsx index c831c28..d2af2c1 100644 --- a/src/features/buyable.tsx +++ b/src/features/buyable.tsx @@ -15,6 +15,7 @@ import { computed, Ref, unref } from "vue"; import { CoercableComponent, Component, + OptionsFunc, GatherProps, getUniqueID, jsx, @@ -87,12 +88,10 @@ export type GenericBuyable = Replace< >; export function createBuyable( - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseBuyable> ): Buyable { return createLazyProxy(persistent => { - // Create temp literally just to avoid explicitly assigning types - const temp = Object.assign(persistent, optionsFunc()); - const buyable: Partial & typeof temp = temp; + const buyable = Object.assign(persistent, optionsFunc()); if (buyable.canPurchase == null && (buyable.resource == null || buyable.cost == null)) { console.warn( diff --git a/src/features/challenges/challenge.tsx b/src/features/challenges/challenge.tsx index 71231c8..9cc6e40 100644 --- a/src/features/challenges/challenge.tsx +++ b/src/features/challenges/challenge.tsx @@ -4,6 +4,7 @@ import ChallengeComponent from "features/challenges/Challenge.vue"; import { CoercableComponent, Component, + OptionsFunc, GatherProps, getUniqueID, jsx, @@ -96,12 +97,12 @@ export type GenericChallenge = Replace< >; export function createChallenge( - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseChallenge> ): Challenge { const completions = persistent(0); const active = persistent(false); return createLazyProxy(() => { - const challenge: T & Partial = optionsFunc(); + const challenge = optionsFunc(); if ( challenge.canComplete == null && diff --git a/src/features/clickables/clickable.ts b/src/features/clickables/clickable.ts index 15ed030..929599c 100644 --- a/src/features/clickables/clickable.ts +++ b/src/features/clickables/clickable.ts @@ -2,6 +2,7 @@ import ClickableComponent from "features/clickables/Clickable.vue"; import { CoercableComponent, Component, + OptionsFunc, GatherProps, getUniqueID, Replace, @@ -69,10 +70,10 @@ export type GenericClickable = Replace< >; export function createClickable( - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseClickable> ): Clickable { return createLazyProxy(() => { - const clickable: T & Partial = optionsFunc(); + const clickable = optionsFunc(); clickable.id = getUniqueID("clickable-"); clickable.type = ClickableType; clickable[Component] = ClickableComponent; diff --git a/src/features/conversion.ts b/src/features/conversion.ts index 4fdc88c..af3b652 100644 --- a/src/features/conversion.ts +++ b/src/features/conversion.ts @@ -1,17 +1,15 @@ import { GenericLayer } from "game/layers"; import Decimal, { DecimalSource } from "util/bignum"; -import { isFunction } from "util/common"; import { Computable, convertComputable, - DoNotCache, GetComputableTypeWithDefault, processComputable, ProcessedComputable } from "util/computed"; import { createLazyProxy } from "util/proxies"; import { computed, isRef, Ref, unref } from "vue"; -import { Replace, setDefault } from "./feature"; +import { OptionsFunc, Replace, setDefault } from "./feature"; import { Resource } from "./resources/resource"; export interface ConversionOptions { @@ -62,10 +60,10 @@ export interface GainModifier { } export function createConversion( - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseConversion> ): Conversion { return createLazyProxy(() => { - const conversion: T = optionsFunc(); + const conversion = optionsFunc(); if (conversion.currentGain == null) { conversion.currentGain = computed(() => { @@ -199,13 +197,13 @@ export function createPolynomialScaling( } export function createCumulativeConversion( - optionsFunc: () => S & ThisType> + optionsFunc: OptionsFunc> ): Conversion { return createConversion(optionsFunc); } export function createIndependentConversion( - optionsFunc: () => S & ThisType> + optionsFunc: OptionsFunc> ): Conversion { return createConversion(() => { const conversion: S = optionsFunc(); diff --git a/src/features/feature.ts b/src/features/feature.ts index 8fc55fd..2946726 100644 --- a/src/features/feature.ts +++ b/src/features/feature.ts @@ -24,6 +24,8 @@ export type FeatureComponent = Omit< export type Replace = S & Omit; +export type OptionsFunc> = () => T & ThisType & Partial; + let id = 0; // Get a unique ID to allow a feature to be found for creating branches // and any other uses requiring unique identifiers for each feature diff --git a/src/features/grids/grid.ts b/src/features/grids/grid.ts index 97033cb..e78f1a1 100644 --- a/src/features/grids/grid.ts +++ b/src/features/grids/grid.ts @@ -2,6 +2,7 @@ import GridComponent from "features/grids/Grid.vue"; import { CoercableComponent, Component, + OptionsFunc, GatherProps, getUniqueID, Replace, @@ -241,12 +242,10 @@ export type GenericGrid = Replace< >; export function createGrid( - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseGrid> ): Grid { return createLazyProxy(persistent => { - // Create temp literally just to avoid explicitly assigning types - const temp = Object.assign(persistent, optionsFunc()); - const grid: Partial & typeof temp = temp; + const grid = Object.assign(persistent, optionsFunc()); grid.id = getUniqueID("grid-"); grid[Component] = GridComponent; diff --git a/src/features/hotkey.tsx b/src/features/hotkey.tsx index e62f432..5714512 100644 --- a/src/features/hotkey.tsx +++ b/src/features/hotkey.tsx @@ -11,7 +11,7 @@ import { } from "util/computed"; import { createLazyProxy } from "util/proxies"; import { shallowReactive, unref } from "vue"; -import { findFeatures, jsx, Replace, setDefault } from "./feature"; +import { OptionsFunc, findFeatures, jsx, Replace, setDefault } from "./feature"; export const hotkeys: Record = shallowReactive({}); export const HotkeyType = Symbol("Hotkey"); @@ -43,10 +43,10 @@ export type GenericHotkey = Replace< >; export function createHotkey( - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseHotkey> ): Hotkey { return createLazyProxy(() => { - const hotkey: T & Partial = optionsFunc(); + const hotkey = optionsFunc(); hotkey.type = HotkeyType; processComputable(hotkey as T, "enabled"); diff --git a/src/features/infoboxes/infobox.ts b/src/features/infoboxes/infobox.ts index 55580de..09ede8d 100644 --- a/src/features/infoboxes/infobox.ts +++ b/src/features/infoboxes/infobox.ts @@ -2,6 +2,7 @@ import InfoboxComponent from "features/infoboxes/Infobox.vue"; import { CoercableComponent, Component, + OptionsFunc, GatherProps, getUniqueID, Replace, @@ -63,12 +64,10 @@ export type GenericInfobox = Replace< >; export function createInfobox( - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseInfobox> ): Infobox { return createLazyProxy(persistent => { - // Create temp literally just to avoid explicitly assigning types - const temp = Object.assign(persistent, optionsFunc()); - const infobox: Partial & typeof temp = temp; + const infobox = Object.assign(persistent, optionsFunc()); infobox.id = getUniqueID("infobox-"); infobox.type = InfoboxType; infobox[Component] = InfoboxComponent; diff --git a/src/features/links/links.ts b/src/features/links/links.ts index 61c4acf..4443b65 100644 --- a/src/features/links/links.ts +++ b/src/features/links/links.ts @@ -1,5 +1,5 @@ import LinksComponent from "./Links.vue"; -import { Component, GatherProps, Replace } from "features/feature"; +import { Component, OptionsFunc, GatherProps, Replace } from "features/feature"; import { Position } from "game/layers"; import { Computable, @@ -44,10 +44,10 @@ export type GenericLinks = Replace< >; export function createLinks( - optionsFunc: (() => T) & ThisType> + optionsFunc: OptionsFunc, BaseLinks> ): Links { return createLazyProxy(() => { - const links: T & Partial = optionsFunc(); + const links = optionsFunc(); links.type = LinksType; links[Component] = LinksComponent; diff --git a/src/features/milestones/milestone.tsx b/src/features/milestones/milestone.tsx index 28c32a0..2e02e53 100644 --- a/src/features/milestones/milestone.tsx +++ b/src/features/milestones/milestone.tsx @@ -2,6 +2,7 @@ import Select from "components/fields/Select.vue"; import { CoercableComponent, Component, + OptionsFunc, GatherProps, getUniqueID, jsx, @@ -83,12 +84,10 @@ export type GenericMilestone = Replace< >; export function createMilestone( - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseMilestone> ): Milestone { return createLazyProxy(persistent => { - // Create temp literally just to avoid explicitly assigning types - const temp = Object.assign(persistent, optionsFunc()); - const milestone: Partial & typeof temp = temp; + const milestone = Object.assign(persistent, optionsFunc()); milestone.id = getUniqueID("milestone-"); milestone.type = MilestoneType; milestone[Component] = MilestoneComponent; diff --git a/src/features/particles/particles.tsx b/src/features/particles/particles.tsx index 14246e2..4120a39 100644 --- a/src/features/particles/particles.tsx +++ b/src/features/particles/particles.tsx @@ -1,6 +1,13 @@ import ParticlesComponent from "features/particles/Particles.vue"; import { Ref, shallowRef, unref } from "vue"; -import { Component, GatherProps, getUniqueID, Replace, StyleValue } from "features/feature"; +import { + Component, + OptionsFunc, + GatherProps, + getUniqueID, + Replace, + StyleValue +} from "features/feature"; import { createLazyProxy } from "util/proxies"; import { Application } from "pixi.js"; import { Emitter, EmitterConfigV3, upgradeConfig } from "@pixi/particle-emitter"; @@ -35,10 +42,10 @@ export type Particles = Replace< export type GenericParticles = Particles; export function createParticles( - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseParticles> ): Particles { return createLazyProxy(() => { - const particles: T & Partial = optionsFunc(); + const particles = optionsFunc(); particles.id = getUniqueID("particles-"); particles.type = ParticlesType; particles[Component] = ParticlesComponent; diff --git a/src/features/reset.ts b/src/features/reset.ts index cc3687e..af0659a 100644 --- a/src/features/reset.ts +++ b/src/features/reset.ts @@ -1,4 +1,4 @@ -import { getUniqueID, Replace } from "features/feature"; +import { OptionsFunc, getUniqueID, Replace } from "features/feature"; import { globalBus } from "game/events"; import { GenericLayer } from "game/layers"; import { DefaultValue, Persistent, persistent, PersistentState } from "game/persistence"; @@ -31,10 +31,10 @@ export type Reset = Replace< export type GenericReset = Reset; export function createReset( - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseReset> ): Reset { return createLazyProxy(() => { - const reset: T & Partial = optionsFunc(); + const reset = optionsFunc(); reset.id = getUniqueID("reset-"); reset.type = ResetType; diff --git a/src/features/tabs/tab.ts b/src/features/tabs/tab.ts index a5ffe38..0993a85 100644 --- a/src/features/tabs/tab.ts +++ b/src/features/tabs/tab.ts @@ -1,6 +1,7 @@ import { CoercableComponent, Component, + OptionsFunc, GatherProps, getUniqueID, Replace, @@ -36,9 +37,11 @@ export type Tab = Replace< export type GenericTab = Tab; -export function createTab(optionsFunc: () => T & ThisType>): Tab { +export function createTab( + optionsFunc: OptionsFunc, BaseTab> +): Tab { return createLazyProxy(() => { - const tab: T & Partial = optionsFunc(); + const tab = optionsFunc(); tab.id = getUniqueID("tab-"); tab.type = TabType; tab[Component] = TabComponent; diff --git a/src/features/tabs/tabFamily.ts b/src/features/tabs/tabFamily.ts index 13ec76b..a113f5c 100644 --- a/src/features/tabs/tabFamily.ts +++ b/src/features/tabs/tabFamily.ts @@ -1,6 +1,7 @@ import { CoercableComponent, Component, + OptionsFunc, GatherProps, getUniqueID, Replace, @@ -91,7 +92,7 @@ export type GenericTabFamily = Replace< export function createTabFamily( tabs: Record TabButtonOptions>, - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseTabFamily> ): TabFamily { if (Object.keys(tabs).length === 0) { console.warn("Cannot create tab family with 0 tabs"); @@ -99,9 +100,7 @@ export function createTabFamily( } return createLazyProxy(persistent => { - // Create temp literally just to avoid explicitly assigning types - const temp = Object.assign(persistent, optionsFunc()); - const tabFamily: Partial & typeof temp = temp; + const tabFamily = Object.assign(persistent, optionsFunc()); tabFamily.id = getUniqueID("tabFamily-"); tabFamily.type = TabFamilyType; diff --git a/src/features/trees/tree.ts b/src/features/trees/tree.ts index 5d00863..25bf5f8 100644 --- a/src/features/trees/tree.ts +++ b/src/features/trees/tree.ts @@ -1,6 +1,7 @@ import { CoercableComponent, Component, + OptionsFunc, GatherProps, getUniqueID, Replace, @@ -74,11 +75,11 @@ export type GenericTreeNode = Replace< >; export function createTreeNode( - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseTreeNode> ): TreeNode { const forceTooltip = persistent(false); return createLazyProxy(() => { - const treeNode: T & Partial = optionsFunc(); + const treeNode = optionsFunc(); treeNode.id = getUniqueID("treeNode-"); treeNode.type = TreeNodeType; @@ -168,10 +169,10 @@ export type GenericTree = Replace< >; export function createTree( - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseTree> ): Tree { return createLazyProxy(() => { - const tree: T & Partial = optionsFunc(); + const tree = optionsFunc(); tree.id = getUniqueID("tree-"); tree.type = TreeType; tree[Component] = TreeComponent; diff --git a/src/features/upgrades/upgrade.ts b/src/features/upgrades/upgrade.ts index 6b47574..2ece38d 100644 --- a/src/features/upgrades/upgrade.ts +++ b/src/features/upgrades/upgrade.ts @@ -2,6 +2,7 @@ import UpgradeComponent from "features/upgrades/Upgrade.vue"; import { CoercableComponent, Component, + OptionsFunc, findFeatures, GatherProps, getUniqueID, @@ -78,12 +79,10 @@ export type GenericUpgrade = Replace< >; export function createUpgrade( - optionsFunc: () => T & ThisType> + optionsFunc: OptionsFunc, BaseUpgrade> ): Upgrade { return createLazyProxy(persistent => { - // Create temp literally just to avoid explicitly assigning types - const temp = Object.assign(persistent, optionsFunc()); - const upgrade: Partial & typeof temp = temp; + const upgrade = Object.assign(persistent, optionsFunc()); upgrade.id = getUniqueID("upgrade-"); upgrade.type = UpgradeType; upgrade[Component] = UpgradeComponent; diff --git a/src/game/layers.tsx b/src/game/layers.tsx index e059eec..99dd826 100644 --- a/src/game/layers.tsx +++ b/src/game/layers.tsx @@ -1,6 +1,7 @@ import Modal from "components/Modal.vue"; import { CoercableComponent, + OptionsFunc, jsx, JSXFunction, Replace, @@ -104,7 +105,7 @@ export const persistentRefs: Record> = {}; export const addingLayers: string[] = []; export function createLayer( id: string, - optionsFunc: (() => T) & ThisType + optionsFunc: OptionsFunc ): Layer { return createLazyProxy(() => { const layer = {} as T & Partial;