[Include] dforeach
#1

dforeach
What is this?
With this include you can easily create, and manage iterators. The include is VERY SIMILAR TO ******' foreach, but the difference is that you can add value between 0 and 2,147,483,647. ofc this include a bit slower than the foreach, because it's based on different logic.


Why this?
Well this include is recommended who want to add arbitrary values to the iterator. Usage is similar to ******' foreach, but the difference is that you need to put a "D" in front of the functions. (example.: Iter_Add -> DIter_Add)


Who created this?
Code:
/*
 *				dforeach 1.0.0
 *	  	All right reserved! By: DrAkE
 *		   Freely redistributable.
 *
 * Owner		: DrAkE
 * Time			: 2014.07.17
 *
 * Thanks to	:
 *			Thiadmer - PAWN.
 *			SA:MP Team past, present, future - SA:MP.
 *			****** - foreach, iterators and functions idea.
 */
Functions
Code:
 * Functions	:
 *          DIterator 		- Create an iterator (example: DIterator:test<10>).
 *          dforeach 		- Loop through an iterator.
 *          DIter_Add 		- Add a value to the iterator.
 *          DIter_Remove 	- Remove a value from the iterator.
 *          DIter_Count 	- Count the iterator items.
 *          DIter_Random 	- Return a random value from the iterator.
 *          DIter_Contain 	- Check if a value is exists in the iterator.
 *          DIter_Sort 		- Sort the iterator's value.
 *          DIter_Clear 	- Clear the iterator's value.
Example for using it
Code:
new DIterator:test<5>;

public OnFilterScriptInit()
{
	DIter_Add(test, 1);
	DIter_Add(test, 2);
	DIter_Add(test, 3);
	DIter_Add(test, 4);
	DIter_Add(test, 5);
	DIter_Add(test, 6);
	
	dforeach(test, azigen)
		printf("Numbers: %d", azigen);
	
	printf("Random: %d", DIter_Random(test));
	printf("Count: %d", DIter_Count(test));
	
	DIter_Sort(test, true);
	
	dforeach(test, azigen)
		printf("Sort: %d", azigen);
	
	DIter_Remove(test, 1);
	
	dforeach(test, azigen)
		printf("After delete: %d", azigen);
		
	return true;
}
Default existing iterators
Code:
Players - contains only the players ID
Bots - contains only the NPCs ID
Characters - containts both players and NPCs ID
Download
Click here


Code (if pastebin is down)
Code:
/*
 *				dforeach 1.0.0
 *	  	All right reserved! € By: DrAkE
 *		   Freely redistributable.
 *
 * Owner		: DrAkE
 * Time			: 2014.07.17
 *
 * Thanks to	:
 *			Thiadmer - PAWN.
 *			SA:MP Team past, present, future - SA:MP.
 *			****** - foreach, iterators and functions idea.
 *
 *
 * Functions	:
 *          DIterator 		- Create an iterator (example: DIterator:test<10>).
 *          dforeach 		- Loop through an iterator.
 *          DIter_Add 		- Add a value to the iterator.
 *          DIter_Remove 	- Remove a value from the iterator.
 *          DIter_Count 	- Count the iterator items.
 *          DIter_Random 	- Return a random value from the iterator.
 *          DIter_Contain 	- Check if a value is exists in the iterator.
 *          DIter_Sort 		- Sort the iterator's value.
 *          DIter_Clear 	- Clear the iterator's value.
 *
 *
 * Existing iterators:
 *			Players 	- Contains only players
 *			Bots 		- Contains only bots
 *			Characters 	- Contains both players and bots
*/

#if defined _dfor_included
	#endinput
#endif	
#define _dfor_included

#define DIteratorArray:%1<%2> %1[%2]
#define DIteratorSizeof:%1<%2> %2(%1)
#define DIteratorType:%1<%2> %2%1
#define DIteratorVariable:%1<%2> DIteratorType:%1<%2>
#define DIteratorSafeIndex:%1<%2> ((%1<0||%1>=%2)?(0):(%1))

/*
 * Name	:
 *		DIterator
 *
 * Type	:
 *		Macro
 *
 * Return:
 *		-
 *
 * Note	:
 *		Create an iterator
 */
#define DIterator:%1<%2> DIteratorVariable:_D_ITER_%1__UTOLSO<>=0,DIteratorVariable:_D_ITER_%1__SZAMLAL<>,dIter:DIteratorVariable:_D_ITER_%1__TOMB<>[%2]={dIter:0xFFFFFFFF, ...}

