Search Unity

delegates/function pointers

Discussion in 'Scripting' started by RickP, Apr 30, 2010.

  1. RickP

    RickP

    Joined:
    Apr 4, 2010
    Posts:
    262
    are there delegates or function pointers for Unity javascript? If so how do I use them?
     
  2. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Yes there are.

    Just assign the function to a variable
     
  3. RickP

    RickP

    Joined:
    Apr 4, 2010
    Posts:
    262
    Is there any sort of type for that?
     
  4. RickP

    RickP

    Joined:
    Apr 4, 2010
    Posts:
    262
    Bump. Anyone know what type this would be declared as? I want to create an array of function pointers/delegates.
     
  5. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    you normally declare arrays as : Array not [] style on JS so it shouldn't be a problem.

    but if thats not fine for you do a bit of experimentation with #pragma strict enabled, I'm sure it will throw you an error directly if the type is not fine :)
     
  6. Quietus2

    Quietus2

    Joined:
    Mar 28, 2008
    Posts:
    2,058
    I believe internally mono uses a class of type Object for this. Sort of a high level container class similar to how Unity uses the gameObject class.

    You could always set myVar = myFunc then see what GetType makes of it to be sure.
     
  7. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Normally mono use delegates for function pointers but I'm not sure if the type delegate is required for JS
     
  8. jmpp

    jmpp

    Joined:
    Jun 1, 2010
    Posts:
    93
    From what I know, Unity's JS does not support declaring delegate types, like we can in C#, or at least not yet...

    One thing you can do, though, is declare function types, as was alluded here in this discussion:

    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4.  
    5. class Foo extends MonoBehaviour
    6. {
    7.  
    8.     private var functionPointer : function(SomeType) : SomeOtherType;
    9.  
    10.  
    11.     function Start()
    12.     {
    13.         if (someCondition)
    14.         {
    15.             functionPointer = FirstMethod;
    16.         }
    17.         else
    18.         {
    19.             functionPointer = SecondMethod;
    20.         }
    21.     }
    22.  
    23.  
    24.     function Update()
    25.     {
    26.         functionPointer();
    27.     }
    28.  
    29.  
    30.     function FirstMethod(aParam : SomeType) : SomeOtherType
    31.     {
    32.         // do whatever, return a SomeOtherType variable appropriately.
    33.     }
    34.  
    35.  
    36.     function SecondMethod(aParam : SomeType) : SomeOtherType
    37.     {
    38.         // do whatever, return a SomeOtherType variable appropriately.
    39.     }
    40.  
    41. }
    42.  
    Here the functionPointer variable is declared to be of type "function taking a parameter of type SomeType and returning a value of type SomeOtherType", which as far as I can see pretty much works just like declaring a delegate type in C# since in both approaches you have to define a method signature and stick to it (just as you would declare a function pointer with a defined function prototype/signature in good 'ol C and only assign functions that stick to it).

    Both First Second methods adhere to the specified signature and therefore can be freely assigned to the functionPointer variable, which gets called as a method itself in Update() every frame. This example is of course rather simplistic, you could just as easily place the if (someCondition) block in Update and call the methods directly, but if performing that test only once is possible then why not leverage that performance enhancement? I'm sure more elaborate examples and uses will make function types shine just as much as full-blown C# delegates.

    HTH! Regards,


    - jmpp
     
  9. jmpp

    jmpp

    Joined:
    Jun 1, 2010
    Posts:
    93
    Two things I forgot to say are that:

    1) The function type variables are a Unity 3.x thing, but being already at 3.3 and with 3.4 close at bay I'm sure the majority of us are already in the clear.

    2) When any of the components of your function type are void you have to be a bit careful, i.e.:

    Code (csharp):
    1.  
    2. var functionPointer : function();
    3.  
    If you don't want your function prototype to take any arguments then you don't get to declare it as function(void), as that will produce a syntax error (don't ask me why! :p). And if you don't want to return any values then I think you can omit the colon and void return entirely (i.e. use plain function(), not function : void), but I'm sure a little experimentation with the syntax will clear things up.

    The documentation I got this from is the 3.x upgrade details page (JavaScript improvements section):

    http://unity3d.com/support/documentation/Manual/MonoUpgradeDetails.html

    Regards,


    -jmpp
     
  10. TheCheese

    TheCheese

    Joined:
    Nov 25, 2009
    Posts:
    82
    Hi,

    Thanks for illuminating this lesser-known functionality of UnityScript.

    I'm attempting to make a UnityScript - based messaging system with function pointers but I can't seem to figure out the syntax for passing parameters to function pointers stored in a dictionary...here's my code:

    This is the basic code to store an event function pointer with no parameters - it works great :)
    Code (csharp):
    1.  
    2.  
    3. otherScript.js
    4. // add event listener
    5. EventController.AddEvent("testing", Test);
    6.  
    7. // send event
    8. EventController.SendEvent("testing");
    9.  
    10. // test function
    11. function Test(){
    12.     print("test success");
    13. }
    14.  
    15.  
    16. //-------------------------------- EventController.js code
    17. import System.Collections.Generic;
    18.  
    19. static var eventDictionary : Dictionary.<String, ArrayList> = new Dictionary.<String, ArrayList>();
    20.  
    21. // add event  function pointer with no parameters
    22. static function AddEvent(eventName : String, func : Function){
    23.  
    24.     // add function pointer to appropriate ArrayList if event already exists
    25.     if (eventDictionary.ContainsKey(eventName)){
    26.         if (!eventDictionary[eventName].Contains(func)){
    27.             eventDictionary[eventName].Add(func);
    28.         }
    29.     }
    30.     // otherwise create new dictionary entry
    31.     else{
    32.         var newArray : ArrayList = new ArrayList();
    33.         newArray.Add(func);
    34.         eventDictionary.Add(eventName, newArray);
    35.     }
    36. }
    37.  
    38. static function SendEvent(eventName : String){
    39.     for (f in eventDictionary[eventName]){
    40.         (f as Function)();
    41.     }
    42. }
    43.  
    As I said, this works great. However, I'd like to be able to send along some info about an event when it happens - so this is how I tried sending along a parameter based on what I've read on the few posts I've seen about this:
    Code (csharp):
    1.  
    2.  
    3. // OtherScript.js
    4. EventController.AddEvent("testing", ParameterTest);
    5.  
    6. // send event
    7. EventController.SendEvent(ParameterTest, "arg");
    8.  
    9. function ParameterTest(ob : Object){
    10.     print(ob.ToString());
    11. }
    12.  
    13. //------------------------------------
    14. //EventController.js
    15.  
    16. // experimental event with parameter
    17. static function AddEvent(eventName : String, func : function(Object)){
    18.  
    19.     if (eventDictionary.ContainsKey(eventName)){
    20.         if (!eventDictionary[eventName].Contains(func)){
    21.             eventDictionary[eventName].Add(func);
    22.         }
    23.     }
    24.     else{
    25.         var newArray : ArrayList = new ArrayList();
    26.        
    27.         newArray.Add(func);
    28.        
    29.         eventDictionary.Add(eventName, newArray);
    30.     }
    31. }
    32.  
    33. // and to send the event
    34. static function SendEvent(func : function(Object), arg : Object){
    35.  
    36.     func(arg);
    37. }
    38.  
    39.  
    Unfortunatey this doesn't work so well:(

    It gives me this error:
    IndexOutOfRangeException: Array index is out of range.
    CompilerGenerated.__EventController_AddEvent$callable0$27_53__.Call (System.Object[] args) (at Assets/_Scripts/EventController.js:27)

    - line 27 refers to the declaration of the AddEvent function.

    I know it has to be something with the syntax, but its completely foreign to me and I haven't been able to figure it out - any help would be much appreciated!

    Thanks!
     
    Last edited: Jan 14, 2012