rbx-extendable-resources
Version:
An extendable object retrieval system for defining folders.
72 lines (60 loc) • 2.27 kB
text/typescript
// @author Validark
const isServer = game.GetService("RunService").IsServer();
/**
* Wraps a function which takes a single argument as a parameter, and makes it idempotent.
* The new function will return the value in the cache, else it will call the wrapped function and cache the result
* @param func The function to wrap
*/
function cacheSingleArgFunc<T, K>(func: (arg: T) => K) {
const cache = new Map<T, K>();
return (arg: T) => {
let value = cache.get(arg);
if (value === undefined) {
value = func(arg);
cache.set(arg, value);
}
return value;
};
}
function constructManager<T extends keyof CreatableInstances>(
folder: Instance,
optionalInstanceType?: T,
): (instanceName: string) => CreatableInstances[T] {
if (isServer) {
return instanceName => {
let target = folder.FindFirstChild(instanceName);
if (target === undefined) {
if (optionalInstanceType) {
target = new Instance(optionalInstanceType);
target.Name = instanceName;
target.Parent = folder;
} else {
return error(`Failed to find ${instanceName} in ${folder.Name}`);
}
}
return target as CreatableInstances[T];
};
} else {
return instanceName => folder.WaitForChild(instanceName);
}
}
const getFolderGetter = cacheSingleArgFunc((folderParent: Instance) => constructManager(folderParent, "Folder"));
/**
* Finds a folder called folderName in folderParent,
* and returns a function which searches this folder for an instance with a given name.
* If this instance does not exist on the client, the function will yield.
* If it does not exist on the server, it will generate an instance of type optionalInstanceType or error.
*
* @param folderParent The parent to search for the folder in
* @param folderName The name of the folder to search for
* @param optionalInstanceType The instance type which can be generated if the instance does not
* exist and is on the server
*/
function makeFolderManager<T extends keyof CreatableInstances>(
folderParent: Instance,
folderName: string,
optionalInstanceType?: T,
) {
return constructManager(getFolderGetter(folderParent)(folderName), optionalInstanceType);
}
export = makeFolderManager;