January 28, 2017
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
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;
    }
}
1 2
Next ›   Last »