• Hi Guest!

    We are extremely excited to announce the release of our first Beta for VaM2, the next generation of Virt-A-Mate which is currently in development.
    To participate in the Beta, a subscription to the Entertainer or Creator Tier is required. Once subscribed, download instructions can be found here.

    Click here for information and guides regarding the VaM2 beta. Join our Discord server for more announcements and community discussion about VaM2.

Question Do we need to use JSONStorable?

henshin

Member
Joined
Dec 29, 2023
Messages
159
Reactions
23
I'm a bit confused about these classes extending JSONStorable, I see they are usually used in UI components (Utils from MacGruber for example)
But are they only required if we need to persiste the state of those components?
I mean if I'm creating components dynamically and use components from MacGruber they will make a mess in the final json creating when saving the scene?

Example:
I'm saving in my plugin the current active morphs in a List (to save keyframe of different facial expressions)
In my UI the user can then select any of those keyframes, the morphs are applied and I want to show a slider for those morphs too so the user can edit them
But I don't need to persist these sliders (or maybe yes, I don't know how to save the state of my plugin with the list of morphs and their settings yet)

I'm doing something like this now:

Code:
private void UpdateCurrentKeyframeMorphs()
        {
            List<DAZMorph> activeExpressionMorphs = GetAllActiveMorphs(true);
            MorphKeyFrame frame = morphFrames[currentKeyframeIndexActive];
            frame.morphsAndValues = new List<MorphUidAndValue>();
            foreach (var morph in activeExpressionMorphs)
            {
                frame.AddMorphAndValue(new MorphUidAndValue(morph.uid, morph.appliedValue, morph.morphName));
            }
        }
        private UIDynamicSlider CreateMorphSlider(DAZMorph morph)
        {
            string morphName = morph.morphName;
            float defaultValue = morph.jsonFloat.defaultVal;
            float min = morph.jsonFloat.min;
            float max = morph.jsonFloat.max;
            JSONStorableFloat storable = new JSONStorableFloat(morphName, defaultValue, min, max, true, true);
            storable.storeType = JSONStorableParam.StoreType.Full;
            UIDynamicSlider slider = this.CreateSlider(storable, true);
            this.RegisterFloat(storable);
            storable.valNoCallback = morph.morphValue;
            // storable.val = morph.morphValue;
            storable.setCallbackFunction += (float newVal) =>
                        {
                            morph.morphValue = newVal;
                            // appliedValue ??
                            UpdateCurrentKeyframeMorphs();
                        };
            return slider;
        }

And when a new Keyframe is selected I remove all the sliders and create new ones:

Code:
private void RefreshMorphSlidersForKeyframe(int selectedKeyframe)
        {
            Utils.RemoveUIElements(this, morphSliders.Cast<object>().ToList());
            morphSliders = new List<UIDynamicSlider>();
            if(selectedKeyframe >= 0 && morphFrames.Count() > selectedKeyframe)
            {
                foreach (MorphUidAndValue muv in morphFrames[selectedKeyframe].morphsAndValues)
                {
                    DAZMorph morph = GetMorphByUid(muv.uid);
                    morphSliders.Add(CreateMorphSlider(morph));
                }
            }
        }

It works fine, but I'm not sure if this is the correct way to work in VAM
 
Classes extending JSONStorables? Wut?

I don't see anything extending a JSONStorable in your code. Only custom sliders which are UI components updating values for a specific JSONStorableFloat.

I actually have trouble understanding your question/issue here. You want to save the data or you don't want to save the data?

Actually, it would be better if you could break down your goal, like :
  1. Update morphs for a character
  2. Save appearance/data
  3. ...etc
... because not knowing your exact goal doesn't help telling you if it's the ideal choice.

Beyong that... did you test your plugin? does it work? do you get the intended result? In local AND .var mode? If the answer is yes, then you're good. Maybe optimizations are possible, but there are dozens of way to do things... result matters, the rest does not. You'll get better and more optimal over time.
 
Upvote 0
Classes extending JSONStorables? Wut?

I don't see anything extending a JSONStorable in your code. Only custom sliders which are UI components updating values for a specific JSONStorableFloat.

I actually have trouble understanding your question/issue here. You want to save the data or you don't want to save the data?

Actually, it would be better if you could break down your goal, like :
  1. Update morphs for a character
  2. Save appearance/data
  3. ...etc
... because not knowing your exact goal doesn't help telling you if it's the ideal choice.

Beyong that... did you test your plugin? does it work? do you get the intended result? In local AND .var mode? If the answer is yes, then you're good. Maybe optimizations are possible, but there are dozens of way to do things... result matters, the rest does not. You'll get better and more optimal over time.

Tested only in local (I don't know how to create a VAR yet)
With classes extending JSONStorable I mean JSONStorableFloat, etc
And my question if it's ok to use that even when I don't want to preserve those sliders, they are dynamic, I'm creating them and destroying when user click some keyframe (this is what I need to preserve, keyframes, not sure how yet).

My problem is to understand the JSONStorable classes, becasue I don't want to store the sliders, but I don't know how to create sliders without JSONStorable, maybe it's not important, just asking to learn something new or to understand it better
 
Upvote 0
You're confusing the data (JSONStorable) and the UI component (Slider).
A slider is not stored, it's only giving a feedback of the JSONStorable data to the user.

You can create a JSONStorableFloat, set it's value, save it, without ever showing a slider to the user.
Check my plugins (for instance VAMStory or VAMMoan 2), you'll see different ways of creating/using JSONStorable.
You can also setup a JSONStorable to not save data like this :

C#:
new JSONStorableString("MyString", "Default"){isStorable=false,isRestorable=false};

One note: be very careful with UI/Sliders etc, having dozens (or more) UI components can kill the frametime. If you're planning on having a huge AI, you will need to make a dynamic UI.
 
Upvote 0
You're confusing the data (JSONStorable) and the UI component (Slider).
A slider is not stored, it's only giving a feedback of the JSONStorable data to the user.

You can create a JSONStorableFloat, set it's value, save it, without ever showing a slider to the user.
Check my plugins (for instance VAMStory or VAMMoan 2), you'll see different ways of creating/using JSONStorable.
You can also setup a JSONStorable to not save data like this :

C#:
new JSONStorableString("MyString", "Default"){isStorable=false,isRestorable=false};

One note: be very careful with UI/Sliders etc, having dozens (or more) UI components can kill the frametime. If you're planning on having a huge AI, you will need to make a dynamic UI.

Yes I know the slider won't be saved, but I thought every JSONStorableX created will be saved automatically (and then recovered too somehow? I don't know how to recover the state of my plugin)
Maybe this is the line:
Code:
this.RegisterFloat(storable);
If I comment that line the slider works fine anyway, and maybe only registered JSONStorableX objects are saved/loaded automatically?
 
Upvote 0
Yes I know the slider won't be saved, but I thought every JSONStorableX created will be saved automatically
My problem is to understand the JSONStorable classes, becasue I don't want to store the sliders, but I don't know how to create sliders without JSONStorable

Are you only starting (as a general concept) with code? Because you clearly stated "store sliders". It's not mean or anything... it's just better to understand each other and use the same terminology. Or maybe you're not a native english speaker?

Yes, a JSONStorable needs to be registered to be saved. You can also create your own save process in the plugin.
 
Upvote 0
Back
Top Bottom