Files
Common/src/client/controllers/settings.ts
T

96 lines
3.2 KiB
TypeScript

import { Controller, OnStart } from "@flamework/core";
import { Atom, atom } from "@rbxts/charm";
import { keys } from "@rbxts/object-utils";
import settingsFile from "../../shared/settings";
import { SettingDefinition, SettingRealType, SettingType } from "../../shared/typings/settings";
import { Events, Functions } from "../network";
/**
* Setting Management Controller
*/
@Controller()
export class SettingsController implements OnStart {
private atomsCache: Map<string, Map<string, Atom<SettingRealType<SettingType>>>> = new Map();
private defCache: Map<string, Map<string, SettingDefinition>> = new Map();
/**
* Fetch player settings from the server.
*/
fetchSettings() {
Functions.settings.GetSettings().then((settings) => {
settings.forEach((section, sectionKey) => {
const sectionAtoms = this.atomsCache.get(sectionKey)!;
section.forEach((val, key) => {
sectionAtoms.get(key)?.(val);
});
});
});
}
/**
* Get all sections names.
* @returns Sections names in the settings file.
*/
getSections() {
return keys(this.atomsCache);
}
/**
* Get All atoms and their definition in the given section.
* @param section The name of the section.
* @returns An array with setting definition and an the atom linked to the type definition.
*/
getSectionWithDef(section: string) {
const ret: [SettingDefinition, Atom<unknown>][] = [];
this.atomsCache.get(section)?.forEach((value, key) => {
ret.push([this.defCache.get(section)!.get(key)!, value]);
});
return ret;
}
/**
* Get an atom with an section name and a setting name.
* @param section Section name.
* @param setting Setting name.
* @returns The atom linked to the setting.
*/
getSetting(section: string, setting: string) {
return this.atomsCache.get(section)?.get(setting);
}
/**
* @inheritdoc
*/
onStart(): void {
this.setupAtoms();
this.fetchSettings();
}
/**
* Send a section of settings to the server to save.
* @param section The section to save.
*/
saveSettings(section: string) {
const atoms = this.atomsCache.get(section);
if (!atoms) return;
const map = new Map<string, boolean | number | string>();
atoms.forEach((value, key) => {
map.set(key, value() as boolean | number | string);
});
Events.settings.SetSettings(section, map);
}
/**
* Setup atoms and definition at service start.
*/
private setupAtoms() {
const sections = keys<Record<string, SettingDefinition[]>>(settingsFile).filter((key) =>
typeIs(settingsFile[key], "table"),
);
sections.forEach((key) => {
const map = new Map<string, Atom<unknown>>();
const defMap = new Map<string, SettingDefinition>();
this.atomsCache.set(key, map);
this.defCache.set(key, defMap);
settingsFile[key].forEach((def) => {
map.set(def.id, atom(def.default));
defMap.set(def.id, def);
});
});
}
}