annotate LibModuleDBShare-1.0/LibModuleDBShare-1.0.lua @ 39:c6d1b0d7f8f9

Added slash command support. Incremented minor version number.
author Andrew Knoll <andrewtknoll@gmail.com>
date Sun, 07 Apr 2013 22:50:00 -0400
parents f971130a84bb
children e1053178ddbf
rev   line source
andrewtknoll@33 1 --- **LibModuleDBShare-1.0** provides a shared profile manager for addons without a central core.
andrewtknoll@33 2 -- A basic options panel for the group is added to the Blizzard options panel, as well as a
andrewtknoll@33 3 -- standard profile manager as a subpanel. Changes through the profiles panel are propagated
andrewtknoll@33 4 -- to member databases. The root panel can be used as a parent for your module config panels,
andrewtknoll@33 5 -- to keep all your addon's config in one place. The root panel's name is the same as the group's
andrewtknoll@33 6 -- name.\\
andrewtknoll@33 7 -- \\
andrewtknoll@35 8 -- A group can be created using the ':NewGroup' library method. The returned object inherits all
andrewtknoll@35 9 -- methods of the DBGroup object described below.\\
andrewtknoll@33 10 -- \\
andrewtknoll@33 11 -- **LibDualSpec Support**\\
andrewtknoll@33 12 -- LibModuleDBShare can use LibDualSpec to manage automatic profile switching with talent spec
andrewtknoll@33 13 -- changes. This integration is handled by the library; there is no need to use LibDualSpec
andrewtknoll@33 14 -- on member databases directly.
>@5 15 --
>@5 16 -- @usage
andrewtknoll@33 17 -- local database;
andrewtknoll@33 18 -- -- this function is called after the ADDON_LOADED event fires
andrewtknoll@33 19 -- function initializeDB()
andrewtknoll@33 20 -- database = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true);
andrewtknoll@33 21 -- local group = LibStub("LibModuleDBShare-1.0"):GetGroup("Group Name");
andrewtknoll@33 22 -- if not group then
andrewtknoll@33 23 -- group = LibStub("LibModuleDBShare-1.0"):NewGroup("Group Name", "A description for this group.", database);
andrewtknoll@33 24 -- else
andrewtknoll@33 25 -- group:AddDB(database);
andrewtknoll@33 26 -- end
andrewtknoll@33 27 -- end
>@5 28 -- @class file
andrewtknoll@33 29 -- @name LibModuleDBShare-1.0
andrewtknoll@39 30 local MAJOR, MINOR = "LibModuleDBShare-1.0", 5
>@3 31 local LibModuleDBShare, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
>@3 32
>@4 33 if not LibModuleDBShare then return end -- No upgrade needed
>@4 34
andrewtknoll@29 35 -- Lua functions
andrewtknoll@26 36 local error, type, pairs, time = error, type, pairs, time;
andrewtknoll@15 37
andrewtknoll@17 38 -- Required Libraries
@12 39 local AceDB = LibStub("AceDB-3.0");
andrewtknoll@17 40 local AceDBOptions = LibStub("AceDBOptions-3.0");
andrewtknoll@17 41 local AceConfigRegistry = LibStub("AceConfigRegistry-3.0");
andrewtknoll@17 42 local AceConfigDialog = LibStub("AceConfigDialog-3.0");
@12 43
andrewtknoll@28 44 -- Optional Libraries
andrewtknoll@28 45 local LibDualSpec = LibStub("LibDualSpec-1.0", true);
andrewtknoll@28 46
>@4 47 LibModuleDBShare.groups = LibModuleDBShare.groups or {};
>@4 48
>@5 49 local DBGroup = {};
>@5 50
>@5 51 --- Creates a new DB group.
andrewtknoll@33 52 -- @param groupName The name of the new DB group, as shown in the options panel.
andrewtknoll@21 53 -- @param groupDescription A description of the group to be shown in the root options panel.
andrewtknoll@21 54 -- @param initialDB The first DB to add to the group.
andrewtknoll@28 55 -- @param usesDualSpec True if this group should use LibDualSpec, false otherwise.
>@5 56 -- @usage
andrewtknoll@33 57 -- local myDB = LibStub("AceDB-3.0"):New("MySavedVar");
andrewtknoll@33 58 -- local myAddonDBGroup = LibStub("LibModuleDBShare-1.0"):NewGroup("MyAddonGroupName", "MyDescription", myDB, true)
>@5 59 -- @return the new DB group object
andrewtknoll@33 60 -- @name LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB[, usesDualSpec]);
andrewtknoll@21 61 function LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec)
andrewtknoll@35 62 -- check to see if LibDualSpec has been loaded
andrewtknoll@35 63 if not LibDualSpec then
andrewtknoll@35 64 LibDualSpec = LibStub("LibDualSpec-1.0", true);
andrewtknoll@35 65 end
andrewtknoll@21 66 -- verify parameters
andrewtknoll@26 67 if type(groupName) ~= "string" then
andrewtknoll@26 68 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): 'groupName' must be a string.", 2);
andrewtknoll@26 69 elseif type(groupDescription) ~= "string" then
andrewtknoll@26 70 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): 'groupDescription' must be a string.", 2);
andrewtknoll@26 71 elseif type(LibModuleDBShare.groups[groupName]) ~= "nil" then
andrewtknoll@31 72 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): group '"..groupName.."' already exists.", 2);
andrewtknoll@27 73 elseif type(initialDB) ~= "table" or not AceDB.db_registry[initialDB] then
andrewtknoll@31 74 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): 'initialDB' must be an AceDB-3.0 database.", 2);
andrewtknoll@31 75 elseif initialDB.parent then
andrewtknoll@31 76 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): 'initialDB' must not be a namespace.", 2)
andrewtknoll@28 77 elseif type(usesDualSpec) ~= "boolean" and type(usesDualSpec) ~= "nil" then
andrewtknoll@31 78 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): 'usesDualSpec' must be a boolean or nil.", 2);
andrewtknoll@28 79 elseif usesDualSpec and not LibDualSpec then
andrewtknoll@31 80 error("Usage: LibModuleDBShare:NewGroup(groupName, groupDescription, initialDB, usesDualSpec): 'usesDualSpec' cannot be true without LibDualSpec-1.0 installed.", 2);
andrewtknoll@26 81 end
andrewtknoll@21 82 -- create group
@12 83 local group = {}
@12 84 group.name = groupName;
andrewtknoll@21 85 group.members = {};
andrewtknoll@21 86 -- create root option panel for group
andrewtknoll@17 87 group.rootOptionsTable = {
andrewtknoll@17 88 type = "group",
andrewtknoll@17 89 name = groupName,
andrewtknoll@17 90 args = {
andrewtknoll@17 91 text = {
andrewtknoll@17 92 type = "description",
andrewtknoll@21 93 name = groupDescription,
andrewtknoll@17 94 },
andrewtknoll@17 95 },
andrewtknoll@17 96 };
andrewtknoll@17 97 AceConfigRegistry:RegisterOptionsTable(groupName, group.rootOptionsTable);
andrewtknoll@17 98 AceConfigDialog:AddToBlizOptions(groupName);
andrewtknoll@21 99 -- create sync DB and profile options page
@12 100 group.syncDBTable = {};
andrewtknoll@21 101 group.syncDB = AceDB:New(group.syncDBTable, nil, initialDB:GetCurrentProfile());
andrewtknoll@17 102 group.profileOptionsTable = AceDBOptions:GetOptionsTable(group.syncDB, false);
andrewtknoll@28 103 if usesDualSpec then
andrewtknoll@29 104 group.usesDualSpec = true;
andrewtknoll@28 105 LibDualSpec:EnhanceDatabase(group.syncDB, groupName);
andrewtknoll@28 106 LibDualSpec:EnhanceOptions(group.profileOptionsTable, group.syncDB);
andrewtknoll@29 107 else
andrewtknoll@29 108 group.usesDualSpec = false;
andrewtknoll@28 109 end
andrewtknoll@17 110 AceConfigRegistry:RegisterOptionsTable(groupName.."Profiles", group.profileOptionsTable);
andrewtknoll@18 111 AceConfigDialog:AddToBlizOptions(groupName.."Profiles", group.profileOptionsTable.name, groupName);
andrewtknoll@21 112 -- add all profiles from initialDB to syncDB
andrewtknoll@21 113 for i, profile in pairs(initialDB:GetProfiles()) do
andrewtknoll@21 114 group.syncDB:SetProfile(profile);
andrewtknoll@21 115 end
andrewtknoll@28 116 -- load profile info from initialDB
andrewtknoll@21 117 group.syncDB:SetProfile(initialDB:GetCurrentProfile());
andrewtknoll@27 118 group.members[initialDB] = initialDB:GetNamespace(MAJOR, true) or initialDB:RegisterNamespace(MAJOR);
andrewtknoll@29 119 local storedData = group.members[initialDB].char;
andrewtknoll@29 120 if type(storedData.logoutTimestamp) == "number" then
andrewtknoll@29 121 group.profileTimestamp = storedData.logoutTimestamp;
andrewtknoll@22 122 else
andrewtknoll@22 123 group.profileTimestamp = 0;
andrewtknoll@22 124 end
andrewtknoll@35 125 if usesDualSpec then
andrewtknoll@35 126 local LDSnamespace = group.syncDB:GetNamespace("LibDualSpec-1.0");
andrewtknoll@35 127 LDSnamespace.char.enabled = storedData.dualSpecEnabled;
andrewtknoll@35 128 LDSnamespace.char.profile = storedData.altProfile;
andrewtknoll@35 129 LDSnamespace.char.specGroup = storedData.activeSpecGroup;
andrewtknoll@30 130 group.syncDB:CheckDualSpecState();
andrewtknoll@35 131 else
andrewtknoll@35 132 group.syncDB.char.enabled = storedData.dualSpecEnabled;
andrewtknoll@35 133 group.syncDB.char.profile = storedData.altProfile;
andrewtknoll@35 134 group.syncDB.char.specGroup = storedData.activeSpecGroup;
andrewtknoll@28 135 end
andrewtknoll@21 136 -- add methods and callbacks
@12 137 for k, v in pairs(DBGroup) do
@12 138 group[k] = v;
@12 139 end
andrewtknoll@19 140 group.syncDB.RegisterCallback(group, "OnProfileChanged", "OnProfileChanged");
andrewtknoll@19 141 group.syncDB.RegisterCallback(group, "OnProfileDeleted", "OnProfileDeleted");
andrewtknoll@19 142 group.syncDB.RegisterCallback(group, "OnProfileCopied", "OnProfileCopied");
andrewtknoll@19 143 group.syncDB.RegisterCallback(group, "OnProfileReset", "OnProfileReset");
andrewtknoll@28 144 group.syncDB.RegisterCallback(group, "OnDatabaseShutdown", "OnSyncShutdown");
andrewtknoll@28 145 initialDB.RegisterCallback(group, "OnDatabaseShutdown", "OnMemberShutdown");
andrewtknoll@20 146 group.squelchCallbacks = false;
andrewtknoll@19 147 LibModuleDBShare.groups[groupName] = group;
@12 148 return group;
>@4 149 end
>@4 150
>@5 151 --- Retrieves an existing DB group.
>@5 152 -- @param groupName The name of the DB group to retrieve.
>@5 153 -- @usage
>@5 154 -- local myAddonDBGroup = LibStub("LibModuleDBShare-1.0"):GetGroup("MyAddonGroupName")
andrewtknoll@35 155 -- @return the DB group object, or ##nil## if not found
>@5 156 function LibModuleDBShare:GetGroup(groupName)
andrewtknoll@27 157 if type(groupName) ~= "string" then
andrewtknoll@27 158 error("Usage: LibModuleDBShare:GetGroup(groupName): 'groupName' must be a string.", 2);
andrewtknoll@27 159 end
@12 160 return LibModuleDBShare.groups[groupName];
>@4 161 end
>@5 162
>@5 163 --- Adds a database to the group.
andrewtknoll@22 164 -- @param newDB The database to add.
>@5 165 -- @usage
>@5 166 -- myAddonDBGroup:AddDB(MyAddon.db)
andrewtknoll@22 167 function DBGroup:AddDB(newDB)
andrewtknoll@22 168 -- verify parameters
andrewtknoll@26 169 if type(newDB) ~= "table" or not AceDB.db_registry[newDB] then
andrewtknoll@31 170 error("Usage: DBGroup:AddDB(newDB): 'newDB' must be an AceDB-3.0 database.", 2);
andrewtknoll@31 171 elseif newDB.parent then
andrewtknoll@31 172 error("Usage: DBGroup:AddDB(newDB): 'newDB' must not be a namespace.", 2)
andrewtknoll@26 173 elseif type(self.members[newDB]) ~= "nil" then
andrewtknoll@31 174 error("Usage: DBGroup:AddDB(newDB): 'newDB' is already a member of DBGroup.", 2);
andrewtknoll@31 175 end
andrewtknoll@31 176 for groupName, group in pairs(LibModuleDBShare.groups) do
andrewtknoll@31 177 if group.members[newDB] ~= nil then
andrewtknoll@31 178 error("Usage: DBGroup:AddDB(newDB): 'newDB' is already a member of group '"..groupName.."'.", 2);
andrewtknoll@31 179 end
andrewtknoll@26 180 end
andrewtknoll@22 181 -- record current profile
andrewtknoll@20 182 local syncProfile = self.syncDB:GetCurrentProfile();
andrewtknoll@22 183 -- add new profiles to syncDB
andrewtknoll@20 184 self.squelchCallbacks = true;
andrewtknoll@22 185 for i, profile in pairs(newDB:GetProfiles()) do
andrewtknoll@20 186 self.syncDB:SetProfile(profile);
andrewtknoll@20 187 end
andrewtknoll@22 188 -- set current profile based on timestamps
andrewtknoll@27 189 local namespace = newDB:GetNamespace(MAJOR, true) or newDB:RegisterNamespace(MAJOR);
andrewtknoll@29 190 local storedData = namespace.char;
andrewtknoll@29 191 if type(storedData.logoutTimestamp) == "number" and storedData.logoutTimestamp > self.profileTimestamp then
andrewtknoll@22 192 self.squelchCallbacks = false;
andrewtknoll@22 193 self.syncDB:SetProfile(newDB:GetCurrentProfile());
andrewtknoll@29 194 self.profileTimestamp = storedData.logoutTimestamp;
andrewtknoll@35 195 if self.usesDualSpec and storedData.altProfile then
andrewtknoll@35 196 local LDSnamespace = group.syncDB:GetNamespace("LibDualSpec-1.0");
andrewtknoll@35 197 LDSnamespace.char.enabled = storedData.dualSpecEnabled;
andrewtknoll@35 198 LDSnamespace.char.profile = storedData.altProfile;
andrewtknoll@35 199 LDSnamespace.char.specGroup = storedData.activeSpecGroup;
andrewtknoll@30 200 group.syncDB:CheckDualSpecState();
andrewtknoll@35 201 elseif storedData.altProfile then
andrewtknoll@35 202 self.syncDB.char.enabled = storedData.dualSpecEnabled;
andrewtknoll@35 203 self.syncDB.char.profile = storedData.altProfile;
andrewtknoll@35 204 self.syncDB.char.specGroup = storedData.activeSpecGroup;
andrewtknoll@28 205 end
andrewtknoll@20 206 else
andrewtknoll@20 207 self.syncDB:SetProfile(syncProfile);
andrewtknoll@22 208 newDB:SetProfile(syncProfile);
andrewtknoll@22 209 self.squelchCallbacks = false;
andrewtknoll@20 210 end
andrewtknoll@22 211 -- add to members list
andrewtknoll@27 212 self.members[newDB] = namespace;
andrewtknoll@28 213 newDB.RegisterCallback(self, "OnDatabaseShutdown", "OnMemberShutdown");
>@5 214 end
andrewtknoll@18 215
andrewtknoll@39 216 -- LibDualSpec support
andrewtknoll@39 217
andrewtknoll@35 218 --- Checks to see if this group uses LibDualSpec.
andrewtknoll@35 219 -- @return ##true## if this group uses LibDualSpec, ##false## otherwise
andrewtknoll@35 220 function DBGroup:IsUsingDualSpec()
andrewtknoll@35 221 return self.usesDualSpec;
andrewtknoll@35 222 end
andrewtknoll@35 223
andrewtknoll@35 224 --- Enables dual spec support if not already enabled.
andrewtknoll@35 225 function DBGroup:EnableDualSpec()
andrewtknoll@35 226 if not LibDualSpec then
andrewtknoll@35 227 LibDualSpec = LibStub("LibDualSpec-1.0"); -- this will error if LDS isn't found
andrewtknoll@35 228 end
andrewtknoll@35 229 if not self.usesDualSpec then
andrewtknoll@35 230 LibDualSpec:EnhanceDatabase(self.syncDB, self.name);
andrewtknoll@35 231 LibDualSpec:EnhanceOptions(self.profileOptionsTable, self.syncDB);
andrewtknoll@37 232 AceConfigRegistry:NotifyChange(self.name.."Profiles");
andrewtknoll@35 233 self.usesDualSpec = true;
andrewtknoll@35 234 local namespace = self.syncDB:GetNamespace("LibDualSpec-1.0");
andrewtknoll@35 235 namespace.char.enabled = self.syncDB.char.enabled;
andrewtknoll@35 236 namespace.char.profile = self.syncDB.char.profile;
andrewtknoll@35 237 namespace.char.specGroup = self.syncDB.char.specGroup;
andrewtknoll@35 238 self.syncDB:CheckDualSpecState();
andrewtknoll@35 239 end
andrewtknoll@35 240 end
andrewtknoll@35 241
andrewtknoll@39 242 -- slash command support
andrewtknoll@39 243
andrewtknoll@39 244 --- Adds a slash command to the group.
andrewtknoll@39 245 -- @name DBGroup:EnableSlashCommand(slug, commandList[, handler])
andrewtknoll@39 246 function DBGroup:EnableSlashCommand(slug, commandList, handler)
andrewtknoll@39 247 if self.slug then
andrewtknoll@39 248 error("Usage: DBGroup:EnableSlashCommand(slug, commandList[, handler]): group already has a slash command.", 2);
andrewtknoll@39 249 elseif type(slug) ~= "string" then
andrewtknoll@39 250 error("Usage: DBGroup:EnableSlashCommand(slug, commandList[, handler]): 'slug' must be a string.", 2);
andrewtknoll@39 251 elseif type(commandList) ~= "string" and type(commandList) ~= "table" then
andrewtknoll@39 252 error("Usage: DBGroup:EnableSlashCommand(slug, commandList[, handler]): 'commandList' must be a string or table.", 2);
andrewtknoll@39 253 elseif handler and type(handler) ~= "function" then
andrewtknoll@39 254 error("Usage: DBGroup:EnableSlashCommand(slug, commandList[, handler]): 'handler' must be nil or a function.", 2);
andrewtknoll@39 255 elseif type(commandList) == "table" then
andrewtknoll@39 256 for i = 1, #commandList do
andrewtknoll@39 257 if type(commandList[i]) ~= "string" then
andrewtknoll@39 258 error("Usage: DBGroup:EnableSlashCommand(slug, commandList[, handler]): 'commandList' must contain only strings.", 2);
andrewtknoll@39 259 end
andrewtknoll@39 260 end
andrewtknoll@39 261 end
andrewtknoll@39 262
andrewtknoll@39 263 self.slug = slug;
andrewtknoll@39 264 self.slashCmdHandler = handler;
andrewtknoll@39 265 self.subCmdList = {};
andrewtknoll@39 266 if type(commandList) == "string" then
andrewtknoll@39 267 _G["SLASH_"..slug.."1"] = commandList;
andrewtknoll@39 268 else
andrewtknoll@39 269 for i = 1, #commandList do
andrewtknoll@39 270 _G["SLASH_"..slug..i] = commandList[i];
andrewtknoll@39 271 end
andrewtknoll@39 272 end
andrewtknoll@39 273
andrewtknoll@39 274 SlashCmdList[slug] = function(msg, editBox)
andrewtknoll@39 275 if self.slashCmdHandler then
andrewtknoll@39 276 self.slashCmdHandler(msg, editBox);
andrewtknoll@39 277 return;
andrewtknoll@39 278 end
andrewtknoll@39 279
andrewtknoll@39 280 for cmd, func in pairs(self.subCmdList) do
andrewtknoll@39 281 if msg == cmd then
andrewtknoll@39 282 func("", editBox);
andrewtknoll@39 283 return;
andrewtknoll@39 284 elseif msg:len() > cmd:len() then
andrewtknoll@39 285 if msg:sub(1, cmd:len() + 1) == (cmd.." ") then
andrewtknoll@39 286 func(msg:sub(cmd:len() + 2), editBox);
andrewtknoll@39 287 return;
andrewtknoll@39 288 end
andrewtknoll@39 289 end
andrewtknoll@39 290 end
andrewtknoll@39 291
andrewtknoll@39 292 for k, button in pairs(InterfaceOptionsFrameAddOns.buttons) do
andrewtknoll@39 293 if button.element.name == self.name and button.element.collapsed then
andrewtknoll@39 294 OptionsListButtonToggle_OnClick(button.toggle);
andrewtknoll@39 295 break;
andrewtknoll@39 296 end
andrewtknoll@39 297 end
andrewtknoll@39 298 InterfaceOptionsFrame_OpenToCategory(self.name);
andrewtknoll@39 299 end;
andrewtknoll@39 300 end
andrewtknoll@39 301
andrewtknoll@39 302 --- Adds an alias for the slash command
andrewtknoll@39 303 function DBGroup:AddSlashCommandAlias(alias)
andrewtknoll@39 304 if type(alias) ~= "string" then
andrewtknoll@39 305 error("Usage: DBGroup:AddSlashCommandAlias(alias): 'alias' must be a string.", 2);
andrewtknoll@39 306 elseif not self.slug then
andrewtknoll@39 307 error("Usage: DBGroup:AddSlashCommandAlias(alias): slash commands for this group have not be enabled.", 2);
andrewtknoll@39 308 end
andrewtknoll@39 309
andrewtknoll@39 310 local i = 1;
andrewtknoll@39 311 while _G["SLASH_"..self.slug..i] do
andrewtknoll@39 312 if _G["SLASH_"..self.slug..i] == alias then
andrewtknoll@39 313 error("Usage: DBGroup:AddSlashCommandAlias(alias): 'alias' is already added.", 2);
andrewtknoll@39 314 end
andrewtknoll@39 315 i = i + 1;
andrewtknoll@39 316 end
andrewtknoll@39 317
andrewtknoll@39 318 _G["SLASH_"..self.slug..i] = alias;
andrewtknoll@39 319 end
andrewtknoll@39 320
andrewtknoll@39 321 --- Adds a secondary command handler to the slash command for this group.
andrewtknoll@39 322 function DBGroup:AddSecondaryCommand(name, handler)
andrewtknoll@39 323 if type(name) ~= "string" then
andrewtknoll@39 324 error("Usage: DBGroup:AddSecondaryCommand(name, handler): 'name' must be a string.", 2);
andrewtknoll@39 325 elseif type(name) ~= "function" then
andrewtknoll@39 326 error("Usage: DBGroup:AddSecondaryCommand(name, handler): 'handler' must be a function.", 2);
andrewtknoll@39 327 elseif not self.slashCmdList then
andrewtknoll@39 328 error("Usage: DBGroup:AddSecondaryCommand(name, handler): slash commands for this group have not be enabled.", 2);
andrewtknoll@39 329 end
andrewtknoll@39 330 for k, v in pairs(self.subCmdList) do
andrewtknoll@39 331 if k == name then
andrewtknoll@39 332 error("Usage: DBGroup:AddSecondaryCommand(name, func): command '"..name.."' already exists.", 2);
andrewtknoll@39 333 end
andrewtknoll@39 334 end
andrewtknoll@39 335
andrewtknoll@39 336 self.subCmdList[name] = handler;
andrewtknoll@39 337 end
andrewtknoll@39 338
andrewtknoll@19 339 -- callback handlers (new profiles are handled by OnProfileChanged)
andrewtknoll@19 340
andrewtknoll@24 341 function DBGroup:OnProfileChanged(callback, syncDB, profile)
andrewtknoll@24 342 if not self.squelchCallbacks then
andrewtknoll@24 343 for db, _ in pairs(self.members) do
andrewtknoll@25 344 db:SetProfile(profile);
andrewtknoll@24 345 end
andrewtknoll@24 346 end
andrewtknoll@18 347 end
andrewtknoll@18 348
andrewtknoll@24 349 function DBGroup:OnProfileDeleted(callback, syncDB, profile)
andrewtknoll@24 350 for db, _ in pairs(self.members) do
andrewtknoll@24 351 db:DeleteProfile(profile, true);
andrewtknoll@24 352 end
andrewtknoll@18 353 end
andrewtknoll@18 354
andrewtknoll@24 355 function DBGroup:OnProfileCopied(callback, syncDB, profile)
andrewtknoll@24 356 for db, _ in pairs(self.members) do
andrewtknoll@24 357 db:CopyProfile(profile, true);
andrewtknoll@24 358 end
andrewtknoll@18 359 end
andrewtknoll@18 360
andrewtknoll@24 361 function DBGroup:OnProfileReset(callback, syncDB)
andrewtknoll@24 362 for db, _ in pairs(self.members) do
andrewtknoll@24 363 db:ResetProfile(false, false);
andrewtknoll@24 364 end
andrewtknoll@18 365 end
andrewtknoll@23 366
andrewtknoll@29 367 local altProfile = nil;
andrewtknoll@29 368 local dualSpecEnabled = nil;
andrewtknoll@29 369 local activeSpecGroup = nil;
andrewtknoll@28 370
andrewtknoll@28 371 function DBGroup:OnSyncShutdown(callback, syncDB)
andrewtknoll@29 372 if self.usesDualSpec and not altProfile then
andrewtknoll@29 373 altProfile = syncDB:GetDualSpecProfile();
andrewtknoll@29 374 dualSpecEnabled = syncDB:IsDualSpecEnabled();
andrewtknoll@29 375 activeSpecGroup = GetActiveSpecGroup();
andrewtknoll@28 376 end
andrewtknoll@28 377 end
andrewtknoll@28 378
andrewtknoll@24 379 local timestamp = nil;
andrewtknoll@24 380
andrewtknoll@28 381 function DBGroup:OnMemberShutdown(callback, db)
andrewtknoll@27 382 if not timestamp then -- ensure uniform timestamps to minimize
andrewtknoll@27 383 timestamp = time(); -- calls to SetProfile in NewGroup
andrewtknoll@24 384 end
andrewtknoll@37 385 self.members[db].char.logoutTimestamp = timestamp;
andrewtknoll@29 386 if self.usesDualSpec then
andrewtknoll@29 387 if not altProfile then
andrewtknoll@29 388 altProfile = self.syncDB:GetDualSpecProfile();
andrewtknoll@29 389 dualSpecEnabled = self.syncDB:IsDualSpecEnabled();
andrewtknoll@29 390 activeSpecGroup = GetActiveSpecGroup();
andrewtknoll@29 391 end
andrewtknoll@29 392 self.members[db].char.altProfile = altProfile;
andrewtknoll@29 393 self.members[db].char.dualSpecEnabled = dualSpecEnabled;
andrewtknoll@29 394 self.members[db].char.activeSpecGroup = activeSpecGroup;
andrewtknoll@28 395 end
andrewtknoll@23 396 end
andrewtknoll@33 397
andrewtknoll@33 398 -- update existing groups
andrewtknoll@33 399 for groupName, group in pairs(LibModuleDBShare.groups) do
andrewtknoll@33 400 for funcName, func in pairs(DBGroup) do
andrewtknoll@33 401 group[funcName] = func;
andrewtknoll@33 402 end
andrewtknoll@33 403 end