Results 1 to 4 of 4

[tuto] SCAR: Adding parameters to rule calls

  1. #1

    [tuto] SCAR: Adding parameters to rule calls

    This is for medium-advanced SCAR coders. The goal is to pass parameters to a function that is started by a Rule.

    One of the drawback of rules is apparently you can't call them with params. You have to create a specific function when you want something to be done after some delay.
    Truth is it is possible to add parameters to rules because of some LUA particularities with local datas.

    Add the following code to your SCAR code.
    Code:
    function Rule_AddOneShotPar( LuaFunction, Delay, ...)
    	local RuleCall=function()
    		LuaFunction(unpack(arg))
    	end
    	Rule_AddOneShot(RuleCall,Delay)
    end
    This function works the same way than Rule_AddOneShot() but it allows params in any number to be transfered.

    Basic example: Rule_AddOneShotPar( print, 2, "Hello")

    Another example is to delay a FX. If we want to call a titan_explosion FX in 2 seconds then it can be done with :
    Rule_AddOneShotPar( World_FXEvent, 2, "DATA:Art/events/titan_explosions", Util_ScarPos(0,0) )

    Any functions (hard coded or SCAR) can be called this way.

    Note that there are three drawbacks:
    - functions are lost on reload. The rule will not restart on reload, you will get a warning (not an error) stating that function was not found and that rule could not be restarted.
    - be carefull with tables. They are duplicated when it is string or numbers but NOT for tables. Altering the table will change the rule execution. I am not even mentioning objects...
    - debug can be a bit tricky especially if you play with tables.

    The two first drawbacks can be worked-around but the function will get much more complex.

    I have the feeling this could be useful to some. What do you think of it?
    Last edited by Dark40k; 22nd Nov 08 at 11:21 AM.

  2. #2
    Member Jaguar-Lord's Avatar
    Join Date
    Feb 2007
    Location
    france
    errr...to be honest i do not understand how this is working, but i'm a bit retarded when it comes to pure coding lingo and such oddities. Anyway if you took the time to write it i'm sure it is not without purpose.

  3. #3
    I am going to try an explanation. Sorry if this sounds confusing but I too had problems understanding why it worked.

    The following is all based on LUA particular way to handle data and functions.

    First of all, each time Rule_AddOneShotPar() starts, a new private environment is created for the function to store local variables.
    All the parameters used in the call of Rule_AddOneShotPar are copied into this environment. This is how LUA allows you to change one of the call parameters without this change reflecting in the upper environment (except for tables and functions for which it is more complex). By upper environment I mean the environment from which Rule_AddOneShotPar() was called.

    The local RuleCall function is then created in this environment and, as such, can access data stored in Rule_AddOneShotPar() environment.

    Basically, when Rule_AddOneShotPar terminates, the garbage collector would clear the environment if it is no more of any use.
    Truth it is still used because because RuleCall() still exists and has use of this environment.

    RuleCall() still exists because Rule_AddOneShot() has stored the function to be able to call it (well, not exactly, it is only a pointer to the function, but it is somewhat the same for LUA).

    The conclusion is that the calling variables have been copied and are now attached to RuleCall(). However, they cannot be accessed directly, it should be possible to do it (not tested) using the function getfenv().

    Lastly, "..." is a way to tell LUA that the number of calling parameters is unknown. All the lasting parameters are then duplicated in a table called arg that is stored in the function local environment.
    These parameters can then be passed to another function using the command unpack(arg).
    See this for more details.

    Tables and functions behave differently because they are pointers. The result is that the pointer is duplicated but it still points to the same table. If you change something in the table it will reflect in the RuleCall() execution and vice-versa.

    It is really funny to see how 6 lines of code can do so many things!

  4. #4
    You are a life-saver. And good call on the warning about tables.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

     

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •