ExposeData() Dictionary but database not loaded

Started by Napoleonite, March 02, 2020, 10:30:21 AM

Previous topic - Next topic

Napoleonite

How do I load&save my
public Dictionary<ThingDef, DrillData> Drillables = new Dictionary<ThingDef, DrillData>();

Note that DrillData inherits IExposable and implements it. The main problem that I have is that DrillData requires the XML-database to be fully loaded before this setting can be loaded. How would I go about this?

Some extra code if it helps (which totally doesn't work at all):

// In my ModSettings:
public Dictionary<ThingDef, DrillData> Drillables = new Dictionary<ThingDef, DrillData>();
        public override void ExposeData()
        {
List<ThingDef> drillableItems = Drillables.Keys.ToList();
            Scribe_Collections.Look<ThingDef>(ref drillableItems, "SEPD_Drillables");
            //Log.Message(keys.Count.ToString());
            drillableItems.ToList()
                .ForEach(td =>
                {
                    if (td != null)
                    {
                        //Log.Message(td.defName);
                        if (!this.Drillables.ContainsKey(td))
                        {
                            this.Drillables.Add(td, new DrillData(td));
                        }
                    }
                    else
                    {
                        Log.Warning("SEPD_OreMissingWarning".Translate().CapitalizeFirst());
                    }
                });
            this.Drillables.Values.ToList().ForEach(d => d.ExposeData());
}


DrillData:
        public void ExposeData()
        {
            Scribe_Defs.Look(ref ThingDefToDrill, Constants.SETTINGS_PREFIX + ThingDefToDrill.defName + "_DefName");
            Scribe_Values.Look(ref WorkAmount, Constants.SETTINGS_PREFIX + ThingDefToDrill.defName + "_WorkAmount", WorkAmount, true);
        }


Hopefully, I'm not too vague or something :P. My English is not that great at this area.

LWM


Napoleonite

#2
Yes that's correct, the Dictionary of DrillData's, which in turn Expose this:
            Scribe_Defs.Look(ref ThingDefToDrill, Constants.SETTINGS_PREFIX + ThingDefToDrill.defName + "_DefName");
            Scribe_Values.Look(ref WorkAmount, Constants.SETTINGS_PREFIX + ThingDefToDrill.defName + "_WorkAmount", WorkAmount, true);


I basically have a dictionary of <ThingDef, DrillData (=CustomClass)> which I need saved & loaded. But ONLY loaded AFTER Rimworld's XML-database is fully initialized. This, however, is not that easy it seems. It almost seems easier to manually serialize the dictionary.

LWM

Yeeeeep.

I'm having the same problem with a list of defs I wanted to store in settings.

The way around it seems to be "save the defNames" and then after defs are loaded (probably using a [StaticConstructorOnStartup] ), resolve the references to actual defs.

I don't recommend trying to simply re-load the settings data - for some reason that was resetting all of it for ppl playing the Steam version of the mod (dunno if that's still true in 1.1).

Napoleonite

#4
I also noticed that it just saves DefNames and when loading it looks them up in the database. However, ExposeData() is called before the database is loaded... Thus the loading fails...

Haha yes, I also simply re-loaded the data thinking I fixed it. And yes, I also noticed that all settings got cleared this way -.-

Solved it by reverting back to strings instead of ThingDefs...

LWM

I think I got it.  Will update with solution once I thoroughly test it.

What, exactly, did you use to try and reload the mod settings after defs had been loaded?

--LWM

LWM

Users are reporting success!!

I realized what was going on: Steam mod names are *different* from non-steam mod names.  I was only searching for the settings file for the non-steam version - the steam version of the mod had a different filename.


    //On DefsLoaded() - this happens in a static method that I know happens after defs are loaded:
    // (a flag has now been set that lets my settings' ExposeData only do stuff with defs only after they are loaded)
    var mod=LoadedModManager.GetMod(typeof(LWM.DeepStorage.DeepStorageMod));
    // "DeepStorageMod"=typeof(DeepStorageMod).Name, by the way:
    var s = LoadedModManager.ReadModSettings<Settings>(mod.Content.FolderName, "DeepStorageMod");


If the Scribe.mode is loading, you can then safely do whatever with the defs that are loaded.  Huzzah!

--LWM