public void RegisterUnits(CobbleContext context) { var dir = Directory.CreateDirectory(Path.Combine(_configUnitLoader.HomePath, "plugins")); foreach (var file in dir.EnumerateFileSystemInfos().Select(x => x.FullName).Concat(_configUnitLoader.Config.Plugins)) { var asm = Assembly.LoadFrom(file); var pluginContext = new CobbleContext(); pluginContext.AddUnmanaged(_configUnitLoader.Config); foreach (var unit in asm.GetExportedTypes().Where(x => x != typeof(IUnitLoader) && typeof(IUnitLoader).IsAssignableFrom(x))) { pluginContext.AddManaged(unit); } pluginContext.Execute(); if (!pluginContext.TryGetImplementations <IUnitLoader>(out var loaders)) { continue; } foreach (var loader in loaders) { loader.RegisterUnits(context); } } }
public void RegisterUnits(CobbleContext context) { // Resolve duplicates: prefer overrides from outside Ceilidh.Standard context.DuplicateResolver = (pattern, implementations) => { var impl = implementations.SingleOrDefault(x => x.GetType().Assembly != typeof(IUnitLoader).Assembly); if (impl == null) { throw new AmbiguousDependencyException(pattern); } return(impl); }; context.AddUnmanaged(_startOptions); // Add start options to the main graph // Add everything that has a CobbleExportAttribute foreach (var exp in typeof(IUnitLoader).Assembly.GetExportedTypes() .Where(x => (x.GetCustomAttribute <CobbleExportAttribute>()?.IsPlatform() ?? false) && !_config.ExcludeClass.Contains(x.FullName))) { context.AddManaged(exp); } }
public void LoadModules(IReadOnlyList <string> files, CobbleContext context) { foreach (var file in files) { var asmLocation = Path.GetDirectoryName(file); AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve; var asm = Assembly.Load(File.ReadAllBytes(file)); AppDomain.CurrentDomain.AssemblyResolve -= AssemblyResolve; foreach (var type in asm.GetExportedTypes() .Where(x => !x.IsAbstract && x.GetCustomAttribute <CobbleLoaderAttribute>() != null)) { context.AddManaged(type); } Assembly AssemblyResolve(object sender, ResolveEventArgs args) { var depPath = Path.Combine(asmLocation, args.Name + ".dll"); return(File.Exists(depPath) ? Assembly.Load(File.ReadAllBytes(depPath)) : null); } } }
public CobbleLoader(CobbleContext context, string pluginStorageDir) { Context = context; PluginStorageDirectory = pluginStorageDir; _earlyCobbleContext = new CobbleContext(); RegisterDefaultHandlers(_earlyCobbleContext); _earlyCobbleContext.Execute(); if (!_earlyCobbleContext.TryGetSingleton(out _resourceLoaderController)) { throw new Exception(); // TODO: Real exceptions } if (!_earlyCobbleContext.TryGetSingleton(out _moduleLoaderController)) { throw new Exception(); } if (!_earlyCobbleContext.TryGetSingleton(out _dotNetModuleLoader)) { throw new Exception(); } Directory.CreateDirectory(pluginStorageDir); }
public async void CobbleLoaderTest() { var context = new CobbleContext(); var loader = new CobbleLoader(context, Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"))); Assert.True((await loader.TryInstallAsync( new Uri("base64:" + Convert.ToBase64String(Encoding.ASCII.GetBytes(MANIFEST_XML))))).ResultCode == CobbleLoader.PluginInstallResultCode.Success); Assert.Single(loader.EnumerateInstalledPlugins()); Assert.True(File.ReadAllText(Path.Combine(loader.PluginStorageDirectory, "test-package", "README")).StartsWith("Linux kernel")); Assert.Equal("TEST TEXT", File.ReadAllText(Path.Combine(loader.PluginStorageDirectory, "test-package", "test.txt"))); loader.LoadPlugins(); await context.ExecuteAsync(); Assert.True(context.TryGetSingleton(out ITestInterface test)); Assert.Equal("test", test.GetValue()); var updateRes = await loader.UpdateAllAsync(); Assert.Single(updateRes); Assert.True(updateRes[0].ResultCode == CobbleLoader.PluginUpdateResultCode.NotSupported); loader.Uninstall("test-package"); Assert.False(Directory.Exists(Path.Combine(loader.PluginStorageDirectory, "test-package"))); Assert.Empty(loader.EnumerateInstalledPlugins()); }
public void RegisterUnits(CobbleContext context) { foreach (var typ in typeof(SelfUnitLoader).Assembly.GetExportedTypes() .Where(x => x.GetCustomAttribute <CobbleExportAttribute>() != null)) { context.AddManaged(typ); } }
public bool TryLoadModules(string loaderId, IReadOnlyList <string> files, CobbleContext context) { if (!TryGetModuleLoader(loaderId, out var loader)) { return(false); } loader.LoadModules(files, context); return(true); }
private static void RegisterDefaultHandlers(CobbleContext context) { context.AddManaged <ResourceLoaderController>(); context.AddManaged <FileResourceLoader>(); context.AddManaged <FtpResourceLoader>(); context.AddManaged <HttpResourceLoader>(); context.AddManaged <Base64ResourceLoader>(); context.AddManaged <ModuleLoaderController>(); context.AddManaged <DotNetModuleLoader>(); }
public static async Task <CobbleContext> LoadCeilidhAsync(CeilidhStartOptions startOptions, Action <CobbleContext> loaderCallback) { if (Instance != null) { throw new NotSupportedException(); } var loaderContext = new CobbleContext(); foreach (var loader in typeof(IUnitLoader).Assembly.GetExportedTypes() .Where(x => x != typeof(IUnitLoader) && typeof(IUnitLoader).IsAssignableFrom(x))) { loaderContext.AddManaged(loader); } foreach (var loader in typeof(CeilidhLoader).Assembly.GetExportedTypes() .Where(x => typeof(IUnitLoader).IsAssignableFrom(x))) { loaderContext.AddManaged(loader); } loaderCallback?.Invoke(loaderContext); loaderContext.AddUnmanaged(startOptions); await loaderContext.ExecuteAsync(); var mainContext = new CobbleContext(); if (!loaderContext.TryGetImplementations(out IEnumerable <IUnitLoader> loaders)) { return(mainContext); } foreach (var loader in loaders) { loader.RegisterUnits(mainContext); } await mainContext.ExecuteAsync(); Instance = mainContext; if (mainContext.TryGetSingleton(out IWindowProvider provider)) { var window = provider.CreateWindow(new MainPage(), 0); window.Size = (640, 480); window.Title = "Ceilidh"; window.IsVisible = true; window.Closing += (sender, args) => Environment.Exit(0); } return(mainContext); }
public void RegisterUnits(CobbleContext context) { foreach (var unit in typeof(XamarinShellUnitLoader).Assembly.GetExportedTypes() .Where(x => { var ann = x.GetCustomAttribute <CobbleExportAttribute>(); if (ann == null) { return(false); } return(ann.Platform == null || RuntimeInformation.IsOSPlatform(ann.Platform.Value)); })) { context.AddManaged(unit); } }
public void RegisterUnits(CobbleContext context) { try { foreach (var api in PortAudioHostApi.SupportedHostApis) { context.AddUnmanaged(new PortAudioOutputController(api)); } } catch (DllNotFoundException) { // I'm ignoring this because if it's not supported, we can just exclude it from the cobble context } catch (PortAudioException) { // Ditto } }
public static CobbleContext ExecuteCeilidh(Action <CobbleContext> contextLoader = null) { var loadContext = new CobbleContext(); loadContext.AddUnmanaged(new CeilidhStartOptions()); foreach (var unit in typeof(IUnitLoader).Assembly.GetExportedTypes() .Where(x => x != typeof(IUnitLoader) && typeof(IUnitLoader).IsAssignableFrom(x))) { loadContext.AddManaged(unit); } foreach (var unit in typeof(CeilidhLoader).Assembly.GetExportedTypes() .Where(x => typeof(IUnitLoader).IsAssignableFrom(x))) { loadContext.AddManaged(unit); } contextLoader?.Invoke(loadContext); loadContext.Execute(); if (!loadContext.TryGetImplementations <IUnitLoader>(out var impl)) { throw new InvalidOperationException("Did not define a single unit loader"); } var ceilidhContext = new CobbleContext(); foreach (var register in impl) { register.RegisterUnits(ceilidhContext); } ceilidhContext.Execute(); return(ceilidhContext); }
public void RegisterUnits(CobbleContext context) { context.AddUnmanaged(Config); }
private static async Task <int> Main(string[] args) { var startOptions = new CeilidhStartOptions(); var help = false; var options = new OptionSet { { "c|config=", "the path to the config file.", path => startOptions.ConfigFile = path }, { "u|user="******"the path to the user data folder.", path => startOptions.UserDataPath = path }, { "h|help", "show this message and exit.", _ => help = true } }; try { options.Parse(args); } catch (OptionException e) { Console.WriteLine("Argument error: {0}", e.Message); Console.WriteLine($"Try '{Path.GetFileName(Environment.GetCommandLineArgs()[0])} --help' for more information."); return(-1); } if (help) { Console.WriteLine($"Ceilidh Console Shell Version {typeof(ConsoleShell).Assembly.GetName().Version}"); Console.WriteLine($"Ceilidh Standard Version {typeof(IUnitLoader).Assembly.GetName().Version}"); Console.WriteLine("Usage:"); options.WriteOptionDescriptions(Console.Out); return(0); } using (var loadContext = new CobbleContext()) { loadContext.AddUnmanaged(startOptions); foreach (var unit in typeof(IUnitLoader).Assembly.GetExportedTypes() .Where(x => x != typeof(IUnitLoader) && typeof(IUnitLoader).IsAssignableFrom(x))) { loadContext.AddManaged(unit); } await loadContext.ExecuteAsync(); if (!loadContext.TryGetImplementations <IUnitLoader>(out var impl)) { return(0); } using (var ceilidhContext = new CobbleContext()) { foreach (var register in impl) { register.RegisterUnits(ceilidhContext); } ceilidhContext.AddManaged <ConsoleOutputConsumer>(); await ceilidhContext.ExecuteAsync(); } } return(0); }
public CobbleContextTests() { _context = new CobbleContext(); }
public void RegisterUnits(CobbleContext context) { context.AddManaged <GtkWindowProvider>(); // context.AddManaged<GtkNotificationProvider>(); }