public bool HasReferences(CastleDB database) { foreach (CastleColumn col in Columns) { if (col.TypeID == CastleType.Ref) { return(true); } else if (col.TypeID == CastleType.List) { string searchSheet = string.Format("{0}@{1}", Name, col.Name); CastleSheet dbSheet = database.Sheets.FirstOrDefault(s => s.Name.Equals(searchSheet)); if (dbSheet != null && dbSheet.HasReferences(database)) { return(true); } } } return(false); }
static readonly string ASProperty = "{2}{0} {1};\r\n"; // Type name;\n public override void WriteClassDefinitions(CastleDB database, string fileBase, string sourceFileName, Dictionary <string, string> switches, List <string> errors) { Dictionary <string, Dictionary <string, string> > IDSTable = new Dictionary <string, Dictionary <string, string> >(); int tabDepth = 0; string fileText = string.Format("// AUTOGENERATED ANGELSCRIPT SOURCE CODE FROM {0}\r\n", sourceFileName); string dbName = "GameDatabase"; if (switches.ContainsKey("db")) { dbName = switches["db"]; } bool integerIDs = false; if (switches.ContainsKey("id")) { integerIDs = switches["id"].Equals("int"); } bool binIO = false; bool jsonOff = false; if (switches.ContainsKey("bin")) { binIO = switches["bin"].Equals("on") || switches["bin"].Equals("only"); jsonOff = switches["bin"].Equals("only"); } string inherit = ""; if (switches.ContainsKey("inherit")) { inherit = switches["inherit"]; } bool hasTilePos = false; bool hasLayers = false; foreach (CastleSheet sheet in database.Sheets) { foreach (CastleColumn column in sheet.Columns) { if (column.TypeID == CastleType.TileLayer || column.TypeID == CastleType.Layer) { hasLayers = true; } else if (column.TypeID == CastleType.TilePos) { hasTilePos = true; } } } // Angelscript namespace need to go externally // Scan for enumerations and flags foreach (CastleSheet sheet in database.Sheets) { IDSTable[sheet.Name] = new Dictionary <string, string>(); foreach (CastleColumn column in sheet.Columns) { if (column.TypeID == CastleType.Enum) { fileText += string.Format("\r\nenum E_{0} {{\r\n", column.Name.ToUpper()); foreach (string value in column.Enumerations) { fileText += string.Format("{0}{1},\r\n", GetTabstring(tabDepth + 0), value.ToUpper()); } fileText += "}\r\n"; } else if (column.TypeID == CastleType.Flags) { fileText += "\r\n"; int index = 0; foreach (string value in column.Enumerations) { fileText += string.Format("const uint {0}_{1} = {2};\r\n", column.Name.ToUpper(), value.ToUpper(), 1 << index); ++index; } } } } if (switches.ContainsKey("ns")) { fileText += string.Format("\r\nnamespace {0} {{\r\n", switches["ns"]); } if (hasTilePos) { fileText += asCastleTileCode; } if (hasLayers) { fileText += asLayerClasses; } foreach (CastleSheet sheet in database.Sheets) { string sheetName = sheet.Name.Replace('@', '_'); string classStr = inherit.Length > 0 ? string.Format(ASClassStartInherit, sheetName, inherit) : string.Format(ASClassStart, sheetName); foreach (CastleColumn column in sheet.Columns) { switch (column.TypeID) { case CastleType.UniqueIdentifier: classStr += string.Format(ASProperty, "String", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.Boolean: classStr += string.Format(ASProperty, "bool", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.Color: classStr += string.Format(ASProperty, "Color", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.Custom: CastleCustom custom = database.CustomTypes.FirstOrDefault(c => c.Name.Equals(column.Key)); if (custom != null) { if (!custom.Constructors[0].returnType.Equals("void")) { classStr += string.Format(ASProperty, custom.Constructors[0].returnType, column.Name, GetTabstring(tabDepth + 0)); } } break; case CastleType.Dynamic: classStr += string.Format(ASProperty, "JSONValue", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.Enum: classStr += string.Format(ASProperty, "int", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.File: classStr += string.Format(ASProperty, "String", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.Flags: classStr += string.Format(ASProperty, "uint", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.Image: classStr += string.Format(ASProperty, "String", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.Integer: classStr += string.Format(ASProperty, "int", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.Layer: classStr += string.Format(ASProperty, "CastleDataLayer@", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.List: classStr += string.Format("{0}Array<{1}@> {2};\r\n", GetTabstring(tabDepth + 0), string.Format("{0}_{1}", sheet.Name, column.Name), column.Name); break; case CastleType.Ref: classStr += string.Format("{0}{1}@ {2};\r\n", GetTabstring(tabDepth + 0), column.Key, column.Name); classStr += string.Format("{0}private string {1}Key;\r\n", GetTabstring(tabDepth + 0), column.Name); break; case CastleType.Text: classStr += string.Format(ASProperty, "String", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.TileLayer: classStr += string.Format(ASProperty, "CastleTileLayer@", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.TilePos: classStr += string.Format(ASProperty, "CastleTile", column.Name, GetTabstring(tabDepth + 0)); break; } } // generate destructor, clears the lists and refs classStr += string.Format("\r\n{0}~{1}() {{\r\n", GetTabstring(tabDepth + 0), sheetName); foreach (CastleColumn col in sheet.Columns) { if (col.TypeID == CastleType.List) { classStr += string.Format("{0}{1}.Clear();\r\n", GetTabstring(tabDepth + 1), col.Name); } else if (col.TypeID == CastleType.Ref) { classStr += string.Format("{0}@{1} = null;\r\n", GetTabstring(tabDepth + 1), col.Name); } } classStr += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 0)); // generate loading function if (!jsonOff) { classStr += string.Format("\r\n{0}void Load(JSONValue&in value) {{\r\n", GetTabstring(tabDepth + 0)); } string loadBinStr = string.Format("\r\n{0}void Load(Deserializer&in source) {{\r\n", GetTabstring(tabDepth + 0)); string saveBinStr = string.Format("\r\n{0}void Save(Serializer&in dest) {{\r\n", GetTabstring(tabDepth + 0)); foreach (CastleColumn col in sheet.Columns) { switch (col.TypeID) { case CastleType.UniqueIdentifier: if (!jsonOff) { classStr += string.Format("{0}{1} = value[\"{1}\"].GetString();\r\n", GetTabstring(tabDepth + 1), col.Name); } loadBinStr += string.Format("{0}{1} = source.ReadString();\r\n", GetTabstring(tabDepth + 1), col.Name); saveBinStr += string.Format("{0}dest.WriteString({1});\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.Boolean: if (!jsonOff) { classStr += string.Format("{0}{1} = value[\"{1}\"].GetBool();\r\n", GetTabstring(tabDepth + 1), col.Name); } loadBinStr += string.Format("{0}{1} = source.ReadBool();\r\n", GetTabstring(tabDepth + 1), col.Name); saveBinStr += string.Format("{0}dest.WriteBool({1});\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.Color: if (!jsonOff) { classStr += string.Format("{0}{1}.FromUInt(value[\"{1}\"].GetUInt());\r\n", GetTabstring(tabDepth + 1), col.Name); } loadBinStr += string.Format("{0}{1} = source.ReadString();\r\n", GetTabstring(tabDepth + 1), col.Name); saveBinStr += string.Format("{0}dest.WriteColor({1});\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.Enum: //TODO! With every angelscript update check for enums updated to accept int if (!jsonOff) { classStr += string.Format("{0}{1} = value[\"{1}\"].GetInt();\r\n", GetTabstring(tabDepth + 1), col.Name); } loadBinStr += string.Format("{0}{1} = source.ReadInt();\r\n", GetTabstring(tabDepth + 1), col.Name); saveBinStr += string.Format("{0}dest.WriteInt({1});\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.Image: if (!jsonOff) { classStr += string.Format("{0}String {1}Str = value[\"{1}\"].GetString();\r\n{0}if ({1}Str.length > 0)\r\n{2}{1} = {1}Str.Substring({1}Str.IndexOf(':'));\r\n", GetTabstring(tabDepth + 1), col.Name, GetTabstring(tabDepth + 2)); } loadBinStr += string.Format("{0}{1} = source.ReadString();\r\n", GetTabstring(tabDepth + 1), col.Name); saveBinStr += string.Format("{0}dest.WriteString({1});\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.File: if (!jsonOff) { classStr += string.Format("{0}{1} = value[\"{1}\"].GetString();\r\n", GetTabstring(tabDepth + 1), col.Name); } loadBinStr += string.Format("{0}{1} = source.ReadString();\r\n", GetTabstring(tabDepth + 1), col.Name); saveBinStr += string.Format("{0}dest.WriteString({1});\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.Flags: if (!jsonOff) { classStr += string.Format("{0}{1} = value[\"{1}\"].GetUInt();\r\n", GetTabstring(tabDepth + 1), col.Name); } loadBinStr += string.Format("{0}{1} = source.ReadUInt();\r\n", GetTabstring(tabDepth + 1), col.Name); saveBinStr += string.Format("{0}dest.WriteUInt({1});\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.Float: if (!jsonOff) { classStr += string.Format("{0}{1} = value[\"{1}\"].GetFloat();\r\n", GetTabstring(tabDepth + 1), col.Name); } loadBinStr += string.Format("{0}{1} = source.ReadFloat();\r\n", GetTabstring(tabDepth + 1), col.Name); saveBinStr += string.Format("{0}dest.WriteFloat({1});\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.Integer: if (!jsonOff) { classStr += string.Format("{0}{1} = value[\"{1}\"].GetInt();\r\n", GetTabstring(tabDepth + 1), col.Name); } loadBinStr += string.Format("{0}{1} = source.ReadInt();\r\n", GetTabstring(tabDepth + 1), col.Name); saveBinStr += string.Format("{0}dest.WriteInt({1});\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.List: if (!jsonOff) { classStr += string.Format("{0}JSONValue {1}Array = value[\"{1}\"];\r\n", GetTabstring(tabDepth + 1), col.Name); classStr += string.Format("{0}for (uint i = 0; i < {1}Array.size; ++i) {{\r\n", GetTabstring(tabDepth + 1), col.Name); classStr += string.Format("{0}{1}@ val = {1}();\r\n", GetTabstring(tabDepth + 2), string.Format("{0}_{1}", sheet.Name, col.Name)); classStr += string.Format("{0}val.Load({1}Array[i]);\r\n{0}{2}.Push(val);\r\n", GetTabstring(tabDepth + 2), col.Name, col.Name); classStr += string.Format("{0}}} \r\n", GetTabstring(tabDepth + 1)); } loadBinStr += string.Format("{0}uint {1}Ct = source.ReadUInt();\r\n{0}for (uint i = 0; i < {1}Ct; ++i) {{\r\n", GetTabstring(tabDepth + 1), col.Name); loadBinStr += string.Format("{0}{1}@ val = {1}();\r\n", GetTabstring(tabDepth + 2), string.Format("{0}_{1}", sheet.Name, col.Name)); loadBinStr += string.Format("{0}val.Load(source);\r\n{0}{2}.Push(val);\r\n", GetTabstring(tabDepth + 2), col.Name, col.Name); loadBinStr += string.Format("{0}}} \r\n", GetTabstring(tabDepth + 1)); saveBinStr += string.Format("{0}dest.WriteUInt({1}.length);\r\n", GetTabstring(tabDepth + 1), col.Name); saveBinStr += string.Format("{0}for (uint i = 0; i < {1}.length; ++i)\r\n", GetTabstring(tabDepth + 1), col.Name); saveBinStr += string.Format("{0}{1}[i].Save(dest);\r\n", GetTabstring(tabDepth + 2), col.Name); break; case CastleType.Ref: if (!jsonOff) { classStr += string.Format("{0}{1}Key = value[\"{1}\"].GetString();\r\n", GetTabstring(tabDepth + 1), col.Name); } loadBinStr += string.Format("{0}{1}Key = source.ReadString();\r\n", GetTabstring(tabDepth + 1), col.Name); saveBinStr += string.Format("{0}if ({2} is null)\r\n{1}source.WriteString(\"\");\r\n{0}else\r\n{1}source.WriteString({2}.{3});\r\n", GetTabstring(tabDepth + 1), GetTabstring(tabDepth + 2), col.Name, database.Sheets.FirstOrDefault(s => s.Name.Equals(col.Key)).IDColumn.Name); break; case CastleType.Text: if (!jsonOff) { classStr += string.Format("{0}{1} = value[\"{1}\"].GetString();\r\n", GetTabstring(tabDepth + 1), col.Name); } loadBinStr += string.Format("{0}{1} = source.ReadString();\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.Custom: CastleCustom customType = database.CustomTypes.FirstOrDefault(t => t.Name.Equals(col.Key)); if (customType != null && !jsonOff) { classStr += string.Format("{0}JSONValue& {1}Array = value[\"{1}\"];\r\n", GetTabstring(tabDepth + 1), col.Name); classStr += string.Format("{0}if ({1}Array.size > 0) {{\r\n{2}int index = {1}Array[0];\r\n", GetTabstring(tabDepth + 1), col.Name, GetTabstring(tabDepth + 2)); classStr += string.Format("{0}switch (index) {{\r\n", GetTabstring(tabDepth + 2)); for (int i = 1; i < customType.Constructors.Count; ++i) { if (customType.Constructors[0].returnType.Equals("void")) { classStr += string.Format("{0}case {1}: {3}; break;\r\n", GetTabstring(tabDepth + 2), i, col.Name, customType.Constructors[i].GetCtor(col.Name, 0 /*cpp*/, database)); } else { classStr += string.Format("{0}case {1}: {2} = {3}; break;\r\n", GetTabstring(tabDepth + 2), i, col.Name, customType.Constructors[i].GetCtor(col.Name, 0 /*cpp*/, database)); } } classStr += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 2)); classStr += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 1)); } break; case CastleType.Dynamic: if (!jsonOff) { classStr += string.Format("{0}{1} = value[\"{1}\"];\r\n", GetTabstring(tabDepth + 1), col.Name); } break; case CastleType.TileLayer: if (!jsonOff) { classStr += string.Format("{0}if (value[\"{1}\"].isNull == false)\r\n{3}{1} = {2}(value[\"{1}\");\r\n", GetTabstring(tabDepth + 1), col.Name, "CastleTileLayer", GetTabstring(tabDepth + 2)); } break; case CastleType.Layer: if (!jsonOff) { classStr += string.Format("{0}if (value[\"{1}\"].isNull == false)\r\n{3}{1} = {2}(value[\"{1}\");\r\n", GetTabstring(tabDepth + 1), col.Name, "CastleDataLayer", GetTabstring(tabDepth + 2)); } break; case CastleType.TilePos: if (!jsonOff) { classStr += string.Format("{0}if (value[\"{1}\"].isNull == false)\r\n{3}{1}.Load(value[\"{1}\"]);\r\n", GetTabstring(tabDepth + 1), col.Name, "CastleTile", GetTabstring(tabDepth + 2)); } break; } } if (!jsonOff) { classStr += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 0)); } if (binIO) { loadBinStr += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 0)); saveBinStr += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 0)); classStr += loadBinStr; classStr += saveBinStr; } classStr += string.Format("\r\n{0}void ResolveReferences({1}@ db) {{\r\n", GetTabstring(tabDepth + 0), dbName); foreach (CastleColumn col in sheet.Columns) { if (col.TypeID == CastleType.Ref) { classStr += string.Format("{0}for (uint i = 0; i < db.{1}List.length; ++i) {{\r\n", GetTabstring(tabDepth + 1), col.Key); classStr += string.Format("{0}if (db.{1}List[i].{2} == {3}) {{\r\n", GetTabstring(tabDepth + 2), col.Key, database.Sheets.FirstOrDefault(s => s.Name.Equals(col.Key)).GetKeyName(), string.Format("{0}Key", col.Name)); classStr += string.Format("{0}@{1} = @db.{2}List[i];\r\n", GetTabstring(tabDepth + 3), col.Name, col.Key); classStr += string.Format("{0}break;\r\n", GetTabstring(tabDepth + 3)); classStr += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 2)); classStr += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 1)); } } classStr += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 0)); classStr += ASClassEnd; fileText += classStr; } // Generate the database class if (inherit.Length == 0) { fileText += string.Format("\r\nclass {0} {{\r\n", dbName); } else { fileText += string.Format("\r\nclass {0} : {1} {{\r\n", dbName, inherit); } foreach (CastleSheet sheet in database.Sheets) { if (sheet.Name.Contains("@")) { continue; } fileText += string.Format("{0}Array<{1}@> {1}List;\r\n", GetTabstring(tabDepth + 0), sheet.Name.Replace("@", "_")); fileText += string.Format("{0}JSONValue {1}Properties;\r\n", GetTabstring(tabDepth + 0), sheet.Name.Replace("@", "_")); } fileText += string.Format("\r\n{0}~{1}() {{\r\n", GetTabstring(tabDepth + 0), dbName); foreach (CastleSheet sheet in database.Sheets) { if (sheet.Name.Contains("@")) { continue; } fileText += string.Format("{0}{1}List.Clear();\r\n", GetTabstring(tabDepth + 1), sheet.Name.Replace("@", "_")); } fileText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 0)); // Database load if (!jsonOff) { fileText += string.Format("\r\n{0}void Load(JSONFile@ file) {{\r\n", GetTabstring(tabDepth + 0)); fileText += string.Format("{0}JSONValue sheetsElem = file.GetRoot()[\"sheets\"];\r\n", GetTabstring(tabDepth + 1)); fileText += string.Format("{0}for (uint i = 0; i < sheetsElem.size; ++i) {{\r\n", GetTabstring(tabDepth + 1)); fileText += string.Format("{0}JSONValue sheet = sheetsElem[i];\r\n{0}String sheetName = sheet[\"name\"].GetString();\r\n", GetTabstring(tabDepth + 2)); bool first = true; foreach (CastleSheet sheet in database.Sheets) { if (sheet.Name.Contains("@")) { continue; } fileText += string.Format("{0}{2} (sheetName == \"{1}\") {{\r\n", GetTabstring(tabDepth + 2), sheet.Name, first ? "if" : "else if"); fileText += string.Format("{0}JSONValue linesElem = sheet[\"lines\"];\r\n", GetTabstring(tabDepth + 3)); fileText += string.Format("{0}{1}Properties = sheet[\"props\"];\r\n", GetTabstring(tabDepth + 3), sheet.Name); fileText += string.Format("{0}for (uint j = 0; j < linesElem.size; ++j) {{\r\n", GetTabstring(tabDepth + 3)); fileText += string.Format("{0}{1}@ val = {1}();\r\n{0}val.Load(linesElem[j]);\r\n{0}{1}List.Push(val);\r\n", GetTabstring(tabDepth + 4), sheet.Name); fileText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 3)); fileText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 2)); first = false; } fileText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 1)); // Write reference resolving code foreach (CastleSheet sheet in database.Sheets) { if (sheet.HasReferences(database)) { fileText += string.Format("{0}for (uint i = 0; i < {1}List.length; ++i)\r\n", GetTabstring(tabDepth + 1), sheet.Name); fileText += string.Format("{0}{1}List[i].ResolveReferences(this);\r\n", GetTabstring(tabDepth + 2), sheet.Name); } } fileText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 0)); } if (binIO) { fileText += string.Format("\r\n{0}void Load(Deserializer& source) {{\r\n", GetTabstring(tabDepth + 0), dbName); foreach (CastleSheet sheet in database.Sheets) { if (sheet.Name.Contains("@")) { continue; } fileText += string.Format("{0}uint {1}Ct = source.ReadUInt();\r\n", GetTabstring(tabDepth + 1), sheet.Name); fileText += string.Format("{0}for (uint i = 0; i < {1}Ct; ++i) {{\r\n{2}{1}@ val = {1}();\r\n{2}{1}.Load(source);\r\n{2}{1}List.Push(val);\r\n{0}}}\r\n", GetTabstring(tabDepth + 1), sheet.Name, GetTabstring(tabDepth + 2)); } // Write reference resolving code foreach (CastleSheet sheet in database.Sheets) { if (sheet.Name.Contains("@")) { continue; } if (sheet.HasReferences(database)) { fileText += string.Format("{0}for (uint i = 0; i < {1}List.length; ++i)\r\n", GetTabstring(tabDepth + 1), sheet.Name); fileText += string.Format("{0}{1}List[i].ResolveReferences(this);\r\n", GetTabstring(tabDepth + 2), sheet.Name); } } fileText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 0)); fileText += string.Format("\r\n{0}void Save(Serializer& dest) {{\r\n", GetTabstring(tabDepth + 0), dbName); foreach (CastleSheet sheet in database.Sheets) { if (sheet.Name.Contains("@")) { continue; } fileText += string.Format("{0}dest.WriteUInt({1}List.length);\r\n", GetTabstring(tabDepth + 1), sheet.Name); fileText += string.Format("{0}for (uint i = 0; i < {1}List.length; ++i)\r\n{2}{1}List[i].Save(dest);\r\n", GetTabstring(tabDepth + 1), sheet.Name, GetTabstring(tabDepth + 2)); } fileText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 0)); } fileText += "}\r\n"; if (switches.ContainsKey("ns")) { fileText += "\r\n}\r\n"; } System.IO.File.WriteAllText(fileBase, fileText); }
static void Main(string[] args) { if (args.Length < 2) { Console.WriteLine("--------------------------------"); Console.WriteLine("CastleDBGen - (C) JSandusky 2015"); Console.WriteLine("--------------------------------"); Console.WriteLine("usage:"); Console.WriteLine(" CastleDBGen <input-db-path> <outputfilename>"); Console.WriteLine(" "); Console.WriteLine("switches:"); Console.WriteLine(" -ns: namespace, follow with namespace"); Console.WriteLine(" default: none"); Console.WriteLine(" C#: REQUIRED"); Console.WriteLine(" -lang: <language>: cpp, as, cs, lua"); Console.WriteLine(" default: cpp"); Console.WriteLine(" option: as"); Console.WriteLine(" option: cs"); Console.WriteLine(" option: lua"); Console.WriteLine(" option: asbind (generate AS bindings)"); Console.WriteLine(" -hd: <header path string>, C++ only"); Console.WriteLine(" -db: name for database class"); Console.WriteLine(" default: GameDatabase"); Console.WriteLine(" -id: type to use for Unique Identifiers"); Console.WriteLine(" default: string"); Console.WriteLine(" option: int"); Console.WriteLine(" -bin: type of binary read/write to support"); Console.WriteLine(" default: none"); Console.WriteLine(" option: on"); Console.WriteLine(" option: only"); Console.WriteLine(" -inherit: <classname>"); Console.WriteLine(" "); Console.WriteLine("examples:"); Console.WriteLine(" CastleDBGen C:\\MyDdatabase.cdb -lang cpp -ns MyNamespace"); Console.WriteLine(" CastleDBGen C:\\MyDdatabase.cdb -lang as"); Console.WriteLine(" CastleDBGen C:\\MyDdatabase.cdb -lang cpp -hd \"../HeaderPath/\""); return; } if (!System.IO.File.Exists(args[0])) { Console.WriteLine(string.Format("ERROR: File does not exist {0}", args[0])); return; } int lang = 0; string outName = args[0]; if (args.Length > 1) { outName = args[1]; } Dictionary <string, string> switches = new Dictionary <string, string>(); for (int i = 0; i < args.Length; i += 1) { if (args[i].StartsWith("-")) { switches[args[i].Replace("-", "")] = args[i + 1]; i += 1; } } if (switches.ContainsKey("lang")) { lang = GetLangIndex(switches["lang"]); if (lang == -1) { lang = 0; } } CastleDB db = new CastleDB(args[0]); List <string> errors = new List <string>(); switch (lang) { case 0: outName = System.IO.Path.ChangeExtension(outName, ".cpp"); new CppWriter().WriteClassDefinitions(db, outName, args[0], switches, errors); break; case 1: outName = System.IO.Path.ChangeExtension(outName, ".as"); new AngelscriptWriter().WriteClassDefinitions(db, outName, args[0], switches, errors); break; case 2: outName = System.IO.Path.ChangeExtension(outName, ".cs"); new CSharpWriter().WriteClassDefinitions(db, outName, args[0], switches, errors); break; case 3: outName = System.IO.Path.ChangeExtension(outName, ".lua"); new LuaWriter().WriteClassDefinitions(db, outName, args[0], switches, errors); break; case 4: outName = System.IO.Path.ChangeExtension(outName, ".cpp"); new ASBindingWriter().WriteClassDefinitions(db, outName, args[0], switches, errors); break; } foreach (string error in errors) { Console.WriteLine(string.Format("ERR: {0}", error)); } MyNamespace.MyDB dbTest = new MyNamespace.MyDB(); dbTest.Load(Newtonsoft.Json.Linq.JObject.Parse(System.IO.File.ReadAllText(args[0]))); }
static readonly string LuaProperty = "{0} {1};\n"; // Type name;\n public override void WriteClassDefinitions(CastleDB database, string fileBase, string sourceFileName, Dictionary <string, string> switches, List <string> errors) { int tabDepth = 0; string fileText = string.Format("-- AUTOGENERATED LUA SOURCE CODE FROM {0}\r\n", sourceFileName); bool integerIDs = false; if (switches.ContainsKey("id")) { integerIDs = switches["id"].Equals("int"); } bool binIO = false; bool jsonOff = false; if (switches.ContainsKey("bin")) { binIO = switches["bin"].Equals("on") || switches["bin"].Equals("only"); jsonOff = switches["bin"].Equals("only"); } foreach (CastleSheet sheet in database.Sheets) { string sheetName = sheet.Name.Replace("@", "_"); fileText += string.Format("\r\nfunction ResolveReferences{0}(self, database)\r\n", sheetName); foreach (CastleColumn col in sheet.Columns) { if (col.TypeID == CastleType.Ref) { fileText += string.Format("{0}self.{1} = database:FindTable(\"{2}\", self.{1}Key, \"{3}\")\r\n", GetTabstring(0), col.Name, col.Key, database.Sheets.FirstOrDefault(s => s.Name.Equals(col.Key)).IDColumn.Name); } } if (!jsonOff) { fileText += string.Format("\r\nfunction Load{0}(self, jobject)\r\n", sheetName); } string binLoadText = string.Format("\r\nfunction Load{0}Binary(self, source)\r\n", sheetName); string binWriteText = string.Format("\r\nfunction Save{0}(self, dest)\r\n", sheetName); foreach (CastleColumn col in sheet.Columns) { switch (col.TypeID) { case CastleType.UniqueIdentifier: if (!jsonOff) { fileText += string.Format("{0}self.{1} = value[\"{1}\"]:GetString()\r\n", GetTabstring(tabDepth + 0), col.Name); } binLoadText += string.Format("{0}self.{1} = source:Readstring()\r\n", GetTabstring(tabDepth + 0), col.Name); binWriteText += string.Format("{0}dest:Writestring(self.{1});\r\n", GetTabstring(tabDepth + 0), col.Name); break; case CastleType.Boolean: if (!jsonOff) { fileText += string.Format("{0}self.{1} = value[\"{1}\"]:GetBool()\r\n", GetTabstring(tabDepth + 0), col.Name); } binLoadText += string.Format("{0}self.{1} = source:ReadBool()\r\n", GetTabstring(tabDepth + 0), col.Name); binWriteText += string.Format("{0}dest:WriteBool(self.{1});\r\n", GetTabstring(tabDepth + 0), col.Name); break; case CastleType.Color: if (!jsonOff) { fileText += string.Format("{0}self.{1}.FromUInt(value[\"{1}\"]:GetUInt())\r\n", GetTabstring(tabDepth + 0), col.Name); } binLoadText += string.Format("{0}self.{1} = source:ReadColor()\r\n", GetTabstring(tabDepth + 0), col.Name); binWriteText += string.Format("{0}dest:WriteColor(self.{1});\r\n", GetTabstring(tabDepth + 0), col.Name); break; case CastleType.Enum: if (!jsonOff) { fileText += string.Format("{0}self.{1} = value[\"{1}\"]:GetInt()\r\n", GetTabstring(tabDepth + 0), col.Name); } binLoadText += string.Format("{0}self.{1} = source:ReadInt()\r\n", GetTabstring(tabDepth + 0), col.Name); binWriteText += string.Format("{0}dest:WriteInt(self.{1});\r\n", GetTabstring(tabDepth + 0), col.Name); break; case CastleType.File: if (!jsonOff) { fileText += string.Format("{0}self.{1} = value[\"{1}\"]:GetString()\r\n", GetTabstring(tabDepth + 0), col.Name); } binLoadText += string.Format("{0}self.{1} = source:Readstring()\r\n", GetTabstring(tabDepth + 0), col.Name); binWriteText += string.Format("{0}dest:Writestring(self.{1});\r\n", GetTabstring(tabDepth + 0), col.Name); break; case CastleType.Flags: if (!jsonOff) { fileText += string.Format("{0}self.{1} = value[\"{1}\"]:GetUInt()\r\n", GetTabstring(tabDepth + 0), col.Name); } binLoadText += string.Format("{0}self.{1} = source:ReadUInt()\r\n", GetTabstring(tabDepth + 0), col.Name); binWriteText += string.Format("{0}dest:WriteUInt(self.{1});\r\n", GetTabstring(tabDepth + 0), col.Name); break; case CastleType.Float: if (!jsonOff) { fileText += string.Format("{0}self.{1} = value[\"{1}\"]:GetFloat()\r\n", GetTabstring(tabDepth + 0), col.Name); } binLoadText += string.Format("{0}self.{1} = source:ReadFloat()\r\n", GetTabstring(tabDepth + 0), col.Name); binWriteText += string.Format("{0}dest:WriteFloat(self.{1});\r\n", GetTabstring(tabDepth + 0), col.Name); break; case CastleType.Integer: if (!jsonOff) { fileText += string.Format("{0}self.{1} = value[\"{1}\"]:GetInt()\r\n", GetTabstring(tabDepth + 0), col.Name); } binLoadText += string.Format("{0}self.{1} = source:ReadInt()\r\n", GetTabstring(tabDepth + 0), col.Name); binWriteText += string.Format("{0}dest:WriteInt(self.{1});\r\n", GetTabstring(tabDepth + 0), col.Name); break; case CastleType.List: if (!jsonOff) { fileText += string.Format("{0}local {1}Array = value[\"{1}\"]\r\n", GetTabstring(tabDepth + 0), col.Name); fileText += string.Format("{0}for i = 0, {1}Array:Size() do\r\n", GetTabstring(tabDepth + 0), col.Name); fileText += string.Format("{0}local val = {{ }}\r\n", GetTabstring(tabDepth + 1), string.Format("{0}_{1}", sheetName, col.Name)); fileText += string.Format("{0}Load{1}(val, {1}Array[i])\r\n{0}{2}[#{2}+1] = val\r\n", GetTabstring(tabDepth + 1), col.Name, col.Name); binLoadText += string.Format("{0}end\r\n", GetTabstring(tabDepth + 0)); } binLoadText += string.Format("{0}local {1}Ct = source:ReadUInt()\r\n", GetTabstring(tabDepth + 0), col.Name); binLoadText += string.Format("{0}for i = 0, {1}Ct - 1 do\r\n", GetTabstring(tabDepth + 0), col.Name); binLoadText += string.Format("{0}local val = {{ }}\r\n", GetTabstring(tabDepth + 1), string.Format("{0}_{1}", sheetName, col.Name)); binLoadText += string.Format("{0}Load{1}(val, source)\r\n{0}{2}[#{2}+1], val)\r\n", GetTabstring(tabDepth + 1), col.Name, col.Name); binLoadText += string.Format("{0}end\r\n", GetTabstring(tabDepth + 0)); binWriteText += string.Format("{0}dest:WriteUInt(table.getn(self.{1}))\r\n", GetTabstring(tabDepth + 0), col.Name); binWriteText += string.Format("{0}for i = 0, table.getn(self.{1}) - 1 do\r\n", GetTabstring(tabDepth + 0), col.Name); binWriteText += string.Format("{0}self.{1}[i]:Save{2}(source)\t\n", GetTabstring(tabDepth + 1), col.Name, col.Key); binWriteText += string.Format("{0}end\r\n", GetTabstring(tabDepth + 0)); break; case CastleType.Ref: if (!jsonOff) { fileText += string.Format("{0}self.{1}Key = value[\"{1}\"]:GetString()\r\n", GetTabstring(tabDepth + 0), col.Name); } binLoadText += string.Format("{0}self.{1}Key = source:Readstring()\r\n", GetTabstring(tabDepth + 0), col.Name); binWriteText += string.Format("{0}dest:Writestring({1}.{2})\r\n", GetTabstring(tabDepth + 0), col.Name, database.Sheets.FirstOrDefault(s => s.Name.Equals(col.Key)).IDColumn.Name); break; case CastleType.Text: if (!jsonOff) { fileText += string.Format("{0}self.{1} = value[\"{1}\"]:GetString()\r\n", GetTabstring(tabDepth + 0), col.Name); } binLoadText += string.Format("{0}self.{1} = source:Readstring()\r\n", GetTabstring(tabDepth + 0), col.Name); binWriteText += string.Format("{0}dest:Writestring(self.{1})\r\n", GetTabstring(tabDepth + 0), col.Name); break; } } fileText += string.Format("{0}self.ResolveReferences = ResolveReference{1}\r\n", GetTabstring(tabDepth + 0), sheetName); binLoadText += string.Format("{0}self.ResolveReferences = ResolveReference{1}\r\n", GetTabstring(tabDepth + 0), sheetName); fileText += "end\r\n"; binLoadText += "end\r\n"; binWriteText += "end\r\n"; if (binIO) { fileText += binLoadText; fileText += binWriteText; } } fileText += "\r\nfunction FindDatabaseTable(self, recordValue, tableName, recordName)\r\n" + " for k, v in ipairs(self) do\r\n" + " if k == tableName then\r\n" + " if v[tableName][recordName] == recordValue then\r\n" + " return v[tableName]\r\n" + " end\r\n" + " end\r\n" + " end\r\n" + "end\r\n"; fileText += "\r\nfunction LoadDatabase(file)\r\n" + " local db = { }\r\n" + " -- load the data from file\r\n" + " for k = 0, file:GetRoot():Size() do\r\n" + " local sheet = file:GetRoot()[k]\r\n" + " local sheetName = sheet:Get(\"name\"):GetString()\r\n"; foreach (CastleSheet sheet in database.Sheets) { string sheetName = sheet.Name.Replace("@", "_"); fileText += string.Format(" if sheetName == \"{0}\" then\r\n", sheetName) + " local linesElem = sheet:Get(\"lines\")\r\n" + " for ln = 0, linesElem:Size() do\r\n" + " local val = { }\r\n"; fileText += string.Format(" Load{0}(linesElem[ln])\r\n", sheetName); fileText += string.Format(" db.{0}List[#db.{0}List + 1] = val\r\n", sheetName); fileText += " end\r\n"; fileText += " end\r\n"; } fileText += " end\r\n"; fileText += " for k,v in ipairs(db) do\r\n"; fileText += " for kk, vv in ipairs(v) do\r\n"; fileText += " vv:ResolveReferences()\r\n"; fileText += " end\r\n"; fileText += " end\r\n"; fileText += "end\r\n"; System.IO.File.WriteAllText(fileBase, fileText); }
public abstract void WriteClassDefinitions(CastleDB database, string fileBase, string sourceFileName, Dictionary <string, string> switches, List <string> errors);
static readonly string ASProperty = "{2}public {0} {1} {{ get; set; }}\r\n"; // Type name;\n public override void WriteClassDefinitions(CastleDB database, string fileBase, string sourceFileName, Dictionary <string, string> switches, List <string> errors) { string dbName = "GameDatabase"; if (switches.ContainsKey("db")) { dbName = switches["db"]; } int tabDepth = 0; string namespaceName = switches["ns"]; string fileText = string.Format("// AUTOGENERATED C# SOURCE CODE FROM {0}\r\n", sourceFileName); fileText += "\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing Newtonsoft.Json.Linq;\r\n"; fileText += string.Format("\r\nnamespace {0} {{\r\n", namespaceName); // Scan for enumerations and flags foreach (CastleSheet sheet in database.Sheets) { foreach (CastleColumn column in sheet.Columns) { if (column.TypeID == CastleType.Enum) { fileText += string.Format("\r\npublic enum E_{0} {{\r\n", column.Name.ToUpper()); foreach (string value in column.Enumerations) { fileText += string.Format("{0}{1},\r\n", GetTabstring(tabDepth + 0), value.ToUpper()); } fileText += "}\r\n"; } } } foreach (CastleSheet sheet in database.Sheets) { string sheetName = sheet.Name.Replace('@', '_'); string classStr = string.Format(ASClassStart, sheetName); foreach (CastleColumn column in sheet.Columns) { switch (column.TypeID) { case CastleType.UniqueIdentifier: classStr += string.Format(ASProperty, "string", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.Boolean: classStr += string.Format(ASProperty, "bool", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.Color: classStr += string.Format(ASProperty, "Color", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.Custom: case CastleType.Dynamic: errors.Add(string.Format("Sheet {0}, type {1} unsupported", column.Name, column.TypeID.ToString())); break; case CastleType.Enum: classStr += string.Format(ASProperty, string.Format("E_{0}", column.Name.ToUpper()), column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.File: classStr += string.Format(ASProperty, "string", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.Flags: classStr += string.Format(ASProperty, "uint", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.Image: errors.Add(string.Format("Sheet {0}, type {1} unsupported", column.Name, column.TypeID.ToString())); //classStr += string.Format(ASProperty, "string", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.Integer: classStr += string.Format(ASProperty, "int", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.Layer: errors.Add(string.Format("Sheet {0}, type {1} unsupported", column.Name, column.TypeID.ToString())); break; case CastleType.List: classStr += string.Format("{0}public List<{1}> {2} = new List<{1}>();\r\n", GetTabstring(tabDepth + 0), string.Format("{0}_{1}", sheet.Name, column.Name), column.Name); break; case CastleType.Ref: classStr += string.Format("{0}public {1} {2} = null;\r\n", GetTabstring(tabDepth + 0), column.Key, column.Name); classStr += string.Format("{0}private string {2}Key;\r\n", GetTabstring(tabDepth + 0), column.Key, column.Name); break; case CastleType.Text: classStr += string.Format(ASProperty, "string", column.Name, GetTabstring(tabDepth + 0)); break; case CastleType.TileLayer: errors.Add(string.Format("Sheet {0}, type {1} unsupported", column.Name, column.TypeID.ToString())); break; case CastleType.TilePos: errors.Add(string.Format("Sheet {0}, type {1} unsupported", column.Name, column.TypeID.ToString())); break; } } // generate loading function classStr += string.Format("\r\n{0}public void Load(JObject value) {{\r\n", GetTabstring(tabDepth + 0)); foreach (CastleColumn col in sheet.Columns) { switch (col.TypeID) { case CastleType.UniqueIdentifier: classStr += string.Format("{0}{1} = value.Property(\"{1}\").Value.ToString();\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.Boolean: classStr += string.Format("{0}{1} = value.Property(\"{1}\").Value.ToString().Equals(\"true\");\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.Color: classStr += string.Format("{0}{1}.FromUInt(uint.Parse(value.Property(\"{1}\").Value.ToString());\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.Enum: classStr += string.Format("{0}{1} = (E_{2})int.Parse(value.Property(\"{1}\").Value.ToString());\r\n", GetTabstring(tabDepth + 1), col.Name, col.Name.ToUpper()); break; case CastleType.Image: // Unimplemented break; case CastleType.File: classStr += string.Format("{0}{1} = value.Property(\"{1}\").ToString();\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.Flags: classStr += string.Format("{0}{1} = uint.Parse(value.Property(\"{1}\").Value.ToString());\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.Float: classStr += string.Format("{0}{1} = float.Parse(value.Property(\"{1}\").Value.ToString());r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.Integer: classStr += string.Format("{0}{1} = int.Parse(value.Property(\"{1}\").Value.ToString());\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.List: classStr += string.Format("{0}JArray {1}Array = value.Property(\"{1}\").Value as JArray;\r\n", GetTabstring(tabDepth + 1), col.Name); classStr += string.Format("{0}for (int i = 0; i < {1}Array.Count; ++i) {{\r\n", GetTabstring(tabDepth + 1), col.Name); classStr += string.Format("{0}{1} val = new {1}();\r\n", GetTabstring(tabDepth + 2), string.Format("{0}_{1}", sheet.Name, col.Name)); classStr += string.Format("{0}val.Load({1}Array[i] as JObject);\r\n{0}{2}.Add(val);\r\n", GetTabstring(tabDepth + 2), col.Name, col.Name); classStr += string.Format("{0}}} \r\n", GetTabstring(tabDepth + 1)); break; case CastleType.Ref: classStr += string.Format("{0}{1}Key = value.Property(\"{1}\").Value.ToString();\r\n", GetTabstring(tabDepth + 1), col.Name); break; case CastleType.Text: classStr += string.Format("{0}{1} = value.Property(\"{1}\").Value.ToString();\r\n", GetTabstring(tabDepth + 1), col.Name); break; } } classStr += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 0)); classStr += string.Format("\r\n{0}public void ResolveReferences({1} db) {{\r\n", GetTabstring(tabDepth + 0), dbName); foreach (CastleColumn col in sheet.Columns) { if (col.TypeID == CastleType.Ref) { classStr += string.Format("{0}for (int i = 0; i < db.{1}List.Count; ++i) {{\r\n", GetTabstring(tabDepth + 1), col.Key); classStr += string.Format("{0}if (db.{1}List[i].{2}.Equals({3})) {{\r\n", GetTabstring(tabDepth + 2), col.Key, database.Sheets.FirstOrDefault(s => s.Name.Equals(col.Key)).GetKeyName(), string.Format("{0}Key", col.Name)); classStr += string.Format("{0}{1} = db.{2}List[i];\r\n", GetTabstring(tabDepth + 3), col.Name, col.Key); classStr += string.Format("{0}break;\r\n", GetTabstring(tabDepth + 3)); classStr += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 2)); classStr += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 1)); } } classStr += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 0)); classStr += ASClassEnd; fileText += classStr; } fileText += string.Format("\r\npublic class {0} {{\r\n", dbName); foreach (CastleSheet sheet in database.Sheets) { if (sheet.Name.Contains("@")) { continue; } fileText += string.Format("{0}public List<{1}> {1}List = new List<{1}>();\r\n", GetTabstring(tabDepth + 0), sheet.Name); } fileText += string.Format("\r\n{0}public void Load(JObject file) {{\r\n", GetTabstring(tabDepth + 0)); fileText += string.Format("{0}JArray sheetsElem = file.Property(\"sheets\").Value as JArray;\r\n", GetTabstring(tabDepth + 1)); fileText += string.Format("{0}for (int i = 0; i < sheetsElem.Count; ++i) {{\r\n", GetTabstring(tabDepth + 1)); fileText += string.Format("{0}JObject sheet = sheetsElem[i] as JObject;\r\n{0}string sheetName = sheet.Property(\"name\").Value.ToString();\r\n", GetTabstring(tabDepth + 2)); bool first = true; foreach (CastleSheet sheet in database.Sheets) { if (sheet.Name.Contains("@")) { continue; } fileText += string.Format("{0}{2} (sheetName.Equals(\"{1}\")) {{\r\n", GetTabstring(tabDepth + 2), sheet.Name, first ? "if" : "else if"); fileText += string.Format("{0}JArray linesElem = sheet.Property(\"lines\").Value as JArray;\r\n", GetTabstring(tabDepth + 3)); fileText += string.Format("{0}for (int j = 0; j < linesElem.Count; ++j) {{\r\n", GetTabstring(tabDepth + 3)); fileText += string.Format("{0}{1} val = new {1}();\r\n{0}val.Load(linesElem[j] as JObject);\r\n{0}{1}List.Add(val);\r\n", GetTabstring(tabDepth + 4), sheet.Name); fileText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 3)); fileText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 2)); first = false; } fileText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 1)); // Write reference resolving code foreach (CastleSheet sheet in database.Sheets) { if (sheet.Name.Contains("@")) { continue; } if (sheet.HasReferences(database)) { fileText += string.Format("{0}for (int i = 0; i < {1}List.Count; ++i)\r\n", GetTabstring(tabDepth + 1), sheet.Name); fileText += string.Format("{0}{1}List[i].ResolveReferences(this);\r\n", GetTabstring(tabDepth + 2), sheet.Name); } } fileText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 0)); fileText += "}\r\n"; fileText += "\r\n}\r\n"; System.IO.File.WriteAllText(fileBase, fileText); }
static readonly string CPPProperty = "{2}{0} {1};\n"; // Type name;\n public override void WriteClassDefinitions(CastleDB database, string fileBase, string sourceFileName, Dictionary <string, string> switches, List <string> errors) { Dictionary <string, Dictionary <string, string> > IDSTable = new Dictionary <string, Dictionary <string, string> >(); string headerText = string.Format("// AUTOGENERATED C++ SOURCE CODE FROM {0}\r\n#pragma once;\r\n\r\n", sourceFileName); string dbName = "GameDatabase"; if (switches.ContainsKey("db")) { dbName = switches["db"]; } bool integerIDs = false; if (switches.ContainsKey("id")) { integerIDs = switches["id"].Equals("int"); } bool binIO = false; bool jsonOff = false; if (switches.ContainsKey("bin")) { binIO = switches["bin"].Equals("on") || switches["bin"].Equals("only"); jsonOff = switches["bin"].Equals("only"); } string inherit = ""; if (switches.ContainsKey("inherit")) { inherit = switches["inherit"]; } string headerPath = System.IO.Path.ChangeExtension(fileBase, ".h"); if (switches.ContainsKey("hd")) { headerPath = string.Format("{0}/{1}", switches["hd"], headerPath); } bool hasTilePos = false; bool hasLayers = false; foreach (CastleSheet sheet in database.Sheets) { foreach (CastleColumn column in sheet.Columns) { if (column.TypeID == CastleType.TileLayer || column.TypeID == CastleType.Layer) { hasLayers = true; } else if (column.TypeID == CastleType.TilePos) { hasTilePos = true; } } } // Write header string sourceText = string.Format("// AUTOGENERATED C++ SOURCE CODE FROM {0}\r\n#include \"{1}\"\r\n", sourceFileName, headerPath); headerText += "#include <Urho3D/Math/Color.h>\r\n"; if (binIO) { headerText += "#include <Urho3D/IO/Deserializer.h>\r\n"; } headerText += "#include <Urho3D/Resource/JSONFile.h>\r\n"; headerText += "#include <Urho3D/Resource/JSONValue.h>\r\n"; if (inherit.Equals("RefCounted")) { headerText += "#include <Urho3D/Container/Ptr.h>\r\n"; headerText += "#include <Urho3D/Container/RefCounted.h>\r\n"; } if (binIO) { headerText += "#include <Urho3D/IO/Serializer.h>\r\n"; } headerText += "#include <Urho3D/Container/Str.h>\r\n"; headerText += "#include <Urho3D/Container/Vector.h>\r\n"; headerText += "using namespace Urho3D;\r\n"; int tabDepth = 0; if (switches.ContainsKey("ns")) { headerText += string.Format("\r\nnamespace {0} {{\r\n", switches["ns"]); sourceText += string.Format("\r\nnamespace {0} {{\r\n", switches["ns"]); } if (hasTilePos) { headerText += cppCastleTileCode; } if (hasLayers) { headerText += cppLayerClasses; } // Forward declarations headerText += "\r\n// Forward declarations\r\n"; foreach (CastleSheet sheet in database.Sheets) { // prepare IDs table IDSTable[sheet.Name] = new Dictionary <string, string>(); headerText += string.Format("class {0};\r\n", sheet.Name.Replace("@", "_")); } headerText += string.Format("class {0};\r\n", dbName); // Scan for enumerations and flags foreach (CastleSheet sheet in database.Sheets) { foreach (CastleColumn column in sheet.Columns) { if (column.TypeID == CastleType.Enum) { headerText += string.Format("\r\nenum E_{0} {{\r\n", column.Name.ToUpper()); foreach (string value in column.Enumerations) { headerText += string.Format("{0}{1},\r\n", GetTabstring(tabDepth + 0), value.ToUpper()); } headerText += "};\r\n"; } else if (column.TypeID == CastleType.Flags) { headerText += "\r\n"; int index = 0; foreach (string value in column.Enumerations) { headerText += string.Format("static const unsigned {0}_{1} = {2};\r\n", column.Name.ToUpper(), value.ToUpper(), 1 << index); ++index; } } } } if (hasLayers) { sourceText += cppSourceBase64; } foreach (CastleSheet sheet in database.Sheets) { string sheetName = sheet.Name.Replace('@', '_'); string classStr = inherit.Length > 0 ? string.Format(CPPClassStartInherit, sheetName, inherit) : string.Format(CPPClassStart, sheetName); string cppClassStr = string.Format("{1}\nvoid {0}::Load(JSONValue& value) {{\r\n", sheetName, GetTabstring(tabDepth)); string binLoadClassStr = ""; string binWriteClassStr = ""; binLoadClassStr = string.Format("{1}\nvoid {0}::Load(Deserializer& source) {{\r\n", sheetName, GetTabstring(tabDepth)); binWriteClassStr = string.Format("{1}\nvoid {0}::Save(Serializer& dest) {{\r\n", sheetName, GetTabstring(tabDepth)); foreach (CastleColumn column in sheet.Columns) { switch (column.TypeID) { case CastleType.UniqueIdentifier: classStr += string.Format(CPPProperty, "String", column.Name, GetTabstring(tabDepth + 0)); cppClassStr += string.Format("{0}{1} = value[\"{1}\"].GetString();\r\n", GetTabstring(tabDepth + 0), column.Name); binLoadClassStr += string.Format("{0}{1} = source.ReadString();\r\n", GetTabstring(tabDepth + 0), column.Name); binWriteClassStr += string.Format("{0}dest.WriteString({1});\r\n", GetTabstring(tabDepth + 0), column.Name); break; case CastleType.Boolean: classStr += string.Format(CPPProperty, "bool", column.Name, GetTabstring(tabDepth + 0)); cppClassStr += string.Format("{0}{1} = value[\"{1}\"].GetBool();\r\n", GetTabstring(tabDepth + 0), column.Name); binLoadClassStr += string.Format("{0}{1} = source.ReadBool();\r\n", GetTabstring(tabDepth + 0), column.Name); binWriteClassStr += string.Format("{0}dest.WriteBool({1});\r\n", GetTabstring(tabDepth + 0), column.Name); break; case CastleType.Color: classStr += string.Format(CPPProperty, "Color", column.Name, GetTabstring(tabDepth + 0)); cppClassStr += string.Format("{0}{1}.FromUInt(value[\"{1}\"].GetUInt());\r\n", GetTabstring(tabDepth + 0), column.Name); binLoadClassStr += string.Format("{0}{1} = source.ReadColor();\r\n", GetTabstring(tabDepth + 0), column.Name); binWriteClassStr += string.Format("{0}dest.WriteColor({1});\r\n", GetTabstring(tabDepth + 0), column.Name); break; case CastleType.Custom: CastleCustom customType = database.CustomTypes.FirstOrDefault(t => t.Name.Equals(column.Key)); if (customType != null) { //Void return types are assume to be method invocations if (!customType.Constructors[0].returnType.Equals("void")) { classStr += string.Format(CPPProperty, string.Format("{0}", customType.Constructors[0].returnType), column.Name, GetTabstring(tabDepth + 0)); } cppClassStr += string.Format("{0}JSONValue& {1}Array = value[\"{1}\"];\r\n", GetTabstring(tabDepth + 0), column.Name); cppClassStr += string.Format("{0}if ({1}Array.Size() > 0) {{\r\n{2}int index = {1}Array[0];\r\n", GetTabstring(tabDepth + 0), column.Name, GetTabstring(tabDepth + 1)); cppClassStr += string.Format("{0}switch (index) {{\r\n", GetTabstring(tabDepth + 1)); for (int i = 1; i < customType.Constructors.Count; ++i) { if (customType.Constructors[0].returnType.Equals("void")) { cppClassStr += string.Format("{0}case {1}: {3}; break;\r\n", GetTabstring(tabDepth + 1), i, column.Name, customType.Constructors[i].GetCtor(column.Name, 0 /*cpp*/, database)); } else { cppClassStr += string.Format("{0}case {1}: {2} = {3}; break;\r\n", GetTabstring(tabDepth + 1), i, column.Name, customType.Constructors[i].GetCtor(column.Name, 0 /*cpp*/, database)); } } cppClassStr += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 1)); cppClassStr += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 0)); } break; case CastleType.Dynamic: classStr += string.Format(CPPProperty, "JSONValue", column.Name, GetTabstring(tabDepth + 0)); cppClassStr += string.Format("{0}{1} = value[\"{1}\"];\r\n", GetTabstring(tabDepth + 0), column.Name); break; case CastleType.Enum: classStr += string.Format(CPPProperty, string.Format("E_{0}", column.Name.ToUpper()), column.Name, GetTabstring(tabDepth + 0)); cppClassStr += string.Format("{0}{1} = (E_{2})value[\"{1}\"].GetInt();\r\n", GetTabstring(tabDepth + 0), column.Name, column.Name.ToUpper()); binLoadClassStr += string.Format("{0}{1} = (E_{2})source.ReadInt();\r\n", GetTabstring(tabDepth + 0), column.Name, column.Name.ToUpper()); binWriteClassStr += string.Format("{0}dest.WriteInt((int){1});\r\n", GetTabstring(tabDepth + 0), column.Name); break; case CastleType.File: classStr += string.Format(CPPProperty, "String", column.Name, GetTabstring(tabDepth + 0)); cppClassStr += string.Format("{0}{1} = value[\"{1}\"].GetString();\r\n", GetTabstring(tabDepth + 0), column.Name); binLoadClassStr += string.Format("{0}{1} = source.ReadString();\r\n", GetTabstring(tabDepth + 0), column.Name); binWriteClassStr += string.Format("{0}dest.WriteString({1});\r\n", GetTabstring(tabDepth + 0), column.Name); break; case CastleType.Flags: classStr += string.Format(CPPProperty, "unsigned", column.Name, GetTabstring(tabDepth + 0)); cppClassStr += string.Format("{0}{1} = value[\"{1}\"].GetUInt();\r\n", GetTabstring(tabDepth + 0), column.Name); binLoadClassStr += string.Format("{0}{1} = source.ReadUInt();\r\n", GetTabstring(tabDepth + 0), column.Name); binWriteClassStr += string.Format("{0}dest.WriteUInt({1});\r\n", GetTabstring(tabDepth + 0), column.Name); break; case CastleType.Image: classStr += string.Format(CPPProperty, "String", column.Name, GetTabstring(tabDepth + 0)); cppClassStr += string.Format("{0}String {1}Str = value[\"{1}\"].GetString();\r\n{0}if ({1}Str.Length() > 0) {1} = {1}Str.Substring({1}Str.Find(':'));\r\n", GetTabstring(tabDepth + 0), column.Name); break; case CastleType.Integer: classStr += string.Format(CPPProperty, "int", column.Name, GetTabstring(tabDepth + 0)); cppClassStr += string.Format("{0}{1} = value[\"{1}\"].GetInt();\r\n", GetTabstring(tabDepth + 0), column.Name); binLoadClassStr += string.Format("{0}{1} = source.ReadInt();\r\n", GetTabstring(tabDepth + 0), column.Name); binWriteClassStr += string.Format("{0}dest.WriteInt({1});\r\n", GetTabstring(tabDepth + 0), column.Name); break; case CastleType.List: if (inherit.Equals("RefCounted")) { classStr += string.Format("{0}Vector<SharedPtr<{1}> > {2};\r\n", GetTabstring(tabDepth + 0), string.Format("{0}_{1}", sheet.Name, column.Name), column.Name); } else { classStr += string.Format("{0}Vector<{1}*> {2};\r\n", GetTabstring(tabDepth + 0), string.Format("{0}_{1}", sheet.Name, column.Name), column.Name); } cppClassStr += string.Format("{0}JSONValue& {1}Array = value[\"{1}\"];\r\n", GetTabstring(tabDepth + 0), column.Name); cppClassStr += string.Format("{0}for (unsigned i = 0; i < {1}Array.Size(); ++i) {{\r\n", GetTabstring(tabDepth + 0), column.Name); if (inherit.Equals("RefCounted")) { cppClassStr += string.Format("{0}SharedPtr<{1}> val(new {1}());\r\n", GetTabstring(tabDepth + 1), string.Format("{0}_{1}", sheet.Name, column.Name)); } else { cppClassStr += string.Format("{0}{1}* val = new {1}();\r\n", GetTabstring(tabDepth + 1), string.Format("{0}_{1}", sheet.Name, column.Name)); } cppClassStr += string.Format("{0}val->Load({1}Array[i]);\r\n{0}{2}.Push(val);\r\n", GetTabstring(tabDepth + 1), column.Name, column.Name); cppClassStr += string.Format("{0}}} \r\n", GetTabstring(tabDepth + 0)); binLoadClassStr += string.Format("{0}const unsigned {1}Ct = source.ReadUInt();\r\n{0}for (unsigned i = 0; i < {1}Ct; ++i) {{\r\n", GetTabstring(tabDepth + 0), column.Name); if (inherit.Equals("RefCounted")) { binLoadClassStr += string.Format("{0}SharedPtr<{1}> val(new {1}());\r\n", GetTabstring(tabDepth + 1), string.Format("{0}_{1}", sheet.Name, column.Name)); } else { binLoadClassStr += string.Format("{0}{1}* val = new {1}();\r\n", GetTabstring(tabDepth + 1), string.Format("{0}_{1}", sheet.Name, column.Name)); } binLoadClassStr += string.Format("{0}val->Load(source);\r\n{0}{2}.Push(val);\r\n", GetTabstring(tabDepth + 1), column.Name, column.Name); binLoadClassStr += string.Format("{0}}} \r\n", GetTabstring(tabDepth + 0)); binWriteClassStr += string.Format("{0}dest.WriteUInt({1}.Size());\r\n", GetTabstring(tabDepth + 0), column.Name); binWriteClassStr += string.Format("{0}for (unsigned i = 0; i < {1}.Size(); ++i)\r\n", GetTabstring(tabDepth + 0), column.Name); binWriteClassStr += string.Format("{0}{1}[i]->Save(dest);\r\n", GetTabstring(tabDepth + 1), column.Name); break; case CastleType.Ref: if (inherit.Equals("RefCounted")) { classStr += string.Format("{0}SharedPtr<{1}> {2};\r\n", GetTabstring(tabDepth + 0), column.Key, column.Name); } else { classStr += string.Format("{0}{1}* {2};\r\n", GetTabstring(tabDepth + 0), column.Key, column.Name); } classStr += string.Format("{0}String {2}Key;\r\n", GetTabstring(tabDepth + 0), column.Key, column.Name); cppClassStr += string.Format("{0}{1} = 0x0;\r\n", GetTabstring(tabDepth + 0), column.Name); cppClassStr += string.Format("{0}{1}Key = value[\"{1}\"].GetString();\r\n", GetTabstring(tabDepth + 0), column.Name); binLoadClassStr += string.Format("{0}{1} = 0x0;\r\n", GetTabstring(tabDepth + 0), column.Name); binLoadClassStr += string.Format("{0}{1}Key = source.ReadString();\r\n", GetTabstring(tabDepth + 0), column.Name); binWriteClassStr += string.Format("{0}if ({2} == 0x0)\r\n{1}source.WriteString(\"\");\r\n{0}else\r\n{1}source.WriteString({2}.{3});\r\n", GetTabstring(tabDepth + 0), GetTabstring(tabDepth + 1), column.Name, database.Sheets.FirstOrDefault(s => s.Name.Equals(column.Key)).IDColumn.Name); break; case CastleType.Text: classStr += string.Format(CPPProperty, "String", column.Name, GetTabstring(tabDepth + 0)); cppClassStr += string.Format("{0}{1} = value[\"{1}\"].GetString();\r\n", GetTabstring(tabDepth + 0), column.Name); binLoadClassStr += string.Format("{0}{1} = source.ReadString();\r\n", GetTabstring(tabDepth + 0), column.Name); binWriteClassStr += string.Format("{0}dest.WriteString({1});\r\n", GetTabstring(tabDepth + 0), column.Name); break; case CastleType.Layer: classStr += string.Format(CPPProperty, "CastleDataLayer", column.Name, GetTabstring(tabDepth + 0)); cppClassStr += string.Format("{0}{1}.Load(value[\"{1}\"]);\r\n", GetTabstring(tabDepth + 0), column.Name); binLoadClassStr += string.Format("{0}{1}.Load(source);\r\n", GetTabstring(tabDepth + 0), column.Name); binWriteClassStr += string.Format("{0}{1}.Save(dest);\r\n", GetTabstring(tabDepth + 0), column.Name); break; case CastleType.TileLayer: classStr += string.Format(CPPProperty, "CastleTileLayer", column.Name, GetTabstring(tabDepth + 0)); cppClassStr += string.Format("{0}{1}.Load(value[\"{1}\"]);\r\n", GetTabstring(tabDepth + 0), column.Name); binLoadClassStr += string.Format("{0}{1}.Load(source);\r\n", GetTabstring(tabDepth + 0), column.Name); binWriteClassStr += string.Format("{0}{1}.Save(dest);\r\n", GetTabstring(tabDepth + 0), column.Name); break; case CastleType.TilePos: classStr += string.Format(CPPProperty, "CastleTile", column.Name, GetTabstring(tabDepth + 0)); cppClassStr += string.Format("{0}{1}.Load(value[\"{1}\"]);\r\n", GetTabstring(tabDepth + 0), column.Name); binLoadClassStr += string.Format("{0}{1}.Load(source);\r\n", GetTabstring(tabDepth + 0), column.Name); binWriteClassStr += string.Format("{0}{1}.Save(dest);\r\n", GetTabstring(tabDepth + 0), column.Name); break; } } classStr += string.Format("\r\n{0}/// Destruct.\r\n{0}virtual ~{1}();\r\n", GetTabstring(tabDepth + 0), sheetName); if (!jsonOff) { classStr += string.Format("\r\n{0}/// Loads the data from a JSON value.\r\n{0}void Load(JSONValue& value);\r\n", GetTabstring(tabDepth + 0)); } if (binIO) { classStr += string.Format("\r\n{0}/// Loads the data from a binary Deserializer.\r\n{0}void Load(Deserializer& source);\r\n", GetTabstring(tabDepth + 0)); classStr += string.Format("\r\n{0}/// Writes the data into a binary Serializer.\r\n{0}void Save(Serializer& source);\r\n", GetTabstring(tabDepth + 0)); } classStr += string.Format("\r\n{0}/// Resolves references to other records by Key string.\r\n{0}void ResolveReferences({1}* database);\r\n", GetTabstring(tabDepth + 0), dbName); classStr += CPPClassEnd; cppClassStr += "}\r\n"; binWriteClassStr += "}\r\n"; binLoadClassStr += "}\r\n"; headerText += classStr; if (!jsonOff) { sourceText += cppClassStr; } if (binIO) { sourceText += binLoadClassStr; sourceText += binWriteClassStr; } // Destructor sourceText += string.Format("\r\n{0}::~{0}() {{\r\n", sheet.Name.Replace("@", "_")); foreach (CastleColumn col in sheet.Columns) { if (col.TypeID == CastleType.Ref) { sourceText += string.Format("{0}{1} = 0x0;\r\n", GetTabstring(tabDepth + 0), col.Name); } else if (col.TypeID == CastleType.List) { sourceText += string.Format("{0}for (unsigned i = 0; i < {1}.Size(); ++i)\r\n{2}delete {1}[i];\r\n{0}{1}.Clear();\r\n", GetTabstring(tabDepth + 0), col.Name, GetTabstring(tabDepth + 1)); } } sourceText += "}\r\n"; // ResolveReferences sourceText += string.Format("\r\nvoid {1}::ResolveReferences({2}* db) {{\r\n", GetTabstring(tabDepth + 0), sheet.Name.Replace("@", "_"), dbName); foreach (CastleColumn col in sheet.Columns) { if (col.TypeID == CastleType.Ref) { sourceText += string.Format("{0}for (unsigned i = 0; i < db->{1}List.Size(); ++i) {{\r\n", GetTabstring(tabDepth + 0), col.Key); sourceText += string.Format("{0}if (db->{1}List[i]->{2} == {3}) {{\r\n", GetTabstring(tabDepth + 1), col.Key, database.Sheets.FirstOrDefault(s => s.Name.Equals(col.Key)).GetKeyName(), string.Format("{0}Key", col.Name)); sourceText += string.Format("{0}{1} = db->{2}List[i];\r\n", GetTabstring(tabDepth + 2), col.Name, col.Key); sourceText += string.Format("{0}break;\r\n", GetTabstring(tabDepth + 2)); sourceText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 1)); sourceText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 0)); } else if (col.TypeID == CastleType.List) { string searchSheet = string.Format("{0}@{1}", sheet.Name, col.Name); CastleSheet srcSheet = database.Sheets.FirstOrDefault(s => s.Name.Equals(searchSheet)); if (srcSheet != null && srcSheet.HasReferences(database)) { sourceText += string.Format("{0}for (unsigned i = 0; i < {1}.Size(); ++i)\r\n", GetTabstring(tabDepth + 1), col.Name); sourceText += string.Format("{0}{1}[i]->ResolveReferences(db);\r\n", GetTabstring(tabDepth + 2), col.Name); } } } sourceText += "}\r\n"; } // Write the Database class if (inherit.Length == 0) { headerText += string.Format("\r\nclass {0} {{\r\npublic:\r\n{1}/// Destruct.\r\n{1}virtual ~{0}();\r\n\r\n", dbName, GetTabstring(tabDepth + 0)); } else { headerText += string.Format("\r\nclass {0} : {2} {{\r\npublic:\r\n{1}/// Destruct.\r\n{1}virtual ~{0}();\r\n\r\n", dbName, GetTabstring(tabDepth + 0), inherit); } foreach (CastleSheet sheet in database.Sheets) { if (sheet.Name.Contains("@")) { continue; } if (inherit.Equals("RefCounted")) { headerText += string.Format("{0}Vector<SharedPtr<{1}> > {1}List;\r\n", GetTabstring(tabDepth + 0), sheet.Name); } else { headerText += string.Format("{0}Vector<{1}*> {1}List;\r\n", GetTabstring(tabDepth + 0), sheet.Name); } headerText += string.Format("{0}JSONValue {1}Properties;\r\n", GetTabstring(tabDepth + 0), sheet.Name); } if (!jsonOff) { headerText += string.Format("\r\n{0}/// Load from JSON file.\r\n{0}void Load(JSONFile* file);\r\n", GetTabstring(tabDepth + 0)); } if (binIO) { headerText += string.Format("\r\n{0}/// Load from binary Deserializer.\r\n{0}void Load(Deserializer& file);\r\n", GetTabstring(tabDepth + 0)); headerText += string.Format("\r\n{0}/// Write to binary Serializer.\r\n{0}void Save(Serializer& file);\r\n", GetTabstring(tabDepth + 0)); } headerText += "};\r\n\r\n"; sourceText += string.Format("\r\n{0}::~{0}() {{\r\n", dbName); foreach (CastleSheet sheet in database.Sheets) { if (sheet.Name.Contains("@")) { continue; } sourceText += string.Format("{0}for (unsigned i = 0; i < {1}List.Size(); ++i)\r\n{2}delete {1}List[i];\r\n", GetTabstring(tabDepth + 0), sheet.Name.Replace("@", "_"), GetTabstring(tabDepth + 1)); sourceText += string.Format("{0}{1}List.Clear();\r\n", GetTabstring(tabDepth + 0), sheet.Name.Replace("@", "_")); } sourceText += "}\r\n"; // Database load if (!jsonOff) { sourceText += string.Format("\r\n{0}void {1}::Load(JSONFile* file) {{\r\n", "", dbName); sourceText += string.Format("{0}JSONValue& sheetsElem = file->GetRoot()[\"sheets\"];\r\n", GetTabstring(tabDepth + 0)); sourceText += string.Format("{0}for (unsigned i = 0; i < sheetsElem.Size(); ++i) {{\r\n", GetTabstring(tabDepth + 0)); sourceText += string.Format("{0}JSONValue& sheet = sheetsElem[i];\r\n{0}String sheetName = sheet[\"name\"].GetString();\r\n", GetTabstring(tabDepth + 1)); bool first = true; foreach (CastleSheet sheet in database.Sheets) { if (sheet.Name.Contains("@")) { continue; } sourceText += string.Format("{0}{2} (sheetName == \"{1}\") {{\r\n", GetTabstring(tabDepth + 1), sheet.Name, first ? "if" : "else if"); sourceText += string.Format("{0}JSONValue& linesElem = sheet[\"lines\"];\r\n", GetTabstring(tabDepth + 2)); sourceText += string.Format("{0}{1}Properties = sheet[\"props\"];\r\n", GetTabstring(tabDepth + 2), sheet.Name); sourceText += string.Format("{0}for (unsigned j = 0; j < linesElem.Size(); ++j) {{\r\n", GetTabstring(tabDepth + 2)); if (inherit.Equals("RefCounted")) { sourceText += string.Format("{0}SharedPtr<{1}> val(new {1}());\r\n{0}val->Load(linesElem[j]);\r\n{0}{1}List.Push(val);\r\n", GetTabstring(tabDepth + 3), sheet.Name); } else { sourceText += string.Format("{0}{1}* val = new {1}();\r\n{0}val->Load(linesElem[j]);\r\n{0}{1}List.Push(val);\r\n", GetTabstring(tabDepth + 3), sheet.Name); } sourceText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 2)); sourceText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 1)); first = false; } sourceText += string.Format("{0}}}\r\n", GetTabstring(tabDepth + 0)); // Write reference resolving code foreach (CastleSheet sheet in database.Sheets) { if (sheet.Name.Contains("@")) { continue; } if (sheet.HasReferences(database)) { sourceText += string.Format("{0}for (unsigned i = 0; i < {1}List.Size(); ++i)\r\n", GetTabstring(tabDepth + 0), sheet.Name); sourceText += string.Format("{0}{1}List[i]->ResolveReferences(this);\r\n", GetTabstring(tabDepth + 1), sheet.Name); } } sourceText += "}\r\n"; } // Database binary load/save if (binIO) { sourceText += string.Format("\r\n{0}void {1}::Load(Deserializer& source) {{\r\n", "", dbName); foreach (CastleSheet sheet in database.Sheets) { if (sheet.Name.Contains("@")) { continue; } sourceText += string.Format("{0}const unsigned {1}Ct = source.ReadUInt();\r\n", GetTabstring(tabDepth + 0), sheet.Name); sourceText += string.Format("{0}for (unsigned i = 0; i < {1}Ct; ++i) {{\r\n{2}{1}* val = new {1}();\r\n{2}{1}->Load(source);\r\n{2}{1}List.Push(val);\r\n{0}}}\r\n", GetTabstring(tabDepth + 0), sheet.Name, GetTabstring(tabDepth + 1)); } // Write reference resolving code foreach (CastleSheet sheet in database.Sheets) { if (sheet.HasReferences(database)) { sourceText += string.Format("{0}for (unsigned i = 0; i < {1}List.Size(); ++i)\r\n", GetTabstring(tabDepth + 0), sheet.Name); sourceText += string.Format("{0}{1}List[i]->ResolveReferences(this);\r\n", GetTabstring(tabDepth + 1), sheet.Name); } } sourceText += "}\r\n"; sourceText += string.Format("\r\n{0}void {1}::Save(Serializer& dest) {{\r\n", "", dbName); foreach (CastleSheet sheet in database.Sheets) { if (sheet.Name.Contains("@")) { continue; } sourceText += string.Format("{0}dest.WriteUInt({1}List.Size());\r\n", GetTabstring(tabDepth + 0), sheet.Name); sourceText += string.Format("{0}for (unsigned i = 0; i < {1}List.Size(); ++i)\r\n{2}{1}List[i]->Save(dest);\r\n", GetTabstring(tabDepth + 0), sheet.Name, GetTabstring(tabDepth + 1)); } sourceText += "}\r\n"; } if (switches.ContainsKey("ns")) { headerText += "\r\n}\t\n"; sourceText += "\r\n}\r\n"; } System.IO.File.WriteAllText(System.IO.Path.ChangeExtension(fileBase, ".h"), headerText); System.IO.File.WriteAllText(System.IO.Path.ChangeExtension(fileBase, ".cpp"), sourceText); }
public override void WriteClassDefinitions(CastleDB database, string fileBase, string sourceFileName, Dictionary <string, string> switches, List <string> errors) { int tabDepth = 0; string headerCode = string.Format("// AUTOGENERATED SOURCE CODE FROM {0}\r\n", sourceFileName); headerCode += "#pragma once\r\n"; string sourceCode = string.Format("// AUTOGENERATED SOURCE CODE FROM {0}\r\n", sourceFileName); // Include headers sourceCode += "#include <AngelScript/angelscript.h>\r\n"; sourceCode += "#include <Urho3D/AngelScript/Addons.h>\r\n"; sourceCode += "#include <Urho3D/AngelScript/APITemplates.h>\r\n"; string inherits = ""; if (switches.ContainsKey("inherits")) { inherits = switches["inherits"]; } if (!inherits.Equals("RefCounted")) { errors.Add("Can only generate AS bindings for RefCounted derived types"); return; } string dbName = "GameDatabase"; if (switches.ContainsKey("db")) { dbName = switches["db"]; } bool integerIDs = false; if (switches.ContainsKey("id")) { integerIDs = switches["id"].Equals("int"); } bool binIO = false; bool jsonOff = false; if (switches.ContainsKey("bin")) { binIO = switches["bin"].Equals("on") || switches["bin"].Equals("only"); jsonOff = switches["bin"].Equals("only"); } // Forward function declarations foreach (CastleSheet sheet in database.Sheets) { string sheetName = sheet.Name.Replace("@", "_"); // Factory constructor sourceCode += string.Format("static {0}* Construct{0}() {{\r\n", sheetName); sourceCode += string.Format("{0}return new {1}();\r\n}}", GetTabstring(tabDepth + 0), sheetName); foreach (CastleColumn col in sheet.Columns) { // implement setter/getters for string types if (col.TypeID == CastleType.List) { sourceCode += string.Format("static CScriptArray* {0}Get{1}({0}& obj) {{\r\n", sheetName, col.Name); sourceCode += string.Format("{0}return VectorToArray<{1}>(obj.{2}, \"Array<{1}@+>\");\r\n}}", GetTabstring(tabDepth + 0), col.Key, col.Name); } } } // Database constructor sourceCode += string.Format("static {0}* Construct{0}() {{\r\n", dbName); sourceCode += string.Format("{0}return new {1}();\r\n}}", GetTabstring(tabDepth + 0), dbName); headerCode += "class asIScriptEngine;\r\n"; headerCode += string.Format("void Register{0}(asIScriptEngine* engine);\r\n", dbName); sourceCode += string.Format("void Register{0}(asIScriptEngine* engine) {{\r\n", dbName); foreach (CastleSheet sheet in database.Sheets) { foreach (CastleColumn col in sheet.Columns) { if (col.TypeID == CastleType.Enum) { sourceCode += string.Format(" engine->RegisterEnum(\"{0}\");\r\n", "E_" + col.Name.ToUpper()); for (int i = 0; i < col.Enumerations.Count; ++i) { sourceCode += string.Format(" engine->RegisterEnum(\"{0}\", {1});\r\n", col.Enumerations[i].ToUpper(), i); } } } } database.Sheets.Sort(new DependencySort()); // Bind types and constructors foreach (CastleSheet sheet in database.Sheets) { string sheetName = sheet.Name.Replace("@", "_"); sourceCode += string.Format(" RegisterRefCounted<{0}>(engine, \"{0}\");\r\n", sheetName); sourceCode += string.Format(" engine->RegisterObjectBehaviour(\"{0}\", asBEHAVE_FACTORY, \"{0}@+ f()\", asFUNCTION(Construct{0}), asCALL_CDECL);\r\n", sheetName); } // Bind methods foreach (CastleSheet sheet in database.Sheets) { string sheetName = sheet.Name.Replace("@", "_"); foreach (CastleColumn col in sheet.Columns) { switch (col.TypeID) { case CastleType.UniqueIdentifier: case CastleType.File: case CastleType.Image: case CastleType.Text: sourceCode += string.Format(" engine->RegisterObjectProperty(\"{0}\", \"{1} {2}\", offsetof({0}, {2}));\r\n", sheetName, "String", col.Name); break; case CastleType.Integer: sourceCode += string.Format(" engine->RegisterObjectProperty(\"{0}\", \"{1} {2}\", offsetof({0}, {2}));\r\n", sheetName, "int", col.Name); break; case CastleType.Enum: sourceCode += string.Format(" engine->RegisterObjectProperty(\"{0}\", \"{1} {2}\", offsetof({0}, {2}));\r\n", sheetName, "int", col.Name); break; case CastleType.Flags: sourceCode += string.Format(" engine->RegisterObjectProperty(\"{0}\", \"{1} {2}\", offsetof({0}, {2}));\r\n", sheetName, "uint", col.Name); break; case CastleType.Float: sourceCode += string.Format(" engine->RegisterObjectProperty(\"{0}\", \"{1} {2}\", offsetof({0}, {2}));\r\n", sheetName, "float", col.Name); break; case CastleType.Boolean: sourceCode += string.Format(" engine->RegisterObjectProperty(\"{0}\", \"{1} {2}\", offsetof({0}, {2}));\r\n", sheetName, "bool", col.Name); break; case CastleType.Color: sourceCode += string.Format(" engine->RegisterObjectProperty(\"{0}\", \"{1} {2}\", offsetof({0}, {2}));\r\n", sheetName, "Color", col.Name); break; case CastleType.Ref: sourceCode += string.Format(" engine->RegisterObjectProperty(\"{0}\", \"{1}@+ {2}\", offsetof({0}, {2}));\r\n", sheetName, col.Key, col.Name); break; case CastleType.List: sourceCode += string.Format(" engine->RegisterObjectMethod(\"{0}\", \"Array<{1}@+>@ get_{2}()\", asFUNCTION({0}Get{2}), asCALL_CDECL_OBJLAST);\r\n", sheetName, col.Key, col.Name); break; case CastleType.Dynamic: sourceCode += string.Format(" engine->RegisterObjectProperty(\"{0}\", \"{1} {2}\", offsetof({0}, {2}));\r\n", sheetName, "JSONValue", col.Name); break; case CastleType.TileLayer: sourceCode += string.Format(" engine->RegisterObjectProperty(\"{0}\", \"{1} {2}\", offsetof({0}, {2}));\r\n", sheetName, "CastleTileLayer@+", col.Name); break; case CastleType.Custom: CastleCustom custom = database.CustomTypes.FirstOrDefault(c => c.Name.Equals(col.Key)); if (custom != null) { if (!custom.Constructors[0].returnType.Equals("void")) { sourceCode += string.Format(" engine->RegisterObjectProperty(\"{0}\", \"{1} {2}\", offsetof({0}, {2}));\r\n", sheetName, custom.Constructors[0].returnType.Replace("*", "@+"), col.Name); } } break; } } sourceCode += "\r\n"; } // Register database sourceCode += string.Format(" RegisterRefCounted<{0}>(engine, \"{0}\");\r\n", dbName); sourceCode += string.Format(" engine->RegisterObjectBehaviour(\"{0}\", asBEHAVE_FACTORY, \"{0}@+ f()\", asFUNCTION(Construct{0}), asCALL_CDECL);\r\n", dbName); if (!jsonOff) { sourceCode += string.Format(" engine->RegisterObjectMethod(\"{0}\", \"void Load(JSONFile@+)\", asMETHODPR({0}, Load, (JSONFile*), void), asCALL_THISCALL);\r\n", dbName); } if (binIO) { sourceCode += string.Format(" engine->RegisterObjectMethod(\"{0}\", \"void Load(Deserializer&)\", asMETHODPR({0}, Load, (Deserializer&), void), asCALL_THISCALL);\r\n", dbName); sourceCode += string.Format(" engine->RegisterObjectMethod(\"{0}\", \"void Save(Serializer&)\", asMETHODPR({0}, Load, (Serializer&), void), asCALL_THISCALL);\r\n", dbName); } sourceCode += "}\r\n"; System.IO.File.WriteAllText(System.IO.Path.ChangeExtension(fileBase, ".h"), headerCode); System.IO.File.WriteAllText(System.IO.Path.ChangeExtension(fileBase, ".cpp"), sourceCode); }
public string GetCtor(string typeName, int langCode, CastleDB database) { StringBuilder ret = new StringBuilder(); ret.Append(Name.Replace("_", "::")); if (ArgNames.Count > 0) { ret.Append("("); for (int i = 0; i < ArgNames.Count; ++i) { if (i > 0) { ret.Append(", "); } string typeStr = ArgTypes[i]; int typeID = 0; if (typeStr.Contains(":")) { string[] words = typeStr.Split(CastleColumn.STRSPLIT, StringSplitOptions.RemoveEmptyEntries); typeID = int.Parse(words[0]); typeStr = words[0]; } else { typeID = int.Parse(typeStr); } switch (langCode) { case 0: //CPP case 1: //Angelscript switch ((CastleType)typeID) { case CastleType.Boolean: ret.AppendFormat("{0}Array[{1}].GetBool()", typeName, i + 1); break; case CastleType.Integer: ret.AppendFormat("{0}Array[{1}].GetInt()", typeName, i + 1); break; case CastleType.Float: ret.AppendFormat("{0}Array[{1}].GetFloat()", typeName, i + 1); break; case CastleType.Text: ret.AppendFormat("{0}Array[{1}].GetString()", typeName, i + 1); break; case CastleType.Custom: // Custom type constructors need to take JSONValue parameters and process themselves ret.AppendFormat("{0}Array[{1}]", typeName, i + 1); break; } break; case 3: //Lua switch ((CastleType)typeID) { case CastleType.Boolean: ret.AppendFormat("{0}Array[{1}]:GetBool()", typeName, i + 1); break; case CastleType.Integer: ret.AppendFormat("{0}Array[{1}]:GetInt()", typeName, i + 1); break; case CastleType.Float: ret.AppendFormat("{0}Array[{1}]:GetFloat()", typeName, i + 1); break; case CastleType.Text: ret.AppendFormat("{0}Array[{1}]:GetString()", typeName, i + 1); break; case CastleType.Custom: // Custom type constructors need to take JSONValue parameters and process themselves ret.AppendFormat("{0}Array[{1}]", typeName, i + 1); break; } break; } } ret.Append(")"); } return(ret.ToString()); }