/************************************************************************************************************************ 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(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; }