/*
 * Name	:
 *		dforeach
 *
 * Type	:
 *		Macro
 *
 * Return:
 *		-
 *
 * Note	:
 *		Loop through iterator
 */
#define dforeach(%1,%2) for(new DIteratorVariable:_D_ITER__%1__CIKLUS<>=0xFFFFFFFF,%2=DIteratorArray:_D_ITER_%1__TOMB<0>;((DIteratorVariable:_D_ITER__%1__CIKLUS<++>)<(DIteratorVariable:_D_ITER_%1__SZAMLAL<>))&&((%2=DIteratorArray:_D_ITER_%1__TOMB<(DIteratorSafeIndex:(DIteratorVariable:_D_ITER__%1__CIKLUS<>)<(DIteratorVariable:_D_ITER_%1__SZAMLAL<>)>)>)>0xFFFFFFFF);)

/*
 * Name	:
 *		DIter_Add (wraps DIter_AddEx)
 *
 * Type	:
 *		Macro
 *
 * Return:
 *		0 - if the last added value is the same
 *		1 - if the given value is exists
 *		2 - if the iterator is full
 *		3 - if the value is added successfully
 *
 * Note	:
 *		Add a given value to the iterator
 */
#define DIter_Add(%1,%2) DIter_AddEx(DIteratorVariable:_D_ITER_%1__TOMB<>,%2,DIteratorVariable:_D_ITER_%1__SZAMLAL<>,.last=DIteratorVariable:_D_ITER_%1__UTOLSO<>)

/*
 * Name	:
 *		DIter_Remove (wraps DIter_RemoveEx)
 *
 * Type	:
 *		Macro
 *
 * Return:
 *		0 - if the given value not exists
 *		1 - if the given value successfully removed
 *
 * Note	:
 *		Remove a given value from the iterator, if it exists
 */
#define DIter_Remove(%1,%2) DIter_RemoveEx(DIteratorVariable:_D_ITER_%1__TOMB<>,%2,DIteratorVariable:_D_ITER_%1__SZAMLAL<>,DIteratorVariable:_D_ITER_%1__UTOLSO<>,DIteratorSizeof:_D_ITER_%1__TOMB<sizeof>)

/*
 * Name	:
 *		DIter_Count
 *
 * Type	:
 *		Macro
 *
 * Return:
 *		-
 *
 * Note	:
 *		Count the iterator's existing value
 */
#define DIter_Count(%1) (DIteratorVariable:_D_ITER_%1__SZAMLAL<>)

/*
 * Name	:
 *		DIter_Random
 *
 * Type	:
 *		Macro
 *
 * Return:
 *		-
 *
 * Note	:
 *		Return a random number from the iterator
 */
#define DIter_Random(%1) ((DIteratorVariable:_D_ITER_%1__SZAMLAL<>?(_:DIteratorArray:_D_ITER_%1__TOMB<random(DIteratorVariable:_D_ITER_%1__SZAMLAL<>)>):(0xFFFFFFFF)))

/*
 * Name	:
 *		DIter_Contain
 *
 * Type	:
 *		Macro
 *
 * Return:
 *		-
 *
 * Note	:
 *		Check if the given value is exists in the iterator
 */
#define DIter_Contain(%1,%2) (DIter_FastInArray(DIteratorVariable:_D_ITER_%1__TOMB<>,%2))
//#define DIter_SafeRemove(%1,%2) ((DIteratorArray:_D_ITER_%1__TOMB<(DIteratorVariable:_D_ITER_CIKLUS<>)>==%2?(DIteratorArray:_D_ITER_%1__TOMB<(DIteratorVariable:_D_ITER_CIKLUS<>)>=0xFFFFFFFF,DIter_Remove(%1,%2),DIteratorVariable:_D_ITER_CIKLUS<>--):(1)))

/*
 * Name	:
 *		DIter_Sort (wraps DIter_SortEx)
 *
 * Type	:
 *		Macro
 *
 * Return:
 *		-
 *
 * Note	:
 *		Sort an iterator
 */
#define DIter_Sort(%1,%2) DIter_SortEx(DIteratorVariable:_D_ITER_%1__TOMB<>,%2,DIteratorVariable:_D_ITER_%1__SZAMLAL<>)

/*
 * Name	:
 *		DIter_Clear
 *
 * Type	:
 *		Macro
 *
 * Return:
 *		-
 *
 * Note	:
 *		Delete the iterator's values
 */
