Back to Home

ESO Lua File v101050

libraries/utility/zo_savedkeys.lua

[◄ back to folders ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
--[[
ZO_SavedKeys stores string and/or numeric keys using the SavedVariables system.
For example, the unique identifiers of Challenges that have already been seen by the player.
Usage:
local existingChallengeIds = SAVED_KEYS:GetOrCreateSavedKeys("ChallengeIds")
existingChallengeIds:RegisterCallback("AddedKeys", function(keys)
for _, key in ipairs(key) do
-- Do something with each added key.
end
end)
existingChallengeIds:RegisterCallback("RemovedKeys", function(keys)
for _, key in ipairs(key) do
-- Do something with each removed key.
end
end)
do
-- Save one or more challenges that have been seen by the player.
local challengeId = 12345
existingChallengeIds:AddKeys(challengeId)
end
do
-- Determine whether a challenge has been seen by the player.
local challengeId = 12345
local hasPlayerSeenChallenge = existingChallengeIds:HasKey(challengeId)
end
do
-- Clear one or more seen challenges.
local challengeId1 = 12345
local challengeId2 = 54321
existingChallengeIds:RemoveKeys(challengeId1, challengeId2)
end
do
-- Clear all seen challenges.
existingChallengeIds:RemoveAllKeys()
end
]]
local SavedKeys = ZO_InitializingCallbackObject:Subclass()
function SavedKeys:__tostring()
    return string.format("SavedKeys(keyTypeName=%q, savedVarsFile=%q, version=%u)", self.keyTypeName or "(nil)", self.savedVarsFile or "(nil)", self.version or 0)
end
function SavedKeys:Initialize(keyTypeName, savedVarsFile, version, ...)
    ZO_InitializingCallbackObject.Initialize(self)
    self.keyTypeName = tostring(keyTypeName)
    if not self.keyTypeName then
        assert(false, "keyTypeName must be a valid string.")
        return
    end
    self.savedVarsFile = savedVarsFile or "ZO_Ingame_SavedVariables"
    self.version = tonumber(version) or 1
    if IsPlayerActivated() then
        -- The saved variables object can be created immediately.
        self:InitializeSavedVars()
    else
        -- Defer saved variables object creation until player activation.
        local eventHandlerDescriptor = string.format("SavedKeys_%s", self.keyTypeName)
        EVENT_MANAGER:RegisterForEvent(eventHandlerDescriptor, EVENT_PLAYER_ACTIVATED, function()
            EVENT_MANAGER:UnregisterForEvent(eventHandlerDescriptor, EVENT_PLAYER_ACTIVATED)
            self:InitializeSavedVars()
        end)
    end
end
function SavedKeys:InitializeSavedVars()
    if self.savedVars then
        return
    end
    local savedVarsKey = self.keyTypeName .. "Keys"
    local defaults = {}
    self.savedVars = ZO_SavedVars:NewAccountWide(self.savedVarsFile, self.version, savedVarsKey, defaults)
    if self:IsInitialized() then
        -- Defer the "Initialized" callback until the subsequent frame so
        -- that the calling code can first register for the callback.
        zo_callLater(function()
            self:FireCallbacks("Initialized")
        end, 1)
    end
end
-- Public Methods
-- Adds the specified keys to the saved keys table.
-- If one or more keys were new and added, fires the "AddedKeys" callback with a numerically indexed table of the added keys.
-- Returns a numerically indexed table of new keys that were added.
function SavedKeys:AddKeys(...)
    local keysTable = self:GetKeys()
    local keys = {...}
    if type(keys[1]) == "table" then
        -- The caller specified a table of keys instead of a series of key arguments.
        -- Note that a copy of the argument is created to prevent unwanted changes to the argument itself.
        keys = {unpack(keys[1])}
    end
    local keyIndex = #keys
    while keyIndex > 0 do
        local key = keys[keyIndex]
        if keysTable[key] then
            -- This key already exists.
            table.remove(keys, keyIndex)
        else
            -- Add this new key.
            keysTable[key] = true
        end
        keyIndex = keyIndex - 1
    end
    if #keys > 0 then
        self:FireCallbacks("AddedKeys", keys)
    end
    return keys
end
-- Returns the saved keys table.
-- Note that the saved keys table is a non-contiguous table containing each key mapped to the Boolean value true.
function SavedKeys:GetKeys()
    local keysTable = self:GetOrCreateSavedTableInternal("keys")
    return keysTable
end
-- Returns the string name for the type of keys saved in the saved keys table.
function SavedKeys:GetKeyTypeName()
    return self.keyTypeName
end
-- Returns the number of keys saved.
function SavedKeys:GetNumKeys()
    local keysTable = self:GetKeys()
    return keysTable and NonContiguousCount(keysTable) or 0
end
-- Returns the SavedVars file name.
function SavedKeys:GetSavedVarsFile()
    return self.savedVarsFile
end
-- Returns the numeric version number of the saved keys table.
function SavedKeys:GetVersion()
    return self.version
end
-- Returns two numerically indexed tables:
-- (1) The specified key(s) that exist in the saved keys table.
-- (2) The specified key(s) that do not exist in the saved keys table.
function SavedKeys:FindKeys(...)
    local keysTable = self:GetKeys()
    local keysMissing = {}
    local keysFound = {...}
    if type(keysFound[1]) == "table" then
        -- The caller specified a table of keys instead of a series of key arguments.
        -- Note that a copy of the argument is created to prevent unwanted changes to the argument itself.
        keysFound = {unpack(keysFound[1])}
    end
    local keyIndex = #keysFound
    while keyIndex > 0 do
        local key = keysFound[keyIndex]
        if keysTable[key] ~= true then
            -- The specified key does not exist in the saved keys table.
            table.remove(keysFound, keyIndex)
            table.insert(keysMissing, key)
        end
        keyIndex = keyIndex - 1
    end
    return keysFound, keysMissing
end
-- Returns true if the specified key exists.
function SavedKeys:HasKey(key)
    local keysTable = self:GetKeys()
    return keysTable[key] == true
end
-- Returns true if all of the specified key(s) exist.
function SavedKeys:HasKeys(...)
    local keysTable = self:GetKeys()
    local keys = {...}
    if type(keys[1]) == "table" then
        -- The caller specified a table of keys instead of a series of key arguments.
        keys = keys[1]
    end
    for _, key in ipairs(keys) do
        if keysTable[key] ~= true then
            return false
        end
    end
    return true
end
-- Returns true if one or more of the specified key(s) exist.
function SavedKeys:HasAnyKey(...)
    local keysTable = self:GetKeys()
    local keys = {...}
    if type(keys[1]) == "table" then
        -- The caller specified a table of keys instead of a series of key arguments.
        keys = keys[1]
    end
    for _, key in ipairs(keys) do
        if keysTable[key] == true then
            return true
        end
    end
    return false
end
-- Returns true if the saved keys table is initialized.
function SavedKeys:IsInitialized()
    return self.savedVars ~= nil
end
-- Removes all keys from the saved keys table.
-- If one or more keys were removed, fires the "RemovedKeys" callback with a numerically indexed table of the removed keys.
-- Returns a numerically indexed table of the removed keys.
function SavedKeys:RemoveAllKeys()
    local keysTable = self:GetKeys()
    local removedKeys = {}
    for key in pairs(keysTable) do
        table.insert(removedKeys, key)
    end
    ZO_ClearTable(keysTable)
    if #removedKeys > 0 then
        self:FireCallbacks("RemovedKeys", removedKeys)
    end
    return removedKeys
end
-- Removes the specified keys from the saved keys table.
-- If one or more existing keys were removed, fires the "RemovedKeys" callback with a numerically indexed table of the removed keys.
-- Returns a numerically indexed table of removed keys.
function SavedKeys:RemoveKeys(...)
    local keysTable = self:GetKeys()
    local keys = {...}
    if type(keys[1]) == "table" then
        -- The caller specified a table of keys instead of a series of key arguments.
        -- Note that a copy of the argument is created to prevent unwanted changes to the argument itself.
        keys = {unpack(keys[1])}
    end
    local keyIndex = #keys
    while keyIndex > 0 do
        local key = keys[keyIndex]
        if keysTable[key] then
            -- Remove this existing key.
            keysTable[key] = nil
        else
            -- This key does not exist.
            table.remove(keys, keyIndex)
        end
        keyIndex = keyIndex - 1
    end
    if #keys > 0 then
        self:FireCallbacks("RemovedKeys", keys)
    end
    return keys
end
-- Private Methods
function SavedKeys:GetSavedVarInternal(savedVarKey)
    local savedVars = self.savedVars
    if not savedVars then
        assert(false, string.format("SavedKeys: %q key table is not ready yet.", self.keyTypeName))
    end
    return savedVars[savedVarKey]
end
function SavedKeys:SetSavedVarInternal(savedVarKey, value)
    local savedVars = self.savedVars
    if not savedVars then
        assert(false, string.format("SavedKeys: %q key table is not ready yet.", self.keyTypeName))
    end
    savedVars[savedVarKey] = value
    return true
end
function SavedKeys:GetOrCreateSavedTableInternal(savedVarKey)
    local savedTable = self:GetSavedVarInternal(savedVarKey)
    if savedTable == nil then
        savedTable = {}
        if not self:SetSavedVarInternal(savedVarKey, savedTable) then
            return nil
        end
    end
    return savedTable
end
-- SAVED_KEYS manages the lifecycle of all SavedKeys instances.
local SavedKeysManager = ZO_InitializingObject:Subclass()
function SavedKeysManager:Initialize()
    self.savedKeysByKeyTypeName = {}
end
-- Public Methods
-- Returns a non-contiguous table containing each key type name mapped to its associated SavedKeys instance.
function SavedKeysManager:GetAllSavedKeys()
    return self.savedKeysByKeyTypeName
end
-- Gets or creates the SavedKeys instance associated with the specified key type name.
function SavedKeysManager:GetOrCreateSavedKeys(keyTypeName, savedVarsFile, version)
    local savedKeys = self.savedKeysByKeyTypeName[keyTypeName]
    if savedKeys then
        return savedKeys
    end
    savedKeys = SavedKeys:New(keyTypeName, savedVarsFile, version)
    self.savedKeysByKeyTypeName[keyTypeName] = savedKeys
    return savedKeys
end
SAVED_KEYS = SavedKeysManager:New()