Example #1
0
        private List <LogInfo> LoadLinks(BackgroundWorker worker)
        {
            List <LogInfo> logs       = new List <LogInfo>(32);
            List <int>     removeIdxs = new List <int>();

            // Doing this will consume memory, but also greatly increase performance.
            DB_ScriptCache[] cacheDB = null;
            if (scriptCache != null)
            {
                cacheDB = scriptCache.Table <DB_ScriptCache>().Where(x => true).ToArray();
            }

            var links = allProjectScripts.Where(x => x.Type == ScriptType.Link);

            Debug.Assert(links.Count(x => x.IsDirLink) == 0);
            Task[] tasks = links.Select(p =>
            {
                return(Task.Run(() =>
                {
                    Script link = null;
                    bool valid = false;
                    int cached = 2;
                    try
                    {
                        do
                        {
                            string linkPath = p.Sections["Main"].IniDict["Link"];
                            string linkFullPath = Path.Combine(baseDir, linkPath);
                            if (File.Exists(linkFullPath) == false) // Invalid link
                            {
                                break;
                            }

                            // Load .link's linked scripts with cache
                            if (scriptCache != null)
                            { // Case of ScriptCache enabled
                                FileInfo f = new FileInfo(linkFullPath);
                                DB_ScriptCache pCache = cacheDB.FirstOrDefault(x => x.Hash == linkPath.GetHashCode());
                                if (pCache != null &&
                                    pCache.Path.Equals(linkPath, StringComparison.Ordinal) &&
                                    DateTime.Equals(pCache.LastWriteTimeUtc, f.LastWriteTimeUtc) &&
                                    pCache.FileSize == f.Length)
                                {
                                    try
                                    {
                                        using (MemoryStream memStream = new MemoryStream(pCache.Serialized))
                                        {
                                            BinaryFormatter formatter = new BinaryFormatter();
                                            link = (Script)formatter.Deserialize(memStream);
                                        }
                                        link.Project = p.Project;
                                        link.IsDirLink = false;
                                        cached = 3;
                                    }
                                    catch { }
                                }
                            }

                            if (link == null)
                            {
                                // TODO : Lazy loading of link, takes too much time at start
                                string ext = Path.GetExtension(linkFullPath);
                                ScriptType type = ScriptType.Script;
                                if (ext.Equals(".link", StringComparison.OrdinalIgnoreCase))
                                {
                                    type = ScriptType.Link;
                                }
                                link = new Script(type, Path.Combine(baseDir, linkFullPath), p.Project, projectRoot, null, false, false, false);

                                Debug.Assert(p != null);
                            }

                            // Check Script Link's validity
                            // Also, convert nested link to one-depth link
                            if (link == null)
                            {
                                break;
                            }

                            if (link.Type == ScriptType.Script)
                            {
                                valid = true;
                                break;
                            }
                            link = link.Link;
                        }while (link.Type != ScriptType.Script);
                    }
                    catch (Exception e)
                    { // Parser Error
                        logs.Add(new LogInfo(LogState.Error, Logger.LogExceptionMessage(e)));
                    }

                    if (valid)
                    {
                        p.LinkLoaded = true;
                        p.Link = link;
                        if (worker != null)
                        {
                            worker.ReportProgress(cached, Path.GetDirectoryName(p.ShortPath));
                        }
                    }
                    else // Error
                    {
                        int idx = allProjectScripts.IndexOf(p);
                        removeIdxs.Add(idx);
                        if (worker != null)
                        {
                            worker.ReportProgress(cached);
                        }
                    }
                }));
            }).ToArray();
            Task.WaitAll(tasks);

            // Remove malformed link
            var idxs = removeIdxs.OrderByDescending(x => x);

            foreach (int idx in idxs)
            {
                allProjectScripts.RemoveAt(idx);
            }

            return(logs);
        }
