예제 #1
0
        private bool ShouldThrottleEvent(EventThrottleKey key)
        {
            Timer timer;

            if (_eventQueue.TryGetValue(key, out timer))
            {
                // do nothing. The same event was published a tick ago.
                return(true);
            }

            _eventQueue[key] = new Timer(RemoveFromEventQueue, key, 500, Timeout.Infinite);
            return(false);
        }
예제 #2
0
        private void OnThemeFileChanged(string name, string fullPath, ThemeFileChangeType changeType)
        {
            // Enable event throttling by allowing the very same event to be published only all 500 ms.
            var throttleKey = new EventThrottleKey(name, changeType);

            if (ShouldThrottleEvent(throttleKey))
            {
                return;
            }

            if (!_fileFilterPattern.IsMatch(Path.GetExtension(name)))
            {
                return;
            }

            var idx = name.IndexOf('\\');

            if (idx < 0)
            {
                // must be a subfolder of "~/Themes/"
                return;
            }

            var themeName    = name.Substring(0, idx);
            var relativePath = name.Substring(themeName.Length + 1).Replace('\\', '/');
            var isConfigFile = relativePath.IsCaseInsensitiveEqual("theme.config");

            if (changeType == ThemeFileChangeType.Modified && !isConfigFile)
            {
                // Monitor changes only for root theme.config
                return;
            }

            BaseThemeChangedEventArgs baseThemeChangedArgs = null;

            if (isConfigFile)
            {
                // config file changes always result in refreshing the corresponding theme manifest
                var di = new DirectoryInfo(Path.GetDirectoryName(fullPath));

                string oldBaseThemeName = null;
                var    oldManifest      = this.GetThemeManifest(di.Name);
                if (oldManifest != null)
                {
                    oldBaseThemeName = oldManifest.BaseThemeName;
                }

                try
                {
                    // FS watcher in conjunction with some text editors fires change events twice and locks the file.
                    // Let's wait max. 250 ms till the lock is gone (hopefully).
                    WaitForUnlock(fullPath);

                    var newManifest = ThemeManifest.Create(di.FullName, _themesBasePath);
                    if (newManifest != null)
                    {
                        this.AddThemeManifestInternal(newManifest, false);

                        if (!oldBaseThemeName.IsCaseInsensitiveEqual(newManifest.BaseThemeName))
                        {
                            baseThemeChangedArgs = new BaseThemeChangedEventArgs
                            {
                                ThemeName    = newManifest.ThemeName,
                                BaseTheme    = newManifest.BaseTheme != null ? newManifest.BaseTheme.ThemeName : null,
                                OldBaseTheme = oldBaseThemeName
                            };
                        }

                        Logger.Debug("Changed theme manifest for '{0}'".FormatCurrent(name));
                    }
                    else
                    {
                        // something went wrong (most probably no 'theme.config'): remove the manifest
                        TryRemoveManifest(di.Name);
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error(ex, "Could not touch theme manifest '{0}': {1}".FormatCurrent(name, ex.Message));
                    TryRemoveManifest(di.Name);
                }
            }

            if (baseThemeChangedArgs != null)
            {
                RaiseBaseThemeChanged(baseThemeChangedArgs);
            }

            RaiseThemeFileChanged(new ThemeFileChangedEventArgs
            {
                ChangeType          = changeType,
                FullPath            = fullPath,
                ThemeName           = themeName,
                RelativePath        = relativePath,
                IsConfigurationFile = isConfigFile
            });
        }