"Denis Koroskin" <[email protected]> wrote:
 
> On Sat, 21 Nov 2009 12:42:35 +0300, Rory McGuire <[email protected]>  
> wrote:
> 
>> "Denis Koroskin" <[email protected]> wrote:
>>
>>> "Denis Koroskin" <[email protected]> wrote:
>>> ...
>>
>> cut
>>
>>> ...
>>
>>
>> Why did you use asm etc...?
>>
>> I made a de/serializer that just uses templates and static ifs.
>>
>> it doesn't do serialization of delegates etc... but I don't know that
>> moving executable code across would be safe (I think java can do it,
>> but then it has a vm).
>>
>> mine does:
>> int, long, double, string, object, struct.
>>
>> I can post the code if you want. So far I have only used it to present
>> the methods of an object as a kind of server, with a client being able
>> to connect to it.
>>
>> Was inspired by hessiand on dsource.org.
>>
>> Can post code if you would like to see. I posted the automatic object
>> wrapping code a couple of days ago as a simple example of template
>> usage Thread: "Metaprogramming in D: Some real world examples".
>>
>> -Rory
>>
> 
> You missed the point. I only used asm to invoke function on remote side.  
> Serialization is done purely with templates.
> 

:) I thought I had missed the point thats why I asked :D.

On the Server side I used a similar method that the guy who wrote hessiand used 
for calling the objects methods, my code:



module servers.ObjectSocketServer;

//import serialize.ISerializer;
import transports.ITransport;
import transports.SocketTransport;
import tango.core.Exception;

version (Tango) {
        alias char[] string;
        import tango.net.Socket;
        import tango.io.Stdout;
        import tango.core.Traits;
//      alias ParameterTupleOf ParameterTypeTuple;
}

class ObjectSocketServer(T,C) {
        Socket request_conn;
        T serializer;
        ITransport transport;
        
        C instance;
        IMethod[string] methods;
        
        this(Socket request_conn) {
                instance = new C();
                transport = new SocketTransport(request_conn);
                serializer = new T(transport);
                this.request_conn = request_conn;
                
        }
        ~this() {
                request_conn = null;
                serializer = null;
                transport = null;
                foreach (key, method; methods) {
                        methods.remove(key);
                }
                instance = null;
        }
        void close() {
                try {
                        if (request_conn !is null) {
                                request_conn.shutdown(SocketShutdown.BOTH);
                                request_conn.detach();
                        }
                } catch (Exception e) {}
        }
        
        /+ void expose(char[] method)() {
                pragma(msg, mixin(MethodType_mixin!(method)()));
        } +/
        void expose(alias M)() {
                const string name = NameOfFunc!(M);
                //pragma(msg, "expose: "~ name);
                
                
                pragma(msg, "expose:\n"~ GenMethod!(C, name));
                methods[name] = mixin(GenMethod!(C, name));
        }
        
        void run() {
                scope(exit) close();
                try {
                        Stdout("run").newline;
                        
                        int i;
                        while (true) {
                                //Stdout("again").newline;
                                auto method = serializer.read!(string)();
                                //Stdout("method = "~ method).newline;
                                
                                try {
                                        if (!(method in methods))
                                                throw new Exception("Not 
Found");
                                        methods[method](serializer, instance);
                                } catch (Exception e) {
                                        e.writeOut((char[] str) { 
Stdout(str).newline;});
                                        Stdout("Caught exception must 
serialize: ")(e.line)(":")
(e.file)(" ")(e.toString).newline;
                                }
                                Stdout(i)("\r")();
                                i++;
                        }
                        Stdout().newline;
                        
                } catch (Exception e) {
                        Stdout("Caught exception: ")(e.toString).newline;
                }
        }
        
        
        
        
        interface IMethod {
                string getName();
                void opCall(T, C);
        }
}
// this would be inside the class but cant be
string GenMethod(alias C, string name)() {
        string ret = "new class IMethod {\n";
        ret ~= "\tstring getName() { return \""~ name ~"\"; }\n";
        ret ~= "\tvoid opCall(T serializer, C instance) {\n";
        ret ~= "\t\tserializer.write(instance."~name~"(serializer.read!
("~ParameterTupleOf!(mixin(MethodType_mixin!(name)()))[0].stringof~")()));\n";
        foreach (i,p; 
ParameterTupleOf!(mixin(MethodType_mixin!(name)()))[1..$]) {
                ret ~= "\t\tserializer.write(instance."~name~"(serializer.read!
("~p.stringof~")()));\n";
        }
        ret ~= "\t\tserializer.getTransport().flush();\n";
        ret ~= "\t}\n";
        ret ~= "}\n";
        return ret;
}

public template NameOfFunc(alias f) {
        version (LDC) {
                const char[] NameOfFunc = (&f).stringof[1 .. $];
        } else {
                const char[] NameOfFunc = (&f).stringof[2 .. $];
        }
}

string MethodType_mixin(string method)() {
        return "typeof(&C.init."~ method ~")";
}






Reply via email to