How do I share data between different Lua contexts

General Tso

Panzer General
Joined
Oct 12, 2007
Messages
1,548
Location
U. S. of A.
I hope this question makes sense - I admit that I'm somewhat confused with what's happening in my mod and I'm not 100% sure what a Lua context is. Anyway here's the situation as I see it.

My mod creates 4 separate Lua contexts - I need to do it this way because my screen uses the XML LuaContext field to create the extra Lua contexts. I need to share data between the 4 but I can't get it to work. No matter how I use the include statement it doesn't work as I would expect it to and causes problems. Should I be doing it differently? Would LuaEvents work in this situation. Are LuaEvents the best way to handle this?
 
what type / how much data do you need to share ?

in a setup screen Modding.OpenUserData could do the job for simple data

Code:
-- below should be your mod ID, but you can also share data between different mods... 
myModId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 
myModVersion = Modding.GetActivatedModVersion(myModId)
modUserData = Modding.OpenUserData(myModId, myModVersion)

and, for example, this is set during game setup:

Code:
modUserData.SetValue("RedLoading", "Euro1940")

then retrieved later, when loading game:

Code:
g_ScenarioName = modUserData.GetValue("RedLoading")
 
It's a large amount of data. I didn't want to use UserData because it's slow. I can't believe that I'm having this much trouble trying to do something as simple as sharing data between code located in two different files.
 
I just tried using LuaEvents and it worked. I was initially concerned that I would need to create a LuaEvent for every situation where I needed a single piece of data but I found that I can just pass a pointer the my data object between files. I need to do a little more testing but it looks like this is going to work just fine.
 
You don't need to pass a pointer like that. The superglobal MapModData is visible from all your Lua states. You can add new indexes (number or string or whatever) to it just like any another table.

One issue is that it's hard to know which file loads first during mod init. I always do something like this:
Code:
MapModData.gT = MapModData.gT or {}
local gT = MapModData.gT
at the top of each Lua file that is in its own state (e.g., every UI Lua file) that might use gT. This way, the table gT is safely inited only once (regardless of file run order) and each file that contains these lines has a localized pointer to gT (localized = much faster).
 
Thanks for the information. I have things working using LuaEvents so I'll probably just leave it the way it is, but it's always good to find a different way to do something. Just in case a problem arises.

I ran across some posts explaining MapModData while trying to find a solution to my problem. I never got around to trying it because my mod needs the data before game play starts (in Advance Setup) and I wasn't sure if MapModData would be available at that time (due to it name - MapModData). With my current system I just retrieve a pointer to my data object by triggering a LuaEvent in the ShowHide handler for my Popup - that always happens after all of the files in my mod have been loaded.
 
I'm not sure when MapModData comes into existence. I'd guess that it is always there, though I only use if for sharing between my mod's main state and various UI states during gameplay.

Watch out for timing when using multiple states!

Code:
--code from one state:
function TestPrint()
	LuaEvents.LuaEventPrintA()
	print("B")
end



--code from another state:
function PrintA()
	... whatever code ...
	print("A")
end
LuaEvents.LuaEventPrintA.Add(PrintA)

TestPrint() may print A [newline] B as you'd expect, but it may also print B [newline] A. I discovered this when some data sharing between states wasn't working as I expected and I was adding print statements to troubleshoot. I think this has something to do with these states running in parallel (?). So the first state continues to run along happily after the LuaEvent call and prints "B" while PrintA is just getting started. I'm not at all confident about my theory, but I'm quite confident about the observation.

I don't really understand why it sometimes happens and sometimes doesn't. The one case where I'm sure it happens is when my mod's main state calls a popup window (in its own state) using a LuaEvent call. Code right after the LuaEvent call was running before the called function completed.
 
That would defiantly be a concern. I do the following:

Code:
		local buffer = {};
		LuaEvents.GetDataObjects(buffer);
		SlotData = buffer[DATA_SLOT];
		MapData = buffer[DATA_MAP];
		GameData = buffer[DATA_GAME];

So far I haven't had any problems with the three data objects having a nil value. but I will defiantly keep an eye out for that.
 
Back
Top Bottom