public Parse(Type t) { maxTypeId = 0; maxFunId = 0; types = new List <TType>(); funs = new List <TFunction>(); AddBaseType(typeof(string)); AddBaseType(typeof(byte)); AddBaseType(typeof(Int32)); AddBaseType(typeof(Int16)); AddBaseType(typeof(Int64)); AddBaseType(typeof(float)); AddBaseType(typeof(bool)); MethodInfo[] infos = t.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); for (int i = 0; i < infos.Length; i++) { maxFunId++; MethodInfo info = infos[i]; TFunction fun = new TFunction(); fun.isClient = false; foreach (Attribute attr in info.GetCustomAttributes(true)) { IsClient isClient = attr as IsClient; if (null != isClient) { fun.isClient = true; } } fun.name = info.Name; fun.id = maxFunId; fun.ret = GetParam(info.ReturnType); ParameterInfo[] ps = info.GetParameters(); fun.vars = new TParam[ps.Length]; for (int j = 0; j < ps.Length; j++) { fun.vars[j] = GetParam(ps[j].ParameterType); fun.vars[j].name = ps[j].Name; } funs.Add(fun); } }
public static void ExportClient(int modId, string path, string name, Parse p) { string file = path + LHead(name) + ".lua"; Begin(file); Format(""); Format("local Class = {0}", "{}"); for (int i = 0; i < p.funs.Count; i++) { TFunction f = p.funs[i]; if (f.isClient) { continue; } string paramStr = ""; for (int j = 0; j < f.vars.Length; j++) { if (j > 0) { paramStr += ","; } paramStr += f.vars[j].name; } Format(""); Format("function Class:{0}({1})", f.name, paramStr); PushTab(); Format("self:begin_send()"); Format("self:write_byte({0})", modId); Format("self:write_int({0})", f.id); for (int j = 0; j < f.vars.Length; j++) { TParam param = f.vars[j]; if (param.isArray) { Format("self:write_array(Class.write_{0},{1})", param.type.name, param.name); } else { Format("self:write_{0}({1})", param.type.name, param.name); } } Format("self:end_send()"); PopTab(); Format("end"); } for (int i = 0; i < p.types.Count; i++) { TType t = p.types[i]; if (t.enums != null) { Format(""); Format("function Class:write_{0}(obj)", t.name); PushTab(); for (int j = 0; j < t.enums.Length; j++) { if (j == 0) { Format("if obj == \"{0}\" then", t.enums[j]); } else { Format("elseif obj == \"{0}\" then", t.enums[j]); } Format("\tself:write_byte({0})", j); } Format("else"); Format("\tself:write_byte({0})", -1); Format("end"); PopTab(); Format("end"); } else if (t.members.Length > 0) { Format(""); Format("function Class:write_{0}(obj)", t.name); PushTab(); for (int j = 0; j < t.members.Length; j++) { TParam param = t.members[j]; if (param.isArray) { Format("self:write_array(Class.write_{0},obj.{1})", param.type.name, param.name); } else { Format("self:write_{0}(obj.{1})", param.type.name, param.name); } } PopTab(); Format("end"); } } // client // Format(""); Format("function Class:init()"); PushTab(); for (int i = 0; i < p.funs.Count; i++) { TFunction f = p.funs[i]; if (f.isClient == false) { continue; } Format("self[{0}] = Class.on_{1}", f.id, f.name); } //Format("setmetatable(obj,Class)"); //Format("return obj"); PopTab(); Format("end"); Format(""); Format("function Class:on_message()"); PushTab(); Format("local n = self:read_int()"); Format("self[n](self)"); PopTab(); Format("end"); for (int i = 0; i < p.funs.Count; i++) { TFunction f = p.funs[i]; if (f.isClient == false) { continue; } Format(""); Format("function Class:on_{0}()", f.name); PushTab(); for (int j = 0; j < f.vars.Length; j++) { TParam param = f.vars[j]; if (param.isArray) { Format("local {0} = self:read_array(Class.read_{1})", param.name, param.type.name); } else { Format("local {0} = self:read_{1}()", param.name, param.type.name); } } string paramStr = ""; for (int j = 0; j < f.vars.Length; j++) { if (j > 0) { paramStr += ","; } paramStr += f.vars[j].name; } Format("self.client:{0}_{1}({2})", LHead(name), f.name, paramStr); PopTab(); Format("end"); } for (int i = 0; i < p.types.Count; i++) { TType t = p.types[i]; if (t.enums != null) { Format(""); Format("function Class:read_{0}(obj)", t.name); PushTab(); Format("local n = self:read_byte()"); Format("local r"); for (int j = 0; j < t.enums.Length; j++) { if (j == 0) { Format("if n == {0} then", j); } else { Format("elseif n == {0} then", j); } Format("\tr = \"{0}\"", t.enums[j]); } Format("else"); Format("\tr = nil"); Format("end"); Format("return r"); PopTab(); Format("end"); } else if (t.members.Length > 0) { Format(""); Format("function Class:read_{0}(obj)", t.name); PushTab(); Format("local r = {0}", "{}"); for (int j = 0; j < t.members.Length; j++) { TParam param = t.members[j]; if (param.isArray) { Format("r.{0} = self:read_array(Class.read_{1})", param.name, param.type.name); } else { Format("r.{0} = self:read_{1}()", param.name, param.type.name); } } Format("return r"); PopTab(); Format("end"); } } Format(""); Format("return Class"); End(); }
public static void ExportServer(int modId, string path, string name, Parse p) { string file = path + "proto_" + LHead(name) + ".ex"; Begin(file); Format(""); Format("defmodule Proto.{0} do", name); PushTab(); Format("import BaseWrite, only: :functions"); Format("import BaseRead, only: :functions"); for (int i = 0; i < p.funs.Count; i++) { TFunction f = p.funs[i]; if (f.isClient == false) { continue; } string paramStr = ""; string paramStrNull = ""; for (int j = 0; j < f.vars.Length; j++) { if (j > 0) { paramStr += ","; } paramStr += LHead(f.vars[j].name); if (j > 0) { paramStrNull += ","; } paramStrNull += "_"; } Format(""); Format("def {0}({1}) do", f.name, paramStr); PushTab(); if (f.vars.Length == 0) { Format("send_{0}(self())", f.name); } else { Format("send_{0}(self(),{1})", f.name, paramStr); } PopTab(); Format("end"); Format(""); if (f.vars.Length == 0) { Format("def send_{0}(nil) do", f.name); } else { Format("def send_{0}(nil,{1}) do", f.name, paramStrNull); } PushTab(); Format(":ok"); PopTab(); Format("end"); if (f.vars.Length == 0) { Format("def send_{0}([]) do", f.name); } else { Format("def send_{0}([],{1}) do", f.name, paramStrNull); } PushTab(); Format(":ok"); PopTab(); Format("end"); if (f.vars.Length == 0) { Format("def send_{0}(list) when is_list(list) do", f.name); } else { Format("def send_{0}(list,{1}) when is_list(list) do", f.name, paramStr); } PushTab(); Format("bin = pack_{0}({1})", f.name, paramStr); Format("Enum.each(list,fn(pid)-> send pid,{0}:client,bin{1} end)", "{", "}"); PopTab(); Format("end"); if (f.vars.Length == 0) { Format("def send_{0}(pid) do", f.name); } else { Format("def send_{0}(pid,{1}) do", f.name, paramStr); } PushTab(); Format("bin = pack_{0}({1})", f.name, paramStr); Format("send pid,{0}:client,bin{1}", "{", "}"); PopTab(); Format("end"); Format("def pack_{0}({1}) do", f.name, paramStr); PushTab(); Format("bin = write_byte(<<>>,{0})", modId); Format("bin = write_int(bin,{0})", f.id); for (int j = 0; j < f.vars.Length; j++) { TParam param = f.vars[j]; if (param.isArray) { Format("bin = write_array(bin,&write_{0}/2,{1})", param.type.name, LHead(param.name)); } else { Format("bin = write_{0}(bin,{1})", param.type.name, LHead(param.name)); } } Format("bin"); PopTab(); Format("end"); } for (int i = 0; i < p.types.Count; i++) { TType t = p.types[i]; if (t.enums != null) { for (int j = 0; j < t.enums.Length; j++) { Format(""); Format("def write_{0}(bin,:{1}) do", t.name, t.enums[j]); PushTab(); Format("write_byte(bin,{0})", j); PopTab(); Format("end"); } Format(""); Format("def write_{0}(bin,_) do", t.name); PushTab(); Format("write_byte(bin,-1)"); PopTab(); Format("end"); } else if (t.members.Length > 0) { Format(""); Format("def write_{0}(bin,obj) do", t.name); PushTab(); for (int j = 0; j < t.members.Length; j++) { TParam param = t.members[j]; if (param.isArray) { Format("bin = write_array(bin,&write_{0}/2,obj.{1})", param.type.name, param.name); } else { Format("bin = write_{0}(bin,obj.{1})", param.type.name, param.name); } } Format("bin"); PopTab(); Format("end"); } } PopTab(); // server // PushTab(); Format(""); Format("def on_message(state,bin) do"); PushTab(); Format("{0}n,bin{1} = read_int(bin)", "{", "}"); Format("on_message(state,n,bin)"); PopTab(); Format("end"); for (int i = 0; i < p.funs.Count; i++) { TFunction f = p.funs[i]; if (f.isClient) { continue; } Format(""); if (f.vars.Length == 0) { Format("def on_message(state,{0},_bin) do", f.id); } else { Format("def on_message(state,{0},bin) do", f.id); } PushTab(); for (int j = 0; j < f.vars.Length; j++) { TParam param = f.vars[j]; string v = ""; if (j == f.vars.Length - 1) { v = "_"; } if (param.isArray) { Format("{2}{0},{4}bin{3}= read_array(bin,&read_{1}/1)", LHead(param.name), param.type.name, "{", "}", v); } else { Format("{2}{0},{4}bin{3} = read_{1}(bin)", LHead(param.name), param.type.name, "{", "}", v); } } string paramStr = ""; for (int j = 0; j < f.vars.Length; j++) { if (j > 0) { paramStr += ","; } paramStr += LHead(f.vars[j].name); } if (f.vars.Length == 0) { Format("{0}.{1}(state)", name, f.name); } else { Format("{0}.{1}(state,{2})", name, f.name, paramStr); } PopTab(); Format("end"); } for (int i = 0; i < p.types.Count; i++) { TType t = p.types[i]; if (t.enums != null) { Format(""); Format("def read_{0}(bin) do", t.name); PushTab(); Format("{0}n,bin{1} = read_byte(bin)", "{", "}"); Format("r ="); Format("case n do"); for (int j = 0; j < t.enums.Length; j++) { Format("{0} -> :{1}", j, t.enums[j]); } Format("_ -> nil"); Format("end"); Format("{0}r,bin{1}", "{", "}"); PopTab(); Format("end"); } else if (t.members.Length > 0) { Format(""); Format("def read_{0}(bin) do", t.name); PushTab(); for (int j = 0; j < t.members.Length; j++) { TParam param = t.members[j]; if (param.isArray) { Format("{2}r_{0},bin{3} = read_array(bin,&read_{1}/1)", param.name, param.type.name, "{", "}"); } else { Format("{2}r_{0},bin{3} = read_{1}(bin)", param.name, param.type.name, "{", "}"); } } Format("r = %{0}", "{"); PushTab(); for (int j = 0; j < t.members.Length; j++) { TParam param = t.members[j]; Format(":{0} => r_{0},", param.name); } PopTab(); Format("{0}", "}"); Format("{0}r,bin{1}", "{", "}"); PopTab(); Format("end"); } } Format(""); PopTab(); Format("end"); End(); }