1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2025-04-09 06:15:49 +02:00

Rewrite plugin cache to use tokens and local paths as multikeys

This commit is contained in:
chylex 2017-03-07 18:31:58 +01:00
parent 4bb35295ca
commit f7ed7703b4
2 changed files with 36 additions and 11 deletions

View File

@ -1,24 +1,35 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using TweetDck.Core.Utils;
using TweetDck.Plugins.Enums;
using TweetDck.Plugins.Events;
namespace TweetDck.Plugins{
class PluginBridge{
private static string SanitizeCacheKey(string key){
return key.Replace('\\', '/').Trim();
}
private readonly PluginManager manager;
private readonly Dictionary<string, string> fileCache = new Dictionary<string, string>(2);
private readonly TwoKeyDictionary<int, string, string> fileCache = new TwoKeyDictionary<int, string, string>(4, 2);
public PluginBridge(PluginManager manager){
this.manager = manager;
this.manager.Reloaded += manager_Reloaded;
this.manager.PluginChangedState += manager_PluginChangedState;
}
private void manager_Reloaded(object sender, PluginLoadEventArgs e){
fileCache.Clear();
}
private void manager_PluginChangedState(object sender, PluginChangedStateEventArgs e){
if (!e.IsEnabled){
fileCache.Remove(manager.GetTokenFromPlugin(e.Plugin));
}
}
private string GetFullPathOrThrow(int token, PluginFolder folder, string path){
Plugin plugin = manager.GetPluginFromToken(token);
string fullPath = plugin == null ? string.Empty : plugin.GetFullPathIfSafe(folder, path);
@ -35,15 +46,17 @@ private string GetFullPathOrThrow(int token, PluginFolder folder, string path){
}
}
private string ReadFileUnsafe(string fullPath, bool readCached){
private string ReadFileUnsafe(int token, string cacheKey, string fullPath, bool readCached){
cacheKey = SanitizeCacheKey(cacheKey);
string cachedContents;
if (readCached && fileCache.TryGetValue(fullPath, out cachedContents)){
if (readCached && fileCache.TryGetValue(token, cacheKey, out cachedContents)){
return cachedContents;
}
try{
return fileCache[fullPath] = File.ReadAllText(fullPath, Encoding.UTF8);
return fileCache[token, cacheKey] = File.ReadAllText(fullPath, Encoding.UTF8);
}catch(FileNotFoundException){
throw new Exception("File not found.");
}catch(DirectoryNotFoundException){
@ -60,17 +73,17 @@ public void WriteFile(int token, string path, string contents){
Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
File.WriteAllText(fullPath, contents, Encoding.UTF8);
fileCache[fullPath] = contents;
fileCache[token, SanitizeCacheKey(path)] = contents;
}
public string ReadFile(int token, string path, bool cache){
return ReadFileUnsafe(GetFullPathOrThrow(token, PluginFolder.Data, path), cache);
return ReadFileUnsafe(token, path, GetFullPathOrThrow(token, PluginFolder.Data, path), cache);
}
public void DeleteFile(int token, string path){
string fullPath = GetFullPathOrThrow(token, PluginFolder.Data, path);
fileCache.Remove(fullPath);
fileCache.Remove(token, SanitizeCacheKey(path));
File.Delete(fullPath);
}
@ -79,7 +92,7 @@ public bool CheckFileExists(int token, string path){
}
public string ReadFileRoot(int token, string path){
return ReadFileUnsafe(GetFullPathOrThrow(token, PluginFolder.Root, path), true);
return ReadFileUnsafe(token, "root*"+path, GetFullPathOrThrow(token, PluginFolder.Root, path), true);
}
public bool CheckFileExistsRoot(int token, string path){

View File

@ -13,6 +13,8 @@ class PluginManager{
public const string PluginNotificationScriptFile = "plugins.notification.js";
public const string PluginGlobalScriptFile = "plugins.js";
private const int InvalidToken = 0;
public string PathOfficialPlugins { get { return Path.Combine(rootPath, "official"); } }
public string PathCustomPlugins { get { return Path.Combine(rootPath, "user"); } }
@ -63,6 +65,16 @@ public bool HasAnyPlugin(PluginEnvironment environment){
return plugins.Any(plugin => plugin.Environments.HasFlag(environment));
}
public int GetTokenFromPlugin(Plugin plugin){
foreach(KeyValuePair<int, Plugin> kvp in tokens){
if (kvp.Value.Equals(plugin)){
return kvp.Key;
}
}
return InvalidToken;
}
public Plugin GetPluginFromToken(int token){
Plugin plugin;
return tokens.TryGetValue(token, out plugin) ? plugin : null;
@ -108,7 +120,7 @@ public void ExecutePlugins(IFrame frame, PluginEnvironment environment, bool inc
int token;
if (tokens.ContainsValue(plugin)){
token = tokens.First(kvp => kvp.Value.Equals(plugin)).Key;
token = GetTokenFromPlugin(plugin);
}
else{
token = GenerateToken();
@ -141,7 +153,7 @@ private int GenerateToken(){
for(int attempt = 0; attempt < 1000; attempt++){
int token = rand.Next();
if (!tokens.ContainsKey(token)){
if (!tokens.ContainsKey(token) && token != InvalidToken){
return token;
}
}