#define DIter_Clear(%1) dforeach(%1,DIteratorVariable:_VALTOZO_%1__I_<>)DIteratorArray:_D_ITER_%1__TOMB<(DIteratorVariable:_D_ITER_CIKLUS<>)>=0xFFFFFFFF,DIter_Remove(%1,DIteratorVariable:_VALTOZO_%1__I_<>)

new
/*
 * Name	:
 *		DIterator:Players
 *
 * Size	:
 *		MAX_PLAYERS
 *
 * Type	:
 *		Variable
 *
 * Note	:
 *		Create an iterator for the players
 */
	DIterator:Players<MAX_PLAYERS>,

/*
 * Name	:
 *		DIterator:Bots
 *
 * Size	:
 *		MAX_PLAYERS
 *
 * Type	:
 *		Variable
 *
 * Note	:
 *		Create an iterator for the NPCs
 */
	DIterator:Bots<MAX_PLAYERS>,

/*
 * Name	:
 *		DIterator:Characters
 *
 * Size	:
 *		MAX_PLAYERS
 *
 * Type	:
 *		Variable
 *
 * Note	:
 *		Create an iterator for the players and NPCs
 */
	DIterator:Characters<MAX_PLAYERS>;

/*
 * Name	:
 *		DIter_SortEx
 *
 * Type	:
 *		Function
 *
 * Return:
 *		-
 *
 * Note	:
 *		Sort an iterator
 */
 
stock
	DIter_SortEx(dIter:DIteratorArray:iter<>, DIteratorType:ascendant<bool:> = true, DIteratorType:num<> = DIteratorSizeof:iter<sizeof>)
{
	new DIteratorVariable:i<> = 0xFFFFFFFF,
		DIteratorVariable:j<> = 0xFFFFFFFF,
		DIteratorVariable:temp<> = 0xFFFFFFFF;
	
	for(;DIteratorVariable:i<++> < DIteratorVariable:num<>;)
	{
		for(DIteratorVariable:<>j = (DIteratorVariable:i<> + 1); j < DIteratorVariable:num<>; DIteratorVariable:j<>++)
		{
			if((DIteratorVariable:ascendant<>) ? (DIteratorArray:iter<(DIteratorVariable:i<>)> > DIteratorArray:iter<(DIteratorVariable:j<>)>) : (DIteratorArray:iter<(DIteratorVariable:i<>)> < DIteratorArray:iter<(DIteratorVariable:j<>)>))
			{
				DIteratorVariable:temp<> = DIteratorArray:iter<(DIteratorVariable:i<>)>;
				DIteratorArray:iter<(DIteratorVariable:i<>)> = DIteratorArray:iter<(DIteratorVariable:j<>)>;
				DIteratorArray:iter<(DIteratorVariable:j<>)> = dIter:DIteratorVariable:temp<>;
			}
		}
	}
}

/*
 * Name	:
 *		DIter_AddEx
 *
 * Type	:
 *		Function
 *
 * Return:
 *		0 - if the last added value is the same
 *		1 - if the given value is exists
 *		2 - if the iterator is full
 *		3 - if the value is added successfully
 *
 * Note	:
 *		Add a given value to the iterator, if it not exists
 */

stock
	DIter_AddEx(dIter:DIteratorArray:iter<>, DIteratorType:value<>, DIteratorType:&count<>, DIteratorType:length<> = sizeof(iter), DIteratorType:&last<> = 0)
{
	if(DIteratorType:last<> == DIteratorType:value<>)
	{
		return 0;
	}
		
	if(DIter_FastInArray(DIteratorType:iter<>, DIteratorType:value<>, DIteratorType:.size<> = DIteratorType:length<>))
	{
		return 1;
	}
	
	if((DIteratorVariable:length<> == DIteratorVariable:count<>))
	{
		return 2;
	}

	DIteratorArray:iter<_:(DIteratorVariable:count++<>)> = dIter:DIteratorType:last<> = dIter:DIteratorVariable:value<>;
	
	return 3;
}

/*
 * Name	:
 *		DIter_RemoveEx
 *
 * Type	:
 *		Function
 *
 * Return:
 *		0 - if the given value not exists
 *		1 - if the given value successfully removed
 *
 * Note	:
 *		Remove a given value from the iterator, if it exists
 */

