January 28, 2017 Re: Reflection in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to medhi558 | On Saturday, 28 January 2017 at 07:10:27 UTC, medhi558 wrote:
> I have a last question, currently i use :
> if(lc.name.indexOf("protocol.messages") != -1)
If they're all in the same module, you can also use the compile time reflection to scan the module for classes. That's
foreach(memberName; __traits(allMembers, mixin(__MODULE__)))
static if(is(__traits(getMember, mixin(__MODULE__), memberName) : NetworkMessage) {
if(memberName == runtime_string_of_class_name) {
auto msg = new __traits(getMember, mixin(__MODULE__), memberName);
// populate msg
}
}
Or something like that. The compile time stuff works well when everything is in a shared module.
If not, the runtime stuff has methods `base` and `interfaces` you can scan for your class. So like
foreach(c; mod.localClasses
if(c.base is typeid(NetworkMessage) {
// work with it
}
Notice it is typeid for runtime, typeof at compile time, and this only gets direct children of NetworkMessage (though you could walk up the parent list to check more).
|
January 28, 2017 Re: Reflection in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | thank you, the second method works perfectly. I have one last problem, I start thread and in thread Protocol.GetInstance(id) return null while in main thread it works. My class : class ProtocolMessageManager { private static TypeInfo_Class[uint] m_types; shared static this() { foreach(mod; ModuleInfo) { foreach(TypeInfo_Class lc; mod.localClasses) { if(lc.base is typeid(NetworkMessage)) { NetworkMessage c = cast(NetworkMessage)lc.create(); ProtocolMessageManager.m_types[c.MessageId] = lc; } } } } public static NetworkMessage GetInstance(uint id) { auto v = (id in ProtocolMessageManager.m_types); if (v !is null) return cast(NetworkMessage)ProtocolMessageManager.m_types[id].create(); else return null; } } |
Copyright © 1999-2021 by the D Language Foundation