Results 1 to 19 of 19

Thread: Function Pointers

  1. #1
    Join Date
    Sep 2012
    Location
    Here.
    Posts
    2,007
    Mentioned
    88 Post(s)
    Quoted
    1014 Post(s)

    Default Function Pointers

    Function Pointers: What are They and Why You Should Care

    Foreword:
    Why hello and welcome, everyone! This tutorial focuses on a concept that I have only rarely seen around here. Function Pointers are the idea of treating a procedure (or function) as a variable. That's a difficult concept for most to wrap their minds around, so I will dedicate a section just to try and explain and help you guys out.
    I have seen a very rare few people implement function pointers, and only in cases where "procs" were already defined and the scripter simply redirected them. And even worse, I have never seen any sort of tutorial on them!

    Table of Contents:
    1. What Is a Function Pointer?
    2. When are they used now?
    3. How you can use them to Improve Script Efficiency!
    4. FAQ

    What Is a Function Pointer?
    A function pointer is simply another variable type that represents a place in script memory instead of a dedicated value. So you can treat this "variable" as a dedicated function to solve your problems.
    Why should you care that you can do this instead of just calling the function you want to call? Occasionally, you don't know at compile time what function you want to call. "Well that's just ridiculous, Kevin. I always know what procedure I want to call and when." Wrong (or maybe you weren't thinking that, and in that case I'm sorry), and you will see why you're wrong next.

    When are they used now?
    My example will be the only case I have ever seen anyone else knowingly use a Function Pointer:
    Simba Code:
    SRL_Procs[srl_OnRSUpdate]:= @SixHourFix;
    Maybe you haven't seen that situation before, so I'll explain it for you. That right there is how our six hour fix currently works by default. SRLProcs[srl_OnRSUpdate] is a function pointer that will call whatever function it is pointing at when the six hour fix is necessary to be run. Using that you can redirect it to point at your own Six Hour Fix procedure (with a different name) to run your own code. The main thing to note with a function pointer is that when you are pointing your variable at a procedure, you must add an at symbol '@' prior to the name of the procedure you plan on pointing at. So let's give a very quick example based on the previous:
    Simba Code:
    procedure RestartSmart;
    begin
    //Your custom smart restart code
    end;

    begin
      SRL_Procs[srl_OnRSUpdate]:= @RestartSmart;
      //Your normal code
    end.
    Well that's a fairly simple example, but it should give the basic syntax of existing scenarios for you. This still seems fairly limited though to most people, I mean outside of that one case, why should you care? Because it can improve the runtime of your script and cut down on 'if' and 'case' statements dramatically!

    How you can use them to Improve Script Efficiency!
    Ok, now I'm obviously just messing with you. I mean, how could this stupid and rare scenario ever matter to you? Because it can remove the necessity of 'if' or 'case' statements when your script allows multiple scenarios. Let's look at the idea of a basic AIO mining script. When you see one right now, the code is sorted roughly like this:
    Simba Code:
    const
      MineWhere = 'Lumbridge'; //Pick Lumbridge, Falador, or AlKharid

    procedure MineLumbridge;
    begin
    //mine a rock at lumbridge
    end;

    procedure MineAlKharid;
    begin
    //mine a rock at Al Kharid
    end;

    procedure MineFalador;
    begin
    //mine a rock at Falador
    end;

    procedure BankLumbridge;
    begin
    //bank your ores in Lumbridge
    end;

    procedure BankAlKharid;
    begin
    //bank your ores in Al Kharid
    end;

    procedure BankFalador;
    begin
    //bank your ores in Falador
    end;

    begin
      SetUpSRL;
      DeclarePlayers;
      LoginPlayer;
      repeat
        repeat
          case MineWhere of
            'Lumbridge':MineLumbridge;
            'AlKharid':MineAlKharid;
            'Falador':MineFalador;
          end;
          FindNormalRandoms;
          if(InvFull)then
          begin
            case MineWhere of
              'Lumbridge':BankLumbridge;
              'AlKharid':BankAlKharid;
              'Falador':BankFalador;
            end;
          end;
        until(not loggedIn);
      until(not logInPlayer);
    end.
    Well, that is one possible setup without function pointers, there could be entire methods that handle the whole looping scenario for each city that ends up wasting a lot of re-usable code space. So how could we possibly enchance this with a Function Pointer? Easily, like this:
    Simba Code:
    const
      MineWhere = 'Lumbridge'; //Pick Lumbridge, Falador, or AlKharid

    var
      Mine, Bank: procedure();
    procedure MineLumbridge;//procedures were all declared like normal
    begin
    //mine a rock at lumbridge
    end;

    procedure MineAlKharid;
    begin
    //mine a rock at Al Kharid
    end;

    procedure MineFalador;
    begin
    //mine a rock at Falador
    end;

    procedure BankLumbridge;
    begin
    //bank your ores in Lumbridge
    end;

    procedure BankAlKharid;
    begin
    //bank your ores in Al Kharid
    end;

    procedure BankFalador;
    begin
    //bank your ores in Falador
    end;

    begin
      SetUpSRL;
      DeclarePlayers;
      LoginPlayer;
      case MineWhere of
        'Lumbridge':begin
          Mine:= @MineLumbridge;//Setting the variable is where you see that '@'
          Bank:= @BankLumbridge;
        end;
        'AlKharid':begin
          Mine:= @MineAlKharid;
          Bank:= @BankAlKharid;
        end;
        'Falador':begin
          Mine:= @MineFalador;
          Bank:= @BankFalador;
        end;
      end;
      repeat
        repeat
          Mine();//Finally when you call it, you must add the parenthesis even if you aren't passing it any variables!  It's a syntax requirement.
          FindNormalRandoms;
          if(InvFull)then
            Bank();
        until(not loggedIn);
      until(not logInPlayer);
    end.
    Not only was this code way smaller, but now we got rid of those case statements - thus improving the scripts efficiency! I hope this has helped you and I hope to see these used more often in the future!

    For a far more realistic and useful example, feel free to look here: http://villavu.com/forum/showthread.php?t=104249

    FAQ:
    Ask me some questions and I'll toss them up here.

  2. #2
    Join Date
    Feb 2006
    Location
    Helsinki, Finland
    Posts
    1,395
    Mentioned
    30 Post(s)
    Quoted
    107 Post(s)

    Default

    Awesome little tutorial on function pointers, Kevin!
    I found this really useful, thanks.

  3. #3
    Join Date
    Sep 2012
    Location
    Here.
    Posts
    2,007
    Mentioned
    88 Post(s)
    Quoted
    1014 Post(s)

    Default

    Quote Originally Posted by Janilabo View Post
    Awesome little tutorial on function pointers, Kevin!
    I found this really useful, thanks.
    Thank you! I hope it helps somehow and the appreciation has an extra kicker coming from a SSRL

  4. #4
    Join Date
    Oct 2006
    Location
    Netherlands
    Posts
    3,285
    Mentioned
    105 Post(s)
    Quoted
    494 Post(s)

    Default

    Nice tut. I am sure it will help some people!

    Just a few things:

    It would be nice/better if a var/const holding a funct/proc got something in it's name to indicate this. mineProc or mineF for example.

    In SRL 6 this won't work anymore. The syntax will change slightly and the new way of setting a function to a var would be simply be: mineProc := MyMineFunction;
    Working on: Tithe Farmer

  5. #5
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Good guide!

  6. #6
    Join Date
    May 2013
    Posts
    205
    Mentioned
    1 Post(s)
    Quoted
    85 Post(s)

    Default

    learned about pointers back when i was using c++, this was a good reminder of the power of pointers

  7. #7
    Join Date
    Sep 2012
    Location
    Australia.
    Posts
    839
    Mentioned
    16 Post(s)
    Quoted
    225 Post(s)

  8. #8
    Join Date
    Feb 2006
    Location
    Canada
    Posts
    2,254
    Mentioned
    21 Post(s)
    Quoted
    238 Post(s)

    Default

    I was just checking out your sig since your new cups...very nice tut, did not know how to use these. Btw speaking of efficiency, is it more efficient in a literal sense of faster compile/run time, or just more efficient in terms of coding[tidiness]? @Kevin
    Last edited by cause; 07-26-2013 at 01:01 AM.

  9. #9
    Join Date
    Dec 2011
    Location
    New York, USA
    Posts
    1,242
    Mentioned
    12 Post(s)
    Quoted
    193 Post(s)

    Default

    I have never needed to use these... why? cause i'm cool and i know a better way.

    Simba Code:
    CallProc('mine' + minewhere, TVariantArray);
    CallProc('bank' + minewhere, TVariantArray);

    now where's my tut cup, cause i'd consider that a tut on using callproc^

  10. #10
    Join Date
    Sep 2012
    Location
    Here.
    Posts
    2,007
    Mentioned
    88 Post(s)
    Quoted
    1014 Post(s)

    Default

    Quote Originally Posted by cause View Post
    I was just checking out your sig since your new cups...very nice tut, did not know how to use these. Btw speaking of efficiency, is it more efficient in a literal sense of faster compile/run time, or just more efficient in terms of coding[tidiness]? @Kevin
    Depending on the situation, both. It's more efficient simply in tidiness by usually taking up less space, and in any situation when you will repeatedly (or at least a few times) follow the same procedure path, it is a faster run time due to the direct call of the desired function with no possible if checks in the meanwhile. These have other uses as well, this just happens to be the most common application, with another application being like this: http://villavu.com/forum/showthread.php?t=104249
    Quote Originally Posted by Nebula View Post
    I have never needed to use these... why? cause i'm cool and i know a better way.

    Simba Code:
    CallProc('mine' + minewhere, TVariantArray);
    CallProc('bank' + minewhere, TVariantArray);

    now where's my tut cup, cause i'd consider that a tut on using callproc^
    Function pointers are faster than CallProc And besides, if anything since this is my tut page, you adding that should give me the tutorial cup

  11. #11
    Join Date
    Feb 2007
    Location
    PA, USA
    Posts
    5,240
    Mentioned
    36 Post(s)
    Quoted
    496 Post(s)

    Default

    kevin,

    thanks for the tut. But i don't think it is needed in this use-case. Why not have your banking function decide what bank to use based on a const integer that the use set?

  12. #12
    Join Date
    Sep 2012
    Location
    Here.
    Posts
    2,007
    Mentioned
    88 Post(s)
    Quoted
    1014 Post(s)

    Default

    Quote Originally Posted by footballjds View Post
    kevin,

    thanks for the tut. But i don't think it is needed in this use-case. Why not have your banking function decide what bank to use based on a const integer that the use set?
    Because it can be done in things that change mid-script run. As a more complicated example, I had that AIO pickpocketer that changed targets as you levelled up, and as opposed to 8 extra checks every single loop, at the desired level, it would change the pointers once and be done.
    Similarly it was helpful in Slayer when the pointers are changed once per new monster as opposed to checking those every time you needed to do something specific for one.

  13. #13
    Join Date
    Oct 2011
    Posts
    805
    Mentioned
    21 Post(s)
    Quoted
    152 Post(s)

    Default

    They are called *function* pointers, but you don't pass functions ,but only procedures to it?

    Nice tut, but maybe add something about CallProc() too? As it enables to pass arguments to function...

  14. #14
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by Kevin View Post
    Because it can be done in things that change mid-script run. As a more complicated example, I had that AIO pickpocketer that changed targets as you levelled up, and as opposed to 8 extra checks every single loop, at the desired level, it would change the pointers once and be done.
    Similarly it was helpful in Slayer when the pointers are changed once per new monster as opposed to checking those every time you needed to do something specific for one.
    Nice tutorial but I felt a bit mislead?

    I would not use a function pointer like that. However, such statements or comparisons between using a const/enum and a switch vs. a function pointer in terms of efficiency is irrelevant and micro-optimisation.

    For complex algorithms or callbacks, a function pointer is best used. I've only found myself ever using function pointers in callbacks or algorithms like below once:

    Simba Code:
    type Comparator = Function (var A, B): Boolean;


    Procedure Sort(var Arr: TStringArray; Func: Comparator);
    var
      I: Integer;
      T: String;
    begin
      If (@Func = nil) Then Exit;

      For I := 0 To High(Arr) - 1 Do
        If (Func(Arr[I], Arr[I + 1])) Then
        Begin
          T := Arr[I + 1];
          Arr[I + 1] := Arr[I];
          Arr[I] := T;
          I := -1;
        End;
    end;


    Function SmallToLarge(var A, B: String): Boolean;
    Begin
      Result := Length(A) > Length(B);
    End;

    Function LargeToSmall(var A, B: String): Boolean;
    Begin
      Result := Length(A) < Length(B);
    End;

    Function Alphabetically(var A, B: String): Boolean;
    var
      I, M: Integer;
    Begin
      Result := True;
      M := Min(Length(A), Length(B));

      For I := 1 To M Do
        If (A[I] <= B[I]) Then
          Exit(False);
    End;

    var
      Arr: TStringArray;
    begin
      Arr := ['a', 'c', 'dde', 'fdgsgsgs', 'sfds', 'd', 'A', 'B'];

      Sort(Arr, @SmallToLarge);
      Sort(Arr, @Alphabetically);
      Sort(Arr, nil);
      writeln(Arr);
    end.

    In the above example, Comparator is a function pointer with un-typed parameters. Its parameters can be of type int or string or whatever you want to compare. Next we have a sort function that uses that comparator to determine when it should swap indices in an array.
    I made the array parameter strongly typed TStringArray because I wasn't sure how to index an untyped variable without an explicit cast.

    Finally, you just write as many comparators as you wish. You never have to re-write your sort algorithm though. Simply write a function comparing a to b and the sort algorithm takes care of business regardless.

    The advantage here is that you can sort many different types in many different ways without ever touching your sort algorithm.



    Not only was this code way smaller, but now we got rid of those case statements - thus improving the scripts efficiency!
    No it doesn't. A function pointer requires an extra deference and can be a couple cycles slower than a simple branch. A function pointer is almost always coupled with branching because you need to choose when to call or pass said function and believe it or not, you know exactly when to do that at compile time. Notice that in both your examples they still use a case statement. However, the first example is more efficient because it doesn't need to dereference any pointers. Just a direct call. Your second example is exactly the same as the first but you're now dereferencing a pointer. Not only that but in order to even pass/assign the functions, you must also take the address of them as well using the @ address-of operator. I'm still inclined to say they are similar or both exactly the same speed. The difference is negligible/non-existent. You won't notice anything at all.

    Imo the only advantage is in callbacks.

    Again nice tutorial and it's fairly unique as I haven't seen anything on function pointers lately. I think you should get a cup still.


    Here's a another (unsafe casting trick) I found today..

    Simba Code:
    type Comparator = Function (var A, B): Boolean;


    Procedure Sort(var Arr: TIntegerArray; Func: Comparator);
    var
      I: Integer;
      T: Integer;
    begin
      If (@Func = nil) Then Exit;

      For I := 0 To High(Arr) - 1 Do
        If (Func(Arr[I], Arr[I + 1])) Then
        Begin
          T := Arr[I + 1];
          Arr[I + 1] := Arr[I];
          Arr[I] := T;
          I := -1;
        End;
    end;


    Function SmallToLarge(var A, B: String): Boolean;
    Begin
      Result := Length(A) > Length(B);
    End;

    Function LargeToSmall(var A, B: String): Boolean;
    Begin
      Result := Length(A) < Length(B);
    End;

    Function Alphabetically(var A, B: String): Boolean;
    var
      I, M: Integer;
    Begin
      Result := True;
      M := Min(Length(A), Length(B));

      For I := 1 To M Do
        If (A[I] <= B[I]) Then
          Exit(False);
    End;

    Function ISmallToLarge(var A, B: Integer): Boolean;
    Begin
      Result := A > B;
    End;

    var
      Arr: TStringArray;
      Arr2: TIntegerArray;
    begin
      Arr := ['a', 'c', 'dde', 'fdgsgsgs', 'sfds', 'd', 'A', 'B'];
      Arr2 := [9, 10, 11, 8, 7, 3, 12, 15, 6, 4, 5, 13, 14, 2, 1];

      Sort(TIntegerArray(Arr), @SmallToLarge);
      Sort(TIntegerArray(Arr), @Alphabetically);
      writeln(Arr);

      Sort(Arr2, @ISmallToLarge);
      writeln(Arr2);
    end.

    That same sort algorithm now accepts a TIntegerArray for sorting integers but I casted a TStringArray to a TIntegerArray and it sorted it just fine without slicing! Lol.. Doesn't work for records though.
    Last edited by Brandon; 01-14-2014 at 02:06 AM.
    I am Ggzz..
    Hackintosher

  15. #15
    Join Date
    Feb 2007
    Location
    PA, USA
    Posts
    5,240
    Mentioned
    36 Post(s)
    Quoted
    496 Post(s)

    Default

    can you set the procedure to null so it does nothing?
    does this work with lape and pascal?
    does this work with OSRS and RS3?(can it be in both sections of tuts?)
    Last edited by footballjds; 01-14-2014 at 01:40 AM.

  16. #16
    Join Date
    Sep 2012
    Location
    Here.
    Posts
    2,007
    Mentioned
    88 Post(s)
    Quoted
    1014 Post(s)

    Default

    Quote Originally Posted by Brandon View Post
    Nice tutorial but I felt a bit mislead?

    I would not use a function pointer like that. However, such statements or comparisons between using a const/enum and a switch vs. a function pointer in terms of efficiency is irrelevant and micro-optimisation.

    ...
    I was trying to give some basic examples although this may be a better use case scenario for people that I didn't include in OP, but just a later comment: http://villavu.com/forum/showthread.php?t=104249 (I'll add to OP on that note).

    As for efficiency, yes both scenarios have a case, however the function pointer scenario only runs the case once (in the original examples), and as both scenarios will have the guaranteed jump/branch scenario, relying on the dereferencing followed by a guaranteed jump should be faster than a comparison leading to a branch (possibly) and then to a jump.

    Although, I do definitely agree that you should not notice any difference in any reasonable scenario. We are discussing individual computer cycles per loop (nanoseconds). The main advantage in these scenarios is I feel it looks far cleaner.

    As for any cup, I don't think this is really deserving of anything beyond what I have =/

    As for your examples, would you mind if I add the first one (with credits) to the OP?

    Quote Originally Posted by footballjds View Post
    can you set the procedure to null so it does nothing?
    does this work with lape and pascal?
    does this work with OSRS and RS3?(can it be in both sections of tuts?)
    Hm... I dunno what happens when a procedure is set to null in these langauges. Probably throws an exception, although I'm unsure...
    It does work in pascalscript, it should work in lape.
    Technically no reason it can't work with both OSRS and RS3. As I'm looking at it... I never put this in the OSR forums, this was supposed to be in general forums as it is concepts that don't have to apply to RS... I wonder if that happened during the re-org. I'll try and have it moved.


    Edit:
    @Ashaman88, hey there buddy old pal. Would you care to move this to a more generic area? Perhaps something like here: http://villavu.com/forum/forumdisplay.php?f=501 (or maybe another better area that isn't coming to mind offhand).

  17. #17
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by Kevin View Post
    I was trying to give some basic examples although this may be a better use case scenario for people that I didn't include in OP, but just a later comment: http://villavu.com/forum/showthread.php?t=104249 (I'll add to OP on that note).

    As for efficiency, yes both scenarios have a case, however the function pointer scenario only runs the case once (in the original examples), and as both scenarios will have the guaranteed jump/branch scenario, relying on the dereferencing followed by a guaranteed jump should be faster than a comparison leading to a branch (possibly) and then to a jump.

    As for your examples, would you mind if I add the first one (with credits) to the OP?
    I don't mind you adding anything. It is your thread. As for the efficiency, consider that you have this code:

    Simba Code:
    repeat
        repeat
          case MineWhere of             //branch every loop.
            'Lumbridge':MineLumbridge;  //jmp every loop.
            'AlKharid':MineAlKharid;
            'Falador':MineFalador;
          end;
        until(not loggedIn);
    until(not logInPlayer);

    and comparing it to:

    Simba Code:
    case MineWhere of
        'Lumbridge':begin       //branch once at the start of the script
          Mine:= @MineLumbridge; //address of + assignment once at the start of the script
        end;
        'AlKharid':begin
          Mine:= @MineAlKharid;
        end;
        'Falador':begin
          Mine:= @MineFalador;
        end;
    end;
    repeat
        repeat
          Mine(); //dereference + jmp every loop.
        until(not loggedIn);
    until(not logInPlayer);


    In that case, option 2 with the function pointer is indeed more efficient because you did only call the branch code ONCE at the start of the script. Which is cleaner though? The first option looks far cleaner to me :S


    However, consider now that the test is fair below:

    Simba Code:
    var
     m: Integer;
     
     
    case MineWhere of
        'Lumbridge':begin       //branch once at the start of the script
          m:= 1;
        end;
        'AlKharid':begin
          m := 2;
        end;
        'Falador':begin
          m := 3;
        end;
    end;

    repeat
        repeat
          case m of  //branch + jmp every loop.
            1: mineLumby;
            2: mineAlk;
            3: mineFal;
          end;
        until(not loggedIn);
    until(not logInPlayer);


    versus:


    Simba Code:
    case MineWhere of
        'Lumbridge':begin       //branch once at the start of the script
          Mine:= @MineLumbridge;
        end;
        'AlKharid':begin
          Mine:= @MineAlKharid;
        end;
        'Falador':begin
          Mine:= @MineFalador;
        end;
    end;
    repeat
        repeat
          Mine(); //dereference + jmp every loop.
        until(not loggedIn);
    until(not logInPlayer);

    Now that the script is fixed, it is now fair to say that a `branch + jmp` every loop is comparable to a `dereference + jmp` since Simba cannot optimise itself.

    However, +1 from me for cleanliness. I didn't exactly see it in the OP but I see it now.


    Now if you really want the first one to out perform the second one via micro-optimisation, you can simply optimise both algorithms as follows:

    Function Pointer:
    Simba Code:
    case MineWhere of
        1:begin       //branch once at the start of the script
          Mine:= @MineLumbridge;
        end;
        2:begin
          Mine:= @MineAlKharid;
        end;
        3:begin
          Mine:= @MineFalador;
        end;
    end;
    repeat
        repeat
          Mine(); //dereference + jmp every loop.
        until(not loggedIn);
    until(not logInPlayer);


    Enumeration:
    Simba Code:
    repeat
        repeat
          case mineWhere of  //branch + jmp every loop.
            1: mineLumby;
            2: mineAlk;
            3: mineFal;
          end;
        until(not loggedIn);
    until(not logInPlayer);

    This removes the first case statement and the string comparison.. Just a single branch and jmp every loop whereas the first one must first be assigned a pointer via address of then it can dereference + jmp.

    Not only is the Non-Function pointer cleaner but it is also faster by a couple instructions at the start of the script. Runtime speed is the same.


    Benchmark:
    Simba Code:
    var
      E: Integer;
      P: Procedure;


    Procedure Proc;
    begin
      Sleep(10);
    end;

    Procedure Pointers;
    begin
      case E of
        1: P := @(Proc);
      end;
    end;

    Procedure NonePointer;
    begin
      case E of
        1: Proc();
      end;
    end;

    var
      I, T: Integer;
    begin
      E := 1;

      T := GetSystemTime;
      Pointers;

      For I := 0 To 1000 do
      begin
        P();
      end;

      writeln('Time: ', ((GetSystemTime - T) - 10000) / 1000);  //1.016;

      T := GetSystemTime;

      For I := 0 To 1000 do
      begin
        NonePointer();
      end;

      writeln('Time: ', ((GetSystemTime - T) - 10000) / 1000);   //1.015
    end.

    Lol. 1ms doesn't count. The nonpointer wins by a hair lol.. EDIT: Ran it multiple times. Both average out at 1.015 - 1.016 in the above run (lowest for both was actually 1.000).

    Anyway, since the Non-Pointer is clean, I personally will be using that and only using pointers where really necessary such as in your link or my sort.
    Last edited by Brandon; 01-15-2014 at 11:33 PM.
    I am Ggzz..
    Hackintosher

  18. #18
    Join Date
    Dec 2011
    Location
    Hyrule
    Posts
    8,662
    Mentioned
    179 Post(s)
    Quoted
    1870 Post(s)

    Default

    Quote Originally Posted by Kevin View Post
    I was trying to give some basic examples although this may be a better use case scenario for people that I didn't include in OP, but just a later comment: http://villavu.com/forum/showthread.php?t=104249 (I'll add to OP on that note).

    As for efficiency, yes both scenarios have a case, however the function pointer scenario only runs the case once (in the original examples), and as both scenarios will have the guaranteed jump/branch scenario, relying on the dereferencing followed by a guaranteed jump should be faster than a comparison leading to a branch (possibly) and then to a jump.

    Although, I do definitely agree that you should not notice any difference in any reasonable scenario. We are discussing individual computer cycles per loop (nanoseconds). The main advantage in these scenarios is I feel it looks far cleaner.

    As for any cup, I don't think this is really deserving of anything beyond what I have =/

    As for your examples, would you mind if I add the first one (with credits) to the OP?


    Hm... I dunno what happens when a procedure is set to null in these langauges. Probably throws an exception, although I'm unsure...
    It does work in pascalscript, it should work in lape.
    Technically no reason it can't work with both OSRS and RS3. As I'm looking at it... I never put this in the OSR forums, this was supposed to be in general forums as it is concepts that don't have to apply to RS... I wonder if that happened during the re-org. I'll try and have it moved.


    Edit:
    @Ashaman88, hey there buddy old pal. Would you care to move this to a more generic area? Perhaps something like here: http://villavu.com/forum/forumdisplay.php?f=501 (or maybe another better area that isn't coming to mind offhand).
    Would love to but I has no power here

    @Justin

  19. #19
    Join Date
    Mar 2007
    Posts
    5,125
    Mentioned
    275 Post(s)
    Quoted
    901 Post(s)

    Default

    Quote Originally Posted by Ashaman88 View Post
    Would love to but I has no power here

    @Justin
    Done.

    Forum account issues? Please send me a PM

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
  •