module bubel.ecs.traits;

import std.traits;

bool isForeachDelegateWithTypes(DG, Types...)()
{
	return is(DG == delegate) && is(ReturnType!DG == int) && is(Parameters!DG == Types);
}

unittest
{
	assert(isForeachDelegateWithTypes!(int delegate(int, int), int, int));
	assert(isForeachDelegateWithTypes!(int delegate(ref int, ref int), int, int));
	assert(!isForeachDelegateWithTypes!(int delegate(double), int, int));
}

/************************************************************************************************************************
	Returns index of Component/Entity array in System's EntitiesData struct
*/
static long getIndexOfTypeInEntitiesData(EntitiesData, Type)()
{
	alias EntitiesDataFields = Fields!(EntitiesData);
	long index = -1;
	foreach (fieldNum, FieldType; Fields!(EntitiesData))
	{

		static if (!isBasicType!(FieldType)) // Not basic type     
		{
				// FieldType should be something like: 'const(SomeComponent)[]'
				enum bool entitiesMatches = is(Type == Unqual!(ForeachType!(FieldType)));
				static if (entitiesMatches)
					{
					index = fieldNum;
					break;
				}
			}
	}
	return index;
}
