1 /*
2  * The MIT License (MIT)
3  *
4  * Copyright (c) 2014 Richard Andrew Cattermole
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 module dakka.base.impl.defs;
25 import dakka.base.defs;
26 import std.traits;
27 
28 pure string getActorImplComs(T : Actor, T t = T.init)() {
29 	string ret;
30 	ret ~= "override {\n";
31 	
32 	foreach(m; __traits(allMembers, T)) {
33 		static if (__traits(compiles, __traits(getMember, t, m)) && __traits(getProtection, __traits(getMember, t, m)) == "public" && !hasMember!(Actor, m)) {
34 			static if (__traits(isVirtualFunction, __traits(getMember, t, m))) {
35 				static if (!isMethodLocalOnly!(T, m)) {
36 					ret ~= funcDeclText!(T, m);
37 					ret ~= generateFuncHandler!(T, m);
38 					ret ~= "    }\n";
39                 }
40 			}
41 		}
42 	}
43 	
44 	ret ~= "}\n";
45 	return ret;
46 }
47 
48 pure string funcDeclText(T : Actor, string m, T t = T.init)(bool multiRet = false) {
49 	string ret;
50 	string ret2;
51 
52 	ret ~= typeText!(ReturnType!(__traits(getMember, t, m)));
53 	if (multiRet)
54 		ret ~= "[]";
55 
56 	ret ~= " " ~ m ~ "(";
57 	
58 	enum names = ParameterIdentifierTuple!(mixin("t." ~ m));
59 	foreach(i, a; ParameterTypeTuple!(mixin("t." ~ m))) {
60 		static if (is(a == class) || is(a == struct) || is(a == union)) {
61 			ret2 ~= "    import " ~ moduleName!a ~ " : " ~ a.stringof ~ ";\n";
62 		}
63 		ret ~= a.stringof ~ " " ~ names[i] ~ ", ";
64 	}
65 	
66 	if (ret[$-2] == ',')
67 		ret.length -= 2;
68 	
69 	ret ~= ") {\n";
70 	return ret2 ~ "    " ~ ret;
71 }
72 
73 pure string generateFuncHandler(T : Actor, string m)() {
74 	import dakka.base.impl.local;
75 	import dakka.base.impl.remote;
76 
77 	string ret;
78 	ret ~= "        if (isLocalInstance) {\n";
79 	ret ~= generateFuncLocalHandler!(T, m);
80 	ret ~= "        } else {\n";
81 	
82 	ret ~= generateFuncRemoteHandler!(T, m);
83 	// theres a few things that need to go on here
84 	// grab arguments of function, serialize them
85 	// send them with our id's to server
86 	// wait and receive the result
87 	// if is an exception, recreate it and throw it
88 	// otherwise deserialize our value and return it
89 	
90 	//ret ~= "            assert(0);\n";
91 	ret ~= "        }\n";
92 	
93 	return ret;
94 }
95 
96 pure string generateFuncCall(T : Actor, string m, T t = T.init)() {
97 	string ret;
98 	foreach(n; ParameterIdentifierTuple!(mixin("t." ~ m))) {
99 		ret ~= n ~ ", ";
100 	}
101 	
102 	if (ret.length > 0)
103 		if (ret[$-2] == ',')
104 			ret.length -= 2;
105 	return ret;
106 }
107 
108 pure bool hasReturnValue(T : Actor, string m, T t = T.init)() {
109 	static if (ReturnType!(__traits(getMember, t, m)).stringof != "void") {
110 		return true;
111 	} else {
112 		foreach(p; ParameterStorageClassTuple!(mixin("t." ~ m))) {
113 			static if (p == ParameterStorageClass.ref_ || p == ParameterStorageClass.out_) {
114 				return true;	
115 			}
116 		}
117 		
118 		return false;
119 	}
120 }