Help converting and saving json to prefs file

AWWalker

Another White Walker (AWWalker)
Featured Contributor
Messages
423
Reactions
2,420
Points
93
Website
www.patreon.com
Need help saving jsonstorablefloats to a file. How do I create a prefs variable and dump that to be loaded later. This is to store slider data for my plugin
 
I assume you just want a slider in your plugin's UI panel and save that with the scene?
If you have a JSONStorableFloat, you just need to "register" it with your MVRScript class. It will create a trigger (other things in your scene can set the value) and it also automatically saves/loads your value.

C#:
public override void Init()
{
    SetupSliderFloat("MySlider", 0.3f, 0.0f, 1.0f, false);
}

private JSONStorableFloat SetupSliderFloat(string label, float defaultValue, float minValue, float maxValue, bool rightSide)
{
    JSONStorableFloat storable = new JSONStorableFloat(label, defaultValue, minValue, maxValue, true, true);
    storable.storeType = JSONStorableParam.StoreType.Full;
    CreateSlider(storable, rightSide);
    RegisterFloat(storable);
    return storable;
}

If you like full access to saving/loading to handle some custom data, you can also override GetJSON and LateRestoreFromJSON in your MVRScript:
C#:
public override JSONClass GetJSON(bool includePhysical = true, bool includeAppearance = true, bool forceStore = false)
{
    JSONClass jc = base.GetJSON(includePhysical, includeAppearance, forceStore);
    if (includePhysical || forceStore)
    {
        needsStore = true;

        // save your custom data in JSON here
        jc["MyData"].AsInt = 42;
    }

    return jc;
}

public override void LateRestoreFromJSON(JSONClass jc, bool restorePhysical = true, bool restoreAppearance = true, bool setMissingToDefault = true)
{
    base.LateRestoreFromJSON(jc, restorePhysical, restoreAppearance, setMissingToDefault);
    if (!base.physicalLocked && restorePhysical)
    {
        // load your custom data from JSON here
        myData = jc["MyData"].AsInt;
    }
}
 
@MacGruber, Cool beans... going to tinker with this and see where i get. Thanks!!! Once i get around this, i need to do figure the file save gui out to allow users to save prefs with a name.
 
How about a way to get all the registered floats and dump them to a save file to be read later on a new scene with this plugin?
 
I think you are looking for these methods on MVRScript:
C#:
public void SaveJSON(JSONClass jc, string saveName)
public void SaveJSON(JSONClass jc, string saveName, UserActionCallback confirmCallback, UserActionCallback denyCallback, ExceptionCallback exceptionCallback)
public JSONNode LoadJSON(string saveName)
These are just helpers that call the methods with the same names/parameters on SuperController. Keep in mind that allowed save paths for plugins are very restricted for security reasons. I think it was just Custom\PluginData and Saves\PluginData folders, plus the screenshot folder.

You could have a look at IdlePoser how to use this:
  • MacGruber_IdlePoserUI.cs => Look at methods UILoadJSON, UISaveJSONDialog, UISaveJSON as well as from where they are called
  • MacGruber_IdlePoserCore.cs => Look at methods LoadPose and SavePose as well as from where they are called
Sadly there is no VaM documentation, but it's always a good idea to use ILSpy to look at VaM_Data\Managed\Assembly-CSharp.dll. It allows you to look at VaM's codebase, so you see what is possible.
 
Copy that :) I've been using VS2022 to peek at source, i should try ILSpy.
What i need to dump is the allparams to a save file somehow.

I found these in JSONStorable.cs , which has the data i need. Now i just gotta figua out how to dump to writeable / readable format for file. They work for the current session.

C#:
  protected Dictionary<string, JSONStorableParam> allParams;

    public void SaveToStore1()
    {
        copyStore1 = GetJSON(includePhysical: true, includeAppearance: true, forceStore: true);
    }


    public void RestoreAllFromStore1()
    {
        RestoreFromStore1();
    }
 
Thank you thank you thank you!!!!!!!!

I fumbled around source, looking at your code, and peeking and poking the dlls. I finally got it ;) I'm sure there is an easier way then listing all my variables individually. once i figure out how to do the lists, so that it can dynamically save all variables, but this works great now!
Saving
C#:
            JSONClass jc = new JSONClass();
            JSONClass info = new JSONClass();
            info["Format"] = "AWWalker.MultiPass";
            info["Version"].AsInt = GMP_VERSION;
            string creatorName = UserPreferences.singleton.creatorName;
            if (string.IsNullOrEmpty(creatorName))
                creatorName = "Unknown";
            info["Author"] = creatorName;
            jc["Info"] = info;
         
            jc["OverallIntensity"].AsFloat = OverallIntensity.val;
            ...
            ...
            jc["LabMinLLowMorphChangeMax"].AsFloat = LabMinLLowMorphChangeMax.val;

            SaveJSON(jc, path);
Loading
C#:
            JSONClass jc = LoadJSON(path).AsObject;
           
            try { OverallIntensity.val = jc["OverallIntensity"].AsFloat; } catch { SuperController.LogError("Couldn't apply settings to :OverallIntensity"); }
            ...
            ...
            try { LabMinLLowMorphChangeMax.val = jc["LabMinLLowMorphChangeMax"].AsFloat; } catch { SuperController.LogError("Couldn't apply settings to :LabMinLLowMorphChangeMax"); }

Also made it sturdy, so that bad values, or missing morphs don't jack it up on the load. Should i do the same to the save?
 
Also made it sturdy, so that bad values, or missing morphs don't jack it up on the load. Should i do the same to the save?
I would recommend to make your code stable enough that you can rely on having your storables (OverallIntensity, ...) initialized at the point your code could reach the loading/saving code?
You might wanna put a try-catch around the whole loading code, though. E.g. what you load may be malformed because someone clueless edited it by hand, because it was saved with an older version of your plugin (*), etc.

(*) That's where saving a version number within your data becomes helpful, I guess you saw that in IdlePoser ;)
 
Yes, Yes, and Yes! Now that i got the mechanics down, and the functions, and save/load. I can focus on cleaning it up. First real script from ground up for VAM, aside from grabing others code and tweaking. You were MOST helpful. Have you checked it out at all? I'm pretty happy with it's functionality, it was one of those things that bothered me and i wanted it to be different.
 
Now if i can make a slider with a toggle all in one...
IdlePoser and LogicBricks have both various examples of custom UI elements. MacGruber_Utils.cs will help you. E.g. there are some labels with checkboxes plus an X button used for the morph captures in IdlePoser.

Have you checked it out at all?
Nope, I'm busy with other things...:ROFLMAO:...working on LogicBricks.14
 
Back
Top Bottom