All pastes #1538082 Raw Edit

foreach

public cpp v1 · immutable
#1538082 ·published 2009-08-21 19:39 UTC
rendered paste body
/*----------------------------------------------------------------------------*-					===========================					 foreach efficient looping					===========================Description:	Provides functionality to loop efficiently through all connected players.	Removes reliance on both modification of MAX_PLAYERS for more efficient	processing on small servers (although still recommended) and 	IsPlayerConnected.Legal:	Copyright (C) 2007 Alex "Y_Less" Cole	This program is free software; you can redistribute it and/or	modify it under the terms of the GNU General Public License	as published by the Free Software Foundation; either version 2	of the License, or (at your option) any later version.	This program is distributed in the hope that it will be useful,	but WITHOUT ANY WARRANTY; without even the implied warranty of	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the	GNU General Public License for more details.	You should have received a copy of the GNU General Public License	along with this program; if not, write to the Free Software	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,	MA 02110-1301, USA.Version:	0.1.3Changelog:	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:		Itter_ShowArray - Displays the contents of the array.		Itter_AddInternal - Add a value to an itterator.		Itter_RemoveInternal - Remove a value from an itterator.		Itter_RandomInternal - Get a random item from an itterator.	Static:		-	Inline:		Itter_Create - Create a new itterator value set.		Itter_Add - Wraps Itter_AddInternal.		Itter_Remove - Wraps Itter_RemoveInternal.		Itter_Random - Wraps Itter_RandomInternal.		Itter_Count - Gets the number of items in an itterator.	API:		-Callbacks:	-Hooks:	Itter_OnPlayerConnect - Hook for the OnPlayerConnect callback.	Itter_OnPlayerDisconnect - Hook for the OnPlayerDisconnect callback.Definitions:	-Enums:	-Macros:	foreach - Command to loop through all connected players efficiently.	foreachex - Like foreach but without a new variable.Tags:	-Variables:	Global:		-	Static:		-Commands:	-Compile options:	YSI_ITTER_NO_SORT - Doesn't sort itterators, so using them comes out random.Operators:	-Iterators:	Player - List of all players connected.	Bot - List of all bots (npcs) connected.	NPC - Alias of Bot.	Character - All players and bots.-*----------------------------------------------------------------------------*/#if defined _foreach_included	#endinput#endif#define _foreach_included#if !defined _samp_included	#include <a_samp>#endif#if defined IsPlayerNPC	#define _FOREACH_BOT#endif/*----------------------------------------------------------------------------*-Function:	Itter_CreateParams:	name - Itterator identifier.	size - Number of values.Return:	-Notes:	Creates a new itterator start/array pair.-*----------------------------------------------------------------------------*/#define Iter_Create Itter_Create#define Itter_Create(%1,%2) \	new \		YSI_g%1S = -1, \		YSI_g%1C = 0, \		YSI_g%1A[%2] = {-1, ...}/*----------------------------------------------------------------------------*-Function:	Itter_AddParams:	itter - Name of the itterator to add the data to.	value - Value to add to the itterator.Return:	-Notes:	Wrapper for Itter_AddInternal-*----------------------------------------------------------------------------*/#define Iter_Add Itter_Add#define Itter_Add(%1,%2) \	Itter_AddInternal(YSI_g%1S, YSI_g%1C, YSI_g%1A, %2)/*----------------------------------------------------------------------------*-Function:	Itter_RemoveParams:	itter - Name of the itterator to remove data from.	value - Data to remove.Return:	-Notes:	Wrapper for Itter_RemoveInternal-*----------------------------------------------------------------------------*/#define Iter_Remove Itter_Remove#define Itter_Remove(%1,%2) \	Itter_RemoveInternal(YSI_g%1S, YSI_g%1C, YSI_g%1A, %2)/*----------------------------------------------------------------------------*-Function:	Itter_RandomParams:	itter - Name of the itterator to get a random slot from4.Return:	-Notes:	Wrapper for Itter_RandomInternal-*----------------------------------------------------------------------------*/#define Iter_Random Itter_Random#define Itter_Random(%1) \	Itter_RandomInternal(YSI_g%1S, YSI_g%1C, YSI_g%1A)/*----------------------------------------------------------------------------*-Function:	Itter_RandomParams:	itter - Name of the itterator to get a random slot from4.Return:	-Notes:	Wrapper for Itter_RandomInternal-*----------------------------------------------------------------------------*/#define Iter_Random Itter_Random#define Itter_Random(%1) \	Itter_RandomInternal(YSI_g%1S, YSI_g%1C, YSI_g%1A)/*----------------------------------------------------------------------------*-Function:	Itter_CountParams:	itter - Name of the itterator to get a random slot from4.Return:	-Notes:	Returns the number of items in this itterator-*----------------------------------------------------------------------------*/#define Iter_Count Itter_Count#define Itter_Count(%1) \	YSI_g%1C/*----------------------------------------------------------------------------*-Create the internal itterators.-*----------------------------------------------------------------------------*/Itter_Create(Player, MAX_PLAYERS);#if defined _FOREACH_BOT	Itter_Create(Bot, MAX_PLAYERS);	Itter_Create(Character, MAX_PLAYERS);		#define YSI_gNPCS YSI_gBotS	#define YSI_gNPCC YSI_gBotC	#define YSI_gNPCA YSI_gBotA#endif/*----------------------------------------------------------------------------*-Function:	foreachParams:	data - Data to itterate through.	as - Variable to set value to.Return:	-Notes:	Not exactly the same as PHP foreach, just itterates through a list and	returns the value of the current slot but uses that slot as the next index	too.  Variables must be in the form YSI_g<name>S for the start index and	YSI_g<name>A for the data array where <name> is what's entered in data.-*----------------------------------------------------------------------------*/#define foreach(%1,%2) \	for (new %2 = YSI_g%1S; %2 != -1; %2 = YSI_g%1A[%2])/*----------------------------------------------------------------------------*-Function:	foreachexParams:	data - Data to itterate through.	as - Variable to set value to.Return:	-Notes:	Similar to foreach but doesn't declare a new variable for the itterator.-*----------------------------------------------------------------------------*/#define foreachex(%1,%2) \	for (%2 = YSI_g%1S; %2 != -1; %2 = YSI_g%1A[%2])/*----------------------------------------------------------------------------*-Function:	Itter_OnPlayerConnectParams:	playerid - Player who joined.Return:	-Notes:	Adds a player to the loop data.  Now sorts the list too.  Note that I found	the most bizzare bug ever (I *think* it may be a compiler but, but it	requires further investigation), basically it seems that multiple variables	were being treated as the same variable (namely YSI_gBotS and	YSI_gCharacterS were the same and YSI_gBotC and YSI_gCharacterC were the	same).  Adding print statements which reference these variables seem to fix	the problem, and I've tried to make sure that the values will never actually	get printed.-*----------------------------------------------------------------------------*/public OnPlayerConnect(playerid){	#if defined _FOREACH_BOT		if (IsPlayerNPC(playerid))		{			if (!Itter_Add(Bot, playerid))			{				printf("", YSI_gBotS);			}		}		else		{			if (!Itter_Add(Player, playerid))			{				printf("", YSI_gPlayerS);			}		}		if (!Itter_Add(Character, playerid))		{			printf("", YSI_gCharacterS);		}	#else		if (!Itter_Add(Player, playerid))		{			printf("", YSI_gPlayerS);		}	#endif	CallLocalFunction("Itter_OnPlayerConnect", "i", playerid);	return 1;}#define OnPlayerConnect Itter_OnPlayerConnectforward Itter_OnPlayerConnect(playerid);/*----------------------------------------------------------------------------*-Function:	Itter_OnPlayerDisconnectParams:	playerid - Player who left.Return:	-Notes:	Removes a player from the loop data.-*----------------------------------------------------------------------------*/public OnPlayerDisconnect(playerid, reason){	#if defined _FOREACH_BOT		if (IsPlayerNPC(playerid))		{			Itter_Remove(Bot, playerid);		}		else		{			Itter_Remove(Player, playerid);		}		Itter_Remove(Character, playerid);	#else		Itter_Remove(Player, playerid);	#endif	CallLocalFunction("Itter_OnPlayerDisconnect", "ii", playerid, reason);	return 1;}#define OnPlayerDisconnect Itter_OnPlayerDisconnectforward Itter_OnPlayerDisconnect(playerid, reason);/*----------------------------------------------------------------------------*-Function:	Itter_ShowArrayParams:	start - Itterator start point.	members[] - Itterator contents.	size - Number of itterator valuesReturn:	-Notes:	Pure debug function.  Has regular prints not debug prints	as it's only called when debug is on.-*----------------------------------------------------------------------------*/stock Itter_ShowArray(start, members[], size){	static		sString[61];	new		i,		j = 10;	printf("Start: %d", start);	while (i < size)	{		sString[0] = '\0';		while (i < j && i < size)		{			format(sString, sizeof (sString), "%s, %d", sString, members[i]);			i++;		}		printf("Array (%d): %s", j, sString);		j += 10;	}}/*----------------------------------------------------------------------------*-Function:	Itter_RandomInternalParams:	start - Array start index.	count - Number of items in the itterator.	array[] - Itterator data.Return:	-Notes:	Returns a random value from an iterator.-*----------------------------------------------------------------------------*/stock Itter_RandomInternal(start, count, array[]){	if (count == 0)	{		return -1;	}	new		rnd = random(count),		cur = start;	while (cur != -1)	{		if (rnd--)		{			cur = array[cur];		}		else		{			return cur;		}	}	return -1;}/*----------------------------------------------------------------------------*-Function:	Itter_AddInternalParams:	&start - Array start index.	&count - Number of items in the itterator.	array[] - Itterator data.	value - Item to add.Return:	-Notes:	Adds a value to a given itterator set.-*----------------------------------------------------------------------------*/stock Itter_AddInternal(&start, &count, array[], value){	if (array[value] != -1)	{		return 0;	}	++count;	#if defined YSI_ITTER_NO_SORT		array[value] = start;		start = value;	#else		if (start == -1)		{			start = value;		}		else if (start > value)		{			array[value] = start;			start = value;		}		else		{			new				cur = start,				last;			do			{				last = cur;				cur = array[cur];				if (cur > value)				{					array[value] = cur;					array[last] = value;					return 1;				}			}			while (cur != -1);			array[last] = value;		}	#endif	return 1;}/*----------------------------------------------------------------------------*-Function:	Itter_AddInternalParams:	&start - Array start index.	&count - Number of items in the itterator.	array[] - Itterator data.	value - Item to remove.Return:	-Notes:	Removes a value from an itterator.-*----------------------------------------------------------------------------*/stock Itter_RemoveInternal(&start, &count, array[], value){	if (start == -1)	{		return 0;	}	if (start == value)	{		start = array[value];	}	else	{		new			cur = start;		while (array[cur] != value)		{			cur = array[cur];			if (cur == -1)			{				return 0;			}		}		array[cur] = array[value];	}	array[value] = -1;	--count;	return 1;}