1 module as.addons.dwrap; 2 import as.def; 3 import as.engine; 4 import core.memory; 5 import core.stdc.stdlib : free; 6 import std.traits; 7 import std.format; 8 import std..string; 9 import std.stdio; 10 11 private { 12 extern(C) void constructClassOrStruct(T)(T* self) { 13 import std.conv : emplace; 14 emplace!T(self); 15 } 16 17 extern(C) void destructClassOrStruct(T)(T* self) { 18 destroy(self); 19 } 20 21 extern(C) T structAssign(T)(ref T in_, ref T self) { 22 writeln(self, " ", in_); 23 self = in_; 24 return self; 25 } 26 27 string toASType(string typeName) { 28 switch(typeName) { 29 30 case "string": 31 case "int": 32 case "float": 33 case "double": return typeName; 34 35 case "ubyte": return "byte"; 36 case "ushort": return "uint16"; 37 case "uint": return "uint"; 38 case "ulong": return "uint64"; 39 default: { 40 while (typeName.endsWith("*")) { 41 typeName.length--; 42 } 43 return typeName; 44 } 45 } 46 } 47 48 string buildArgList(alias T)() { 49 string[] o; 50 static foreach(param; Parameters!T) { 51 o ~= toASType(param.stringof); 52 } 53 return o.length == 0 ? "" : o.join(", "); 54 } 55 } 56 57 void registerDStruct(T, string namespace = "")(ScriptEngine engine) if (is(T == struct)) { 58 mixin("import ", moduleName!T, ";"); 59 60 static if (namespace.length != 0) { 61 string prevNamespace = engine.getDefaultNamespace(); 62 scope(exit) engine.setDefaultNamespace(prevNamespace); 63 64 // Set up namespace 65 engine.setDefaultNamespace(namespace); 66 } 67 68 engine.registerObjectType(T.stringof, T.sizeof, asEObjTypeFlags.asOBJ_VALUE | asEObjTypeFlags.asOBJ_APP_CLASS_CDAK); 69 engine.registerObjectBehaviour( 70 T.stringof, 71 asEBehaviours.asBEHAVE_CONSTRUCT, 72 "void f()", 73 cast(asFUNCTION_t)&constructClassOrStruct!T, 74 DCallConvClass, 75 null 76 ); 77 78 engine.registerObjectBehaviour( 79 T.stringof, 80 asEBehaviours.asBEHAVE_DESTRUCT, 81 "void f()", 82 cast(asFUNCTION_t)&destructClassOrStruct!T, 83 DCallConvClass, 84 null 85 ); 86 engine.registerObjectMethod( 87 T.stringof, 88 "%s &opAssign(const %s &in)".format(T.stringof, T.stringof), 89 &structAssign!T, 90 DCallConvClassR 91 ); 92 93 94 static foreach(member; __traits(allMembers, T)) { 95 { 96 alias mInstance = mixin(T.stringof, ".", member); 97 enum visibility = __traits(getProtection, mInstance); 98 static if (visibility == "public" || visibility == "static") { 99 static if (is(typeof(mInstance) == function)) { 100 { 101 string retType = (ReturnType!mInstance).stringof; 102 103 engine.registerObjectMethod(T.stringof, "%s %s(%s)".format(toASType(retType), member, buildArgList!mInstance()), cast(asFUNCTION_t)&mInstance, DCallConvClassR, null); 104 } 105 } else static if(!is(typeof(mInstance) == struct) && !is(typeof(mInstance) == class)) { 106 engine.registerObjectProperty(T.stringof, "%s %s".format(toASType(typeof(mInstance).stringof), member), mInstance.offsetof); 107 } else static if(is(typeof(mInstance) == struct)) { 108 // TODO: Auto register structs if needed 109 } 110 } 111 } 112 } 113 114 }