GoonCord/src/lib/api/assets.ts

65 lines
2 KiB
TypeScript
Raw Normal View History

2024-05-10 02:15:32 +08:00
// TODO: Rewrite the whole thing to fit new metro :3
import { after } from "@lib/api/patcher";
2024-05-20 15:36:33 +08:00
import { getMetroCache, registerAssetCacheId } from "@metro/caches";
import { getImportingModuleId, requireModule } from "@metro/modules";
2022-10-22 23:26:06 +01:00
export const assetsMap: Record<string, Asset> = new Proxy<any>({}, {
get(target, p) {
if (typeof p !== "string") return undefined;
if (target[p]) return target[p];
const moduleId = getMetroCache().assetsIndex[p];
if (moduleId == null) return undefined;
const assetIndex = requireModule(moduleId);
const assetDefinition = assetsModule.getAssetByID(assetIndex);
assetDefinition.index ??= assetDefinition.id ??= assetIndex;
assetDefinition.moduleId ??= moduleId;
return target[p] = assetDefinition;
},
ownKeys(target) {
const keys = Reflect.ownKeys(getMetroCache().assetsIndex);
for (const key of keys) target[key] = this.get!(target, key, {});
return keys;
},
});
2022-10-22 23:26:06 +01:00
2024-02-23 15:11:35 +08:00
export interface Asset {
/** @deprecated */
2024-02-23 15:11:35 +08:00
id: number;
index: number;
name: string;
2024-05-10 02:15:32 +08:00
moduleId: number;
}
interface AssetModule {
registerAsset(assetDefinition: any): number;
getAssetByID(id: number): any;
2024-02-23 15:11:35 +08:00
}
2024-05-10 02:15:32 +08:00
let assetsModule: AssetModule;
2024-03-11 15:04:11 +08:00
/**
* @internal
*/
2024-05-10 02:15:32 +08:00
export function patchAssets(module: AssetModule) {
if (assetsModule) return;
assetsModule = module;
const unpatch = after("registerAsset", assetsModule, ([asset]: Asset[]) => {
const moduleId = getImportingModuleId();
if (moduleId !== -1) registerAssetCacheId(asset.name, moduleId);
});
2022-10-22 23:26:06 +01:00
return unpatch;
2022-10-22 23:26:06 +01:00
}
export const findAsset = (filter: (a: any) => void): Asset | null | undefined => Object.values(assetsMap).find(filter);
export const requireAssetByName = (name: string): Asset => assetsMap[name];
export const requireAssetByIndex = (id: number): Asset => assetsModule.getAssetByID(id);
export const requireAssetIndex = (name: string) => assetsMap[name]?.index;