Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions Fastedit/Extensibility/CustomSyntaxHighlightLanguage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TextControlBoxNS;

namespace Fastedit.Extensibility;

/// <summary>
/// Create a constructor without parameters and set values for all properties.
/// </summary>
public class CustomSyntaxHighlightLanguage : SyntaxHighlightLanguage, IExtensionInterface
{
public CustomSyntaxHighlightLanguage() { }
}

public class CustomSyntaxHighlights : SyntaxHighlights
{
public CustomSyntaxHighlights
(string pattern, string colorLight, string colorDark, bool bold = false, bool italic = false, bool underlined = false)
: base(pattern, colorLight, colorDark, bold, italic, underlined)
{
}
}
34 changes: 34 additions & 0 deletions Fastedit/Extensibility/IAboutPlugin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Fastedit.Extensibility;

/// <summary>
/// Implement this interface to give Ease Pass some information about your plugin. It is highly recommended to implement this interface a single time in every plugin.
/// </summary>
public interface IAboutPlugin : IExtensionInterface
{
/// <summary>
/// Name of your plugin
/// </summary>
string PluginName { get; }
/// <summary>
/// Description of your plugin
/// </summary>
string PluginDescription { get; }
/// <summary>
/// Author of your plugin
/// </summary>
string PluginAuthor { get; }
/// <summary>
/// URL to the authors webpage
/// </summary>
string PluginAuthorURL { get; }
/// <summary>
/// URI to the icon of the plugin
/// </summary>
Uri PluginIcon { get; }
}
11 changes: 11 additions & 0 deletions Fastedit/Extensibility/IExtensionInterface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Fastedit.Extensibility;

public interface IExtensionInterface
{
}
20 changes: 20 additions & 0 deletions Fastedit/Extensibility/IExtensionSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Fastedit.Extensibility;

public interface IExtensionSource : IExtensionInterface
{
/// <summary>
/// Name of the extension source.
/// </summary>
string SourceName { get; }
/// <summary>
/// Ease Pass will call this function to get the extension sources.
/// </summary>
/// <returns>The extension source and name.</returns>
(Uri Source, string Name)[] GetExtensionSources();
}
3 changes: 3 additions & 0 deletions Fastedit/Fastedit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Folder Include="Extensibility\" />
</ItemGroup>

<!--
Defining the "HasPackageAndPublishMenuAddedByProject" property here allows the Solution
Expand Down
82 changes: 82 additions & 0 deletions Fastedit/Helper/ExtensionHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using Fastedit.Extensibility;
using Fastedit.Models;
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;

namespace Fastedit.Helper;

internal static class ExtensionHelper
{
public static List<Extension> Extensions = new List<Extension>();

public static void Init()
{
Task.Run(new Action(async () =>
{
if (Directory.Exists(ApplicationData.Current.LocalFolder.Path + "\\extensions\\"))
{
if (File.Exists(ApplicationData.Current.LocalFolder.Path + "\\delete_extensions.dat"))
{
foreach (string extensionID in File.ReadLines(ApplicationData.Current.LocalFolder.Path + "\\delete_extensions.dat"))
{
if (File.Exists(ApplicationData.Current.LocalFolder.Path + "\\extensions\\" + extensionID + ".dll"))
{
await (await (await ApplicationData.Current.LocalFolder.GetFolderAsync("extensions")).GetFileAsync(extensionID + ".dll")).DeleteAsync();
}
}
}

File.WriteAllText(ApplicationData.Current.LocalFolder.Path + "\\delete_extensions.dat", "");
string[] extensionPaths = Directory.GetFiles(ApplicationData.Current.LocalFolder.Path + "\\extensions\\");
Extensions.Clear();
for (int i = 0; i < extensionPaths.Length; i++)
{
if (Path.GetExtension(extensionPaths[i]).ToLower() == ".dll")
{
Extensions.Add(new Extension(ReflectionHelper.GetAllExternalInstances(extensionPaths[i]), Path.GetFileNameWithoutExtension(extensionPaths[i])));
}
}
}
}));
}

public static T[] GetAllClassesWithInterface<T>() where T : IExtensionInterface
{
List<T> result = new List<T>();
for (int i = 0; i < Extensions.Count; i++)
{
int length = Extensions[i].Interfaces.Length;
for (int j = 0; j < length; j++)
{
if (Extensions[i].Interfaces[j] is T t)
{
result.Add(t);
}
}
}
return result.ToArray();
}

public static List<FetchedExtension> GetExtensionsFromSources()
{
List<FetchedExtension> res = new List<FetchedExtension>();
for (int i = 0; i < Extensions.Count; i++)
{
int length = Extensions[i].Interfaces.Length;
for (int j = 0; j < length; j++)
{
if (Extensions[i].Interfaces[j] is IExtensionSource source)
{
res.AddRange(source.GetExtensionSources().Select((item) => { return new FetchedExtension(item.Source, item.Name, source.SourceName); }));
}
}
}
return res;
}
}
70 changes: 70 additions & 0 deletions Fastedit/Helper/ReflectionHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using Fastedit.Extensibility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Fastedit.Helper;

