/************************************************************************************************************************ 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; } static string attachParentName(alias T, string str)() { alias parent = __traits(parent, T); enum parent_str = parent.stringof; static if(parent_str[0..7] == "module ") { static if(__traits(compiles, __traits(parent, parent))) { return attachParentName!(parent, parent_str[7 .. $] ~ '.' ~ str); } else return parent_str[7 .. $] ~ '.' ~ str; } else static if(parent_str[0..8] == "package ") { static if(__traits(compiles, __traits(parent, parent))) { return attachParentName!(parent, parent_str[8 .. $] ~ '.' ~ str); } else return parent_str[8 .. $] ~ '.' ~ str; } else static if(__traits(compiles, __traits(parent, parent))) { return attachParentName!(parent, parent_str ~ '.' ~ str); } else return parent_str ~ '.' ~ str; } static string fullName(T)() { return attachParentName!(T, T.stringof); }