예제 #1
0
 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);
 }
예제 #2
0
        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);
        }
예제 #3
0
        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])));
        }
예제 #4
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);
        }
예제 #5
0
 public abstract void WriteClassDefinitions(CastleDB database, string fileBase, string sourceFileName, Dictionary <string, string> switches, List <string> errors);
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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());
        }