internal class ReflectionHelper
{
public static IExtensionInterface[] GetAllExternalInstances(string path)
{
try
{
List<IExtensionInterface> res = new List<IExtensionInterface>();
Assembly plugin = Assembly.LoadFrom(path);
IEnumerable<System.Type> types = GetLoadableTypes(plugin);
foreach (System.Type t in types)
{
if (t.GetInterfaces().Contains(typeof(IExtensionInterface)))
{
IExtensionInterface obj = (IExtensionInterface)GetInstanceOf(t);
if (obj != null) res.Add(obj);
}
}
return res.ToArray();
}
catch
{
return new IExtensionInterface[0];
}
}

private static object GetInstanceOf(Type type)
{
try
{
ConstructorInfo[] cis = type.GetConstructors();
foreach (ConstructorInfo ci in cis)
{
if (ci.GetParameters().Length == 0)
{
return type.Assembly.CreateInstance(type.FullName);
}
}
}
catch { }
return null;
}

private static IEnumerable<Type> GetLoadableTypes(Assembly assembly)
{
if (assembly == null) throw new ArgumentNullException(nameof(assembly));
try
{
List<Type> types = new List<Type>();
foreach (TypeInfo ti in assembly.DefinedTypes)
{
types.Add(ti.AsType());
}
return types;
}
catch (ReflectionTypeLoadException e)
{
return e.Types.Where(t => t != null);
}
}
}
3 changes: 3 additions & 0 deletions Fastedit/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Fastedit.Core;
using Fastedit.Helper;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
Expand Down Expand Up @@ -37,6 +38,8 @@ public MainWindow()

this.Title = "Fastedit";
this.AppWindow.SetIcon(Path.Combine(Package.Current.InstalledLocation.Path, "Assets\\AppIcon\\Icon.ico"));

ExtensionHelper.Init();
}

private void MainWindow_Closed(object sender, WindowEventArgs args)
Expand Down
21 changes: 21 additions & 0 deletions Fastedit/Models/DummyExtensionPage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Fastedit.Extensibility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Fastedit.Models;

internal class DummyAboutExtensionPage : IAboutPlugin
{
public string PluginName => "Unknown name";

public string PluginDescription => "Unknown description";

public string PluginAuthor => "Unknown author";

public string PluginAuthorURL => "";

public Uri PluginIcon => new Uri("ms-appx:///Assets/AppIcon/Icon.png");
}
87 changes: 87 additions & 0 deletions Fastedit/Models/Extension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using Fastedit.Extensibility;
using Microsoft.UI.Xaml.Media.Imaging;
using Microsoft.UI.Xaml.Media;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Fastedit.Models;

internal class Extension
{
public IExtensionInterface[] Interfaces;

public IAboutPlugin AboutPlugin = null;

public ImageSource IconSource
{
get
{
if (AboutPlugin != null) return new BitmapImage(AboutPlugin.PluginIcon);
return null;
}
}

public string ID = "";

public Extension(IExtensionInterface[] interfaces, string id)
{
Interfaces = interfaces;
int length = interfaces.Length;
for (int i = 0; i < length; i++)
{
if (interfaces[i] is IAboutPlugin plugin)
{
AboutPlugin = plugin;
}
}
if (AboutPlugin == null)
{
AboutPlugin = new DummyAboutExtensionPage();
}
ID = id;
}

public override string ToString()
{
return ToString(true);
}

public string ToString(bool headline)
{
List<string> items = new List<string>();
int length = Interfaces.Length;
for (int i = 0; i < length; i++)
{
if (Interfaces[i] is CustomSyntaxHighlightLanguage) items.Add("• add custom syntax highlighting");
if (Interfaces[i] is IExtensionSource) items.Add("• add extensions to the store");
// fill up with other interfaces
}
List<string> itemsFinal = new List<string>();
for (int i = 0; i < items.Count; i++)
{
if (!itemsFinal.Contains(items[i]))
itemsFinal.Add(items[i]);
}

StringBuilder sb = new StringBuilder();
if (headline)
{
sb.AppendLine("Authorizations requested by plugin:");
}

for (int i = 0; i < itemsFinal.Count; i++)
{
sb.AppendLine(itemsFinal[i]);
}

return sb.ToString();
}

public string GetPluginInterfaceGUID(IExtensionInterface extInterface)
{
return extInterface.GetType().GUID.ToString();
}
}
Loading