stock
	DIter_RemoveEx(dIter:DIteratorArray:iter<>, DIteratorType:value<>, DIteratorType:&count<>, DIteratorType:&last<> = 0, length = 0xFFFFFFFF)
{
	new DIteratorType:index<>;
	if(!DIter_FastInArray(DIteratorType:iter<>, DIteratorType:value<>, DIteratorType:index<>, DIteratorType:length<>))
	{
		return false;
	}
	
	new DIteratorVariable:i<> = DIteratorType:index<>;

	DIteratorArray:iter<(DIteratorVariable:i<>)> = dIter:0xFFFFFFFF;
	
	if(DIteratorVariable:last<> == DIteratorVariable:value<>)
		DIteratorVariable:last<> = 0xFFFFFFFF;

	new DIteratorVariable:k<> = DIteratorVariable:i<> - 1;
	
	for(;DIteratorVariable:k<++> < DIteratorVariable:count<> - 1;)
	{
		DIteratorArray:iter<(DIteratorVariable:k<>)> = DIteratorArray:iter<(DIteratorVariable:k<>) + 1>;
	}
	
	DIteratorArray:iter<(DIteratorVariable:length<> - 1)> = dIter:0xFFFFFFFF;
	DIteratorVariable:count--<>;
		
	return true;
}

/*
 * Name	:
 *		DIter_FastInArray
 *
 * Type	:
 *		Function
 *
 * Return:
 *		0 - if the given value is not exists in the iterator
 *		1 - if the given value is exists in the iterator
 *
 * Note	:
 *		Search for a given value in the iterator
 */

stock
	DIter_FastInArray(dIter:DIteratorArray:iter<>, DIteratorType:elem<>, DIteratorType:&index<> = 0xFFFFFFFF, DIteratorType:size<> = sizeof(iter))
{
	new DIteratorType:top<> = (size - 1);
	new DIteratorType:bot<> = 0;
	new DIteratorType:p<>;
 
	while(DIteratorType:top<> >= DIteratorType:bot<>)
	{
		DIteratorType:p<> = floatround(((DIteratorType:top<> + DIteratorType:bot<>) / 2), floatround_floor);
		
		if (_:DIteratorArray:iter<(DIteratorVariable:p<>)> < DIteratorType:elem<>)
		{
			DIteratorType:bot<> = DIteratorType:p<> + 1;
		}
		else if (_:DIteratorArray:iter<(DIteratorVariable:p<>)> > DIteratorType:elem<>)
		{
			DIteratorType:top<> = DIteratorType:p<> - 1;
		}
		else
		{
			return true;
		}
	}
 
	return false;
}

/*
 * Name	:
 *		DIter_OnFilterScriptInit
 *
 * Type	:
 *		OnFilterScriptInit hook
 *
 * Return:
 *		-
 *
 * Note	:
 *		Hook the OnFilterScriptInit
 */

#if defined FILTERSCRIPT
	public
		OnFilterScriptInit()
	{
		new
			DIteratorVariable:i<> = 0xFFFFFFFF;
		
		for(;DIteratorVariable:i<++> < MAX_PLAYERS;)
		{
			if(IsPlayerConnected(DIteratorVariable:i<>))
			{
				if(IsPlayerNPC(DIteratorVariable:i<>))
				{
					DIter_Add(Bots, DIteratorVariable:i<>);
				}
				else
				{
					DIter_Add(Players, DIteratorVariable:i<>);
				}
				
				DIter_Add(Characters, DIteratorVariable:i<>);
			}
		}
		
		return
			CallLocalFunction("DIter_OnFilterScriptInit", "");
	}

	#if defined _ALS_OnFilterScriptInit
		#undef OnFilterScriptInit
	#else
		#define _ALS_OnFilterScriptInit
	#endif
	#define OnFilterScriptInit DIter_OnFilterScriptInit
	forward DIter_OnFilterScriptInit();
#else
/*
 * Name	:
 *		DIter_OnGameModeInit
 *
 * Type	:
 *		OnGameModeInit hook
 *
 * Return:
 *		-
 *
 * Note	:
 *		Hook the OnGameModeInit
 */
	public
		OnGameModeInit()
	{
		new
			DIteratorVariable:i<> = 0xFFFFFFFF;
		
		for(;DIteratorVariable:i<++> < MAX_PLAYERS;)
		{
			if(IsPlayerConnected(DIteratorVariable:i<>))
			{
				if(IsPlayerNPC(DIteratorVariable:i<>))
				{
					DIter_Add(Bots, DIteratorVariable:i<>);
				}
				else
				{
					DIter_Add(Players, DIteratorVariable:i<>);
				}
				
				DIter_Add(Characters, DIteratorVariable:i<>);
			}
		}
		
		return
			CallLocalFunction("DIter_OnGameModeInit", "");
	}

	#if defined _ALS_OnGameModeInit
		#undef OnGameModeInit
	#else
		#define _ALS_OnGameModeInit
	#endif
	#define OnGameModeInit DIter_OnGameModeInit
	forward DIter_OnGameModeInit();
