diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj
index 399048bda..74c96f047 100644
--- a/src/Artemis.Core/Artemis.Core.csproj
+++ b/src/Artemis.Core/Artemis.Core.csproj
@@ -104,6 +104,9 @@
..\packages\Sanford.Multimedia.Midi.6.4.2\lib\net20\Sanford.Multimedia.Midi.dll
+
+ ..\packages\Stylet.1.1.21\lib\net45\Stylet.dll
+
..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll
@@ -184,12 +187,8 @@
-
-
-
-
diff --git a/src/Artemis.Core/Exceptions/ArtemisPluginException.cs b/src/Artemis.Core/Exceptions/ArtemisPluginException.cs
index 0282b0295..a2c96d709 100644
--- a/src/Artemis.Core/Exceptions/ArtemisPluginException.cs
+++ b/src/Artemis.Core/Exceptions/ArtemisPluginException.cs
@@ -1,5 +1,5 @@
using System;
-using Artemis.Core.Models;
+using Artemis.Plugins.Models;
namespace Artemis.Core.Exceptions
{
diff --git a/src/Artemis.Core/Scripting.Extensions.cs b/src/Artemis.Core/Scripting.Extensions.cs
deleted file mode 100644
index 070536442..000000000
--- a/src/Artemis.Core/Scripting.Extensions.cs
+++ /dev/null
@@ -1,295 +0,0 @@
-using CSScriptLibrary;
-using System;
-using System.Diagnostics;
-using System.Reflection;
-using System.Runtime.Remoting.Lifetime;
-using System.Threading;
-using System.Threading.Tasks;
-
-// Read in more details about all aspects of CS-Script hosting in applications
-// here: http://www.csscript.net/help/Script_hosting_guideline_.html
-//
-// This file contains samples for the script hosting scenarios requiring asynchronous script execution as well as unloading the
-// scripts being executed.
-// AsyncSamples
-// Samples demonstrate the use of Async and Await mechanism available in C# 5 and higher. Note that the async method extensions
-// cover the complete set of CSScript.Evaluator methods.
-//
-// UnloadingSamples
-// Samples demonstrate the use of temporary AppDoamain for loading and executing dynamic C# code (script). It is the
-// only mechanism available for unloading dynamically loaded assemblies. This is a well known CLR design limitation that leads to
-// memory leaks if the assembly/script loaded in the caller AppDomain. The problem affects all C# script engines (e.g. Roslyn, CodeDom)
-// and it cannot be solved by the engine itself thus CS-Script provides a work around in form of the MethodExtensions for the
-// CSScript.Evaluator methods that are compatible with the unloading mechanism.
-//
-// Nevertheless you should try to avoid using remote AppDoamain unless you have to. It is very heavy and also imposes the serialization
-// constrains.
-//
-// All samples rely on the compiler agnostic CSScript.Evaluator API.
-namespace CSScriptEvaluatorExtensions
-{
- public class HostApp
- {
- public static void Test()
- {
- Console.WriteLine("---------------------------------------------");
- Console.WriteLine("Testing asynchronous API");
- Console.WriteLine("---------------------------------------------");
- new AsyncSamples().RunAll();
- Thread.Sleep(2000);
- Console.WriteLine("\nPress 'Enter' to run uloading samples...");
- Console.ReadLine();
- Console.WriteLine("---------------------------------------------");
- Console.WriteLine("Testing unloading API");
- Console.WriteLine("---------------------------------------------");
- new UnloadingSamples().RunAll();
- }
-
- class AsyncSamples
- {
- public void RunAll()
- {
- Action run = (action, name) => { action(); Console.WriteLine(name); };
-
- run(LoadDelegateAsync, "Start of " + nameof(LoadDelegateAsync));
- run(LoadMethodAsync, "Start of " + nameof(LoadMethodAsync));
- run(LoadCodeAsync, "Start of " + nameof(LoadCodeAsync));
- run(CreateDelegateAsync, "Start of " + nameof(CreateDelegateAsync));
- run(CompileCodeAsync, "Start of " + nameof(CompileCodeAsync));
- run(RemoteAsynch, "Start of " + nameof(RemoteAsynch));
- }
-
- async void LoadDelegateAsync()
- {
- var product = await CSScript.Evaluator
- .LoadDelegateAsync>(
- @"int Product(int a, int b)
- {
- return a * b;
- }");
-
- Console.WriteLine(" End of {0}: {1}", nameof(LoadDelegateAsync), product(4, 2));
- }
-
- public async void LoadMethodAsync()
- {
- dynamic script = await CSScript.Evaluator
- .LoadMethodAsync(@"public int Sum(int a, int b)
- {
- return a + b;
- }
- public int Div(int a, int b)
- {
- return a/b;
- }");
-
- Console.WriteLine(" End of {0}: {1}", nameof(LoadMethodAsync), script.Div(15, 3));
- }
-
- public async void LoadCodeAsync()
- {
- //This use-case uses Interface Alignment and this requires all assemblies involved to have
- //non-empty Assembly.Location
- CSScript.GlobalSettings.InMemoryAssembly = false;
-
- ICalc calc = await CSScript.Evaluator
- .LoadCodeAsync(
- @"using System;
- public class Script
- {
- public int Sum(int a, int b)
- {
- return a+b;
- }
- }");
-
- Console.WriteLine(" End of {0}: {1}", nameof(LoadCodeAsync), calc.Sum(1, 2));
- }
-
- public async void CreateDelegateAsync()
- {
- var product = await CSScript.Evaluator
- .CreateDelegateAsync(
- @"int Product(int a, int b)
- {
- return a * b;
- }");
-
- Console.WriteLine(" End of {0}: {1}", nameof(CreateDelegateAsync), product(15, 3));
- }
-
- public async void CompileCodeAsync()
- {
- Assembly script = await CSScript.Evaluator
- .CompileCodeAsync(@"using System;
- public class Script
- {
- public int Sum(int a, int b)
- {
- return a+b;
- }
- }");
- dynamic calc = script.CreateObject("*");
-
- Console.WriteLine(" End of {0}: {1}", nameof(CompileCodeAsync), calc.Sum(15, 3));
- }
-
- public async void RemoteAsynch()
- {
- var sum = await Task.Run(() =>
- CSScript.Evaluator
- .CreateDelegateRemotely(
- @"int Sum(int a, int b)
- {
- return a+b;
- }")
- );
- Console.WriteLine(" End of {0}: {1}", nameof(RemoteAsynch), sum(1, 2));
-
- sum.UnloadOwnerDomain();
- }
- }
-
- class UnloadingSamples
- {
- public void RunAll()
- {
- CreateDelegateRemotely();
- LoadMethodRemotely();
- LoadCodeRemotely();
- LoadCodeRemotelyWithInterface();
- }
-
- public void CreateDelegateRemotely()
- {
- var sum = CSScript.Evaluator
- .CreateDelegateRemotely(@"int Sum(int a, int b)
- {
- return a+b;
- }");
-
- Console.WriteLine("{0}: {1}", nameof(CreateDelegateRemotely), sum(15, 3));
-
- sum.UnloadOwnerDomain();
- }
-
- public void LoadCodeRemotely()
- {
- // Class Calc doesn't implement ICals interface. Thus the compiled object cannot be typecasted into
- // the interface and Evaluator will emit duck-typed assembly instead.
- // But Mono and Roslyn build file-less assemblies, meaning that they cannot be used to build
- // duck-typed proxies and CodeDomEvaluator needs to be used explicitly.
- // Note class Calc also inherits from MarshalByRefObject. This is required for all object that
- // are passed between AppDomain: they must inherit from MarshalByRefObject or be serializable.
-
- //This use-case uses Interface Alignment and this requires all assemblies involved to have
- //non-empty Assembly.Location
- CSScript.GlobalSettings.InMemoryAssembly = false;
-
- var script = CSScript.CodeDomEvaluator
- .LoadCodeRemotely(
- @"using System;
- public class Calc : MarshalByRefObject
- {
- object t;
- public int Sum(int a, int b)
- {
- t = new Test();
- return a+b;
- }
- }
-
- class Test
- {
- ~Test()
- {
- Console.WriteLine(""Domain is unloaded: ~Test()"");
- }
- }
- ");
-
- Console.WriteLine("{0}: {1}", nameof(LoadCodeRemotely), script.Sum(15, 3));
-
- script.UnloadOwnerDomain();
- }
-
- public void LoadCodeRemotelyWithInterface()
- {
- // Note class Calc also inherits from MarshalByRefObject. This is required for all object that
- // are passed between AppDomain: they must inherit from MarshalByRefObject or be serializable.
- var script = CSScript.Evaluator
- .LoadCodeRemotely(
- @"using System;
- public class Calc : MarshalByRefObject, CSScriptEvaluatorExtensions.ICalc
- {
- public int Sum(int a, int b)
- {
- return a+b;
- }
- }
- ");
-
- Console.WriteLine("{0}: {1}", nameof(LoadCodeRemotelyWithInterface), script.Sum(15, 3));
-
- script.UnloadOwnerDomain();
- }
-
- public void LoadMethodRemotely()
- {
- // LoadMethodRemotely is essentially the same as LoadCodeRemotely. It just deals not with the
- // whole class definition but a single method(s) only. And the rest of the class definition is
- // added automatically by CS-Script. The auto-generated class declaration also indicates
- // that the class implements ICalc interface. Meaning that it will trigger compile error
- // if the set of methods in the script code doesn't implement all interface members.
-
- //This use-case uses Interface Alignment and this requires all assemblies involved to have
- //non-empty Assembly.Location
- CSScript.GlobalSettings.InMemoryAssembly = false;
-
- var script = CSScript.Evaluator
- .LoadMethodRemotely(
- @"public int Sum(int a, int b)
- {
- return a+b;
- }
- public int Sub(int a, int b)
- {
- return a-b;
- }");
-
- Console.WriteLine("{0}: {1}", nameof(LoadMethodRemotely), script.Sum(15, 3));
-
- script.UnloadOwnerDomain();
- }
-
- MethodDelegate sum;
- ClientSponsor sumSponsor;
-
- public void KeepRemoteObjectAlive()
- {
- sum = CSScript.Evaluator
- .CreateDelegateRemotely(@"int Sum(int a, int b)
- {
- return a+b;
- }");
-
- //Normally remote objects are disposed if they are not accessed withing a default timeout period.
- //It is not even enough to keep transparent proxies or their wrappers (e.g. 'sum') referenced.
- //To prevent GC collection in the remote domain use .NET ClientSponsor mechanism as below.
- sumSponsor = sum.ExtendLifeFromMinutes(30);
- }
- }
- }
-
- public interface ICalc
- {
- int Sum(int a, int b);
- }
-
- public interface IFullCalc
- {
- int Sum(int a, int b);
-
- int Sub(int a, int b);
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.Core/Scripting.evaluator.cs b/src/Artemis.Core/Scripting.evaluator.cs
deleted file mode 100644
index 0e195776f..000000000
--- a/src/Artemis.Core/Scripting.evaluator.cs
+++ /dev/null
@@ -1,345 +0,0 @@
-using CSScriptLibrary;
-using System;
-using System.Diagnostics;
-
-// Read in more details about all aspects of CS-Script hosting in applications
-// here: http://www.csscript.net/help/Script_hosting_guideline_.html
-//
-// This file contains samples for the script hosting scenarios relying on CS-Script Evaluator interface (API).
-// This API is a unified generic interface allowing dynamic switch of the underlying compiling services (Mono, Roslyn, CodeDom)
-// without the need for changing the hosting code.
-//
-// Apart from Evaluator (compiler agnostic) API CS-Script offers alternative hosting model: CS-Script Native,
-// which relies solely on CodeDom compiler. CS-Script Native offers some features that are not available with CS-Script Evaluator
-// (e.g. script unloading).
-//
-// The choice of the underlying compiling engine (e.g. Mono vs CodeDom) when using CS-Script Evaluator is always dictated by the
-// specifics of the hosting scenario. Thanks to in-process compiler hosting, Mono and Roslyn demonstrate much better compiling
-// performance comparing to CodeDom engine. However they don't allow script debugging and caching easily supported with CodeDom.
-// Mono and particularly Roslyn also leas create more memory pressure due to the higher volume of the temp assemblies loaded into
-// the hosting AppDomain. Roslyn (at least CSharp.Scripting-v1.2.0.0) also has very high initial loading overhead up to 4 seconds.
-//
-// One of the possible approaches would be to use EvaluatorEngine.CodeDom during the active development and later on switch to Mono/Roslyn.
-
-namespace CSScriptEvaluatorApi
-{
- public class HostApp
- {
- public static void Test()
- {
- // Just in case clear AlternativeCompiler so it is not set to Roslyn or anything else by
- // the CS-Script installed (if any) on the host OS
- CSScript.GlobalSettings.UseAlternativeCompiler = null;
-
- var samples = new EvaluatorSamples();
-
- Console.WriteLine("Testing compiling services");
- Console.WriteLine("---------------------------------------------");
-
- CSScript.EvaluatorConfig.Engine = EvaluatorEngine.Mono;
- Console.WriteLine(CSScript.Evaluator.GetType().Name + "...");
- samples.RunAll();
-
- Console.WriteLine("---------------------------------------------");
-
- CSScript.EvaluatorConfig.Engine = EvaluatorEngine.Roslyn;
- Console.WriteLine(CSScript.Evaluator.GetType().Name + "...");
- samples.RunAll();
-
- Console.WriteLine("---------------------------------------------");
-
- CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom;
- Console.WriteLine(CSScript.Evaluator.GetType().Name + "...");
-
- samples.RunAll();
-
- //samples.DebugTest(); //uncomment if want to fire an assertion during the script execution
-
- //Profile(); //uncomment if want to test performance of the engines
- }
-
- class EvaluatorSamples
- {
- public void RunAll()
- {
- Action run = (action, name) => { action(); Console.WriteLine(name + " - OK"); };
-
- run(CompileMethod_Instance, nameof(CompileMethod_Instance));
- run(CompileMethod_Static, nameof(CompileMethod_Static));
- run(CreateDelegate, nameof(CreateDelegate));
- run(LoadDelegate, nameof(LoadDelegate));
- run(LoadCode, nameof(LoadCode));
- run(LoadMethod, nameof(LoadMethod));
- run(LoadMethodWithInterface, nameof(LoadMethodWithInterface));
- run(LoadCode_WithInterface, nameof(LoadCode_WithInterface));
- run(LoadCode_WithDuckTypedInterface, nameof(LoadCode_WithDuckTypedInterface));
- }
-
- public void CompileMethod_Instance()
- {
- // 1- CompileMethod wraps method into a class definition and returns compiled assembly
- // 2 - CreateObject creates instance of a first class in the assembly
-
- dynamic script = CSScript.Evaluator
- .CompileMethod(@"int Sqr(int data)
- {
- return data * data;
- }")
- .CreateObject("*");
-
- var result = script.Sqr(7);
- }
-
- public void CompileMethod_Static()
- {
- // 1 - CompileMethod wraps method into a class definition and returns compiled assembly
- // 2 - GetStaticMethod returns duck-typed delegate that accepts 'params object[]' arguments
- // Note: GetStaticMethodWithArgs can be replaced with a more convenient/shorter version
- // that takes the object instead of the Type and then queries objects type internally:
- // "GetStaticMethod("*.Test", data)"
-
- var test = CSScript.Evaluator
- .CompileMethod(@"using CSScriptEvaluatorApi;
- static void Test(InputData data)
- {
- data.Index = GetIndex();
- }
- static int GetIndex()
- {
- return Environment.TickCount;
- }")
- .GetStaticMethodWithArgs("*.Test", typeof(InputData));
-
- var data = new InputData();
- test(data);
- }
-
- public void CreateDelegate()
- {
- // Wraps method into a class definition, compiles it and loads the compiled assembly.
- // It returns duck-typed delegate. A delegate with 'params object[]' arguments and
- // without any specific return type.
-
- var sqr = CSScript.Evaluator
- .CreateDelegate(@"int Sqr(int a)
- {
- return a * a;
- }");
-
- var r = sqr(3);
- }
-
- public void LoadDelegate()
- {
- // Wraps method into a class definition, loads the compiled assembly
- // and returns the method delegate for the method, which matches the delegate specified
- // as the type parameter of LoadDelegate
-
- var product = CSScript.Evaluator
- .LoadDelegate>(
- @"int Product(int a, int b)
- {
- return a * b;
- }");
-
- int result = product(3, 2);
- }
-
- public void LoadCode()
- {
- // LoadCode compiles code and returns instance of a first class
- // in the compiled assembly
-
- dynamic script = CSScript.Evaluator
- .LoadCode(@"using System;
- public class Script
- {
- public int Sum(int a, int b)
- {
- return a+b;
- }
- }");
-
- int result = script.Sum(1, 2);
- }
-
- public void LoadMethod()
- {
- // LoadMethod compiles code and returns instance of a first class
- // in the compiled assembly.
- // LoadMethod is essentially the same as LoadCode. It just deals not with the
- // whole class definition but a single method(s) only. And the rest of the class definition is
- // added automatically by CS-Script.
- // 'public' is optional as it will be injected if the code doesn't start with it.
- dynamic script = CSScript.Evaluator
- .LoadMethod(@"using System;
- public int Sum(int a, int b)
- {
- return a+b;
- }");
-
- int result = script.Sum(1, 2);
- }
-
- public void LoadMethodWithInterface()
- {
- // LoadMethod compiles code and returns instance of a first class
- // in the compiled assembly.
- // LoadMethod is essentially the same as LoadCode. It just deals not with the
- // whole class definition but a single method(s) only. And the rest of the class definition is
- // added automatically by CS-Script. The auto-generated class declaration also indicates
- // that the class implements ICalc interface. Meaning that it will trigger compile error
- // if the set of methods in the script code doesn't implement all interface members.
-
- //This use-case uses Interface Alignment and this requires all assemblies involved to have
- //non-empty Assembly.Location
- CSScript.GlobalSettings.InMemoryAssembly = false;
-
- ICalc script = CSScript.Evaluator
- .LoadMethod(
- @"int Sum(int a, int b)
- {
- return a+b;
- }");
-
- int result = script.Sum(1, 2);
- }
-
- public void LoadCode_WithInterface()
- {
- // 1 - LoadCode compiles code and returns instance of a first class in the compiled assembly
- // 2 - The script class implements host app interface so the returned object can be type casted into it
-
- var script = (ICalc)CSScript.Evaluator
- .LoadCode(@"using System;
- public class Script : CSScriptEvaluatorApi.ICalc
- {
- public int Sum(int a, int b)
- {
- return a+b;
- }
- }");
-
- int result = script.Sum(1, 2);
- }
-
- public void LoadCode_WithDuckTypedInterface()
- {
- // 1 - LoadCode compiles code and returns instance of a first class in the compiled assembly
- // 2- The script class doesn't implement host app interface but it can still be aligned to
- // one as long at it implements the interface members
-
- //This use-case uses Interface Alignment and this requires all assemblies involved to have
- //non-empty Assembly.Location
- CSScript.GlobalSettings.InMemoryAssembly = false;
-
- ICalc script = CSScript.MonoEvaluator
- .LoadCode(@"using System;
- public class Script
- {
- public int Sum(int a, int b)
- {
- return a+b;
- }
- }");
-
- int result = script.Sum(1, 2);
- }
-
- public void PerformanceTest(int count = -1)
- {
- var code = @"int Sqr(int a)
- {
- return a * a;
- }";
-
- if (count != -1)
- code += "//" + count; //this unique extra code comment ensures the code to be compiled cannot be cached
-
- dynamic script = CSScript.Evaluator
- .CompileMethod(code)
- .CreateObject("*");
-
- var r = script.Sqr(3);
- }
-
- public void DebugTest()
- {
- //pops up an assertion dialog
-
- CSScript.EvaluatorConfig.DebugBuild = true;
- CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom;
-
- dynamic script = CSScript.Evaluator
- .LoadCode(@"using System;
- using System.Diagnostics;
- public class Script
- {
- public int Sum(int a, int b)
- {
- Debug.Assert(false,""Testing CS-Script debugging..."");
- return a+b;
- }
- }");
-
- var r = script.Sum(3, 4);
- }
- }
-
- public static void Profile()
- {
- var sw = new Stopwatch();
- var samples = new EvaluatorSamples();
- var count = 20;
- var inxed = 0;
- bool preventCaching = false;
-
- Action run = () =>
- {
- sw.Restart();
- for (int i = 0; i < count; i++)
- if (preventCaching)
- samples.PerformanceTest(inxed++);
- else
- samples.PerformanceTest();
-
- Console.WriteLine(CSScript.Evaluator.GetType().Name + ": " + sw.ElapsedMilliseconds);
- };
-
- Action runAll = () =>
- {
- Console.WriteLine("\n---------------------------------------------");
- Console.WriteLine($"Caching enabled: {!preventCaching}\n");
-
- CSScript.EvaluatorConfig.Engine = EvaluatorEngine.Mono;
- run();
-
- CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom;
- run();
-
- CSScript.EvaluatorConfig.Engine = EvaluatorEngine.Roslyn;
- run();
- };
-
- RoslynEvaluator.LoadCompilers(); //Roslyn is extremely heavy so exclude startup time from profiling
-
- Console.WriteLine("Testing performance");
-
- preventCaching = true;
- runAll();
-
- preventCaching = false;
- runAll();
- }
- }
-
- public interface ICalc
- {
- int Sum(int a, int b);
- }
-
- public class InputData
- {
- public int Index = 0;
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.Core/Scripting.native.cs b/src/Artemis.Core/Scripting.native.cs
deleted file mode 100644
index 37c7ef2f7..000000000
--- a/src/Artemis.Core/Scripting.native.cs
+++ /dev/null
@@ -1,354 +0,0 @@
-using CSScriptLibrary;
-using System;
-using System.Linq;
-using System.IO;
-using csscript;
-using System.CodeDom.Compiler;
-
-// Read in more details about all aspects of CS-Script hosting in applications
-// here: http://www.csscript.net/help/Script_hosting_guideline_.html
-//
-// This file contains samples for the script hosting scenarios relying on CS-Script Native interface (API).
-// This API is a compiler specific interface, which relies solely on CodeDom compiler. In most of the cases
-// CS-Script Native model is the most flexible and natural choice
-//
-// Apart from Native API CS-Script offers alternative hosting model: CS-Script Evaluator, which provides
-// a unified generic interface allowing dynamic switch the underlying compiling services (Mono, Roslyn, CodeDom)
-// without the need for changing the hosting code.
-//
-// The Native interface is the original API that was designed to take maximum advantage of the dynamic C# code
-// execution with CodeDom. The original implementation of this API was developed even before any compiler-as-service
-// solution became available. Being based solely on CodeDOM the API doesn't utilize neither Mono nor Roslyn
-// scripting solutions. Despite that CS-Script Native is the most mature, powerful and flexible API available with CS-Script.
-//
-// Native interface allows some unique features that are not available with CS-Script Evaluator:
-// - Debugging scripts
-// - Script caching
-// - Script unloading
-
-namespace CSScriptNativeApi
-{
- public class HostApp
- {
- public static void Test()
- {
- var host = new HostApp();
- host.Log("Testing compiling services CS-Script Native API");
- Console.WriteLine("---------------------------------------------");
-
- CodeDomSamples.LoadMethod_Instance();
- CodeDomSamples.LoadMethod_Static();
- CodeDomSamples.LoadDelegate();
- CodeDomSamples.CreateAction();
- CodeDomSamples.CreateFunc();
- CodeDomSamples.LoadCode();
- CodeDomSamples.LoadCode_WithInterface(host);
- CodeDomSamples.LoadCode_WithDuckTypedInterface(host);
- CodeDomSamples.ExecuteAndUnload();
- //CodeDomSamples.DebugTest(); //uncomment if want to fire an assertion during the script execution
- }
-
- public class CodeDomSamples
- {
- public static void LoadMethod_Instance()
- {
- // 1- LoadMethod wraps method into a class definition, compiles it and returns loaded assembly
- // 2 - CreateObject creates instance of a first class in the assembly
-
- dynamic script = CSScript.LoadMethod(@"int Sqr(int data)
- {
- return data * data;
- }")
- .CreateObject("*");
-
- var result = script.Sqr(7);
- }
-
- public static void LoadMethod_Static()
- {
- // 1 - LoadMethod wraps method into a class definition, compiles it and returns loaded assembly
- // 2 - GetStaticMethod returns first found static method as a duck-typed delegate that
- // accepts 'params object[]' arguments
- //
- // Note: you can use GetStaticMethodWithArgs for higher precision method search: GetStaticMethodWithArgs("*.SayHello", typeof(string));
- var sayHello = CSScript.LoadMethod(@"static void SayHello(string greeting)
- {
- Console.WriteLine(greeting);
- }")
- .GetStaticMethod();
-
- sayHello("Hello World!");
- }
-
- public static void LoadDelegate()
- {
- // LoadDelegate wraps method into a class definition, compiles it and loads the compiled assembly.
- // It returns the method delegate for the method, which matches the delegate specified
- // as the type parameter of LoadDelegate
-
- // The 'using System;' is optional; it demonstrates how to specify 'using' in the method-only syntax
-
- var sayHello = CSScript.LoadDelegate>(
- @"void SayHello(string greeting)
- {
- Console.WriteLine(greeting);
- }");
-
- sayHello("Hello World!");
- }
-
- public static void CreateAction()
- {
- // Wraps method into a class definition, compiles it and loads the compiled assembly.
- // It returns duck-typed delegate. A delegate with 'params object[]' arguments and
- // without any specific return type.
-
- var sayHello = CSScript.CreateAction(@"void SayHello(string greeting)
- {
- Console.WriteLine(greeting);
- }");
-
- sayHello("Hello World!");
- }
-
- public static void CreateFunc()
- {
- // Wraps method into a class definition, compiles it and loads the compiled assembly.
- // It returns duck-typed delegate. A delegate with 'params object[]' arguments and
- // int as a return type.
-
- var Sqr = CSScript.CreateFunc(@"int Sqr(int a)
- {
- return a * a;
- }");
- int r = Sqr(3);
- }
-
- public static void LoadCode()
- {
- // LoadCode compiles code and returns instance of a first class
- // in the compiled assembly
-
- dynamic script = CSScript.LoadCode(@"using System;
- public class Script
- {
- public int Sum(int a, int b)
- {
- return a+b;
- }
- }")
- .CreateObject("*");
-
- int result = script.Sum(1, 2);
- }
-
- public static void LoadCodeWithConfig()
- {
- // LoadCode compiles code and returns instance of a first class
- // in the compiled assembly
-
- string file = Path.GetTempFileName();
- try
- {
- File.WriteAllText(file, @"using System;
- public class Script
- {
- public int Sum(int a, int b)
- {
- return a+b;
- }
- }");
-
- var settings = new Settings();
- //settings = null; // set to null to foll back to defaults
-
- dynamic script = CSScript.LoadWithConfig(file, null, false, settings, "/define:TEST")
- .CreateObject("*");
-
- int result = script.Sum(1, 2);
- }
- finally
- {
- if (File.Exists(file))
- File.Delete(file);
- }
- }
-
- public static void LoadCode_WithInterface(HostApp host)
- {
- // 1 - LoadCode compiles code and returns instance of a first class in the compiled assembly.
- // 2 - The script class implements host app interface so the returned object can be type casted into it.
- // 3 - In this sample host object is passed into script routine.
-
- var calc = (ICalc) CSScript.LoadCode(@"using CSScriptNativeApi;
- public class Script : ICalc
- {
- public int Sum(int a, int b)
- {
- if(Host != null)
- Host.Log(""Sum is invoked"");
- return a + b;
- }
-
- public HostApp Host { get; set; }
- }")
- .CreateObject("*");
- calc.Host = host;
- int result = calc.Sum(1, 2);
- }
-
- public static void LoadCode_WithDuckTypedInterface(HostApp host)
- {
- // 1 - LoadCode compiles code and returns instance of a first class in the compiled assembly
- // 2- The script class doesn't implement host app interface but it can still be aligned to
- // one as long at it implements the interface members
- // 3 - In this sample host object is passed into script routine.
-
- //This use-case uses Interface Alignment and this requires all assemblies involved to have
- //non-empty Assembly.Location
- CSScript.GlobalSettings.InMemoryAssembly = false;
-
- ICalc calc = CSScript.LoadCode(@"using CSScriptNativeApi;
- public class Script
- {
- public int Sum(int a, int b)
- {
- if(Host != null)
- Host.Log(""Sum is invoked"");
- return a + b;
- }
-
- public HostApp Host { get; set; }
- }")
- .CreateObject("*")
- .AlignToInterface();
- calc.Host = host;
- int result = calc.Sum(1, 2);
- }
-
- public static void ExecuteAndUnload()
- {
- // The script will be loaded into a temporary AppDomain and unloaded after the execution.
-
- // Note: remote execution is a subject of some restrictions associated with the nature of the
- // CLR cross-AppDomain interaction model:
- // * the script class must be serializable or derived from MarshalByRefObject.
- //
- // * any object (call arguments, return objects) that crosses ApPDomain boundaries
- // must be serializable or derived from MarshalByRefObject.
- //
- // * long living script class instances may get disposed in remote domain even if they are
- // being referenced in the current AppDomain. You need to use the usual .NET techniques
- // to prevent that. See LifetimeManagement.cs sample for details.
-
- //This use-case uses Interface Alignment and this requires all assemblies involved to have
- //non-empty Assembly.Location
- CSScript.GlobalSettings.InMemoryAssembly = false;
-
- var code = @"using System;
- public class Script : MarshalByRefObject
- {
- public void Hello(string greeting)
- {
- Console.WriteLine(greeting);
- }
- }";
-
- //Note: usage of helper.CreateAndAlignToInterface("Script") is also acceptable
- using (var helper = new AsmHelper(CSScript.CompileCode(code), null, deleteOnExit: true))
- {
- IScript script = helper.CreateAndAlignToInterface("*");
- script.Hello("Hi there...");
- }
- //from this point AsmHelper is disposed and the temp AppDomain is unloaded
- }
-
- public static void DebugTest()
- {
- //pops up an assertion dialog
- dynamic script = CSScript.LoadCode(@"using System;
- using System.Diagnostics;
- public class Script
- {
- public int Sum(int a, int b)
- {
- Debug.Assert(false,""Testing CS-Script debugging..."");
- return a+b;
- }
- }", null, debugBuild: true).CreateObject("*");
-
- int result = script.Sum(1, 2);
- }
- }
-
- public void Log(string message)
- {
- Console.WriteLine(message);
- }
- }
-
- public interface IScript
- {
- void Hello(string greeting);
- }
-
- public interface ICalc
- {
- HostApp Host { get; set; }
-
- int Sum(int a, int b);
- }
-
- public class Samples
- {
- static public void CompilingHistory()
- {
- string script = Path.GetTempFileName();
- string scriptAsm = script + ".dll";
- CSScript.KeepCompilingHistory = true;
-
- try
- {
- File.WriteAllText(script, @"using System;
- using System.Windows.Forms;
- public class Script
- {
- public int Sum(int a, int b)
- {
- return a+b;
- }
- }");
-
-
-
- CSScript.CompileFile(script, scriptAsm, false, null);
-
- CompilingInfo info = CSScript.CompilingHistory
- .Values
- .FirstOrDefault(item => item.ScriptFile == script);
- if (info != null)
- {
- Console.WriteLine("Script: " + info.ScriptFile);
-
- Console.WriteLine("Referenced assemblies:");
- foreach (string asm in info.Input.ReferencedAssemblies)
- Console.WriteLine(asm);
-
- if (info.Result.Errors.HasErrors)
- {
- foreach (CompilerError err in info.Result.Errors)
- if (!err.IsWarning)
- Console.WriteLine("Error: " + err.ErrorText);
- }
- }
-
- CSScript.CompilingHistory.Clear();
-
- }
- finally
- {
- CSScript.KeepCompilingHistory = false;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Interfaces/IPluginService.cs b/src/Artemis.Core/Services/Interfaces/IPluginService.cs
index f086b1513..112c01053 100644
--- a/src/Artemis.Core/Services/Interfaces/IPluginService.cs
+++ b/src/Artemis.Core/Services/Interfaces/IPluginService.cs
@@ -2,8 +2,8 @@
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Artemis.Core.Events;
-using Artemis.Core.Models;
using Artemis.Plugins.Interfaces;
+using Artemis.Plugins.Models;
namespace Artemis.Core.Services.Interfaces
{
diff --git a/src/Artemis.Core/Services/PluginService.cs b/src/Artemis.Core/Services/PluginService.cs
index 475fbdace..e11e981ae 100644
--- a/src/Artemis.Core/Services/PluginService.cs
+++ b/src/Artemis.Core/Services/PluginService.cs
@@ -6,9 +6,9 @@ using System.Linq;
using System.Threading.Tasks;
using Artemis.Core.Events;
using Artemis.Core.Exceptions;
-using Artemis.Core.Models;
using Artemis.Core.Services.Interfaces;
using Artemis.Plugins.Interfaces;
+using Artemis.Plugins.Models;
using CSScriptLibrary;
using Newtonsoft.Json;
using Ninject;
@@ -24,7 +24,7 @@ namespace Artemis.Core.Services
{
_kernel = kernel;
_plugins = new List();
-
+
if (!Directory.Exists(Constants.DataFolder + "plugins"))
Directory.CreateDirectory(Constants.DataFolder + "plugins");
}
@@ -66,9 +66,11 @@ namespace Artemis.Core.Services
throw new ArtemisPluginException(pluginInfo, "Cannot locate a view model for this plugin.");
// Instantiate the ViewModel with Ninject
- return (IPluginViewModel) _kernel.Get(vmType);
+ var vm = (IPluginViewModel) _kernel.Get(vmType);
+ vm.PluginInfo = pluginInfo;
+ return vm;
}
-
+
public void Dispose()
{
}
diff --git a/src/Artemis.Core/packages.config b/src/Artemis.Core/packages.config
index 51fe9d3d6..34f6373ff 100644
--- a/src/Artemis.Core/packages.config
+++ b/src/Artemis.Core/packages.config
@@ -28,6 +28,7 @@
+
diff --git a/src/Artemis.Plugins/Abstract/PluginViewModel.cs b/src/Artemis.Plugins/Abstract/PluginViewModel.cs
index 269cb1869..cba287e00 100644
--- a/src/Artemis.Plugins/Abstract/PluginViewModel.cs
+++ b/src/Artemis.Plugins/Abstract/PluginViewModel.cs
@@ -1,9 +1,11 @@
using Artemis.Plugins.Interfaces;
+using Artemis.Plugins.Models;
using Stylet;
namespace Artemis.Plugins.Abstract
{
public abstract class PluginViewModel : Screen, IPluginViewModel
{
+ public PluginInfo PluginInfo { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Plugins/Artemis.Plugins.csproj b/src/Artemis.Plugins/Artemis.Plugins.csproj
index 1f0dbc33a..04adf6b1f 100644
--- a/src/Artemis.Plugins/Artemis.Plugins.csproj
+++ b/src/Artemis.Plugins/Artemis.Plugins.csproj
@@ -30,6 +30,9 @@
4
+
+ ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
+
..\packages\Ninject.3.3.4\lib\net45\Ninject.dll
@@ -47,11 +50,13 @@
+
+
diff --git a/src/Artemis.Plugins/Interfaces/IDataModelExpansion.cs b/src/Artemis.Plugins/Interfaces/IDataModelExpansion.cs
new file mode 100644
index 000000000..9c0f1025a
--- /dev/null
+++ b/src/Artemis.Plugins/Interfaces/IDataModelExpansion.cs
@@ -0,0 +1,10 @@
+namespace Artemis.Plugins.Interfaces
+{
+ ///
+ ///
+ /// Allows you to expand the application-wide datamodel
+ ///
+ public interface IDataModelExpansion : IPlugin
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Plugins/Interfaces/IDevice.cs b/src/Artemis.Plugins/Interfaces/IDevice.cs
index b6508af47..b40566156 100644
--- a/src/Artemis.Plugins/Interfaces/IDevice.cs
+++ b/src/Artemis.Plugins/Interfaces/IDevice.cs
@@ -1,5 +1,9 @@
namespace Artemis.Plugins.Interfaces
{
+ ///
+ ///
+ /// Allows you to implement your own RGB device
+ ///
public interface IDevice : IPlugin
{
}
diff --git a/src/Artemis.Plugins/Interfaces/ILayerType.cs b/src/Artemis.Plugins/Interfaces/ILayerType.cs
index 012322ce5..1a06bc0ea 100644
--- a/src/Artemis.Plugins/Interfaces/ILayerType.cs
+++ b/src/Artemis.Plugins/Interfaces/ILayerType.cs
@@ -1,5 +1,9 @@
namespace Artemis.Plugins.Interfaces
{
+ ///
+ ///
+ /// Allows you to create your own layer type
+ ///
public interface ILayerType : IPlugin
{
}
diff --git a/src/Artemis.Plugins/Interfaces/IModule.cs b/src/Artemis.Plugins/Interfaces/IModule.cs
index c666ecc8e..0eac4ca47 100644
--- a/src/Artemis.Plugins/Interfaces/IModule.cs
+++ b/src/Artemis.Plugins/Interfaces/IModule.cs
@@ -1,5 +1,9 @@
namespace Artemis.Plugins.Interfaces
{
+ ///
+ ///
+ /// Allows you to add support for new games/applications
+ ///
public interface IModule : IPlugin
{
}
diff --git a/src/Artemis.Plugins/Interfaces/IPlugin.cs b/src/Artemis.Plugins/Interfaces/IPlugin.cs
index d9063dacc..1c6da9f41 100644
--- a/src/Artemis.Plugins/Interfaces/IPlugin.cs
+++ b/src/Artemis.Plugins/Interfaces/IPlugin.cs
@@ -1,10 +1,10 @@
-using System.Threading.Tasks;
-
-namespace Artemis.Plugins.Interfaces
+namespace Artemis.Plugins.Interfaces
{
+ ///
+ /// This is the base plugin type, use the other interfaces such as IModule to create plugins
+ ///
public interface IPlugin
- {
- ///
+ {///
/// Called when the plugin is loaded
///
void LoadPlugin();
diff --git a/src/Artemis.Plugins/Interfaces/IPluginViewModel.cs b/src/Artemis.Plugins/Interfaces/IPluginViewModel.cs
index 9ba9cf6d1..711fb20b7 100644
--- a/src/Artemis.Plugins/Interfaces/IPluginViewModel.cs
+++ b/src/Artemis.Plugins/Interfaces/IPluginViewModel.cs
@@ -1,8 +1,14 @@
-using Stylet;
+using Artemis.Plugins.Models;
+using Stylet;
namespace Artemis.Plugins.Interfaces
{
+ ///
+ ///
+ /// Allows you to create a view model for a plugin
+ ///
public interface IPluginViewModel : IScreen
{
+ PluginInfo PluginInfo { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/PluginInfo.cs b/src/Artemis.Plugins/Models/PluginInfo.cs
similarity index 96%
rename from src/Artemis.Core/Models/PluginInfo.cs
rename to src/Artemis.Plugins/Models/PluginInfo.cs
index 1c8e2fa2b..f4819a1dc 100644
--- a/src/Artemis.Core/Models/PluginInfo.cs
+++ b/src/Artemis.Plugins/Models/PluginInfo.cs
@@ -1,7 +1,7 @@
using Artemis.Plugins.Interfaces;
using Newtonsoft.Json;
-namespace Artemis.Core.Models
+namespace Artemis.Plugins.Models
{
public class PluginInfo
{
diff --git a/src/Artemis.Plugins/packages.config b/src/Artemis.Plugins/packages.config
index 90d89f33c..9295a4bb5 100644
--- a/src/Artemis.Plugins/packages.config
+++ b/src/Artemis.Plugins/packages.config
@@ -1,5 +1,6 @@
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj
index 8158fc1d2..569fbeec4 100644
--- a/src/Artemis.UI/Artemis.UI.csproj
+++ b/src/Artemis.UI/Artemis.UI.csproj
@@ -93,6 +93,8 @@
+
+
diff --git a/src/Artemis.UI/Ninject/UiModule.cs b/src/Artemis.UI/Ninject/UiModule.cs
index a04c20fe3..85df21828 100644
--- a/src/Artemis.UI/Ninject/UiModule.cs
+++ b/src/Artemis.UI/Ninject/UiModule.cs
@@ -1,4 +1,5 @@
-using Artemis.UI.ViewModels.Interfaces;
+using Artemis.UI.Services.Interfaces;
+using Artemis.UI.ViewModels.Interfaces;
using Ninject.Extensions.Conventions;
using Ninject.Modules;
@@ -17,6 +18,16 @@ namespace Artemis.UI.Ninject
.InheritedFrom()
.BindAllInterfaces();
});
+
+ // Bind all UI services as singletons
+ Kernel.Bind(x =>
+ {
+ x.FromThisAssembly()
+ .SelectAllClasses()
+ .InheritedFrom()
+ .BindAllInterfaces()
+ .Configure(c => c.InSingletonScope());
+ });
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Services/Interfaces/IArtemisUIService.cs b/src/Artemis.UI/Services/Interfaces/IArtemisUIService.cs
new file mode 100644
index 000000000..38a201599
--- /dev/null
+++ b/src/Artemis.UI/Services/Interfaces/IArtemisUIService.cs
@@ -0,0 +1,8 @@
+namespace Artemis.UI.Services.Interfaces
+{
+ // ReSharper disable once InconsistentNaming
+ public interface IArtemisUIService
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Stylet/ArtemisViewManager.cs b/src/Artemis.UI/Stylet/ArtemisViewManager.cs
new file mode 100644
index 000000000..d77dd6502
--- /dev/null
+++ b/src/Artemis.UI/Stylet/ArtemisViewManager.cs
@@ -0,0 +1,46 @@
+using System.IO;
+using System.Windows;
+using System.Windows.Markup;
+using Artemis.Core.Exceptions;
+using Artemis.Plugins.Interfaces;
+using Stylet;
+
+namespace Artemis.UI.Stylet
+{
+ public class ArtemisViewManager : ViewManager
+ {
+ public ArtemisViewManager(ViewManagerConfig config) : base(config)
+ {
+ }
+
+ public override UIElement CreateViewForModel(object model)
+ {
+ if (model is IPluginViewModel)
+ return CreateViewForPlugin(model);
+
+ return base.CreateViewForModel(model);
+ }
+
+ private UIElement CreateViewForPlugin(object model)
+ {
+ var pluginInfo = ((IPluginViewModel) model).PluginInfo;
+ var viewPath = pluginInfo.Folder + pluginInfo.ViewModel.Replace("ViewModel", "View").Replace(".cs", ".xaml");
+ // There doesn't have to be a view so make sure one exists
+ if (!File.Exists(viewPath))
+ return null;
+
+ // Compile the view if found, must be done on UI thread sadly
+ object view = null;
+ Execute.OnUIThread(() => view = XamlReader.Parse(File.ReadAllText(viewPath)));
+ var viewType = view.GetType();
+ // Make sure it's a valid UIElement
+ if (viewType.IsAbstract || !typeof(UIElement).IsAssignableFrom(viewType))
+ {
+ var e = new ArtemisPluginException(pluginInfo, $"Found type for view: {viewType.Name}, but it wasn't a class derived from UIElement");
+ throw e;
+ }
+
+ return (UIElement) view;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Stylet/NinjectBootstrapper.cs b/src/Artemis.UI/Stylet/NinjectBootstrapper.cs
index 51a364424..d09cff98e 100644
--- a/src/Artemis.UI/Stylet/NinjectBootstrapper.cs
+++ b/src/Artemis.UI/Stylet/NinjectBootstrapper.cs
@@ -31,7 +31,7 @@ namespace Artemis.UI.Stylet
ViewFactory = GetInstance,
ViewAssemblies = new List {GetType().Assembly}
};
- kernel.Bind().ToConstant(new ViewManager(viewManagerConfig));
+ kernel.Bind().ToConstant(new ArtemisViewManager(viewManagerConfig));
kernel.Bind().ToConstant(this).InTransientScope();
kernel.Bind().ToMethod(c => new WindowManager(c.Kernel.Get(),
diff --git a/src/Artemis.UI/ViewModels/HomeViewModel.cs b/src/Artemis.UI/ViewModels/HomeViewModel.cs
index 367ec1a12..25d99189d 100644
--- a/src/Artemis.UI/ViewModels/HomeViewModel.cs
+++ b/src/Artemis.UI/ViewModels/HomeViewModel.cs
@@ -1,6 +1,5 @@
using System;
using System.Diagnostics;
-using Artemis.Core.Services.Interfaces;
using Artemis.UI.ViewModels.Interfaces;
using Stylet;
@@ -8,15 +7,6 @@ namespace Artemis.UI.ViewModels
{
public class HomeViewModel : Screen, IHomeViewModel
{
- private readonly IPluginService _pluginService;
-
- public HomeViewModel(IPluginService pluginService)
- {
- _pluginService = pluginService;
-
- _pluginService.FinishedLoadedPlugins += PluginServiceOnFinishedLoadedPlugins;
- }
-
public string Title => "Home";
public void OpenUrl(string url)
@@ -25,15 +15,5 @@ namespace Artemis.UI.ViewModels
if (Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute))
Process.Start(url);
}
-
- ///
- /// Populates the sidebar with plugins when they are finished loading
- ///
- ///
- ///
- private void PluginServiceOnFinishedLoadedPlugins(object sender, EventArgs eventArgs)
- {
- throw new NotImplementedException();
- }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/ViewModels/Interfaces/IArtemisViewModel.cs b/src/Artemis.UI/ViewModels/Interfaces/IArtemisViewModel.cs
index fae827f1c..5ac9f1683 100644
--- a/src/Artemis.UI/ViewModels/Interfaces/IArtemisViewModel.cs
+++ b/src/Artemis.UI/ViewModels/Interfaces/IArtemisViewModel.cs
@@ -1,6 +1,8 @@
-namespace Artemis.UI.ViewModels.Interfaces
+using Stylet;
+
+namespace Artemis.UI.ViewModels.Interfaces
{
- public interface IArtemisViewModel
+ public interface IArtemisViewModel : IScreen
{
string Title { get; }
}
diff --git a/src/Artemis.UI/ViewModels/RootViewModel.cs b/src/Artemis.UI/ViewModels/RootViewModel.cs
index f77b30f2b..2f1ac82ba 100644
--- a/src/Artemis.UI/ViewModels/RootViewModel.cs
+++ b/src/Artemis.UI/ViewModels/RootViewModel.cs
@@ -1,24 +1,57 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
+using Artemis.Core.Services.Interfaces;
+using Artemis.Plugins.Interfaces;
+using Artemis.Plugins.Models;
+using Artemis.UI.Services.Interfaces;
using Artemis.UI.ViewModels.Interfaces;
using Stylet;
namespace Artemis.UI.ViewModels
{
- public class RootViewModel : Conductor.Collection.OneActive
+ public class RootViewModel : Conductor.Collection.OneActive
{
private readonly ICollection _artemisViewModels;
+ private readonly IPluginService _pluginService;
- public RootViewModel(ICollection artemisViewModels)
+ public RootViewModel(ICollection artemisViewModels, IPluginService pluginService)
{
_artemisViewModels = artemisViewModels;
+ _pluginService = pluginService;
+
// Add the built-in items
Items.AddRange(artemisViewModels);
// Activate the home item
ActiveItem = _artemisViewModels.First(v => v.GetType() == typeof(HomeViewModel));
+
+ // Sync up with the plugin service
+ Modules = new BindableCollection();
+ LoadingPlugins = _pluginService.LoadingPlugins;
+ _pluginService.StartedLoadingPlugins += PluginServiceOnStartedLoadingPlugins;
+ _pluginService.FinishedLoadedPlugins += PluginServiceOnFinishedLoadedPlugins;
+
+ if (!LoadingPlugins)
+ Modules.AddRange(_pluginService.Plugins.Where(p => p.Plugin is IModule));
}
+ public IObservableCollection Modules { get; set; }
+
public bool MenuOpen { get; set; }
+ public bool LoadingPlugins { get; set; }
+
+ private void PluginServiceOnStartedLoadingPlugins(object sender, EventArgs eventArgs)
+ {
+ LoadingPlugins = true;
+ Modules.Clear();
+ }
+
+ private void PluginServiceOnFinishedLoadedPlugins(object sender, EventArgs eventArgs)
+ {
+ LoadingPlugins = false;
+ Modules.AddRange(_pluginService.Plugins.Where(p => p.Plugin is IModule));
+ NavigateToModule(Modules.First());
+ }
public void NavigateToHome()
{
@@ -39,5 +72,13 @@ namespace Artemis.UI.ViewModels
ActivateItem(_artemisViewModels.First(v => v.GetType() == typeof(SettingsViewModel)));
MenuOpen = false;
}
+
+ public async void NavigateToModule(PluginInfo pluginInfo)
+ {
+ // Create a view model for the given plugin info (which will be a module)
+ var viewModel = await _pluginService.GetPluginViewModel(pluginInfo);
+ // Tell Stylet to active the view model, the view manager will compile and show the XAML
+ ActivateItem(viewModel);
+ }
}
}
\ No newline at end of file