コード例 #1
0
ファイル: CodeGen.cs プロジェクト: DuckMonster/ecs_engine
        static void CollectDirectory(string dir, CodeGenerationManifest manifest)
        {
            dir = Path.GetFullPath(dir);

            if (!Directory.Exists(dir))
            {
                Error("Directory \"{0}\" doesn't exist", dir);
            }

            // Get all header files
            string[] files = Directory.GetFiles(dir);
            foreach (string file in files)
            {
                if (Path.GetExtension(file) != ".h")
                {
                    continue;
                }

                FileParser.Parse(file, manifest);
            }

            // Continue recursively
            string[] childDirs = Directory.GetDirectories(dir);
            foreach (string child in childDirs)
            {
                CollectDirectory(child, manifest);
            }
        }
コード例 #2
0
        public static void ProcessComponent(Component comp, CodeGenerationManifest manifest)
        {
            string serializeSource  = "",
                   initializeSource = "",
                   staticTypeSource = "";

            List <Function> generatedFunctions = new List <Function>();

            //---------- Type binder
            {
                StringWriter sourceWriter = new StringWriter();
                sourceWriter.WriteLine("namespace {");
                sourceWriter.WriteLine("ComponentType::Bind<{0}> {0}_BIND( \"{0}\", {1} );", comp.Name, comp.Id);
                sourceWriter.WriteLine("}");
                comp.GeneratedTypeBinder = sourceWriter.ToString();
            }

            //---------- Serialize Function
            if (!comp.HasUserSerialize)
            {
                const string SERIALIZE_FORMAT = "archive.Serialize<{0}>(\"{1}\", {2});";
                StringWriter sourceWriter     = new StringWriter();

                sourceWriter.WriteLine("{0}::Serialize( archive );", comp.Parent);

                foreach (Property prop in comp.Properties)
                {
                    if (Array.IndexOf(prop.MetaData, "Serialize") == -1)
                    {
                        continue;
                    }

                    sourceWriter.WriteLine(SERIALIZE_FORMAT, prop.Parameter.Type, prop.CleanName, prop.Parameter.Name);
                }

                sourceWriter.WriteLine("OnSerialized();");

                serializeSource = sourceWriter.ToString();
                generatedFunctions.Add(ConstructFunction("public", "void", "Serialize", "", "override", serializeSource, ConstructParameter("NamedArchive&", "archive")));
            }

            //---------- Initialize function
            {
                StringWriter sourceWriter = new StringWriter();
                sourceWriter.WriteLine("{0}::InitializeInternal();", comp.Parent, comp.Id);
                sourceWriter.WriteLine("m_Type = StaticType();");

                foreach (Property prop in comp.Properties)
                {
                    sourceWriter.WriteLine("RegisterProperty<{0}>( \"{1}\", &{2} );", prop.Parameter.Type, prop.CleanName, prop.Parameter.Name);
                }

                initializeSource = sourceWriter.ToString();
                generatedFunctions.Add(ConstructFunction("public", "void", "InitializeInternal", "", "override", initializeSource));
            }

            //---------- Static Type function
            {
                StringWriter sourceWriter = new StringWriter();
                sourceWriter.WriteLine("return {0}_BIND.ToType();", comp.Name);

                staticTypeSource = sourceWriter.ToString();
                generatedFunctions.Add(ConstructFunction("public", "const ComponentType&", "StaticType", "static", "", staticTypeSource));
            }

            comp.GeneratedFunctions = generatedFunctions.ToArray();
        }
