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