Page 1 of 1

Communicating between Gadgets

Posted: 02 Aug 2007, 13:54
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?

Posted: 02 Aug 2007, 16:29
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[])

Posted: 05 Aug 2007, 10:13
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?

Posted: 06 Aug 2007, 05:32
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.

Posted: 29 Sep 2007, 12:18
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?

Posted: 29 Sep 2007, 13:10
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

Posted: 29 Sep 2007, 13:29
by Pressure Line
Zpock wrote:cool lua stuff
you also spelt Transferring wrong, not that it's a biggie.

Posted: 04 Oct 2007, 19:12
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?