| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430 |
- /**--------------------------------------------------------------------------**\
- ===========================
- foreach efficient looping
- ===========================
- Description:
- Provides efficient looping through sparse data sets, such as connected
- players. Significantly improved from the original version to be a generic
- loop system, rather then purely a player loop system. When used for
- players this has constant time O(n) for number of connected players (n),
- unlike standard player loops which are O(MAX_PLAYERS), regardless of the
- actual number of connected players. Even when n is MAX_PLAYERS this is
- still faster.
-
- For extensive documentation on writing and using iterators, see this topic:
-
- http://forum.sa-mp.com/showthread.php?t=481877
-
- Legal:
- Version: MPL 1.1
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- [url]http://www.mozilla.org/MPL/[/url]
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is the YSI foreach include.
-
- The Initial Developer of the Original Code is Alex "Y_Less" Cole.
- Portions created by the Initial Developer are Copyright (C) 2011
- the Initial Developer. All Rights Reserved.
-
- Contributors:
- ZeeX, koolk, JoeBullet/Google63, g_aSlice/Slice
-
- Thanks:
- JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL.
- ZeeX - Very productive conversations.
- koolk - IsPlayerinAreaEx code.
- TheAlpha - Danish translation.
- breadfish - German translation.
- Fireburn - Dutch translation.
- yom - French translation.
- 50p - Polish translation.
- Zamaroht - Spanish translation.
- Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes
- for me to strive to better.
- Pixels^ - Running XScripters where the idea was born.
- Matite - Pestering me to release it and using it.
-
- Very special thanks to:
- Thiadmer - PAWN, whose limits continue to amaze me!
- Kye/Kalcor - SA:MP.
- SA:MP Team past, present and future - SA:MP.
-
- Version:
- 0.4
- Changelog:
- 29/03/15:
- More testing.
- Repaired special iterators.
- 28/03/15:
- Breaking change: "Iter_Add" returns value added, not true/false.
- Breaking change: Special iterators take "cellmin", not "-1".
- Wrote many tests.
- Split in to multiple files.
- Added multi-iterators.
- Officially deprecated "foreach (Player, i)".
- 26/03/15:
- Re-added reverse iterators.
- Added support for extra spaces in "foreach".
- 26/12/13:
- Added sections.
- 17/10/12:
- Fixed a bug that was here but not in "foreach.inc".
- 04/10/12:
- Added a tiny tweak to detect tag-returning iterator functions.
- Added Iter_InternalSize.
- 13/01/12:
- Fixed the count thanks to AndreT.
- 05/01/12:
- Fixed multi-dimensional iterators.
- Fixed "FOREACH_NO_BOTS".
- Made "Iterator:" support multi-dimensional arrays.
- 24/12/11:
- Added _YSI_SPECIAL_DEBUG support.
- Added fix for function iterators.
- Ported back to YSI.
- Changed to use internal YSI "__" natives.
- Fixed calls order by using ALS.
- 31/10/11:
- Changed the underlying loop code to be slightly faster.
- Added support for Iter_SafeRemove, prompting refactoring.
- 17/09/11:
- Fixed arrays under the new syntax.
- 28/04/11:
- Moved iterator identifiers to end of variables.
- Rewrote "foreach" to accept two syntaxes for "foreach (new i : Iter)".
- 16/08/10:
- Removed all the "2" versions of the functions.
- 14/08/10:
- Added Iter_Clear to reset an array.
- 06/08/10:
- Added special array declaration format.
- 18/12/09:
- Added Iter_Func2 functions for multi-dimensional iterators.
- Renamed foreact et al as keywords in the documentation.
- Changed licensing from GPL to MPL.
- 02/09/09:
- Fixed (again) for 0.3.
- Added free slot finding.
- 21/08/09:
- Updated to include random functions.
- Made entirely stand alone.
- Ported to 0.3 (separate version).
- Added automatic callback hook code.
- Removed debug information from stand alone version.
- 06/01/08:
- Added debug information.
- 09/10/07:
- Moved to system.
- 16/09/07:
- Added list sorting.
- Made this part of Y SeRver Includes, not Y Sever Includes.
- Made list sorting optional.
- Fixed version number.
- 08/09/07:
- First version.
- Functions:
- Public:
- OnPlayerDisconnect - Called when a player leaves to remove them.
- OnPlayerConnect - Called when a player connects to add them.
- Core:
- -
- Stock:
- Iter_ShowArray - Displays the contents of the array.
- Iter_AddInternal - Add a value to an iterator.
- Iter_RemoveInternal - Remove a value from an iterator.
- Iter_RandomInternal - Get a random item from an iterator.
- Iter_FreeInternal - Gets the first free slot in the iterator.
- Iter_InitInternal - Initialises a multi-dimensional iterator.
- Static:
- -
- Inline:
- Iter_Create - Create a new iterator value set.
- Iter_Add - Wraps Iter_AddInternal.
- Iter_Remove - Wraps Iter_RemoveInternal.
- Iter_Random - Wraps Iter_RandomInternal.
- Iter_Count - Gets the number of items in an iterator.
- Iter_Debug - Wraps around Iter_ShowArray.
- Iter_Free - Wraps around Iter_FreeInternal.
- Iter_Create2 - Create a new iterator array value set.
- Iter_Add2 - Wraps Iter_AddInternal for arrays.
- Iter_Remove2 - Wraps Iter_RemoveInternal for arrays.
- Iter_Random2 - Wraps Iter_RandomInternal for arrays.
- Iter_Count2 - Gets the number of items in an iterator array.
- Iter_Debug2 - Wraps around Iter_ShowArray for arrays.
- Iter_Free2 - Wraps around Iter_FreeInternal for arrays.
- API:
- -
- Callbacks:
- -
- Hooks:
- Iter_OnPlayerConnect - Hook for the OnPlayerConnect callback.
- Iter_OnPlayerDisconnect - Hook for the OnPlayerDisconnect callback.
- Iter_OnGameModeInit - Only exists to make the code compile correctly...
- Definitions:
- -
- Enums:
- -
- Macros:
- -
- Keywords:
- foreach - Command to loop an iterator.
- foreachex - Like foreach but without a new variable.
- foreach2 - Command to loop through an iterator array.
- foreachex - Like foreach2 but without a new variable.
- Tags:
- Iterator - Declare an iterator.
- Variables:
- Global:
- -
- Static:
- YSI_g_OPC - Records wether Iter_OnPlayerConnect exists for speed.
- YSI_g_OPDC - Records wether Iter_OnPlayerDisconnect exists for speed.
- Commands:
- -
- Compile options:
- YSI_ITTER_NO_SORT - Removed.
- FOREACH_NO_BOTS - Remove the bot iterators for smaller code.
- FOREACH_NO_PLAYERS - Remove all default code for player itteration.
- Operators:
- -
- Iterators:
- Player - List of all players connected.
- Bot - List of all bots (npcs) connected.
- NPC - Alias of Bot.
- Character - All players and bots.
- \**--------------------------------------------------------------------------**/
- /*
- ad88888ba
- d8" "8b ,d
- Y8, 88
- `Y8aaaaa, ,adPPYba, MM88MMM 88 88 8b,dPPYba,
- `"""""8b, a8P_____88 88 88 88 88P' "8a
- `8b 8PP""""""" 88 88 88 88 d8
- Y8a a8P "8b, ,aa 88, "8a, ,a88 88b, ,a8"
- "Y88888P" `"Ybbd8"' "Y888 `"YbbdP'Y8 88`YbbdP"'
- 88
- 88
-
- */
- // "y_iterate" is always higher than "foreach".
- #define _Y_ITERATE_LOCAL_VERSION 42
- #if __Pawn != 0x030A
- #define NO_CUSTOM_WARNINGS
- #endif
- #if !defined _inc_y_iterate
- // The stand-alone version looks for this symbol, even on the new compiler.
- #define _inc_y_iterate
- #endif
- // Extra macro so that those paranoid about accidentally including YSI can
- // ensure it never happens.
- #if defined NEVER_Y_ITERATE
- // Set `FOREACH_VERSION` as equal to whatever the version of the stand-alone
- // include is.
- #define FOREACH_VERSION _FOREACH_LOCAL_VERSION
- #undef _inc_y_iterate
- #undef _Y_ITERATE_LOCAL_VERSION
- #if defined _FOREACH_INC_TEST
- // This is `foreach` testing our version - nothing more need doing.
- #endinput
- #endif
- // Otherwise, include `foreach`. Don't use `#tryinclude`, since they want
- // a version of `foreach` and it would be an error to not give them one.
- #define _FOREACH_NO_TEST
- #include <foreach>
- #endinput
- #endif
- // Foreach is testing us.
- #if defined _FOREACH_INC_TEST
- #if !defined _Y_ITERATE_FOUND
- // Set up so that you can use `FOREACH_VERSION` even if the older
- // stand-alone version doesn't support it.
- #define FOREACH_VERSION _FOREACH_LOCAL_VERSION
- #define _FOREACH_CUR_VERSION _Y_ITERATE_LOCAL_VERSION
- #endif
- #endinput
- #endif
- #if !defined _FOREACH_NO_TEST
- #define _FOREACH_INC_TEST
- // Ignore the broken stand-alone version.
- #define _foreach_included
- #tryinclude <foreach>
- #undef _FOREACH_INC_TEST
- // <foreach> exists - test which is newer.
- #if defined _FOREACH_LOCAL_VERSION
- #if _FOREACH_LOCAL_VERSION > _Y_ITERATE_LOCAL_VERSION
- // Foreach is newer.
- #if defined _inc_foreach
- #undef _inc_foreach
- #endif
- #define _FOREACH_NO_TEST
- // Actually include the code.
- #include <foreach>
- // Mark the include as found and exit.
- #define FOREACH_VERSION _FOREACH_LOCAL_VERSION
- #define _FOREACH_INC_TEST
- #define _Y_ITERATE_FOUND
- #endinput
- #endif
- #elseif defined foreach
- // I made this a warning on compilers that supported them, but that's a
- // silly idea!
- #error The old <foreach> include is no longer compatible with YSI.
- #endif
- #endif
- // Set `FOREACH_VERSION` as this file's version.
- #if defined FOREACH_VERSION
- #undef FOREACH_VERSION
- #endif
- #define FOREACH_VERSION _Y_ITERATE_LOCAL_VERSION
- #define _FOREACH_INC_TEST
- #define _Y_ITERATE_FOUND
- // Remove `_FOREACH_CUR_VERSION` incase someone includes an older version of
- // `foreach` later on that doesn't check if this symbol is already defined.
- #if defined _FOREACH_CUR_VERSION
- #undef _FOREACH_CUR_VERSION
- #endif
- #if !defined _samp_included
- #error "Please include a_samp or a_npc before foreach"
- #endif
- #if defined _YSI_SPECIAL_DEBUG
- #define PS_IS_PLAYER_CONNECTED(%0) (%0 != INVALID_PLAYER_ID)
- #else
- #define PS_IS_PLAYER_CONNECTED IsPlayerConnected
- #endif
- //
- // _FOREACH_BOTS
- //
- // Should the "NPC", "Bot", and "Character" iterators be included by default?
- // Disabled by declaring "FOREACH_NO_BOTS".
- //
- #define _FOREACH_BOTS 0
- #if defined IsPlayerNPC
- #define _FOREACH_BOT
- #if !defined FOREACH_NO_BOTS
- #undef _FOREACH_BOTS
- #define _FOREACH_BOTS 1
- #endif
- #endif
- //
- // _FOREACH_LOCALS
- //
- // Should the "LocalActor" and "LocalVehicle" iterators be included? These only
- // loop through ones created by the current script, instead of through ones
- // created in any script.
- //
- #define _FOREACH_LOCALS 1
- #if defined SendChat || defined FOREACH_NO_LOCALS
- #undef _FOREACH_LOCALS
- #define _FOREACH_LOCALS 0
- #endif
- //
- // _FOREACH_VEHICLES
- //
- // Should the "Vehicle" iterator be included? "Vehicle" loops over all vehicles
- // created on the server, "LocalVehicle" iterates over vehicles created only in
- // the current script. They are the same when "YSI_NO_MASTER" is declared.
- // Disabled by declaring "FOREACH_NO_VEHICLES".
- //
- #define _FOREACH_VEHICLES 1
- #if defined SendChat || defined FOREACH_NO_VEHICLES
- #undef _FOREACH_VEHICLES
- #define _FOREACH_VEHICLES 0
- #endif
- //
- // _FOREACH_ACTORS
- //
- // Should the "Actor" iterator be included? "Actor" loops over all actors
- // created on the server, "LocalActor" iterates over actors created only in the
- // current script. They are the same when "YSI_NO_MASTER" is declared.
- // Disabled by declaring "FOREACH_NO_ACTORS".
- //
- #define _FOREACH_ACTORS 0
- #if defined GetActorPos
- #if !defined FOREACH_NO_ACTORS
- #undef _FOREACH_ACTORS
- #define _FOREACH_ACTORS 1
- #endif
- #endif
- //
- // _FOREACH_PLAYERS
- //
- // Should the "Player" iterator be included? If "_FOREACH_BOTS" is set, the
- // "Player" iterator only loops over human players, "NPC" and "Bot" loop over
- // computer players, and "Character" loops over them all. If "_FOREACH_BOTS" is
- // not set, then the "Player" iterator loops over every player in the server,
- // the same as "Character" would do otherwise, since it has no way to know if a
- // player is human or not. Disabled by declaring "FOREACH_NO_PLAYERS".
- //
- #define _FOREACH_PLAYERS 1
- #if defined SendChat || defined FOREACH_NO_PLAYERS
- #undef _FOREACH_PLAYERS
- #define _FOREACH_PLAYERS 0
- #endif
- //
- // _FOREACH_CHARACTERS
- //
- // Bot or Player iterators included.
- //
- #define _FOREACH_CHARACTERS (_FOREACH_BOTS || _FOREACH_PLAYERS)
- #if !defined BOTSYNC_IS_BOT
- forward Iter_OPDCInternal(playerid);
- #endif
- #include "..\YSI_Internal\y_natives"
- #include "..\YSI_Internal\y_shortfunc"
- #include "..\YSI_Internal\y_compilerpass"
- #include "..\YSI_Core\y_debug"
- #include "y_foreach/impl"
- #if _FOREACH_CHARACTERS || _FOREACH_VEHICLES || _FOREACH_ACTORS
- #include "..\YSI_Coding\y_hooks"
- #endif
- #if _FOREACH_VEHICLES || _FOREACH_ACTORS
- #include "..\YSI_Coding\y_remote"
- #endif
- #include "y_foreach/iterators"
- #if defined YSI_TESTS
- #include "..\YSI_Core\y_testing"
- #include "y_foreach/tests"
- #endif
|