• 2 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Pawn] YSI Daily Tips
#39
2021-05-21: Pass An Iterator As A Parameter



Sometimes you want to pass an iterator to a function.? Iterators are often global, but they don't have to be, and there are still times when you might want them as generic parameters.? There's no simple way to do this, it wasn't really a design consideration, but it is possible.



Under the hood an iterator is two variables - an array containing the data, and a single variable containing the count (the count is also an array for multi-iterators).? For the iterator Player these are called Iterator@Player and Iter_Count@Player (so you get vaguely readable warnings).? Thus, to receive an iterator in a function as use it within that function you need the following two parameters:



Quote:

MyFunction(Iterator@iter[MAX_PLAYERS 1], Iter_Count@iter)

{

____foreach (new i : iter)

____{

____}

}




You can't use the `Iterator:` macro for this, because it also generates initialisation code, but you could create your own.? The size is %1 1 to hold some internal data.? This does mean you have to know what size of iterator you want to pass in advance, because currently foreach uses sizeof a lot internally.? This might be fixable, but isn't currently:



Quote:

#define IterParam:%0<%1> Iterator@%0[%1 1], Iter_Count@%0



MyFunction(IterParam:iter<MAX_PLAYERS>)

{

____foreach (new i : iter)

____{

____}

}




With this code, PASSING the iterator is again fairly straightforward:



Quote:

main()

{

____MyFunction(Iterator@Player, Iter_Count@Player);

}




But we've just changed one nice parameter in to two horrible parameters.? Fortunately the calling side of things is far better defined (since the y_iterate) API functions like Iter_Add already take plain iterators as parameters.? The functions might not be defined nicely, but they can be called nicely.? The macro for this is _ITER, which does all the work detecting which type of iterator was passed (normal or multi), the size and start, and calls an InternalA or InternalB version of another macro depending on normal- or multi-:



Quote:

#define MyFunction _ITER<MyFunction>

#define Iter_MyFunction_InternalA(%0,%1)? ? MyFunction_(_:%1,%0)

#define Iter_MyFunction_InternalB(%0,%2,%1) MyFunction_(_:%1,%0)





This renames MyFunction to MyFunction_, then defines MyFunction as a macro that takes an iterator.? InternalA has two parameters given - the count and array.? InternalB has three parameters given - the count, the start, and the array.? If you want to pass the size of the iterator it's F@s(%1)-F@s(%0).? You can also just call your function? Iter_MyFunction_InternalA and you don't need the extra macros.? If your function takes more parameters after the iterator, they are all passed to the macros/functions in an additional %9 at the end of the parameter list.



Now the call is very simply:



Quote:

main()

{

____MyFunction(Player);

}



Messages In This Thread
YSI Daily Tips - by Y_Less - 2021-05-01, 05:25 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 05:40 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 06:59 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 06:59 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 06:59 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 07:06 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 07:06 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 07:06 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 07:07 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 07:07 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 07:08 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 07:08 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 07:08 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 07:09 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 07:09 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 07:09 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 07:09 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 07:10 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-01, 07:11 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-02, 07:44 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-03, 01:17 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-04, 08:08 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-05, 09:44 AM
RE: YSI Daily Tips - by Y_Less - 2021-05-06, 02:46 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-07, 05:13 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-08, 08:08 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-09, 10:58 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-11, 08:55 AM
RE: YSI Daily Tips - by Y_Less - 2021-05-11, 08:56 AM
RE: YSI Daily Tips - by Y_Less - 2021-05-12, 09:41 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-13, 01:20 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-14, 08:20 PM
RE: YSI Daily Tips - by Y_Less - 2021-05-16, 07:41 AM
RE: YSI Daily Tips - by Y_Less - 2021-05-16, 07:49 AM
RE: YSI Daily Tips - by Y_Less - 2021-05-19, 11:25 AM
RE: YSI Daily Tips - by Y_Less - 2021-05-19, 11:26 AM
RE: YSI Daily Tips - by Y_Less - 2021-05-19, 11:27 AM
RE: YSI Daily Tips - by Y_Less - 2021-05-20, 10:05 AM
RE: YSI Daily Tips - by Y_Less - 2021-06-01, 09:26 AM
RE: YSI Daily Tips - by Y_Less - 2021-06-25, 08:06 PM
RE: YSI Daily Tips - by Y_Less - 2021-11-17, 09:12 PM
RE: YSI Daily Tips - by Y_Less - 2021-11-19, 12:21 AM
RE: YSI Daily Tips - by Y_Less - 2022-12-30, 09:56 PM
RE: YSI Daily Tips - by Y_Less - 2023-01-02, 01:25 AM
RE: YSI Daily Tips - by Y_Less - 2023-01-03, 12:17 AM

Forum Jump: