2022-04-18 08:42:02 +02:00
|
|
|
local storage = require('openmw.storage')
|
2022-03-07 21:28:05 +01:00
|
|
|
local core = require('openmw.core')
|
|
|
|
local types = require('openmw.types')
|
2022-04-18 08:42:02 +02:00
|
|
|
local selfObject
|
|
|
|
do
|
|
|
|
local success, result = pcall(function() return require('openmw.self') end)
|
|
|
|
selfObject = success and result or nil
|
|
|
|
end
|
|
|
|
local playerObject = selfObject and selfObject.type == types.Player and selfObject or nil
|
2022-03-07 21:28:05 +01:00
|
|
|
|
2022-04-18 08:42:02 +02:00
|
|
|
local eventPrefix = 'omwSettings'
|
2022-03-07 21:28:05 +01:00
|
|
|
local EVENTS = {
|
2022-04-18 08:42:02 +02:00
|
|
|
SettingChanged = eventPrefix .. 'Changed',
|
|
|
|
SetValue = eventPrefix .. 'GlobalSetValue',
|
|
|
|
GroupRegistered = eventPrefix .. 'GroupRegistered',
|
|
|
|
RegisterGroup = eventPrefix .. 'RegisterGroup',
|
|
|
|
Subscribe = eventPrefix .. 'Subscribe',
|
2022-03-07 21:28:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
local SCOPE = {
|
|
|
|
Global = 'Global',
|
|
|
|
Player = 'Player',
|
|
|
|
SaveGlobal = 'SaveGlobal',
|
|
|
|
SavePlayer = 'SavePlayer',
|
|
|
|
}
|
|
|
|
|
2022-04-18 08:42:02 +02:00
|
|
|
local function isPlayerScope(scope)
|
|
|
|
return scope == SCOPE.Player or scope == SCOPE.SavePlayer
|
2022-03-07 21:28:05 +01:00
|
|
|
end
|
|
|
|
|
2022-04-18 08:42:02 +02:00
|
|
|
local function isSaveScope(scope)
|
|
|
|
return scope == SCOPE.SaveGlobal or scope == SCOPE.SavePlayer
|
2022-03-07 21:28:05 +01:00
|
|
|
end
|
|
|
|
|
2022-04-18 08:42:02 +02:00
|
|
|
local prefix = 'omw_settings_'
|
|
|
|
local settingsPattern = prefix .. 'settings_%s%s'
|
2022-03-07 21:28:05 +01:00
|
|
|
|
2022-04-18 08:42:02 +02:00
|
|
|
local groupsSection = storage.globalSection(prefix .. 'groups')
|
|
|
|
if groupsSection.removeOnExit then
|
|
|
|
groupsSection:removeOnExit()
|
2022-03-07 21:28:05 +01:00
|
|
|
end
|
|
|
|
|
2022-04-18 08:42:02 +02:00
|
|
|
local function values(groupKey, scope)
|
|
|
|
local player = isPlayerScope(scope)
|
|
|
|
local save = isSaveScope(scope)
|
|
|
|
local sectionKey = settingsPattern:format(groupKey, save and '_save' or '')
|
|
|
|
local section
|
|
|
|
if player then
|
|
|
|
section = storage.playerSection and storage.playerSection(sectionKey) or nil
|
|
|
|
else
|
|
|
|
section = storage.globalSection(sectionKey)
|
2022-03-07 21:28:05 +01:00
|
|
|
end
|
2022-04-18 08:42:02 +02:00
|
|
|
if save and section and section.removeOnExit then
|
|
|
|
section:removeOnExit()
|
2022-03-07 21:28:05 +01:00
|
|
|
end
|
2022-04-18 08:42:02 +02:00
|
|
|
return section
|
2022-03-07 21:28:05 +01:00
|
|
|
end
|
|
|
|
|
2022-04-18 08:42:02 +02:00
|
|
|
local function saveScope(scope)
|
|
|
|
local saved = {}
|
|
|
|
for _, group in pairs(groupsSection:asTable()) do
|
|
|
|
saved[group.key] = values(group.key, scope):asTable()
|
2022-03-07 21:28:05 +01:00
|
|
|
end
|
2022-04-18 08:42:02 +02:00
|
|
|
return saved
|
|
|
|
end
|
|
|
|
|
|
|
|
local function loadScope(scope, saved)
|
|
|
|
if not saved then return end
|
|
|
|
for _, group in pairs(saved) do
|
|
|
|
values(group.key, scope):reset(saved[group.key])
|
2022-03-07 21:28:05 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-04-18 08:42:02 +02:00
|
|
|
local function groupSubscribeEvent(groupKey)
|
|
|
|
return ('%sSubscribe%s'):format(eventPrefix, groupKey)
|
|
|
|
end
|
|
|
|
|
|
|
|
local subscriptions = {}
|
|
|
|
local function handleSubscription(event)
|
|
|
|
if not subscriptions[event.groupKey] then
|
|
|
|
subscriptions[event.groupKey] = {}
|
2022-03-07 21:28:05 +01:00
|
|
|
end
|
2022-04-18 08:42:02 +02:00
|
|
|
table.insert(subscriptions[event.groupKey], event.object or false)
|
2022-03-07 21:28:05 +01:00
|
|
|
end
|
|
|
|
|
2022-04-18 08:42:02 +02:00
|
|
|
local function subscribe(self)
|
|
|
|
local groupKey = rawget(self, 'groupKey')
|
2022-03-07 21:28:05 +01:00
|
|
|
local event = {
|
2022-04-18 08:42:02 +02:00
|
|
|
groupKey = groupKey,
|
|
|
|
object = selfObject,
|
2022-03-07 21:28:05 +01:00
|
|
|
}
|
2022-04-18 08:42:02 +02:00
|
|
|
core.sendGlobalEvent(EVENTS.Subscribe, event)
|
|
|
|
if playerObject then
|
|
|
|
playerObject:sendEvent(EVENTS.Subscribe, event)
|
2022-03-07 21:28:05 +01:00
|
|
|
end
|
2022-04-18 08:42:02 +02:00
|
|
|
return groupSubscribeEvent(groupKey)
|
2022-03-07 21:28:05 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
local groupMeta = {
|
2022-04-18 08:42:02 +02:00
|
|
|
__newindex = function(self, settingKey, value)
|
|
|
|
local group = groupsSection:get(rawget(self, 'groupKey'))
|
|
|
|
local setting = group.settings[settingKey]
|
|
|
|
if not setting then
|
|
|
|
error(('Setting %s does not exist'):format(settingKey))
|
|
|
|
end
|
|
|
|
local section = values(group.key, setting.scope)
|
|
|
|
local event = {
|
|
|
|
groupKey = group.key,
|
|
|
|
settingKey = settingKey,
|
|
|
|
value = value,
|
|
|
|
}
|
|
|
|
if section.set then
|
|
|
|
section:set(settingKey, value)
|
|
|
|
if playerObject then
|
|
|
|
playerObject:sendEvent(EVENTS.SettingChanged, event)
|
|
|
|
else
|
|
|
|
core.sendGlobalEvent(EVENTS.SettingChanged, event)
|
|
|
|
end
|
|
|
|
if subscriptions[group.key] then
|
|
|
|
local eventKey = groupSubscribeEvent(group.key)
|
|
|
|
for _, object in ipairs(subscriptions[group.key]) do
|
|
|
|
if object then
|
|
|
|
object:sendEvent(eventKey, event)
|
|
|
|
else
|
|
|
|
core.sendGlobalEvent(eventKey, event)
|
|
|
|
end
|
|
|
|
end
|
2022-03-07 21:28:05 +01:00
|
|
|
end
|
2022-04-18 08:42:02 +02:00
|
|
|
else
|
|
|
|
if isPlayerScope(setting.scope) then
|
|
|
|
error(("Can't change player scope setting %s from global scope"):format(settingKey))
|
|
|
|
else
|
|
|
|
core.sendGlobalEvent(EVENTS.SetValue, event)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
__index = function(self, key)
|
|
|
|
if key == "subscribe" then return subscribe end
|
|
|
|
local settingKey = key
|
|
|
|
local group = groupsSection:get(rawget(self, 'groupKey'))
|
|
|
|
local setting = group.settings[settingKey]
|
|
|
|
if not setting then
|
|
|
|
error(('Unknown setting %s'):format(settingKey))
|
|
|
|
end
|
|
|
|
local section = rawget(self, 'sections')[setting.scope]
|
|
|
|
if not section then
|
|
|
|
error(("Can't access setting %s from scope %s"):format(settingKey, setting.scope))
|
|
|
|
end
|
|
|
|
return section:get(setting.key) or setting.default
|
|
|
|
end,
|
2022-03-07 21:28:05 +01:00
|
|
|
}
|
2022-04-18 08:42:02 +02:00
|
|
|
|
|
|
|
local function group(groupKey)
|
|
|
|
if not groupsSection:get(groupKey) then
|
|
|
|
print(("Settings group %s wasn't registered yet"):format(groupKey))
|
2022-03-07 21:28:05 +01:00
|
|
|
end
|
2022-04-18 08:42:02 +02:00
|
|
|
local s = {}
|
|
|
|
for _, scope in pairs(SCOPE) do
|
|
|
|
local section = values(groupKey, scope)
|
|
|
|
if section then
|
|
|
|
s[scope] = section
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return setmetatable({
|
|
|
|
groupKey = groupKey,
|
|
|
|
sections = s,
|
|
|
|
}, groupMeta)
|
2022-03-07 21:28:05 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
return {
|
|
|
|
SCOPE = SCOPE,
|
2022-04-18 08:42:02 +02:00
|
|
|
EVENTS = EVENTS,
|
|
|
|
isPlayerScope = isPlayerScope,
|
|
|
|
isSaveScope = isSaveScope,
|
|
|
|
values = values,
|
|
|
|
groups = function()
|
|
|
|
return groupsSection
|
|
|
|
end,
|
|
|
|
saveScope = saveScope,
|
|
|
|
loadScope = loadScope,
|
|
|
|
group = group,
|
|
|
|
handleSubscription = handleSubscription,
|
2022-03-07 21:28:05 +01:00
|
|
|
}
|