|Go to Page...|
|Thread Tools||Display Modes|
|08/12/14, 09:57 AM||#1|
work in progress - libASV (Advanced Saved Variables)
The built in system of accessing the saved variables is a mixed blessing. While it helps with keeping the settings ordered, is relatively simple to use and allows simple versioning/return to default, it has downsides & limitations galore.
Nothing made this as obvious as the broken GetDisplayName function in 1.2.3 and it's fix in 1.3.3 and thier effect on ZO_SavedVars.
In the end a saved variable is nothing but a global variable that get's dumped to disk on UI unload and read in from disk on UI load. So many have started working with them directly. So I got the idea to make a library for that. Trying to get a bit of the simplicity and order of the original, without the limitations.
Unified approach wich simplifies debugging and development.
Ability to override everything - account name and character name - to get everyones data.
A new Scale "OS account wide". A specific area of the saved variable not tied to any account. This is helpfull if you want to share data between accounts, but mostly if you have data that is in no way bound to one account (runtime gathered harvensting nodes or skyshard positions, for example).
No versioning control (so no simple return). This is something I will not be likely to support. I might think of some way to do it later. You have to keep track of the version yourself.
No defaults - this is temporary till I ironed the basic code out.
If you switch from the Built in version to this one, you either have to reset the data or write basic migration code yourself (this should be a one time work. I can give examples).
This is the data structure (wich can be found inside your saved variable file) how it would appear in a multi-zen account, multi Character situation:
:AccessOSUserWide("SavedVariableName") will return the table at "libASV_OS_user_wide" and create all tables that are missing along the way.
:AccountWide("SavedVariableName", [accountOverride]) gives you the libASV_AccountWide table of your account by default. Can be overridden via optional argument. This is for data not tied to any character.
:AllCharacters("SavedVariableName", [accountOverride]) Gives you a table containing all the Characters for the specified account inlcuding all the subtables. This is everything under the account name, aside from the Accont wide area. Defaults to current account. Usefull if you just want to cross access data stored on the Character level.
:CharacterWide("SavedVariableName", [accountOverride], [characterOverride]) - gives you the table for the specified account, specified character and creates tables along the way. Defaults to current, but can be overridden.
|08/13/14, 09:40 AM||#2|
The silence is deafening.
What do you guys think?
Would this be usefull or pointless (as you go full custom way anyway)?
Anything I forgot to cover?
|08/13/14, 09:56 AM||#3|
I'm accessing the saved var directly, with a utility function which auto-vivifies deeply nested subtables. That way I have a single point of access to everything, per-character, account-wide and cross-account data. And I think I'll stick with it. Until I shoot myself in the foot by breaking compatibility (due to having no versioning )
|08/13/14, 09:59 AM||#4|
I'd much rather use this than ZO_SavedVars if it means I'll be less likely to be affected by shenanigans similar to 1.2.
It all sounds great. I'd really like to see version control, since it would be nice if the replacement method didn't have any drawbacks to the default.
|08/13/14, 12:41 PM||#5|
Versioning shouldn't be too hard to implement and I'd think it'd be almost required to implement if looking to replace the ZO_SavedVars. Here's some ideas for doing versioning and default values:
Store version number
I think this would be best done per data group. Account-wide and OS-wide you could put one level up from where the data is stored easily. Per character you either need to put in with the data (and just have the version field be reserved) or put under the account level and prefix with character name.
New format sample:
You'd need to pass in the version number and an upgrade function. You could do a variable-wide upgrade, but that would expose your underlying structure, which is hardly ideal.
:AccessOSUserWide("SavedVariableName", version, [defaults], [upgradeFunction])
:AccountWide("SavedVariableName", version, [defaults], [upgradeFunction], [accountOverride])
:CharacterWide("SavedVariableName", version, [defaults], [upgradeFunction], [accountOverride], [characterOverride])
The function behavior (except AllCharacters) would be:
IF not initialized THEN COPY in default values RETURN table END IF version different THEN IF upgradeFunction THEN CALL upgrade function on table ELSE COPY in default values END END RETURN table
- existing version
- existing table
Could either have the function modify the table in-place (more efficient) or just return the new table (susceptible to errors if not familiar with tables are reference).
Again, you don't know what to do for upgrade in the default, so you'd just reset to defaults.
|08/15/14, 06:18 AM||#6|
First, it is alot of work and a lot of added complexity.
Second, I also propably need some sub-division (like the namespaces) so the programmer can reset part of the data without affecting others. Doing this account or even Character wide is not granular enough.
Third and most importantly: It is pretty trivial to make versionoing yourself. Once you started making your own (for more advanced cases like migrating applicable settings from previous versions), those extra checks built into the function will be a resource drain.
I might add it later. But I don't see the need to hardcode this personally.
|08/15/14, 06:27 AM||#7|
can this new idea solve this problem with too large savedvariables file?
|08/15/14, 12:20 PM||#8|
mby dynamic loading for each zone& to prevent this lags and errors when we have alot of nodes
|08/15/14, 01:03 PM||#9|
|08/15/14, 01:18 PM||#10|
nothing "not possible" for a good programmer =)
|08/17/14, 01:18 AM||#11|
More seriously, we are limited by the API. The game itself loads the whole file, so we can't change that unless we work at Zenimax and can access the game code.
2. I don't see the need for namespaces, as the library doesn't try for namespaces from the API. I can't come up with a decent use case of why that'd be needed either, so guess you'd need to elaborate.
3a. If it's trivial, that seems to me more argument to put it in library to limit code re-use.
3b. It's called once on the library call which should only be done for an individual bucket once per /reloadui, so it's negligible cost on setup. If someone's calling ZO_SavedVars or this every frame update (when it would have an impact), that's bad usage and should be changed regardless.
It almost seems you're trying to build in something more advanced than the ZO_SavedVars versioning, then declaring that's too much and saying no versioning is needed.I was trying to think of how to lay it out clearer, and ended up pretty much dry-coding the whole thing...
Sample upgrade function, showing it upgrade in-place.
|ESOUI » AddOns » Alpha/Beta AddOns » work in progress - libASV (Advanced Saved Variables)|