Made no features extend Persistent

This commit is contained in:
thepaperpilot 2022-04-23 18:20:15 -05:00
parent cfe378020a
commit aae6455ea6
7 changed files with 70 additions and 60 deletions

View file

@ -11,7 +11,7 @@ import {
Visibility
} from "features/feature";
import "game/notifications";
import { Persistent, PersistentState, persistent } from "game/persistence";
import { Persistent, persistent } from "game/persistence";
import {
Computable,
GetComputableType,
@ -21,7 +21,7 @@ import {
} from "util/computed";
import { createLazyProxy } from "util/proxies";
import { coerceComponent } from "util/vue";
import { Ref, unref, watchEffect } from "vue";
import { unref, watchEffect } from "vue";
import { useToast } from "vue-toastification";
const toast = useToast();
@ -39,9 +39,9 @@ export interface AchievementOptions {
onComplete?: VoidFunction;
}
export interface BaseAchievement extends Persistent<boolean> {
export interface BaseAchievement {
id: string;
earned: Ref<boolean>;
earned: Persistent<boolean>;
complete: VoidFunction;
type: typeof AchievementType;
[Component]: typeof AchievementComponent;
@ -70,15 +70,16 @@ export type GenericAchievement = Replace<
export function createAchievement<T extends AchievementOptions>(
optionsFunc: OptionsFunc<T, Achievement<T>, BaseAchievement>
): Achievement<T> {
return createLazyProxy(persistent => {
const achievement = Object.assign(persistent, optionsFunc());
const earned = persistent<boolean>(false);
return createLazyProxy(() => {
const achievement = optionsFunc();
achievement.id = getUniqueID("achievement-");
achievement.type = AchievementType;
achievement[Component] = AchievementComponent;
achievement.earned = achievement[PersistentState];
achievement.earned = earned;
achievement.complete = function () {
achievement[PersistentState].value = true;
earned.value = true;
};
processComputable(achievement as T, "visibility");
@ -122,5 +123,5 @@ export function createAchievement<T extends AchievementOptions>(
}
return achievement as unknown as Achievement<T>;
}, persistent<boolean>(false));
});
}

View file

@ -1,6 +1,6 @@
import ClickableComponent from "features/clickables/Clickable.vue";
import { Resource } from "features/resources/resource";
import { Persistent, PersistentState, persistent } from "game/persistence";
import { Persistent, persistent } from "game/persistence";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import {
Computable,
@ -49,9 +49,9 @@ export interface BuyableOptions {
onPurchase?: (cost: DecimalSource) => void;
}
export interface BaseBuyable extends Persistent<DecimalSource> {
export interface BaseBuyable {
id: string;
amount: Ref<DecimalSource>;
amount: Persistent<DecimalSource>;
maxed: Ref<boolean>;
canAfford: Ref<boolean>;
canClick: ProcessedComputable<boolean>;
@ -90,8 +90,9 @@ export type GenericBuyable = Replace<
export function createBuyable<T extends BuyableOptions>(
optionsFunc: OptionsFunc<T, Buyable<T>, BaseBuyable>
): Buyable<T> {
return createLazyProxy(persistent => {
const buyable = Object.assign(persistent, optionsFunc());
const amount = persistent<DecimalSource>(0);
return createLazyProxy(() => {
const buyable = optionsFunc();
if (buyable.canPurchase == null && (buyable.resource == null || buyable.cost == null)) {
console.warn(
@ -105,7 +106,7 @@ export function createBuyable<T extends BuyableOptions>(
buyable.type = BuyableType;
buyable[Component] = ClickableComponent;
buyable.amount = buyable[PersistentState];
buyable.amount = amount;
buyable.canAfford = computed(() => {
const genericBuyable = buyable as GenericBuyable;
const cost = unref(genericBuyable.cost);
@ -239,5 +240,5 @@ export function createBuyable<T extends BuyableOptions>(
};
return buyable as unknown as Buyable<T>;
}, persistent<DecimalSource>(0));
});
}

View file

@ -20,7 +20,7 @@ import {
} from "util/computed";
import { createLazyProxy } from "util/proxies";
import { computed, Ref, unref } from "vue";
import { State, Persistent, PersistentState, persistent } from "game/persistence";
import { State, Persistent, persistent } from "game/persistence";
export const GridType = Symbol("Grid");
@ -205,12 +205,13 @@ export interface GridOptions {
onHold?: (id: string | number, state: State) => void;
}
export interface BaseGrid extends Persistent<Record<string | number, State>> {
export interface BaseGrid {
id: string;
getID: (id: string | number, state: State) => string;
getState: (id: string | number) => State;
setState: (id: string | number, state: State) => void;
cells: Record<string | number, GridCell>;
cellState: Persistent<Record<string | number, State>>;
type: typeof GridType;
[Component]: typeof GridComponent;
[GatherProps]: () => Record<string, unknown>;
@ -244,22 +245,25 @@ export type GenericGrid = Replace<
export function createGrid<T extends GridOptions>(
optionsFunc: OptionsFunc<T, Grid<T>, BaseGrid>
): Grid<T> {
return createLazyProxy(persistent => {
const grid = Object.assign(persistent, optionsFunc());
const cellState = persistent<Record<string | number, State>>({});
return createLazyProxy(() => {
const grid = optionsFunc();
grid.id = getUniqueID("grid-");
grid[Component] = GridComponent;
grid.cellState = cellState;
grid.getID = function (this: GenericGrid, cell: string | number) {
return grid.id + "-" + cell;
};
grid.getState = function (this: GenericGrid, cell: string | number) {
if (this[PersistentState].value[cell] != undefined) {
return this[PersistentState].value[cell];
if (this.cellState.value[cell] != undefined) {
return cellState.value[cell];
}
return this.cells[cell].startState;
};
grid.setState = function (this: GenericGrid, cell: string | number, state: State) {
this[PersistentState].value[cell] = state;
cellState.value[cell] = state;
};
grid.cells = createGridProxy(grid as GenericGrid);
@ -301,5 +305,5 @@ export function createGrid<T extends GridOptions>(
};
return grid as unknown as Grid<T>;
}, persistent({}));
});
}

View file

@ -1,15 +1,16 @@
import InfoboxComponent from "features/infoboxes/Infobox.vue";
import {
CoercableComponent,
Component,
OptionsFunc,
GatherProps,
getUniqueID,
OptionsFunc,
Replace,
setDefault,
StyleValue,
Visibility
} from "features/feature";
import InfoboxComponent from "features/infoboxes/Infobox.vue";
import { Persistent, persistent } from "game/persistence";
import {
Computable,
GetComputableType,
@ -18,8 +19,7 @@ import {
ProcessedComputable
} from "util/computed";
import { createLazyProxy } from "util/proxies";
import { Ref, unref } from "vue";
import { Persistent, PersistentState, persistent } from "game/persistence";
import { unref } from "vue";
export const InfoboxType = Symbol("Infobox");
@ -34,9 +34,9 @@ export interface InfoboxOptions {
display: Computable<CoercableComponent>;
}
export interface BaseInfobox extends Persistent<boolean> {
export interface BaseInfobox {
id: string;
collapsed: Ref<boolean>;
collapsed: Persistent<boolean>;
type: typeof InfoboxType;
[Component]: typeof InfoboxComponent;
[GatherProps]: () => Record<string, unknown>;
@ -66,13 +66,14 @@ export type GenericInfobox = Replace<
export function createInfobox<T extends InfoboxOptions>(
optionsFunc: OptionsFunc<T, Infobox<T>, BaseInfobox>
): Infobox<T> {
return createLazyProxy(persistent => {
const infobox = Object.assign(persistent, optionsFunc());
const collapsed = persistent<boolean>(false);
return createLazyProxy(() => {
const infobox = optionsFunc();
infobox.id = getUniqueID("infobox-");
infobox.type = InfoboxType;
infobox[Component] = InfoboxComponent;
infobox.collapsed = infobox[PersistentState];
infobox.collapsed = collapsed;
processComputable(infobox as T, "visibility");
setDefault(infobox, "visibility", Visibility.Visible);
@ -112,5 +113,5 @@ export function createInfobox<T extends InfoboxOptions>(
};
return infobox as unknown as Infobox<T>;
}, persistent<boolean>(false));
});
}

View file

@ -14,7 +14,7 @@ import {
import MilestoneComponent from "features/milestones/Milestone.vue";
import { globalBus } from "game/events";
import "game/notifications";
import { persistent, Persistent, PersistentState } from "game/persistence";
import { persistent, Persistent } from "game/persistence";
import settings, { registerSettingField } from "game/settings";
import { camelToTitle } from "util/common";
import {
@ -26,7 +26,7 @@ import {
} from "util/computed";
import { createLazyProxy } from "util/proxies";
import { coerceComponent, isCoercableComponent } from "util/vue";
import { computed, Ref, unref, watchEffect } from "vue";
import { computed, unref, watchEffect } from "vue";
import { useToast } from "vue-toastification";
const toast = useToast();
@ -57,9 +57,9 @@ export interface MilestoneOptions {
onComplete?: VoidFunction;
}
export interface BaseMilestone extends Persistent<boolean> {
export interface BaseMilestone {
id: string;
earned: Ref<boolean>;
earned: Persistent<boolean>;
complete: VoidFunction;
type: typeof MilestoneType;
[Component]: typeof MilestoneComponent;
@ -86,15 +86,16 @@ export type GenericMilestone = Replace<
export function createMilestone<T extends MilestoneOptions>(
optionsFunc: OptionsFunc<T, Milestone<T>, BaseMilestone>
): Milestone<T> {
const earned = persistent<boolean>(false);
return createLazyProxy(persistent => {
const milestone = Object.assign(persistent, optionsFunc());
milestone.id = getUniqueID("milestone-");
milestone.type = MilestoneType;
milestone[Component] = MilestoneComponent;
milestone.earned = milestone[PersistentState];
milestone.earned = earned;
milestone.complete = function () {
milestone[PersistentState].value = true;
earned.value = true;
};
processComputable(milestone as T, "visibility");
@ -168,7 +169,7 @@ export function createMilestone<T extends MilestoneOptions>(
}
return milestone as unknown as Milestone<T>;
}, persistent<boolean>(false));
});
}
declare module "game/settings" {

View file

@ -11,7 +11,7 @@ import {
} from "features/feature";
import TabButtonComponent from "features/tabs/TabButton.vue";
import TabFamilyComponent from "features/tabs/TabFamily.vue";
import { Persistent, PersistentState, persistent } from "game/persistence";
import { Persistent, persistent } from "game/persistence";
import {
Computable,
GetComputableType,
@ -65,11 +65,11 @@ export interface TabFamilyOptions {
style?: Computable<StyleValue>;
}
export interface BaseTabFamily extends Persistent<string> {
export interface BaseTabFamily {
id: string;
tabs: Record<string, TabButtonOptions>;
activeTab: Ref<GenericTab | CoercableComponent | null>;
selected: Ref<string>;
selected: Persistent<string>;
type: typeof TabFamilyType;
[Component]: typeof TabFamilyComponent;
[GatherProps]: () => Record<string, unknown>;
@ -99,8 +99,10 @@ export function createTabFamily<T extends TabFamilyOptions>(
throw "Cannot create tab family with 0 tabs";
}
return createLazyProxy(persistent => {
const tabFamily = Object.assign(persistent, optionsFunc?.());
const selected = persistent(Object.keys(tabs)[0]);
return createLazyProxy(() => {
const tabFamily =
optionsFunc?.() || ({} as ReturnType<OptionsFunc<T, TabFamily<T>, BaseTabFamily>>);
tabFamily.id = getUniqueID("tabFamily-");
tabFamily.type = TabFamilyType;
@ -124,15 +126,14 @@ export function createTabFamily<T extends TabFamilyOptions>(
},
{}
);
tabFamily.selected = tabFamily[PersistentState];
tabFamily.selected = selected;
tabFamily.activeTab = computed(() => {
const tabs = unref(processedTabFamily.tabs);
if (
tabFamily[PersistentState].value in tabs &&
unref(tabs[processedTabFamily[PersistentState].value].visibility) ===
Visibility.Visible
selected.value in tabs &&
unref(tabs[selected.value].visibility) === Visibility.Visible
) {
return unref(tabs[processedTabFamily[PersistentState].value].tab);
return unref(tabs[selected.value].tab);
}
const firstTab = Object.values(tabs).find(
tab => unref(tab.visibility) === Visibility.Visible
@ -156,5 +157,5 @@ export function createTabFamily<T extends TabFamilyOptions>(
// This is necessary because board.types is different from T and TabFamily
const processedTabFamily = tabFamily as unknown as TabFamily<T>;
return processedTabFamily;
}, persistent(Object.keys(tabs)[0]));
});
}

View file

@ -24,7 +24,7 @@ import {
} from "util/computed";
import { createLazyProxy } from "util/proxies";
import { computed, Ref, unref } from "vue";
import { persistent, Persistent, PersistentState } from "game/persistence";
import { persistent, Persistent } from "game/persistence";
export const UpgradeType = Symbol("Upgrade");
@ -47,9 +47,9 @@ export interface UpgradeOptions {
onPurchase?: VoidFunction;
}
export interface BaseUpgrade extends Persistent<boolean> {
export interface BaseUpgrade {
id: string;
bought: Ref<boolean>;
bought: Persistent<boolean>;
canPurchase: Ref<boolean>;
purchase: VoidFunction;
type: typeof UpgradeType;
@ -81,8 +81,9 @@ export type GenericUpgrade = Replace<
export function createUpgrade<T extends UpgradeOptions>(
optionsFunc: OptionsFunc<T, Upgrade<T>, BaseUpgrade>
): Upgrade<T> {
return createLazyProxy(persistent => {
const upgrade = Object.assign(persistent, optionsFunc());
const bought = persistent<boolean>(false);
return createLazyProxy(() => {
const upgrade = optionsFunc();
upgrade.id = getUniqueID("upgrade-");
upgrade.type = UpgradeType;
upgrade[Component] = UpgradeComponent;
@ -94,7 +95,7 @@ export function createUpgrade<T extends UpgradeOptions>(
);
}
upgrade.bought = upgrade[PersistentState];
upgrade.bought = bought;
if (upgrade.canAfford == null) {
upgrade.canAfford = computed(() => {
const genericUpgrade = upgrade as GenericUpgrade;
@ -124,7 +125,7 @@ export function createUpgrade<T extends UpgradeOptions>(
unref(genericUpgrade.cost)
);
}
genericUpgrade[PersistentState].value = true;
bought.value = true;
genericUpgrade.onPurchase?.();
};
@ -167,7 +168,7 @@ export function createUpgrade<T extends UpgradeOptions>(
};
return upgrade as unknown as Upgrade<T>;
}, persistent<boolean>(false));
});
}
export function setupAutoPurchase(