1 module hunt.imf.core.routing; 2 3 import std.traits; 4 import std.conv; 5 import std.stdint; 6 7 8 struct route 9 { 10 int32_t cmd; 11 } 12 13 struct namespace 14 { 15 string name; 16 } 17 18 alias VoidProcessFunc = void function(ubyte[]); 19 alias VoidProcessDele = void delegate(ubyte[]); 20 21 struct RouterData 22 { 23 VoidProcessFunc func; 24 string className; 25 } 26 27 class Router 28 { 29 __gshared static RouterData[int64_t][string] g_router; 30 31 static void addRouter(string fullClassName , string ns , int64_t value, VoidProcessFunc func) 32 { 33 RouterData data; 34 data.func = func; 35 data.className = fullClassName; 36 g_router[ns][value] = data; 37 } 38 39 static RouterData * findRouter( string ns , int64_t value) 40 { 41 auto updata = ns in g_router; 42 if(updata == null) 43 return null; 44 auto data = value in g_router[ns]; 45 return data; 46 } 47 } 48 49 mixin template MakeRouter(string moduleName = __MODULE__) 50 { 51 mixin("import google.protobuf;"); 52 mixin(__MakeRouter0!(typeof(this))); 53 mixin(__MakeRouter1!(typeof(this) , moduleName)); 54 } 55 56 57 string __MakeRouter0(T)() 58 { 59 string str; 60 foreach (m; __traits(derivedMembers, T)) 61 { 62 foreach( u ; getUDAs!(__traits(getMember , T , m) , route)) 63 { 64 str ~= "void " ~ m ~ "_message(ubyte[] data){"; 65 alias classArr = Parameters!(__traits(getMember , T , m)); 66 static if (classArr.length == 0) 67 { 68 str ~= m ~ "();}"; 69 } 70 else 71 { 72 str ~= "auto proto = new " ~ classArr[0].stringof ~"();"; 73 str ~= "try{ data.fromProtobuf!"~classArr[0].stringof~"(proto); " ~m~ "(proto); }"; 74 str ~= "catch(Throwable e){ import hunt.logging;logError(e.msg);} }"; 75 } 76 } 77 } 78 return str; 79 } 80 81 82 string __MakeRouter1(T , string moduleName)() 83 { 84 string ns = ""; 85 string str = "shared static this(){"; 86 87 foreach(n ; getSymbolsByUDA!(T,namespace)) 88 { 89 if(n.stringof == T.stringof) 90 ns = getUDAs!(n , namespace)[0].name; 91 } 92 93 foreach (m; __traits(derivedMembers, T)) 94 { 95 foreach( u ; getUDAs!(__traits(getMember , T , m) , route)) 96 { 97 str ~= "Router.addRouter(\"" ~ moduleName ~ "." ~ T.stringof ~ "\",\"" ~ ns ~"\" , " ~ to!string(u.cmd) ~ ",&" ~ T.stringof ~ "." ~ m ~ "_message);"; 98 } 99 } 100 str ~= "}"; 101 return str; 102 } 103