1 module metacall; 2 3 import std.stdio; 4 import std.exception; 5 import std.string; 6 import std.variant; 7 import core.vararg; 8 import core.stdc.string; 9 10 enum metacall_value_id_enum : int { 11 METACALL_BOOL = 0, 12 METACALL_CHAR = 1, 13 METACALL_SHORT = 2, 14 METACALL_INT = 3, 15 METACALL_LONG = 4, 16 METACALL_FLOAT = 5, 17 METACALL_DOUBLE = 6, 18 METACALL_STRING = 7, 19 METACALL_BUFFER = 8, 20 METACALL_ARRAY = 9, 21 METACALL_MAP = 10, 22 METACALL_PTR = 11, 23 METACALL_FUTURE = 12, 24 METACALL_FUNCTION = 13, 25 METACALL_NULL = 14, 26 METACALL_SIZE, 27 METACALL_INVALID 28 } 29 30 extern(C) { 31 int metacall_initialize(); 32 int metacall_destroy(); 33 int metacall_load_from_file(const(char*) tag, const(char**) paths, size_t size, void** handle); 34 void* metacall_value_create_bool(int b); 35 void* metacall_value_create_char(char c); 36 void* metacall_value_create_short(short s); 37 void* metacall_value_create_int(int i); 38 void* metacall_value_create_long(long l); 39 void* metacall_value_create_float(float f); 40 void* metacall_value_create_double(double d); 41 void* metacall_value_create_string(const(char*) str, size_t length); 42 void* metacall_value_create_buffer(const(void*) buffer, size_t size); 43 void* metacall_value_create_array(const(void**) values, size_t size); 44 void* metacall_value_create_ptr(const(void*) ptr); 45 void* metacall_value_create_null(); 46 char metacall_value_to_char(void* v); 47 short metacall_value_to_short(void* v); 48 int metacall_value_to_int(void* v); 49 long metacall_value_to_long(void* v); 50 float metacall_value_to_float(void* v); 51 double metacall_value_to_double(void* v); 52 void* metacall_value_to_ptr(void* v); 53 char* metacall_value_to_string(void* v); 54 void metacall_value_destroy(void*); 55 metacall_value_id_enum metacall_value_id(void* v); 56 void* metacall(const(char*) name, ...); 57 void* metacallv(const(char*) name, void** args); 58 } 59 60 61 62 class MetaCallException : Exception { 63 mixin basicExceptionCtors; 64 } 65 66 int dmetacall_initialize() { 67 if(metacall_initialize() != 0) { 68 throw new MetaCallException("failed to initialize MetaCall"); 69 } 70 return 0; 71 } 72 73 int dmetacall_load_from_file(const char[] tag, string[] paths) { 74 char*[] good_paths; 75 good_paths.length += paths.length; 76 for(int i = 0; i < paths.length; i++) { 77 good_paths[i] = cast(char*)paths[i].toStringz(); 78 } 79 if(metacall_load_from_file(tag.ptr,cast(const(char**))good_paths,paths.length,null) != 0) { 80 throw new MetaCallException("MetaCall failed to load script(s)"); 81 } 82 return 0; 83 } 84 85 Variant dmetacall(T...)(string name,T args) { 86 void*[args.length] values; 87 int i = 0; 88 foreach(arg; args) { 89 static if(is(typeof(arg) == bool)) { 90 values[i] = metacall_value_create_bool(cast(int)arg); 91 } else static if(is(typeof(arg) == char)) { 92 values[i] = metacall_value_create_char(arg); 93 } else static if(is(typeof(arg) == short)) { 94 values[i] = metacall_value_create_short(arg); 95 } else static if(is(typeof(arg) == int)) { 96 values[i] = metacall_value_create_int(arg); 97 } else static if(is(typeof(arg) == long)) { 98 values[i] = metacall_value_create_long(arg); 99 } else static if(is(typeof(arg) == float)) { 100 values[i] = metacall_value_create_float(arg); 101 } else static if(is(typeof(arg) == double)) { 102 values[i] = metacall_value_create_double(arg); 103 } else static if(is(typeof(arg) == string) || is(typeof(arg) == char[])) { 104 values[i] = metacall_value_create_string(arg.ptr,arg.sizeof); 105 /*} else static if(is(typeof(arg) == ubyte[]) || is(typeof(arg) == char[]) || is(typeof(arg) == char*)) { 106 values[i] = metacall_value_create_buffer(cast(const(void*))arg.ptr,arg.sizeof);*/ 107 } else static if(is(typeof(arg) == void*)) { 108 values[i] = metacall_value_create_ptr(arg); 109 } 110 i++; 111 } 112 113 void* ret = metacallv(name.toStringz(),cast(void**)values.ptr); 114 foreach(void* value; values) { 115 metacall_value_destroy(value); 116 } 117 118 Variant returnvariant; 119 switch(metacall_value_id(ret)) { 120 case metacall_value_id_enum.METACALL_CHAR: 121 returnvariant = metacall_value_to_char(ret); 122 break; 123 case metacall_value_id_enum.METACALL_SHORT: 124 returnvariant = metacall_value_to_short(ret); 125 break; 126 case metacall_value_id_enum.METACALL_INT: 127 returnvariant = metacall_value_to_int(ret); 128 break; 129 case metacall_value_id_enum.METACALL_LONG: 130 returnvariant = metacall_value_to_long(ret); 131 break; 132 case metacall_value_id_enum.METACALL_FLOAT: 133 returnvariant = metacall_value_to_float(ret); 134 break; 135 case metacall_value_id_enum.METACALL_DOUBLE: 136 returnvariant = metacall_value_to_double(ret); 137 break; 138 case metacall_value_id_enum.METACALL_STRING: 139 returnvariant = metacall_value_to_string(ret).fromStringz(); 140 break; 141 case metacall_value_id_enum.METACALL_PTR: 142 returnvariant = metacall_value_to_ptr(ret); 143 break; 144 case metacall_value_id_enum.METACALL_NULL: 145 returnvariant = null; 146 break; 147 default: 148 returnvariant = null; 149 break; 150 } 151 return returnvariant; 152 } 153 154 int dmetacall_destroy() { 155 return metacall_destroy(); 156 }