bubel-ecs/source/bubel/ecs/traits.d
Mergul 1a5452d6cc Improve fullName template
fullName now support multi-pararmeter templates
2023-05-24 22:15:05 +02:00

92 lines
No EOL
2.9 KiB
D

/************************************************************************************************************************
Copyright: Copyright © 2018-2023, Dawid Masiukiewicz, Michał Masiukiewicz
License: BSD 3-clause, see LICENSE file in project root folder.
*/
module bubel.ecs.traits;
import std.traits;
/************************************************************************************************************************
Return Component/System/Event unique ID
*/
ref ushort becsID(T)()
{
/// Embed id in struct so export can be added to variable definition
static struct LocalStruct {
export __gshared ushort id = ushort.max;
}
return LocalStruct.id;
}
/************************************************************************************************************************
Return Component/System/Event unique ID
*/
ref ushort becsID(T)(T obj)
{
static if(isPointer!T)return becsID!(PointerTarget!T);
else return becsID!T;
}
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;
}
template fullName(alias T : X!A, alias X, A...)
{
alias parent = __traits(parent, X);
enum fullName = fullName!parent ~ '.' ~ __traits(identifier, X) ~ "!(" ~ fullName!A ~ ")";
}
template fullName(T...)
{
static if(__traits(compiles, __traits(parent, T[0])))
{
alias parent = __traits(parent, T[0]);
enum fullName = fullName!parent ~ '.' ~ __traits(identifier, T[0]) ~ ", " ~ fullName!(T[1 .. $]);
}
else static if(__traits(compiles, __traits(identifier, T[0])))enum fullName = __traits(identifier, T[0]) ~ ", " ~ fullName!(T[1 .. $]);
else enum fullName = T[0].stringof ~ ", " ~ fullName!(T[1 .. $]);
}
template fullName(alias T)
{
static if(__traits(compiles, __traits(parent, T)))
{
alias parent = __traits(parent, T);
enum fullName = fullName!parent ~ '.' ~ __traits(identifier, T);
}
else static if(__traits(compiles, __traits(identifier, T)))enum fullName = __traits(identifier, T);
else enum fullName = T.stringof;
}