#endif

/*
 * Name	:
 *		DIter_OnPlayerConnect
 *
 * Type	:
 *		OnPlayerConnect hook
 *
 * Return:
 *		-
 *
 * Note	:
 *		Hook the OnPlayerConnect
 */
 
public
	OnPlayerConnect(playerid)
{
	if(IsPlayerNPC(playerid))
	{
		DIter_Add(Bots, playerid);
	}
	else
	{
		DIter_Add(Players, playerid);
	}
	
	DIter_Add(Characters, playerid);
	
	return
		CallLocalFunction("DIter_OnPlayerConnect", "d", playerid);
}

#if defined _ALS_OnPlayerConnect
	#undef OnPlayerConnect
#else
	#define _ALS_OnPlayerConnect
#endif
#define OnPlayerConnect DIter_OnPlayerConnect
forward DIter_OnPlayerConnect(playerid);

/*
 * Name	:
 *		DIter_OnPlayerDisconnect
 *
 * Type	:
 *		OnPlayerDisconnect hook
 *
 * Return:
 *		-
 *
 * Note	:
 *		Hook the OnPlayerDisconnect
 */

public
	OnPlayerDisconnect(playerid, reason)
{
	if(IsPlayerNPC(playerid))
	{
		DIter_Remove(Bots, playerid);
	}
	else
	{
		DIter_Remove(Players, playerid);
	}
	
	DIter_Remove(Characters, playerid);
	
	return
		CallLocalFunction("DIter_OnPlayerDisconnect", "dd", playerid, reason);
}

#if defined _ALS_OnPlayerDisconnect
	#undef OnPlayerDisconnect
#else
	#define _ALS_OnPlayerDisconnect
#endif
#define OnPlayerDisconnect DIter_OnPlayerDisconnect
forward DIter_OnPlayerDisconnect(playerid, reason);
Reply
#2

Nice job. So the problem that ****** told about (if you create an iterator like "new Iterator:iter<200>;" and you add a value superior to 200) is not present here ?

But you should delete the "D" at the begin of the natives. It's annoying as hell.


EDIT : You've left a sentence in a different language than English (unfortunately I don't know this language), but it must stand for "function list".

Quote:
Originally Posted by Drake1994
Funkciуk
Reply
#3

Can you run some tests to see how fast it is??

Good work btw. +REP TO YOU
Reply
#4

Quote:
Originally Posted by S4t3K
View Post
Nice job. So the problem that ****** told about (if you create an iterator like "new Iterator:iter<200>;" and you add a value superior to 200) is not present here ?

But you should delete the "D" at the begin of the natives. It's annoying as hell.
Well ******' foreach is very simple. If you create an iterator, like Iterator:iter<10>, then you can just only add value between 0 and 9. I want to keep the "D" at the beggining, because it's different from foreach, but similar to.
Reply
#5

****** should be in the credits too, since you got the idea from him and basically used his syntax.

I'm a bit confused, please attempt to tell me again what this can do that y_iterate can't do again?
Reply
#6

If you use y_iterate, and create an iterator, for example: Iterator:test<10>;
Then you can just only add value between 0 and 9 to the iterator. With this you can add values between 0 and 2,147,483,647. (sorry for the mispelling, and bad English)
Reply
#7

Can we get benchmark tests of ****** foreach and your foreach version? Please.
Reply
#8

Really a completely pointless include there is really no practical application for this and y_iterate is already standard.
Reply
#9

@Pottus : I think you haven't seen the point of the include.

Using y_iterate, this is completely impossible, unlike using this include or using arrays :

pawn Code:
new Iterator:iter<3>;
Iter_Add(iter, 70);
Reply
#10

Quote:
Originally Posted by S4t3K
View Post
@Pottus : I think you haven't seen the point of the include.

Using y_iterate, this is completely impossible, unlike using this include or using arrays :

pawn Code:
new Iterator:iter<3>;
Iter_Add(iter, 70);
There is no application where you would ever NEED even the smallest fraction of an iterator of the max size it is therefore of no PRACTICAL use I mean really what would I use this for?
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)