Example #2
0
        /// <summary>
        /// Launch after Application.Current is loaded
        /// </summary>
        public static void Init()
        {
            string baseDir = Environment.CurrentDirectory;

            for (int i = 0; i < Args.Length; i++)
            {
                if (Args[i].Equals("/basedir", StringComparison.OrdinalIgnoreCase))
                {
                    if (i + 1 < Args.Length)
                    {
                        baseDir = Path.GetFullPath(Args[i + 1]);
                        if (!Directory.Exists(baseDir))
                        {
                            MessageBox.Show($"Directory [{baseDir}] does not exist", "Invalid BaseDir", MessageBoxButton.OK, MessageBoxImage.Error);
                            Environment.Exit(1); // Force Shutdown
                        }
                        Environment.CurrentDirectory = baseDir;
                    }
                    else
                    {
                        // ReSharper disable once LocalizableElement
                        Console.WriteLine("\'/basedir\' must be used with path\r\n");
                    }
                }
                else if (Args[i].Equals("/?", StringComparison.OrdinalIgnoreCase) ||
                         Args[i].Equals("/help", StringComparison.OrdinalIgnoreCase) ||
                         Args[i].Equals("/h", StringComparison.OrdinalIgnoreCase))
                {
                    // ReSharper disable once LocalizableElement
                    Console.WriteLine("Sorry, help message not implemented\r\n");
                }
            }
            BaseDir = baseDir;

            // Database directory
            string dbDir = Path.Combine(BaseDir, "Database");

            if (!Directory.Exists(dbDir))
            {
                Directory.CreateDirectory(dbDir);
            }

            // Log Database
            string logDbFile = Path.Combine(dbDir, "PEBakeryLog.db");

            try
            {
                Logger = new Logger(logDbFile);
                Logger.SystemWrite(new LogInfo(LogState.Info, "PEBakery launched"));
            }
            catch (SQLiteException e)
            { // Update failure
                string msg = $"SQLite Error : {e.Message}\r\n\r\nLog database is corrupted.\r\nPlease delete PEBakeryLog.db and restart.";
                MessageBox.Show(msg, "SQLite Error!", MessageBoxButton.OK, MessageBoxImage.Error);
                if (Application.Current != null)
                {
                    Application.Current.Shutdown(1);
                }
                else
                {
                    Environment.Exit(1);
                }
            }

            // Init ProjectCollection
            Projects = new ProjectCollection(BaseDir);

            // Setting File
            string settingFile = Path.Combine(BaseDir, "PEBakery.ini");

            Setting = new Setting(settingFile);
            Setting.ApplySetting();

            // Custom Title
            if (Setting.Interface.UseCustomTitle)
            {
                MainViewModel.TitleBar = Setting.Interface.CustomTitle;
            }

            // Load script cache
            if (Setting.Script.EnableCache)
            {
                string cacheDbFile = Path.Combine(dbDir, "PEBakeryCache.db");
                try
                {
                    ScriptCache = new ScriptCache(cacheDbFile);
                    Logger.SystemWrite(new LogInfo(LogState.Info, $"ScriptCache enabled, {ScriptCache.Table<CacheModel.ScriptCache>().Count()} cached scripts found"));
                }
                catch (SQLiteException e)
                { // Load failure
                    string msg = $"SQLite Error : {e.Message}\r\n\r\nCache database is corrupted.\r\nPlease delete PEBakeryCache.db and restart.";
                    MessageBox.Show(msg, "SQLite Error!", MessageBoxButton.OK, MessageBoxImage.Error);
                    if (Application.Current != null)
                    {
                        Application.Current.Shutdown(1);
                    }
                    else
                    {
                        Environment.Exit(1);
                    }
                }
            }
            else
            {
                Logger.SystemWrite(new LogInfo(LogState.Info, "ScriptCache disabled"));
            }
        }
