feat(lib/assets)!: store asset IDs separately, prepare for asset override support

This commit is contained in:
PalmDevs 2025-05-06 23:54:55 +07:00
parent 4371b95bd9
commit 7450447c1b
No known key found for this signature in database
GPG key ID: 6FAE8F8677ACA8BA
6 changed files with 32 additions and 25 deletions

View file

@ -1,3 +1,5 @@
import type { Asset } from '.'
import type { Asset, AssetId } from '.'
export const _assets: Map<string, [first: Asset, all: Record<Asset['type'], Asset>]> = new Map()
export const _assets = new Map<string, [first: Asset, all: Record<Asset['type'], Asset>]>()
export const _overrides = new Map<string, Asset>()
export const _ids = new WeakMap<Asset, AssetId>()

View file

@ -1,6 +1,6 @@
import { ReactNative } from '@revenge-mod/react'
import { _assets } from './_internal'
import { _assets, _ids, _overrides } from './_internal'
import { AssetRegistry } from './patches'
import type { ReactNative as RN } from '@revenge-mod/types'
@ -20,6 +20,15 @@ export function getAssetById(id: AssetId): Asset | undefined {
return AssetRegistry.getAssetByID(id)
}
/**
* Get the ID of an asset.
*
* @param asset The asset to get the ID for.
*/
export function getAssetId(asset: Asset) {
return _ids.get(asset)
}
/**
* Get an asset by its name.
* If more than one asset is registered with the same name, this will return the one with the preferred type, or the first registered one.
@ -30,7 +39,7 @@ export function getAssetByName(name: string): Asset | undefined {
const reg = _assets.get(name)
if (!reg) return
return reg[1][_preferredType] ?? reg[0]
return _overrides.get(name) ?? reg[1][_preferredType] ?? reg[0]
}
/**

View file

@ -3,7 +3,7 @@ import { waitForModules } from '@revenge-mod/modules/finders'
import { byProps } from '@revenge-mod/modules/finders/filters'
import { getModuleDependencies } from '@revenge-mod/modules/metro'
import { _assets } from './_internal'
import { _assets, _ids } from './_internal'
import type { ReactNative } from '@revenge-mod/types'
import type { Asset } from '.'
@ -24,7 +24,9 @@ const unsubForAssetRegistry = waitForModules(byProps('registerAsset'), (arId, ex
const reg = _assets.get(name)!
reg[1][type] = asset
return (asset.id = orig(asset))
const result = orig(asset)
_ids.set(asset, result)
return result
}
return
@ -33,15 +35,13 @@ const unsubForAssetRegistry = waitForModules(byProps('registerAsset'), (arId, ex
unsubForAssetRegistry()
// TODO(assets/patches): conditionally run this if cache does not exist
if (true) {
// More fragile way, but more performant:
// There is exactly one asset before the reexported asset registry, thanks Discord!
const firstAssetModuleId = arId - 1
for (const id of _mUninited) {
if (id < firstAssetModuleId) continue
// More fragile way, but more performant:
// There is exactly one asset before the reexported asset registry, thanks Discord!
const firstAssetModuleId = arId - 1
for (const id of _mUninited) {
if (id < firstAssetModuleId) continue
const deps = getModuleDependencies(id)!
if (deps.length === 1 && deps[0] === arId) __r(id)
}
const deps = getModuleDependencies(id)!
if (deps.length === 1 && deps[0] === arId) __r(id)
}
})

View file

@ -108,11 +108,6 @@ export namespace ReactNative {
type: string
resolver?: AssetDestPathResolver
}
// Revenge-added
export interface PackagerAsset {
id: number
}
}
export interface AssetsRegistry {

View file

@ -1,9 +1,10 @@
import { getAssetByName } from '@revenge-mod/assets'
import type { DiscordModules } from '@revenge-mod/discord/types'
import { getAssetByName, getAssetId } from '@revenge-mod/assets'
import { Components } from '@revenge-mod/discord/ui'
import type { DiscordModules } from '@revenge-mod/discord/types'
export default function AssetIcon(props: AssetIconProps) {
return <Components.TableRow.Icon source={getAssetByName(props.name)?.id!} {...props} />
return <Components.TableRow.Icon source={getAssetId(getAssetByName(props.name)!)!} {...props} />
}
export interface AssetIconProps extends Omit<DiscordModules.Components.TableRowIconProps, 'source'> {

View file

@ -1,4 +1,4 @@
import { getAssetByName } from '@revenge-mod/assets'
import { getAssetByName, getAssetId } from '@revenge-mod/assets'
import { ToastActionCreators } from '@revenge-mod/discord/actions'
import { React } from '@revenge-mod/react'
import { getErrorStack } from '@revenge-mod/utils/errors'
@ -28,7 +28,7 @@ subscriptions.add((e, err) => {
ToastActionCreators.open({
key: 'DEVTOOLS_ERROR',
icon: getAssetByName('CircleXIcon-primary')!.id,
icon: getAssetId(getAssetByName('CircleXIcon-primary')!)!,
content: actualError,
})
}