Communicating between Gadgets

Communicating between Gadgets

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

Moderator: Moderators

Post Reply
User avatar
Maelstrom
Posts: 1950
Joined: 23 Jul 2005, 14:52

Communicating between Gadgets

Post by Maelstrom »

Like the title says, I need some way of communicating from one LuaRules Gadget to another. Can this be done, and if so, how?
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Post by jK »

yes it is,
  • first there is a global table "GG" which you can use. It is recommended if you want to access variables or function with return values.
    please note this is not the way trepan advise!
  • trepan wrote a special oneway custom event interface, the advantage is you can interact with all other synced luas like luaGaia and luaCOB.
    To use it you first have to register a custom event function which handles the new event, you do so with:

    Code: Select all

    gadgetHandler:RegisterGlobal('xyz_event', xyz_event_func)
    and deregister with:

    Code: Select all

    gadgetHandler:DeregisterGlobal('xyz_event')
    where 'xyz_event' is the name of your custom event and xyz_event_func the corresponding function in your gadget.
    Now you call this event from in any gadget with:

    Code: Select all

    if (Script.LuaRules('xyz_event')) then
      Script.LuaRules.xyz_event(arg1,arg2,arg3,...)
    end
  • there is also a Script.LuaUI but it is only accessible in the unsyned section of the gadget. so to fire a global event (to all luas) you have to send the event first to the unsynced section with:

    Code: Select all

    SendToUnsynced("abc_event",arg1,arg2,arg3)
    and handle it with a registered function. to do so use:

    Code: Select all

    gadgetHandler:AddSyncAction("abc_event", abc_event_func)
    and

    Code: Select all

    gadgetHandler:RemoveSyncAction("abc_event")
    or you simple catch all sync->unsynced events with:

    Code: Select all

    function RecvFromSynced(...)
      if (arg[1] == 'myevent') then
        dosomething()
      end
    end
    (don't replace "..." in the argument field of the function, it means that you want to recieve a unknown numbers of arguments which you can access with arg[])
User avatar
Maelstrom
Posts: 1950
Joined: 23 Jul 2005, 14:52

Post by Maelstrom »

Im having a problem with this. I can call and execute functions in other Gadgets successfully, but what ever function called Spring.LuaRules.event() stops executing. I have the following code:

Code: Select all

onUpgrade = function(oldUnitID, newUnitID, _) 
  Spring.Echo("Trasnferring HQ " .. oldUnitID)
  if (Script.LuaRules('HQIDUpdate')) then
    Script.LuaRules.HQIDUpdate(oldUnitID, newUnitID)
  end
  Spring.Echo("Trasnferring HQ Done")
end
The Spring.Echo()'s are there to try and debug this.

Spring.Echo("Trasnferring HQ " .. oldUnitID) is executed, and Spring.LuaRules.HQIDUpdate() is executed, but Spring.Echo("Trasnferring HQ Done") is never executed, and nor is the rest of the function that calls onUpdate. Any idea why?
User avatar
Maelstrom
Posts: 1950
Joined: 23 Jul 2005, 14:52

Post by Maelstrom »

OK, I worked out the problem. It has two parts.

First, global functions can not have more than one argument. If you want to pass more than one argument to a global function, you have to use a table.

Secondly, the global function has to return something. What it returns isn't always guaranteed to return correctly (It appears strings don't return, while tables do).

Just a heads up to whoever else wants to use global functions.
User avatar
Zpock
Posts: 1218
Joined: 16 Sep 2004, 23:20

Post by Zpock »

How do you communicate gadget to widget? It's possible I hope, since widgets are the only way to get user input like mouse clicks. This is essential to writing a gadget that depends on a user interface. Do you use the global events, but with Script.LuaUI?

The 2nd dot is very unclear to me how it works:

Code: Select all

if (Script.LuaRules('xyz_event')) then
  Script.LuaRules.xyz_event(arg1,arg2,arg3,...)
end
What's the purpose of the if here?

Code: Select all

gadgetHandler:RegisterGlobal('xyz_event', xyz_event_func)
Should this be in the gadget that calls the global event, or in the widget that receives it? both?
User avatar
Zpock
Posts: 1218
Joined: 16 Sep 2004, 23:20

Post by Zpock »

Ok, I figured it out, so to answer my own questions and hopefully make this a bit more clear:

You put this in the widget that you want to receive the event:

Code: Select all

function widget:Initialize()
    widgetHandler:RegisterGlobal('myevent', myevent)
end
Should also have the deregistering of course, but that not's so important to just get it to work. You could also put this in some other call then initialize, but for starters that's a good choice I guess.

Then you put this in the gadget that should send stuff over to the widget, in the unsynced part:

Code: Select all

	if (Script.LuaUI('myevent')) then
  		Script.LuaUI.myevent(666)
	end
There's nothing else needed in the gadgets code, and I think the if is to check if the event is registered somewhere.

Finally, to receive the event, put a function like this in your widget:

Code: Select all

local function myevent(nr)
	Spring.Echo(nr)
	return false
end
User avatar
Pressure Line
Posts: 2283
Joined: 21 May 2007, 02:09

Post by Pressure Line »

Zpock wrote:cool lua stuff
you also spelt Transferring wrong, not that it's a biggie.
User avatar
Zpock
Posts: 1218
Joined: 16 Sep 2004, 23:20

Post by Zpock »

Is there anyway to control so that only some players receive from the sendtosynced. For example if you want to send information to one player's UI but not so that other players could use a potential "cheater" unsynced code to receive and sneak peak?
Post Reply

Return to “Lua Scripts”