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 class AbstractExecutor(T) : Executor if (is(T == class)) { 34 35 this() { 36 } 37 38 shared static this() { 39 40 version(HUNT_DEBUG) tracef("Registering %s", T.stringof); 41 Class c = T.metaof; 42 const(Method)[] methods = c.getMethods(); 43 ExecutorInfo[] executors; 44 45 foreach (const Method method; methods ) { 46 // trace(method.toString()); 47 const(Attribute)[] attrs = method.getAttributes!(MessageId)(); 48 // tracef("name: %s, MessageId: %s", method.getName(), method.hasAttribute!(MessageId)()); 49 foreach(const(Attribute) attr; attrs) { 50 // trace(attr.toString()); 51 if(!attr.isExpression()) 52 continue; 53 54 Variant value = attr.get(); 55 // trace(value.type.toString()); 56 MessageId messageId = value.get!(MessageId)(); 57 // trace(messageId.value); 58 59 int messageCode = messageId.value; 60 bool isFound = executors.canFind!((ExecutorInfo a, uint b) => a.messageId() == b)(messageCode); 61 if(isFound) { 62 warningf("message code collision: %d in %s", messageCode, c.getFullName()); 63 } else { 64 // Annoying const 65 executors ~= cast(ExecutorInfo)ExecutorInfo(messageCode, cast(Class)c, cast(Method)method); 66 67 } 68 } 69 } 70 71 // Register executor for Server 72 const(Attribute)[] attrs = c.getAttributes!(TransportServer)(); 73 foreach(const(Attribute) attr; attrs) { 74 // trace(attr.toString()); 75 if(!attr.isExpression()) 76 continue; 77 78 Variant value = attr.get(); 79 // trace(value.type.toString()); 80 TransportServer messageServer = value.get!(TransportServer)(); 81 // trace(messageServer.name); 82 Executor.registerExecutors(TransportServer.NAME_PREFIX ~ messageServer.name, executors); 83 } 84 85 86 // Register executor for Client 87 attrs = c.getAttributes!(TransportClient)(); 88 foreach(const(Attribute) attr; attrs) { 89 // trace(attr.toString()); 90 if(!attr.isExpression()) 91 continue; 92 93 Variant value = attr.get(); 94 // trace(value.type.toString()); 95 TransportClient messageclient = value.get!(TransportClient)(); 96 // trace(messageclient.name); 97 Executor.registerExecutors(TransportClient.NAME_PREFIX ~ messageclient.name, executors); 98 } 99 100 } 101 102 mixin Witchcraft!T; 103 }