コード例 #3
0
ファイル: CodeGen.cs プロジェクト: DuckMonster/ecs_engine
        static int Main(string[] args)
        {
            if (args.Length < 2)
            {
                Utils.Print("Usage: CodeGen source target [/G] [/V]\n  /G - Allow generating new files. Otherwise will error if new files have to be created.\n  /V - Verbal, will display additional debug information.");
                Utils.Print("\nSupplied {0} arguments:", args.Length);
                foreach (string arg in args)
                {
                    Utils.Print("\t{0}", arg);
                }

                return(1);
            }

            GenData             = new GenerationData();
            GenData.SourcePath  = Path.GetFullPath(args[0]);
            GenData.TargetPath  = Path.GetFullPath(args[1]);
            GenData.CanGenerate = args.Contains("/G");
            GenData.Verbal      = args.Contains("/V");

            if (Path.HasExtension(GenData.SourcePath) || Path.HasExtension(GenData.TargetPath))
            {
                Utils.Print("Using a file as source/target is invalid, only directories are supported");
                return(1);
            }

            if (!Directory.Exists(GenData.SourcePath))
            {
                Utils.Print("Couldn't find source directory \"{0}\"", GenData.SourcePath);
                return(1);
            }

            Utils.Print("-- GENERATING FILES --\n\"{0}\" => \"{1}\"", GenData.SourcePath, GenData.TargetPath, GenData.CanGenerate);
            Utils.PrintVerbal("CanGenerate: {2}", GenData.SourcePath, GenData.TargetPath, GenData.CanGenerate);

            if (!Directory.Exists(GenData.TargetPath))
            {
                Directory.CreateDirectory(GenData.TargetPath);
                Utils.Print("Created directory \"{0}\"", GenData.TargetPath);
            }

            if (!Directory.Exists(GenData.CachePath))
            {
                Directory.CreateDirectory(GenData.CachePath);
                Utils.Print("Created directory \"{0}\"", GenData.CachePath);
            }

            // Collect manifest
            CodeGenerationManifest manifest = new CodeGenerationManifest();

            manifest.Components = new List <Component>();

            CollectDirectory(GenData.SourcePath, manifest);

            manifest.Print();

            Utils.PrintVerbal("\n- Generating...");

            // Process
            foreach (Component comp in manifest.Components)
            {
                Process.ProcessComponent(comp, manifest);
            }

            // Generate
            if (GenData.CanGenerate)
            {
                // If generate is enabled, clean the directory first
                string[] files = Directory.GetFiles(GenData.TargetPath);
                foreach (string file in files)
                {
                    File.Delete(file);
                }
            }

            foreach (Component comp in manifest.Components)
            {
                if (!comp.File.IsDirty)
                {
                    continue;
                }

                // Source
                using (FileStream fileStream = OpenSource(comp.File))
                {
                    SourceWriter writer = new SourceWriter(comp.File, fileStream);

                    writer.WriteComponent(comp);

                    writer.Flush();
                    writer.Close();

                    Utils.Print(comp.File.GenSrcFileName);
                }

                // Header
                using (FileStream fileStream = OpenHeader(comp.File))
                {
                    HeaderWriter writer = new HeaderWriter(comp.File, fileStream);

                    writer.WriteComponent(comp);

                    writer.Flush();
                    writer.Close();

                    Utils.Print(comp.File.GenHeaderFileName);
                }
            }

            Utils.Print("-- GENERATION DONE --");

            return(0);
        }
コード例 #4
0
        public static void Parse(string sourcePath, CodeGenerationManifest manifest)
        {
            if (!File.Exists(sourcePath))
            {
                CodeGen.Error("File \"{0}\" does not exist.", sourcePath);
                return;
            }

            SourceFile file = new SourceFile();

            file.FileName = Path.GetFileName(sourcePath);
            file.FullPath = sourcePath;
            file.Source   = File.ReadAllText(sourcePath).Replace("\r", "");
            file.IsDirty  = false;

            CurrentFile = file;

            bool fileShouldBeGenerated = false;

            // ----------------------------- Collect Components
            MatchCollection match = COMP_RGX.Matches(file.Source);

            if (match.Count > 0)
            {
                fileShouldBeGenerated = true;

                string[] namespaces = Utils.FindNamespaces(file.Source, match[0].Index);
                string[] metadata   = ParseMetadata(match[0].Groups[1].Value);

                Component comp = new Component();
                comp.File             = file;
                comp.Name             = match[0].Groups[2].Value;
                comp.Parent           = match[0].Groups[3].Value;
                comp.MetaData         = metadata;
                comp.Namespaces       = namespaces;
                comp.Id               = manifest.Components.Count;
                comp.HasUserSerialize = SERIALIZE_RGX.Match(match[0].Groups[4].Value).Success;

                // Parse functions
                {
                    MatchCollection funcMatch     = FUNC_RGX.Matches(match[0].Value);
                    Function[]      compFunctions = new Function[funcMatch.Count];

                    for (int f = 0; f < funcMatch.Count; ++f)
                    {
                        string[] funcMetaData = ParseMetadata(funcMatch[f].Groups[1].Value);

                        Function func = new Function();
                        func.Name       = funcMatch[f].Groups[3].Value;
                        func.ReturnType = funcMatch[f].Groups[2].Value;
                        func.Arguments  = ParseParameters(funcMatch[f].Groups[4].Value);
                        func.MetaData   = funcMetaData;

                        compFunctions[f] = func;
                    }

                    comp.Functions = compFunctions;
                }

                // Parse properties
                {
                    MatchCollection propMatch      = PROP_RGX.Matches(match[0].Value);
                    Property[]      compProperties = new Property[propMatch.Count];

                    for (int p = 0; p < propMatch.Count; ++p)
                    {
                        string[] propMetaData = ParseMetadata(propMatch[p].Groups[1].Value);

                        Property prop = new Property();
                        prop.Parameter.Type = propMatch[p].Groups[2].Value;
                        prop.Parameter.Name = propMatch[p].Groups[3].Value;
                        prop.CleanName      = CleanPropertyName(prop.Parameter.Name);

                        prop.MetaData = propMetaData;

                        compProperties[p] = prop;
                    }

                    comp.Properties = compProperties;
                }

                Utils.PrintVerbal("({0}) Parsed component \"{1}\"...", file.FileName, comp.Name);
                manifest.Components.Add(comp);
            }

            if (fileShouldBeGenerated)
            {
                file.IsDirty = GetFileIsDirty(file);
            }
        }