Synced/Unsynced Communication

Synced/Unsynced Communication

Discuss Lua based Spring scripts (LuaUI widgets, mission scripts, gaia scripts, mod-rules scripts, scripted keybindings, etc...)

Moderator: Moderators

Post Reply
Freezerburn
Posts: 20
Joined: 26 Jan 2011, 20:25

Synced/Unsynced Communication

Post by Freezerburn »

To start off, I would like to say that yes, I did read this page and the pastbinned code. It looks like it works great. However, it doesn't quite solve the problem that I am having.
What I would like to have is a way to facilitate two-way communication between synced/unsynced portions of a gadget. I'm setting up a regions system that will allow me to cause things to happen when units enter a region. (similar to the pacman map that someone linked me to, but less static regions and more dynamic regions that can be created/destroyed on the fly)

The main problem with this is that of the two-way communication. The Wiki entry and the pastebinned code, as far as I can tell, only go in one direction: synced -> unsynced. This is further made obvious by the test scripts that I wrote, in which I can not find a way to send a newly-defined region from unsynced code to synced code. (I get a nil function, it won't let me write to SYNCED.something, etc.) I'm trying to do this because I would like to be able to draw regions with a mouse in unsynced code, then send it over to the synced code for storage and checking for units. Creating a region would be some combination of using GUI buttons and mouse input to define it, which requires the unsynced code.

If you want me to post any of my code to look at, let me know.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7049
Joined: 16 Nov 2004, 13:08

Re: Synced/Unsynced Communication

Post by zwzsg »

For unsynced -> synced

In the unsynced part use the command: Spring.SendLuaRulesMsg(some_string_of_yours)

In the synced part use the callin: function gadget:RecvLuaMsg(msg,player)

To avoid gadgets wrongly acting on message from other gadgets, it's recommended to put some identifier in your strings.

Here's a small working exemple: http://springrts.com/phpbb/viewtopic.ph ... 3&start=15
Freezerburn
Posts: 20
Joined: 26 Jan 2011, 20:25

Re: Synced/Unsynced Communication

Post by Freezerburn »

Ah ha, I feel dumb now. I noticed those before, but for some reason assumed that all of them were used for transmitting data from one person to all other people as well and that they would incur a large upload overhead from that and was thinking there was another way to do it purely locally or something. (was reading a thread about them, I think they were only talking about SendLuaUIMsg thinking back on it) I will play around with that and see if I can get something working. Much appreciated :mrgreen:
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7049
Joined: 16 Nov 2004, 13:08

Re: Synced/Unsynced Communication

Post by zwzsg »

Freezerburn wrote:I noticed those before, but for some reason assumed that all of them were used for transmitting data from one person to all other people as well and that they would incur a large upload overhead from that and was thinking there was another way to do it purely locally or something.
Yes, but there's no way around that. Think about the very concept of the synced / unsynced split.
Freezerburn
Posts: 20
Joined: 26 Jan 2011, 20:25

Re: Synced/Unsynced Communication

Post by Freezerburn »

zwzsg wrote:
Freezerburn wrote:I noticed those before, but for some reason assumed that all of them were used for transmitting data from one person to all other people as well and that they would incur a large upload overhead from that and was thinking there was another way to do it purely locally or something.
Yes, but there's no way around that. Think about the very concept of the synced / unsynced split.
Yeah I suppose that's true. I'll try to keep messages to a minimum, especially since they'll basically be serializing regions.

I do have a question though: are there any limitations on when messages can be successfully sent/received? I tried doing a test message in a gadget:Initialize and in a gadget:DrawWorld (both of them go through two more functions before it sends the actual message however, Initialize->test_message->add_region->SendLuaRulesMsg, so I don't know if that would be messing with it), and both times I see my debug output saying that it's in the function that sends the message, but then I never see the output from the call-in telling me that it received the message. Any idea why this might be happening?

EDIT: Durrrr, never mind. I should learn to double-check my function names next time, as ReceiveLuaMsg ~= RecvLuaMsg.
Freezerburn
Posts: 20
Joined: 26 Jan 2011, 20:25

Re: Synced/Unsynced Communication

Post by Freezerburn »

Sorry to double-post, but I didn't feel that my question warranted an entirely new thread when it's on the same topic as I posted before.

I've been re-doing my code a good amount, and I currently have communication between an unsynced widget and a synced gadget working properly with nice parsing and everything. However, I seem to be having a small issue with communication between the synced portion of a gadget and an unsynced portion of a gadget. I'm using the technique mentioned in the wiki to set _G.someValue to something, and then access that in the unsynced code via SYNCED.someValue. However, the SYNCED.someValue is giving me nil.

My code is basically this:

Code: Select all

local regions = {}
_G.regions = regions

gadget:RecvLuaMsg(msg)
-- parse stuff, this all works
table.insert(regions, parsedTable)
end

--unsynced section
gadget:DrawWorld()
local regions = SYNCED.regions
--regions is now nil, and the function doesn't run
end
I have also had it where I did a regions[ someName ] = parsedTable, and only have the insert in there just to test if that would make it work. If you need any more code or anything, I'll be happy to pastebin the gadget.
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Synced/Unsynced Communication

Post by knorke »

Code: Select all

_G.regions = regions
everytime you change the regions table in synced, you must do this. It only "sends over" the variable once and does not create a pointer or something like that. You init with local regions = {} and so regions is nil/empty when you send it.

ie you could add it here:

Code: Select all

gadget:RecvLuaMsg(msg)
-- parse stuff, this all works
table.insert(regions, parsedTable)
_G.regions = regions
end
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Synced/Unsynced Communication

Post by jK »

knorke wrote:

Code: Select all

_G.regions = regions
everytime you change the regions table in synced, you must do this. It only "sends over" the variable once and does not create a pointer or something like that. You init with local regions = {} and so regions is nil/empty when you send it.

ie you could add it here:

Code: Select all

gadget:RecvLuaMsg(msg)
-- parse stuff, this all works
table.insert(regions, parsedTable)
_G.regions = regions
end
Incorrect. Tables are handled via reference and not by value.
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Synced/Unsynced Communication

Post by knorke »

ah ok.
i just thought because i saw some gadgets doing something like

Code: Select all

GameFrame()
_G.bla = bla--update unsynced
end
so that is wrong/not nessecary?
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Synced/Unsynced Communication

Post by jK »

yups, unnecessary.

PS: It can be necessary when you create a new table!
Freezerburn
Posts: 20
Joined: 26 Jan 2011, 20:25

Re: Synced/Unsynced Communication

Post by Freezerburn »

So since the tables are handled by reference, and I put the reference into _G.regions, and access it via SYNCED.regions, why am I still getting a nil value in my unsynced section? Is the reference wiped when I access it once, so I have to store it separately and use that? Or is there something else going on?

Edit: Did a quick couple tests to see if certain things would work.
Changed synced portion of code to be:

Code: Select all

table.insert(regions, parsedRegion)
_G.regions = regions
I know jk said it was useless, but I figured I might as well try it anyway just to see if by some quirk that would fix it.
Also change unsynced portion to:

Code: Select all

local regions = nil
gadget:DrawWorld()
regions = SYNCED.regions or regions
--do other stuff, include output the number of times that regions has been non-nil versus nil, and the number of items inside regions, which is 0
So I'm getting a non-nil region now, but I'm not getting any of the stuff that is stored inside it. Hmm...
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Synced/Unsynced Communication

Post by knorke »

maybe post full code then
Freezerburn
Posts: 20
Joined: 26 Jan 2011, 20:25

Re: Synced/Unsynced Communication

Post by Freezerburn »

Here is the entire gadget at pastebin: http://pastebin.com/HWqktM11
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Re: Synced/Unsynced Communication

Post by Tobi »

You want to use spairs instead of pairs/ipairs on the table for iterating it. (It's not a real table but a proxy, hence pairs doesn't work on it.)

See also: http://springrts.com/wiki/Lua_sync_to_unsync
Freezerburn
Posts: 20
Joined: 26 Jan 2011, 20:25

Re: Synced/Unsynced Communication

Post by Freezerburn »

Tobi wrote:You want to use spairs instead of pairs/ipairs on the table for iterating it. (It's not a real table but a proxy, hence pairs doesn't work on it.)

See also: http://springrts.com/wiki/Lua_sync_to_unsync
Ah ha! I never saw that subtle detail when looking at that page before. Much appreciated for pointing that out. :mrgreen:
kfriars
Posts: 36
Joined: 28 Sep 2011, 01:00

Re: Synced/Unsynced Communication

Post by kfriars »

Lua is not recognizing spairs. Anything special I need to do here?
kfriars
Posts: 36
Joined: 28 Sep 2011, 01:00

Re: Synced/Unsynced Communication

Post by kfriars »

SOLVED.

Has to be in a gadget to have access to spairs.
Post Reply

Return to “Lua Scripts”