Files
rojo/plugin/src/Settings.lua
2023-08-20 12:37:40 -07:00

108 lines
2.5 KiB
Lua

--[[
Persistent plugin settings.
]]
local plugin = plugin or script:FindFirstAncestorWhichIsA("Plugin")
local Rojo = script:FindFirstAncestor("Rojo")
local Packages = Rojo.Packages
local Log = require(Packages.Log)
local Roact = require(Packages.Roact)
local defaultSettings = {
openScriptsExternally = false,
twoWaySync = false,
showNotifications = true,
syncReminder = true,
confirmationBehavior = "Initial",
largeChangesConfirmationThreshold = 5,
playSounds = true,
typecheckingEnabled = false,
logLevel = "Info",
priorEndpoints = {},
}
local Settings = {}
Settings._values = table.clone(defaultSettings)
Settings._updateListeners = {}
Settings._bindings = {}
if plugin then
for name, defaultValue in pairs(Settings._values) do
local savedValue = plugin:GetSetting("Rojo_" .. name)
if savedValue == nil then
-- plugin:SetSetting hits disc instead of memory, so it can be slow. Spawn so we don't hang.
task.spawn(plugin.SetSetting, plugin, "Rojo_" .. name, defaultValue)
Settings._values[name] = defaultValue
else
Settings._values[name] = savedValue
end
end
Log.trace("Loaded settings from plugin store")
end
function Settings:get(name)
if defaultSettings[name] == nil then
error("Invalid setings name " .. tostring(name), 2)
end
return self._values[name]
end
function Settings:set(name, value)
self._values[name] = value
if self._bindings[name] then
self._bindings[name].set(value)
end
if plugin then
-- plugin:SetSetting hits disc instead of memory, so it can be slow. Spawn so we don't hang.
task.spawn(plugin.SetSetting, plugin, "Rojo_" .. name, value)
end
if self._updateListeners[name] then
for callback in pairs(self._updateListeners[name]) do
task.spawn(callback, value)
end
end
Log.trace(string.format("Set setting '%s' to '%s'", name, tostring(value)))
end
function Settings:onChanged(name, callback)
local listeners = self._updateListeners[name]
if listeners == nil then
listeners = {}
self._updateListeners[name] = listeners
end
listeners[callback] = true
Log.trace(string.format("Added listener for setting '%s' changes", name))
return function()
listeners[callback] = nil
Log.trace(string.format("Removed listener for setting '%s' changes", name))
end
end
function Settings:getBinding(name)
local cached = self._bindings[name]
if cached then
return cached.bind
end
local bind, set = Roact.createBinding(self._values[name])
self._bindings[name] = {
bind = bind,
set = set,
}
Log.trace(string.format("Created binding for setting '%s'", name))
return bind
end
return Settings