public TParam GetParam(Type t) { TParam p = new TParam(); p.isArray = t.IsArray; string typeName = t.Name; if (t.IsArray) { typeName = typeName.Substring(0, typeName.Length - 2); } typeName = typeName.ToLower(); for (int i = 0; i < types.Count; i++) { if (types[i].name == typeName) { p.type = types[i]; return(p); } } maxTypeId++; TType newType = new TType(); if (t.IsArray) { Assembly a = Assembly.GetEntryAssembly(); string name = t.FullName; t = a.GetType(name.Substring(0, name.Length - 2)); } newType.id = maxTypeId; newType.name = typeName; newType.members = GetMenbers(t); if (t.IsEnum) { MemberInfo[] m = t.GetMembers( BindingFlags.Public | BindingFlags.Static); newType.enums = new string[m.Length]; for (int i = 0; i < m.Length; i++) { newType.enums[i] = m[i].Name; } } types.Add(newType); p.type = newType; return(p); }
public TParam[] GetMenbers(Type t) { FieldInfo[] infos = t.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); int count = infos.Length; TParam[] ret = new TParam[count]; for (int i = 0; i < infos.Length; i++) { ret[i] = GetParam(infos[i].FieldType); ret[i].name = infos[i].Name; } return(ret); }
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(); }