[SOLVED] Reloading from save into Texture different thread issues

Started by l2evy, August 30, 2016, 09:49:13 PM

Previous topic - Next topic

l2evy

Working on updating the Storage Crates mod, ran into a bug.

You can start the game, place down the workbenches from the mod and all is ok
However you save, quit, and reloading causes a string of errors and turns both workbenches pink. The main ones I believe are causing it say:

"Tried to get a resource "X" from a different thread. All resources must be loaded in the main thread."

I thought I knew the fix for this from the subtle warnings from the log about [StaticConstructorOnStartup]

I added that at I believe the right spot but it did not solve the prob. I have tried a few different spots and I keep getting the error. The way it was built has a button and animation for changing the workbench into another workbench (switching between packing/un-packing workbenches).

Can anyone please point me in the right direction? I could not find any documentation on that function but from comparing other mods seems to be in the right spot.

Here is the 3 scripts it told me to put it into.

http://dpaste.com/3RX4EG2
http://dpaste.com/3JJNXRH
http://dpaste.com/1YFAKQW

Any help would be much appreciated!
Mod Maintainer/Coder of:

Jaxxa

You have the [StaticConstructorOnStartup] tag. But I think you actually need to load your images inside a Static Constructor.

1000101

As Jaxxa said, you need to actually have a static constructor for that attribute to do anything and you need to load the textures inside the static constructor to resolve the error.
(2*b)||!(2*b) - That is the question.
There are 10 kinds of people in this world - those that understand binary and those that don't.

Powered By

l2evy

Quote from: Jaxxa on August 30, 2016, 09:54:48 PM
You have the [StaticConstructorOnStartup] tag. But I think you actually need to load your images inside a Static Constructor.
Quote from: 1000101 on August 30, 2016, 10:01:52 PM
As Jaxxa said, you need to actually have a static constructor for that attribute to do anything and you need to load the textures inside the static constructor to resolve the error.

Thanks for the guidance you two! I figured there was more to it than just that. So studied abit on static constructors and I believe I got it on right now, but the problem is not going away. So I am still missing something. I made a static constructor from how I understand it from my study, put on the tag above it for loading priority, moved and changed all the references to use the new ones I put inside the static constructor.

Could it be backwards from my initial thought of the StaticConstructorOnStartup was causing the hash collisions? I am getting a TON of hash collisions before I made any changes and the map is flat, could that flow down and cause this other error and my code is alright now? How can I determine which is causing the other or if they both are problems? Every change I started a fresh game > saved > reloaded just to be on the safe side where the old code would not bug out the map completely. I have dabbed in other languages and usually the whole cascading of 1 error causing multiple other errors is for the most part easy to tell most of the time. Why I thought being the hash errors was a ton of them and only a few about image loading. I did not notice the map until I read another post about hash errors and they detailed it makes the map flat.

Another idea now that I think of it..maybe I need to put the actual image calls inside a static container as well not just the images? That might be what it is but I will post this anyways to hopefully help others follow me along.

For reference this string:
Cimages.UnLockIco = ContentFinder<Texture2D>.Get("Things/Building/Ui/Ui_unPack", true);

inside of a static constructor such as


public static ImageLoad1
    {
      Cimages.UnLockIco = ContentFinder<Texture2D>.Get("Things/Building/Ui/Ui_unPack", true);
    }


Here is all my changes I came up with over the past few hours. I am aware there is a StaticConstructorOnStartup on the main class and its likely not needed was just for testing. I have tried with and without it and it was the same either way. Also I think there is another thing wrong with my "public override Graphic Graphic" part.

http://dpaste.com/3JPEPB9
http://dpaste.com/17B2KSX
http://dpaste.com/3591A1K

I appreciate the guidance and any further tips/help! Gonna sleep and continue tomorrow with putting the other part of the code inside of a static constructor as well to see what that does.
Mod Maintainer/Coder of:

Jaxxa

"Fun" Times, For the HashSet errors it looks like you are using a Custom ThingDef "KompressionModThingDefs" in "Crate"

Main discussion about the issue here:
https://ludeon.com/forums/index.php?topic=25249.0

l2evy

Quote from: Jaxxa on August 31, 2016, 02:58:28 AM
"Fun" Times, For the HashSet errors it looks like you are using a Custom ThingDef "KompressionModThingDefs" in "Crate"

Main discussion about the issue here:
https://ludeon.com/forums/index.php?topic=25249.0

Yeah I have determined by switching back to Alpha 14 that my issue with the textures is a problem on its own and the Hash is another hill of beans [Confirmed to be Logic Bug aimed to be fixed in Alpha 15c].