Example #3
0
        /// <summary>
        /// Launch after Application.Current is loaded
        /// </summary>
        public static void Init()
        {
            // Set fallback BaseDir
            string baseDir = BaseDir = Environment.CurrentDirectory;

            // Setup unhandled exception handler (requires BaseDir to be set)
            AppDomain.CurrentDomain.UnhandledException += AppDomain_UnhandledException;

            // Run ArgumentParser
            ArgumentParser  argParser = new ArgumentParser();
            PEBakeryOptions opts      = argParser.Parse(Args);

            if (opts == null)        // Arguments parse fail
            {
                Environment.Exit(1); // Force Shutdown
            }
            // Setup BaseDir
            if (opts.BaseDir != null)
            {
                baseDir = Path.GetFullPath(opts.BaseDir);
                if (Directory.Exists(baseDir) == false)
                {
                    MessageBox.Show($"Directory [{baseDir}] does not exist.\r\nRun [PEBkaery --help] for commnad line help message.", "PEBakery CommandLine Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    Environment.Exit(1); // Force Shutdown
                }
                Environment.CurrentDirectory = BaseDir = baseDir;
            }

            // Database directory
            string dbDir = Path.Combine(BaseDir, "Database");

            if (!Directory.Exists(dbDir))
            {
                Directory.CreateDirectory(dbDir);
            }

            // Log Database
            string logDbFile = Path.Combine(dbDir, "PEBakeryLog.db");

            try
            {
                Logger = new Logger(logDbFile);
                Logger.SystemWrite(new LogInfo(LogState.Info, "PEBakery launched"));
            }
            catch (SQLiteException)
            { // Update failure -> retry with clearing existing log db
                File.Delete(logDbFile);
                try
                {
                    Logger = new Logger(logDbFile);
                    Logger.SystemWrite(new LogInfo(LogState.Info, "PEBakery launched, log cleared due to an error"));
                }
                catch (SQLiteException e)
                { // Unable to continue -> raise an error message
                    string msg = $"SQLite Error : {e.Message}\r\n\r\nThe Log database is corrupted and was not able to be repaired.\r\nPlease delete {dbDir}\\PEBakeryLog.db and restart.";
                    MessageBox.Show(msg, "SQLite Error!", MessageBoxButton.OK, MessageBoxImage.Error);
                    if (Application.Current != null)
                    {
                        Application.Current.Shutdown(1);
                    }
                    else
                    {
                        Environment.Exit(1);
                    }
                }
            }

            // Init ProjectCollection
            Projects = new ProjectCollection(BaseDir);

            // Setting File
            string settingFile = Path.Combine(BaseDir, "PEBakery.ini");

            Setting = new Setting(settingFile);
            Setting.ApplySetting();

            // Custom Title
            if (Setting.Interface.UseCustomTitle)
            {
                MainViewModel.TitleBar = Setting.Interface.CustomTitle;
            }

            // Init script cache DB, regardless of Setting.Script.EnableCache
            string cacheDbFile = Path.Combine(dbDir, "PEBakeryCache.db");

            try
            {
                ScriptCache = new ScriptCache(cacheDbFile);
                int cachedScriptCount = ScriptCache.Table <CacheModel.ScriptCache>().Count();

                if (Setting.Script.EnableCache)
                {
                    Logger.SystemWrite(new LogInfo(LogState.Info, $"ScriptCache enabled, {cachedScriptCount} cached scripts found"));
                }
                else
                {
                    Logger.SystemWrite(new LogInfo(LogState.Info, "ScriptCache disabled"));
                }
            }
            catch (SQLiteException)
            { // Load failure -> Fallback, delete and remake database
                File.Delete(cacheDbFile);
                try
                {
                    ScriptCache = new ScriptCache(cacheDbFile);
                    Logger.SystemWrite(new LogInfo(LogState.Info, $"ScriptCache enabled, cache cleared due to an error"));
                }
                catch (SQLiteException e)
                { // Unable to continue -> raise an error message
                    string msg = $"SQLite Error : {e.Message}\r\n\r\nThe Cache database is corrupted and was not able to be repaired.\r\nPlease delete {dbDir}\\PEBakeryCache.db and restart.";
                    MessageBox.Show(msg, "SQLite Error!", MessageBoxButton.OK, MessageBoxImage.Error);
                    if (Application.Current != null)
                    {
                        Application.Current.Shutdown(1);
                    }
                    else
                    {
                        Environment.Exit(1);
                    }
                }
            }
        }