diff --git a/src/features/feature.ts b/src/features/feature.ts index 60631dd..2a99351 100644 --- a/src/features/feature.ts +++ b/src/features/feature.ts @@ -2,46 +2,83 @@ import Decimal from "util/bignum"; import { DoNotCache } from "util/computed"; import { CSSProperties, DefineComponent, isRef } from "vue"; +/** + * A symbol to use as a key for a vue component a feature can be rendered with + * @see {@link VueFeature} + */ export const Component = Symbol("Component"); +/** + * A symbol to use as a key for a prop gathering function that a feature can use to send to its component + * @see {@link VueFeature} + */ export const GatherProps = Symbol("GatherProps"); +/** + * A type referring to a function that returns JSX and is marked that it shouldn't be wrapped in a ComputedRef + * @see {@link jsx} + */ export type JSXFunction = (() => JSX.Element) & { [DoNotCache]: true }; +/** + * Any value that can be coerced into (or is) a vue component + */ export type CoercableComponent = string | DefineComponent | JSXFunction; +/** + * Any value that can be passed into an HTML element's style attribute. + * Note that Profectus uses its own StyleValue and CSSProperties that are extended, + * in order to have additional properties added to them, such as variable CSS variables. + */ export type StyleValue = string | CSSProperties | Array; -// TODO if importing .vue components in .tsx can become type safe, -// this type can probably be safely removed +/** A type that refers to any vue component */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export type GenericComponent = DefineComponent; +/** Utility type that is S, with any properties from T that aren't already present in S */ export type Replace = S & Omit; +/** + * Utility function for a function that returns an object of a given type, + * with "this" bound to what the type will eventually be processed into. + * Intended for making lazily evaluated objects. + */ 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 -// IDs are gauranteed unique, but should not be saved as they are not -// guaranteed to be persistent through updates and such +/** + * Gets a unique ID to give to each feature, used for any sort of system that needs to identify + * elements in the DOM rather than references to the feature itself. (For example, branches) + * IDs are guaranteed unique, but _NOT_ persistent - they likely will change between updates. + * @param prefix A string to prepend to the id to make it more readable in the inspector tools + */ export function getUniqueID(prefix = "feature-"): string { return prefix + id++; } +/** Enum for what the visibility of a feature or component should be */ export enum Visibility { + /** The feature or component should be visible */ Visible, + /** The feature or component should not appear but still take up space */ Hidden, + /** The feature or component should not appear not take up space */ None } +/** + * Takes a function and marks it as JSX so it won't get auto-wrapped into a ComputedRef. + * The function may also return empty string as empty JSX tags cause issues. + */ export function jsx(func: () => JSX.Element | ""): JSXFunction { (func as Partial)[DoNotCache] = true; return func as JSXFunction; } +/** Utility function to convert a boolean value into a Visbility value */ export function showIf(condition: boolean, otherwise = Visibility.None): Visibility { return condition ? Visibility.Visible : otherwise; } +/** Utility function to set a property on an object if and only if it doesn't already exist */ export function setDefault( object: T, key: K, @@ -52,6 +89,11 @@ export function setDefault( } } +/** + * Traverses an object and returns all features of the given type(s) + * @param obj The object to traverse + * @param types The feature types that will be searched for + */ export function findFeatures(obj: Record, ...types: symbol[]): unknown[] { const objects: unknown[] = []; const handleObject = (obj: Record) => { @@ -71,6 +113,12 @@ export function findFeatures(obj: Record, ...types: symbol[]): return objects; } +/** + * Traverses an object and returns all features that are _not_ any of the given types. + * Features are any object with a "type" property that has a symbol value. + * @param obj The object to traverse + * @param types The feature types that will be skipped over + */ export function excludeFeatures(obj: Record, ...types: symbol[]): unknown[] { const objects: unknown[] = []; const handleObject = (obj: Record) => { diff --git a/src/game/modifiers.tsx b/src/game/modifiers.tsx index 87db764..b4ea335 100644 --- a/src/game/modifiers.tsx +++ b/src/game/modifiers.tsx @@ -14,13 +14,9 @@ import { computed, unref } from "vue"; * {@link createModifierSection}. */ export interface Modifier { - /** - * Applies some operation on the input and returns the result. - */ + /** Applies some operation on the input and returns the result. */ apply: (gain: DecimalSource) => DecimalSource; - /** - * Reverses the operation applied by the apply property. Required by some features. - */ + /** Reverses the operation applied by the apply property. Required by some features. */ revert?: (gain: DecimalSource) => DecimalSource; /** * Whether or not this modifier should be considered enabled.