Exposing and Scribing

Started by Wivex, August 29, 2015, 02:20:33 AM

Previous topic - Next topic

Wivex

I tried to deal with saving my data to the save file, but haven't made it work. I wanted to have my own databate (like OutfitDatabase) which could be carried through save\loads. The variables to be saved are:


public class PresetDatabase : IExposable
    {
        public static List<Preset> presetsList;
        public static Dictionary<Pawn, Preset> assignedPresets;

        public void ExposeData()
        {
            Scribe_Collections.LookList<Preset>(ref presetsList, "presetsList", LookMode.Deep, new object[0]);
            Scribe_Collections.LookDictionary<Pawn, Preset>(ref assignedPresets, "assignedPresets", LookMode.Deep, LookMode.Deep);
        }
    }


Where Preset is:


public class Preset : IExposable
    {
        public string name;
        public Dictionary<WorkTypeDef, int> priority;

        public Preset()
        {
            this.name = string.Empty;
            this.priority = new Dictionary<WorkTypeDef, int>();
        }

        public string Name
        {
            get
            {
                return name ?? string.Empty;
            }
            set
            {
                name = value;
            }
        }

        public void ExposeData()
        {
            Scribe_Values.LookValue<string>(ref name, "name", "unassigned", false);
            Scribe_Collections.LookDictionary<WorkTypeDef, int>(ref priority, "priority", LookMode.DefReference, LookMode.Value);
        }
    }


In result, i haven't got any errors, but neither any data saved (i checked the save file itself too). I've beed adviced to use MapComponents with it's own ExposeData method, but i want to get the understanding why i can't make my own class being exposeable. Could you help me here?

Latta

I might not be able to help you since I had similar problem with Deep scribing back in A10. (Not solved) The difference is that you use LookList with mode Deep.

First, where is this PresetDatabase instantiated? From this part:
Quote from: Wivex on August 29, 2015, 02:20:33 AM
In result, i haven't got any errors, but neither any data saved (i checked the save file itself too). I've beed adviced to use MapComponents with it's own ExposeData method, but i want to get the understanding why i can't make my own class being exposeable. Could you help me here?

I suspect you don't use MapComponent for this?

Wivex

Quote from: Latta on August 29, 2015, 02:43:33 AM
I suspect you don't use MapComponent for this?

Not yet. So far i've wanted to add ExposeData() method using IExposeable interface to my own class itself. Not inheritance from vanilla exposable classes.

Latta

#3
The interface only provide "interface", and does not get called automatically. You should call the interface somewhere, and that's where MapComp is needed.

Let's see OutfitDB you mentioned.
OutfitDatabase is being scribed by Map's ExposeComponents().

Scribe_Deep.LookDeep<TaleManager>(ref this.taleManager, "taleManager", new object[0]);
Scribe_Deep.LookDeep<OutfitDatabase>(ref this.outfitDatabase, "outfitDatabase", new object[0]);
Scribe_Deep.LookDeep<AreaManager>(ref this.areaManager, "areaManager", new object[0]);


So you need to have similar fashion (as a Database), but you can't add anything to existing method, right? There is this though:

Scribe_Collections.LookList<MapComponent>(ref this.components, "components", LookMode.Deep, new object[0]);


The Map saves all MapComponents. So you need to make a MapComp, that has ExposeData, that calls your class' interface ExposeData.
Oh, and please don't forget to add the MapComp you made to Map. Using CCL or your custom class.

Wivex

#4
So not all ExposeData methods are called automatically. Only in vanilla classes and their successors, which have their own ExposeData methods. Good to know.

About look modes and other stuff. Should i scribe all the variables and collections in all used classes, which i want to be saved, hierarchically (In PresetDatabase AND Preset). Or just for the first class with proper look mode only (PresetDatabase).

And what is the difference between Scribe_Deep.LookDeep and Scribe_Collections.LookList ... (..., LookMode.Deep); ?

Latta

#5
Calling DB's ExposeData will also call Preset's ExposeData, as far as you Scribe with Deep mode. (I guess! Never had this deep)

As for the difference:
LookDeep can only looks at one class, while Collection with Deep mode will iterate through the collection and for each of its element, do Deep Scribing. It applies to all other mods: With Reference mode, Scriber will iterate and do Reference Scribing for each one.

Edit: I'm not sure about Dictionary, though. Pawns should be Scribed with Reference mode, while your preset should be with Deep.

Wivex

So for vanilla classes ExposeData is called after loading and before saves, to read\write data in save file?
I can call ExposeData for my custom, not vanilla's successor class after loading when i'm opening my own UI MainTab, where i'm using this class as a database. But how can i call it before save? Can i send a reference to it somewhere, or get info that game is about to be saved?

mipen

When the game loads, it creates an instance of any MapComponent that it can find, and stores them in a list. When the game saves/loads, it calls exposedata for each component in that list. This goes for anything in the game, there are lists of things and buildings and pawns and during save/load their exposedata method is called. Simply implementing the interface doesn't mean it will get called. This is why I suggested you use a MapComponent, as it will be added to the list of MapComponents and saved. Scribe deep is used on things that implement the IExposable interface, and will call their exposedata method during save/load. So the hierarchy of methods calls goes MapComponents list - > your MapComponent database - > your preset class. Exposedata reads and saves what you tell it to, depending on whether the game is saving or loading

Wivex


Fluffy (l2032)

And thanks from me too, this should be stickied somewhere, helped clarify what (deep) scribing actually does.

Fingers crossed I can get it to work!