1 /* 2 * MsgTrans - Message Transport Framework for DLang. Based on TCP, WebSocket, UDP transmission protocol. 3 * 4 * Copyright (C) 2019 HuntLabs 5 * 6 * Website: https://www.msgtrans.org 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module msgtrans.executor.AbstractExecutor; 13 14 import msgtrans.MessageBuffer; 15 import msgtrans.MessageTransport; 16 import msgtrans.channel.TransportSession; 17 import msgtrans.executor.ExecutorInfo; 18 19 public import msgtrans.executor.Executor; 20 public import msgtrans.executor.MessageId; 21 22 import hunt.logging.ConsoleLogger; 23 import witchcraft; 24 25 import std.algorithm; 26 import std.conv; 27 import std.range; 28 import std.variant; 29 30 31 /** 32 * 33 */ 34 class AbstractExecutor(T) : Executor if (is(T == class)) { 35 36 this() { 37 } 38 39 shared static this() { 40 41 version(HUNT_DEBUG) tracef("Registering %s", T.stringof); 42 Class c = T.metaof; 43 const(Method)[] methods = c.getMethods(); 44 ExecutorInfo[] executors; 45 46 foreach (const Method method; methods ) { 47 // trace(method.toString()); 48 const(Attribute)[] attrs = method.getAttributes!(MessageId)(); 49 // tracef("name: %s, MessageId: %s", method.getName(), method.hasAttribute!(MessageId)()); 50 foreach(const(Attribute) attr; attrs) { 51 // trace(attr.toString()); 52 if(!attr.isExpression()) 53 continue; 54 55 Variant value = attr.get(); 56 // trace(value.type.toString()); 57 MessageId messageId = value.get!(MessageId)(); 58 // trace(messageId.value); 59 60 int messageCode = messageId.value; 61 bool isFound = executors.canFind!((ExecutorInfo a, uint b) => a.messageId() == b)(messageCode); 62 if(isFound) { 63 warningf("message code collision: %d in %s", messageCode, c.getFullName()); 64 } else { 65 // Annoying const 66 executors ~= cast(ExecutorInfo)ExecutorInfo(messageCode, cast(Class)c, cast(Method)method); 67 68 } 69 } 70 } 71 72 // Register executor for Server 73 const(Attribute)[] attrs = c.getAttributes!(TransportServer)(); 74 foreach(const(Attribute) attr; attrs) { 75 // trace(attr.toString()); 76 if(!attr.isExpression()) 77 continue; 78 79 Variant value = attr.get(); 80 // trace(value.type.toString()); 81 TransportServer messageServer = value.get!(TransportServer)(); 82 // trace(messageServer.name); 83 Executor.registerExecutors(TransportServer.NAME_PREFIX ~ messageServer.name, executors); 84 } 85 86 87 // Register executor for Client 88 attrs = c.getAttributes!(TransportClient)(); 89 foreach(const(Attribute) attr; attrs) { 90 // trace(attr.toString()); 91 if(!attr.isExpression()) 92 continue; 93 94 Variant value = attr.get(); 95 // trace(value.type.toString()); 96 TransportClient messageclient = value.get!(TransportClient)(); 97 // trace(messageclient.name); 98 Executor.registerExecutors(TransportClient.NAME_PREFIX ~ messageclient.name, executors); 99 } 100 101 } 102 103 mixin Witchcraft!T; 104 }