I have been tinkering around all morning, read lots of info on static constructors and being as I did not write this and the guy who did is long gone I really am stumped on how to load them inside a static constructor the way they are implemented now with the current code. I understand from the info I read on how static constructors work and the general idea behind it.

I have tried picking at the code, snipping bits and pieces behind new static classes and changing references to point to the new location and while doing that the code shows no build errors and looks like that would solve it, it still does not work (even with the [StaticConstructorOnStartup] tag above it).

Could someone please review the code and give me a small example with how I should go about this? I really feel like its something only people that are real experienced in C# would get. Once I understand how to load them correctly with how this code is setup it should be smooth sailing fixing the rest. The reason I feel this mod is weird is cause I have looked at everyone elses dlls mods with graphics for items and they seem completely different in such a way I can't seem to grasp exactly how I can base theirs on how to reverse engineer the code I am working with. I have a feeling it is cause of all the wizardry to flipflop 1 workbench into another with a button while you got it highlighted and animation for the graphics while changing, as well as remembering the last state it was in.

I really REALLY appreciate any advice or wisdom on all this mess.
Mod Maintainer/Coder of:

mrofa

public override void SpawnSetup()
    {
      base.SpawnSetup();
      this.powerComp = this.GetComp<CompPowerTrader>();
  LongEventHandler.ExecuteWhenFinished(SS2);
      this.factionthing = this.factionInt;
}

public void SS2()
{
   PackingBenchTierOne.Ui_Pmode1 = ContentFinder<Texture2D>.Get("Things/Building/Ui/Ui_Pack", true);
      PackingBenchTierOne.Ui_Pmode2 = ContentFinder<Texture2D>.Get("Things/Building/Ui/Ui_unPack", true);
      PackingBenchTierOne.TexOpen = GraphicDatabase.Get<Graphic_Single>("Things/Building/Frames/PackingBenchTier1_Open");
      PackingBenchTierOne.TexClosed = GraphicDatabase.Get<Graphic_Single>("Things/Building/Frames/PackingBenchTier1_Closed");
      PackingBenchTierOne.TexResFrames = (Graphic[]) new Graphic_Single[12];
      for (int index = 0; index < 12; ++index)
      {
        PackingBenchTierOne.TexResFrames[index] = GraphicDatabase.Get<Graphic_Single>("Things/Building/Frames/PackingBenchTier1_Frame" + (object) (index + 1));
        PackingBenchTierOne.TexResFrames[index].drawSize = this.Graphic.drawSize;
        PackingBenchTierOne.TexResFrames[index].color = this.Graphic.color;
        PackingBenchTierOne.TexResFrames[index].colorTwo = this.Graphic.colorTwo;
        PackingBenchTierOne.TexResFrames[index].MatSingle.color = this.Graphic.MatSingle.color;
      }
}


This should work for you
All i do is clutter all around.

l2evy

Quote from: mrofa on August 31, 2016, 02:31:11 PM
public override void SpawnSetup()
    {
      base.SpawnSetup();
      this.powerComp = this.GetComp<CompPowerTrader>();
  LongEventHandler.ExecuteWhenFinished(SS2);
      this.factionthing = this.factionInt;
}

public void SS2()
{
   PackingBenchTierOne.Ui_Pmode1 = ContentFinder<Texture2D>.Get("Things/Building/Ui/Ui_Pack", true);
      PackingBenchTierOne.Ui_Pmode2 = ContentFinder<Texture2D>.Get("Things/Building/Ui/Ui_unPack", true);
      PackingBenchTierOne.TexOpen = GraphicDatabase.Get<Graphic_Single>("Things/Building/Frames/PackingBenchTier1_Open");
      PackingBenchTierOne.TexClosed = GraphicDatabase.Get<Graphic_Single>("Things/Building/Frames/PackingBenchTier1_Closed");
      PackingBenchTierOne.TexResFrames = (Graphic[]) new Graphic_Single[12];
      for (int index = 0; index < 12; ++index)
      {
        PackingBenchTierOne.TexResFrames[index] = GraphicDatabase.Get<Graphic_Single>("Things/Building/Frames/PackingBenchTier1_Frame" + (object) (index + 1));
        PackingBenchTierOne.TexResFrames[index].drawSize = this.Graphic.drawSize;
        PackingBenchTierOne.TexResFrames[index].color = this.Graphic.color;
        PackingBenchTierOne.TexResFrames[index].colorTwo = this.Graphic.colorTwo;
        PackingBenchTierOne.TexResFrames[index].MatSingle.color = this.Graphic.MatSingle.color;
      }
}


This should work for you

This is amazing! I adapted it into all the code and works like a DREAM now! Thanks so much mrofa and everyone for helping me in the right direction!
Mod Maintainer/Coder of: