NodeServices

immutable
auto NodeServices = q{ this(string id, Node parent = CoreEngine.get.activeScene.tree) { if (parent is null) { assert(0, "Parent object cannot be null"); } super(id, parent); import std.traits: hasUDA; enum finalClass = __traits(isFinalClass, this); enum abstractClass = __traits(isAbstractClass, this); static if (!(finalClass || abstractClass)) { static assert(0, "A node object class must either be final or abstract!"); } static foreach (i, member; __traits(derivedMembers, typeof(this))) { static if (mixin("hasUDA!(" ~ typeof(this).stringof ~ "." ~ member ~ ", Constructor)")) { enum accessFun = __traits(getProtection, __traits(getMember, this, member)); enum finalFun = __traits(isFinalFunction, __traits(getMember, this, member)); enum abstractFun = __traits(isAbstractFunction, __traits(getMember, this, member)); static if (accessFun == "private" || accessFun == "protected") { static if ((!finalFun || finalClass) && !abstractFun) { static if (member.stringof == "\"_\"") { mixin(member ~ "();"); } else { static assert(0, "NodeObject's constructor must be named '_'!"); } } else { static assert(0, "NodeObject's constructor cannot be final or abstract!"); } } else { static assert(0, "NodeObject's constructor must be private or protected!"); } } } static if (__traits(isFinalClass, this)) { static foreach (el; ["start", "update", "process", "render"]) { static foreach (super_member; __traits(derivedMembers, typeof(super))) { static if (super_member.stringof == "\"" ~ el ~ "\"") { mixin("scene." ~ el ~ "List[id] = this;"); } } static foreach (member; __traits(derivedMembers, typeof(this))) { static if (member.stringof == "\"" ~ el ~ "\"") { mixin("scene." ~ el ~ "List[id] = this;"); } } } } } };

Meta