diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj
index 6654080aa..aafe6a280 100644
--- a/Artemis/Artemis/Artemis.csproj
+++ b/Artemis/Artemis/Artemis.csproj
@@ -415,11 +415,16 @@
+
-
+
+
+
+
-
+
+
diff --git a/Artemis/Artemis/Models/EffectModel.cs b/Artemis/Artemis/Models/EffectModel.cs
index 428a435c7..7dad6f719 100644
--- a/Artemis/Artemis/Models/EffectModel.cs
+++ b/Artemis/Artemis/Models/EffectModel.cs
@@ -8,6 +8,7 @@ using Artemis.Models.Interfaces;
using Artemis.Profiles;
using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models;
+using Artemis.Profiles.Lua;
using Artemis.Settings;
using Newtonsoft.Json;
@@ -40,8 +41,10 @@ namespace Artemis.Models
public virtual void Dispose()
{
- if (Profile != null)
- Profile.LuaWrapper = null;
+ if (Profile?.LuaWrapper == null)
+ return;
+ Profile.LuaWrapper.Dispose();
+ Profile.LuaWrapper = null;
}
// Called on creation
@@ -66,12 +69,16 @@ namespace Artemis.Models
// Get all enabled layers who's conditions are met
var renderLayers = GetRenderLayers(keyboardOnly);
+ // If the profile has no active LUA wrapper, create one
+ if (Profile.LuaWrapper == null && !string.IsNullOrEmpty(Profile.LuaScript))
+ Profile.LuaWrapper = new LuaWrapper(Profile, MainManager.DeviceManager.ActiveKeyboard);
+
// Render the keyboard layer-by-layer
var keyboardRect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
using (var g = Graphics.FromImage(frame.KeyboardBitmap))
{
Profile?.DrawLayers(g, renderLayers.Where(rl => rl.LayerType.DrawType == DrawType.Keyboard),
- DataModel, keyboardRect, false, true);
+ DataModel, keyboardRect, false, true, true);
}
// Render mice layer-by-layer
var devRec = new Rect(0, 0, 40, 40);
diff --git a/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs b/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs
index 2313363fe..f547cd0ec 100644
--- a/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs
+++ b/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs
@@ -7,6 +7,7 @@ using Artemis.Models;
using Artemis.Models.Interfaces;
using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models;
+using Artemis.Profiles.Lua;
using Artemis.ViewModels.Profiles;
using Castle.Components.DictionaryAdapter;
using MoonSharp.Interpreter;
@@ -52,13 +53,16 @@ namespace Artemis.Modules.Effects.ProfilePreview
// Get all enabled layers who's conditions are met
var renderLayers = GetRenderLayers(keyboardOnly);
+ // If the profile has no active LUA wrapper, create one
+ if (Profile.LuaWrapper == null && !string.IsNullOrEmpty(Profile.LuaScript))
+ Profile.LuaWrapper = new LuaWrapper(Profile, MainManager.DeviceManager.ActiveKeyboard);
+
// Render the keyboard layer-by-layer
var keyboardRect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(KeyboardScale);
using (var g = Graphics.FromImage(frame.KeyboardBitmap))
{
Profile.DrawLayers(g, renderLayers.Where(rl => rl.LayerType.DrawType == DrawType.Keyboard),
- DataModel,
- keyboardRect, true, true);
+ DataModel, keyboardRect, true, true, true);
}
// Render mice layer-by-layer
var devRec = new Rect(0, 0, 40, 40);
diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs
index db2122ec2..a3de34dbf 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs
+++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs
@@ -55,9 +55,9 @@ namespace Artemis.Profiles.Layers.Types.Audio
[JsonIgnore]
public List SpectrumData { get; set; } = new List();
- public string Name { get; } = "Keyboard - Audio visualization";
- public bool ShowInEdtor { get; } = true;
- public DrawType DrawType { get; } = DrawType.Keyboard;
+ public string Name => "Keyboard - Audio visualization";
+ public bool ShowInEdtor => true;
+ public DrawType DrawType => DrawType.Keyboard;
public ImageSource DrawThumbnail(LayerModel layer)
{
diff --git a/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs
index 896592b2e..01f2db9b8 100644
--- a/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs
+++ b/Artemis/Artemis/Profiles/Layers/Types/KeyPress/KeyPressType.cs
@@ -19,13 +19,13 @@ namespace Artemis.Profiles.Layers.Types.KeyPress
{
internal class KeyPressType : ILayerType
{
- private readonly MainManager _mainManager;
+ private readonly DeviceManager _deviceManager;
private List _keyPressLayers = new List();
private LayerModel _layerModel;
- public KeyPressType(MainManager mainManager)
+ public KeyPressType(DeviceManager deviceManager)
{
- _mainManager = mainManager;
+ _deviceManager = deviceManager;
KeyboardHook.KeyDownCallback += KeyboardHookOnKeyDownCallback;
}
@@ -61,8 +61,8 @@ namespace Artemis.Profiles.Layers.Types.KeyPress
public void Update(LayerModel layerModel, IDataModel dataModel, bool isPreview = false)
{
// Key press is always as large as the entire keyboard it is drawn for
- layerModel.Properties.Width = _mainManager.DeviceManager.ActiveKeyboard.Width;
- layerModel.Properties.Height = _mainManager.DeviceManager.ActiveKeyboard.Height;
+ layerModel.Properties.Width = _deviceManager.ActiveKeyboard.Width;
+ layerModel.Properties.Height = _deviceManager.ActiveKeyboard.Height;
layerModel.Properties.X = 0;
layerModel.Properties.Y = 0;
layerModel.Properties.Contain = true;
@@ -126,7 +126,7 @@ namespace Artemis.Profiles.Layers.Types.KeyPress
return;
}
- var keyMatch = _mainManager.DeviceManager.ActiveKeyboard.GetKeyPosition(e.KeyCode);
+ var keyMatch = _deviceManager.ActiveKeyboard.GetKeyPosition(e.KeyCode);
if (keyMatch == null)
return;
diff --git a/Artemis/Artemis/Profiles/Lua/Brushes/LuaBrushWrapper.cs b/Artemis/Artemis/Profiles/Lua/Brushes/LuaBrushWrapper.cs
new file mode 100644
index 000000000..e6a4f30db
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Lua/Brushes/LuaBrushWrapper.cs
@@ -0,0 +1,45 @@
+using System.Collections.Generic;
+using System.Windows.Media;
+using Artemis.Utilities;
+using CUE.NET.Helper;
+using MoonSharp.Interpreter;
+
+namespace Artemis.Profiles.Lua.Brushes
+{
+ [MoonSharpUserData]
+ public class LuaBrushWrapper
+ {
+ public LuaColor GetColor(string hexCode)
+ {
+ return new LuaColor(hexCode);
+ }
+
+ public LuaColor GetColor(byte a, byte r, byte g, byte b)
+ {
+ return new LuaColor(a, r, g, b);
+ }
+
+ public LuaColor GetRandomColor()
+ {
+ return new LuaColor(ColorHelpers.GetRandomRainbowMediaColor());
+ }
+
+ public LuaSolidColorBrush GetSolidColorBrush(LuaColor color)
+ {
+ return new LuaSolidColorBrush(color);
+ }
+
+ public LuaLinearGradientBrush GetLinearGradientBrush(Dictionary gradientColors,
+ double startX = 0.5, double startY = 0.0, double endX = 0.5, double endY = 1.0)
+ {
+ return new LuaLinearGradientBrush(gradientColors, startX, startY, endX, endY);
+ }
+
+ // TODO: Check default values
+ public LuaRadialGradientBrush GetRadialGradientBrush(Dictionary gradientColors,
+ double centerX = 0.5, double centerY = 0.5, double originX = 0.5, double originY = 0.5)
+ {
+ return new LuaRadialGradientBrush(gradientColors, centerX, centerY, originX, originY);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/Brushes/LuaColor.cs b/Artemis/Artemis/Profiles/Lua/Brushes/LuaColor.cs
new file mode 100644
index 000000000..25e9a67cd
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Lua/Brushes/LuaColor.cs
@@ -0,0 +1,59 @@
+using System.Windows.Media;
+using Artemis.Utilities;
+using MoonSharp.Interpreter;
+using MoonSharp.Interpreter.Interop;
+
+namespace Artemis.Profiles.Lua.Brushes
+{
+ [MoonSharpUserData]
+ public class LuaColor
+ {
+ public LuaColor(Color color)
+ {
+ Color = color;
+ }
+
+ public LuaColor(string hexCode)
+ {
+ Color = new Color().FromHex(hexCode);
+ }
+
+ public LuaColor(byte a, byte r, byte g, byte b)
+ {
+ Color = Color.FromArgb(a, r, g, b);
+ }
+
+ [MoonSharpVisible(false)]
+ public Color Color { get; set; }
+
+ public string HexCode
+ {
+ get { return Color.ToHex(); }
+ set { Color = Color.FromHex(value); }
+ }
+
+ public byte A
+ {
+ get { return Color.A; }
+ set { Color = Color.FromArgb(value, R, G, B); }
+ }
+
+ public byte R
+ {
+ get { return Color.R; }
+ set { Color = Color.FromArgb(A, value, G, B); }
+ }
+
+ public byte G
+ {
+ get { return Color.G; }
+ set { Color = Color.FromArgb(A, R, value, B); }
+ }
+
+ public byte B
+ {
+ get { return Color.B; }
+ set { Color = Color.FromArgb(A, R, G, value); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/Brushes/LuaLinearGradientBrush.cs b/Artemis/Artemis/Profiles/Lua/Brushes/LuaLinearGradientBrush.cs
index a9787fbe4..bcc784215 100644
--- a/Artemis/Artemis/Profiles/Lua/Brushes/LuaLinearGradientBrush.cs
+++ b/Artemis/Artemis/Profiles/Lua/Brushes/LuaLinearGradientBrush.cs
@@ -1,7 +1,7 @@
-using System.Linq;
+using System.Collections.Generic;
+using System.Linq;
using System.Windows;
using System.Windows.Media;
-using Artemis.Utilities;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
@@ -10,19 +10,16 @@ namespace Artemis.Profiles.Lua.Brushes
[MoonSharpUserData]
public class LuaLinearGradientBrush : LuaBrush
{
- private readonly Script _script;
private LinearGradientBrush _brush;
- public LuaLinearGradientBrush(Script script, LinearGradientBrush linearGradientBrush)
+ public LuaLinearGradientBrush(LinearGradientBrush linearGradientBrush)
{
- _script = script;
LinearGradientBrush = linearGradientBrush;
}
- public LuaLinearGradientBrush(Script script, Table gradientColors,
- double startX, double startY, double endX, double endY)
+ public LuaLinearGradientBrush(Dictionary gradientColors, double startX, double startY,
+ double endX, double endY)
{
- _script = script;
SetupBrush(gradientColors, startX, startY, endX, endY);
}
@@ -44,13 +41,18 @@ namespace Artemis.Profiles.Lua.Brushes
///
/// Gets or sets the Brush's GradientStops using a LUA table
///
- public Table Colors
+ public Dictionary GradientColors
{
- get { return CreateGradientTable(_script, LinearGradientBrush.GradientStops); }
+ get
+ {
+ return LinearGradientBrush.GradientStops.ToDictionary(gs => new LuaColor(gs.Color), gs => gs.Offset);
+ }
set
{
var updatedBrush = LinearGradientBrush.CloneCurrentValue();
- updatedBrush.GradientStops = CreateGradientCollection(value);
+ updatedBrush.GradientStops = new GradientStopCollection(value
+ .Select(gc => new GradientStop(gc.Key.Color, gc.Value)));
+
LinearGradientBrush = updatedBrush;
}
}
@@ -63,45 +65,13 @@ namespace Artemis.Profiles.Lua.Brushes
///
///
///
- private void SetupBrush(Table gradientColors, double startX, double startY, double endX, double endY)
+ private void SetupBrush(Dictionary gradientColors, double startX, double startY, double endX,
+ double endY)
{
- var collection = CreateGradientCollection(gradientColors);
+ var collection = new GradientStopCollection(gradientColors
+ .Select(gc => new GradientStop(gc.Key.Color, gc.Value)));
+
LinearGradientBrush = new LinearGradientBrush(collection, new Point(startX, startY), new Point(endX, endY));
}
-
- ///
- /// Maps a LUA table to a GradientStopsCollection
- ///
- ///
- ///
- public static GradientStopCollection CreateGradientCollection(Table gradientColors)
- {
- var collection = new GradientStopCollection();
- foreach (var gradientColor in gradientColors.Values)
- {
- var pair = gradientColor.Table.Values.ToList();
- var hexCode = pair[0].String;
- var position = pair[1].Number;
- collection.Add(new GradientStop(new Color().FromHex(hexCode), position));
- }
- return collection;
- }
-
- ///
- /// Maps the current brush's GradientStopsCollection to a LUA table
- ///
- ///
- public static Table CreateGradientTable(Script script, GradientStopCollection gradientStops)
- {
- var table = new Table(script);
- foreach (var gradientStop in gradientStops)
- {
- var inner = new Table(script);
- inner.Append(DynValue.NewString(gradientStop.Color.ToHex()));
- inner.Append(DynValue.NewNumber(gradientStop.Offset));
- table.Append(DynValue.NewTable(inner));
- }
- return table;
- }
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/Brushes/LuaRadialGradientBrush.cs b/Artemis/Artemis/Profiles/Lua/Brushes/LuaRadialGradientBrush.cs
index b698d86b7..d26b7fc94 100644
--- a/Artemis/Artemis/Profiles/Lua/Brushes/LuaRadialGradientBrush.cs
+++ b/Artemis/Artemis/Profiles/Lua/Brushes/LuaRadialGradientBrush.cs
@@ -1,4 +1,6 @@
-using System.Windows;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows;
using System.Windows.Media;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
@@ -8,19 +10,16 @@ namespace Artemis.Profiles.Lua.Brushes
[MoonSharpUserData]
public class LuaRadialGradientBrush : LuaBrush
{
- private readonly Script _script;
private RadialGradientBrush _brush;
- public LuaRadialGradientBrush(Script script, RadialGradientBrush radialGradientBrush)
+ public LuaRadialGradientBrush(RadialGradientBrush radialGradientBrush)
{
- _script = script;
RadialGradientBrush = radialGradientBrush;
}
- public LuaRadialGradientBrush(Script script, Table gradientColors,
- double centerX, double centerY, double originX, double originY)
+ public LuaRadialGradientBrush(Dictionary gradientColors, double centerX,
+ double centerY, double originX, double originY)
{
- _script = script;
SetupBrush(gradientColors, centerX, centerY, originX, originY);
}
@@ -42,13 +41,18 @@ namespace Artemis.Profiles.Lua.Brushes
///
/// Gets or sets the Brush's GradientStops using a LUA table
///
- public Table Colors
+ public Dictionary GradientColors
{
- get { return LuaLinearGradientBrush.CreateGradientTable(_script, RadialGradientBrush.GradientStops); }
+ get
+ {
+ return RadialGradientBrush.GradientStops.ToDictionary(gs => new LuaColor(gs.Color), gs => gs.Offset);
+ }
set
{
var updatedBrush = RadialGradientBrush.CloneCurrentValue();
- updatedBrush.GradientStops = LuaLinearGradientBrush.CreateGradientCollection(value);
+ updatedBrush.GradientStops = new GradientStopCollection(value
+ .Select(gc => new GradientStop(gc.Key.Color, gc.Value)));
+
RadialGradientBrush = updatedBrush;
}
}
@@ -61,9 +65,12 @@ namespace Artemis.Profiles.Lua.Brushes
///
///
///
- private void SetupBrush(Table gradientColors, double centerX, double centerY, double originX, double originY)
+ private void SetupBrush(Dictionary gradientColors, double centerX, double centerY,
+ double originX, double originY)
{
- var collection = LuaLinearGradientBrush.CreateGradientCollection(gradientColors);
+ var collection = new GradientStopCollection(gradientColors
+ .Select(gc => new GradientStop(gc.Key.Color, gc.Value)));
+
RadialGradientBrush = new RadialGradientBrush(collection)
{
Center = new Point(centerX, centerY),
diff --git a/Artemis/Artemis/Profiles/Lua/Brushes/LuaSolidColorBrush.cs b/Artemis/Artemis/Profiles/Lua/Brushes/LuaSolidColorBrush.cs
index 9124d2d96..a06e1b78e 100644
--- a/Artemis/Artemis/Profiles/Lua/Brushes/LuaSolidColorBrush.cs
+++ b/Artemis/Artemis/Profiles/Lua/Brushes/LuaSolidColorBrush.cs
@@ -1,5 +1,4 @@
using System.Windows.Media;
-using Artemis.Utilities;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
@@ -10,21 +9,16 @@ namespace Artemis.Profiles.Lua.Brushes
{
private SolidColorBrush _brush;
- public LuaSolidColorBrush(SolidColorBrush solidColorBrush)
+ public LuaSolidColorBrush(LuaColor luaColor)
{
- SolidColorBrush = solidColorBrush;
- }
-
- public LuaSolidColorBrush(string hexCode)
- {
- SolidColorBrush = new SolidColorBrush(new Color().FromHex(hexCode));
+ SolidColorBrush = new SolidColorBrush(luaColor.Color);
}
///
/// The underlying brush
///
[MoonSharpVisible(false)]
- public SolidColorBrush SolidColorBrush
+ public SolidColorBrush SolidColorBrush
{
get { return _brush; }
set
@@ -35,13 +29,10 @@ namespace Artemis.Profiles.Lua.Brushes
}
}
- ///
- /// Gets or sets the brush's color using a hex notation
- ///
- public string Color
+ public LuaColor Color
{
- get { return SolidColorBrush.Color.ToHex(); }
- set { SolidColorBrush = new SolidColorBrush(new Color().FromHex(value)); }
+ get { return new LuaColor(SolidColorBrush.Color); }
+ set { SolidColorBrush = new SolidColorBrush(value.Color); }
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/Events/LuaEventsWrapper.cs b/Artemis/Artemis/Profiles/Lua/Events/LuaEventsWrapper.cs
new file mode 100644
index 000000000..bf9327c7c
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Lua/Events/LuaEventsWrapper.cs
@@ -0,0 +1,117 @@
+using System;
+using System.Windows.Forms;
+using System.Windows.Media;
+using Artemis.Models.Interfaces;
+using MoonSharp.Interpreter;
+using NLog;
+
+namespace Artemis.Profiles.Lua.Events
+{
+ [MoonSharpUserData]
+ public class LuaEventsWrapper
+ {
+ private readonly Logger _logger = LogManager.GetCurrentClassLogger();
+ public event EventHandler ProfileUpdating;
+ public event EventHandler ProfileDrawing;
+ public event EventHandler KeyboardKeyPressed;
+
+ internal void InvokeProfileUpdate(ProfileModel profileModel, IDataModel dataModel, bool preview)
+ {
+ try
+ {
+ OnProfileUpdating(new LuaProfileWrapper(profileModel),
+ new LuaProfileUpdatingEventArgs(dataModel, preview));
+ }
+ catch (Exception)
+ {
+ // ignored
+ }
+ }
+
+ internal void InvokeProfileDraw(ProfileModel profileModel, IDataModel dataModel, bool preview, DrawingContext c)
+ {
+ try
+ {
+ OnProfileDrawing(new LuaProfileWrapper(profileModel),
+ new LuaProfileDrawingEventArgs(dataModel, preview, new LuaDrawWrapper(c)));
+ }
+ catch (Exception)
+ {
+ // ignored
+ }
+ }
+
+ internal void InvokeKeyPressed(ProfileModel profileModel, LuaKeyboardWrapper keyboard, Keys key, int x, int y)
+ {
+ try
+ {
+ OnKeyboardKeyPressed(new LuaProfileWrapper(profileModel), keyboard, new LuaKeyPressEventArgs(key, x, y));
+ }
+ catch (Exception)
+ {
+ // ignored
+ }
+ }
+
+ protected virtual void OnProfileUpdating(LuaProfileWrapper profileModel, LuaProfileUpdatingEventArgs e)
+ {
+ try
+ {
+ ProfileUpdating?.Invoke(profileModel, e);
+ }
+ catch (InternalErrorException ex)
+ {
+ _logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
+ }
+ catch (SyntaxErrorException ex)
+ {
+ _logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
+ }
+ catch (ScriptRuntimeException ex)
+ {
+ _logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
+ }
+ }
+
+ protected virtual void OnProfileDrawing(LuaProfileWrapper profileModel, LuaProfileDrawingEventArgs e)
+ {
+ try
+ {
+ ProfileDrawing?.Invoke(profileModel, e);
+ }
+ catch (InternalErrorException ex)
+ {
+ _logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
+ }
+ catch (SyntaxErrorException ex)
+ {
+ _logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
+ }
+ catch (ScriptRuntimeException ex)
+ {
+ _logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
+ }
+ }
+
+ protected virtual void OnKeyboardKeyPressed(LuaProfileWrapper profileModel, LuaKeyboardWrapper keyboard,
+ LuaKeyPressEventArgs e)
+ {
+ try
+ {
+ KeyboardKeyPressed?.Invoke(profileModel, e);
+ }
+ catch (InternalErrorException ex)
+ {
+ _logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
+ }
+ catch (SyntaxErrorException ex)
+ {
+ _logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
+ }
+ catch (ScriptRuntimeException ex)
+ {
+ _logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/Events/LuaKeyPressEventArgs.cs b/Artemis/Artemis/Profiles/Lua/Events/LuaKeyPressEventArgs.cs
new file mode 100644
index 000000000..9b595fb3b
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Lua/Events/LuaKeyPressEventArgs.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Windows.Forms;
+using MoonSharp.Interpreter;
+
+namespace Artemis.Profiles.Lua.Events
+{
+ [MoonSharpUserData]
+ public class LuaKeyPressEventArgs : EventArgs
+ {
+ private readonly Keys _key;
+
+ public LuaKeyPressEventArgs(Keys key, int x, int y)
+ {
+ _key = key;
+ X = x;
+ Y = y;
+ }
+
+ public string Key => _key.ToString();
+ public int X { get; }
+ public int Y { get; }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/Events/LuaProfileDrawingEventArgs.cs b/Artemis/Artemis/Profiles/Lua/Events/LuaProfileDrawingEventArgs.cs
new file mode 100644
index 000000000..8043af8e2
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Lua/Events/LuaProfileDrawingEventArgs.cs
@@ -0,0 +1,21 @@
+using System;
+using Artemis.Models.Interfaces;
+using MoonSharp.Interpreter;
+
+namespace Artemis.Profiles.Lua.Events
+{
+ [MoonSharpUserData]
+ public class LuaProfileDrawingEventArgs : EventArgs
+ {
+ public LuaProfileDrawingEventArgs(IDataModel dataModel, bool preview, LuaDrawWrapper luaDrawWrapper)
+ {
+ DataModel = dataModel;
+ Preview = preview;
+ Drawing = luaDrawWrapper;
+ }
+
+ public IDataModel DataModel { get; }
+ public bool Preview { get; }
+ public LuaDrawWrapper Drawing { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/Events/LuaProfileUpdatingEventArgs.cs b/Artemis/Artemis/Profiles/Lua/Events/LuaProfileUpdatingEventArgs.cs
new file mode 100644
index 000000000..04da54a97
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Lua/Events/LuaProfileUpdatingEventArgs.cs
@@ -0,0 +1,19 @@
+using System;
+using Artemis.Models.Interfaces;
+using MoonSharp.Interpreter;
+
+namespace Artemis.Profiles.Lua.Events
+{
+ [MoonSharpUserData]
+ public class LuaProfileUpdatingEventArgs : EventArgs
+ {
+ public LuaProfileUpdatingEventArgs(IDataModel dataModel, bool preview)
+ {
+ DataModel = dataModel;
+ Preview = preview;
+ }
+
+ public IDataModel DataModel { get; }
+ public bool Preview { get; }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/LuaBrushWrapper.cs b/Artemis/Artemis/Profiles/Lua/LuaBrushWrapper.cs
deleted file mode 100644
index 3b899914a..000000000
--- a/Artemis/Artemis/Profiles/Lua/LuaBrushWrapper.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using Artemis.Profiles.Lua.Brushes;
-using MoonSharp.Interpreter;
-
-namespace Artemis.Profiles.Lua
-{
- [MoonSharpUserData]
- public class LuaBrushWrapper
- {
- private readonly Script _script;
-
- public LuaBrushWrapper(Script script)
- {
- _script = script;
- }
-
- public LuaSolidColorBrush GetSolidColorBrush(string hexCode)
- {
- return new LuaSolidColorBrush(hexCode);
- }
-
- public LuaLinearGradientBrush GetLinearGradientBrush(Table gradientColors,
- double startX = 0.5, double startY = 0.0, double endX = 0.5, double endY = 1.0)
- {
- return new LuaLinearGradientBrush(_script, gradientColors, startX, startY, endX, endY);
- }
-
- // TODO: Check default values
- public LuaRadialGradientBrush GetRadialGradientBrush(Table gradientColors,
- double centerX = 0.5, double centerY = 0.5, double originX = 0.5, double originY = 0.5)
- {
- return new LuaRadialGradientBrush(_script, gradientColors, centerX, centerY, originX, originY);
- }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/LuaEventsWrapper.cs b/Artemis/Artemis/Profiles/Lua/LuaEventsWrapper.cs
deleted file mode 100644
index a1d3f8e3b..000000000
--- a/Artemis/Artemis/Profiles/Lua/LuaEventsWrapper.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-using System;
-using System.Windows.Media;
-using Artemis.Models.Interfaces;
-using MoonSharp.Interpreter;
-using NLog;
-
-namespace Artemis.Profiles.Lua
-{
- [MoonSharpUserData]
- public class LuaEventsWrapper
- {
- private readonly Logger _logger = LogManager.GetCurrentClassLogger();
- public event EventHandler LuaProfileUpdating;
- public event EventHandler LuaProfileDrawing;
-
- internal void InvokeProfileUpdate(ProfileModel profileModel, IDataModel dataModel, bool preview)
- {
- try
- {
- OnLuaProfileUpdating(new LuaProfileWrapper(profileModel),
- new LuaProfileUpdatingEventArgs(dataModel, preview));
- }
- catch (Exception)
- {
-
- }
-
- }
-
- internal void InvokeProfileDraw(ProfileModel profileModel, IDataModel dataModel, bool preview, DrawingContext c)
- {
- try
- {
- OnLuaProfileDrawing(new LuaProfileWrapper(profileModel),
- new LuaProfileDrawingEventArgs(dataModel, preview, new LuaDrawWrapper(c)));
- }
- catch (Exception)
- {
-
- }
-
- }
-
-
- protected virtual void OnLuaProfileUpdating(LuaProfileWrapper profileModel, LuaProfileUpdatingEventArgs e)
- {
- try
- {
- LuaProfileUpdating?.Invoke(profileModel, e);
- }
- catch (InternalErrorException ex)
- {
- _logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
- }
- catch (SyntaxErrorException ex)
- {
- _logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
- }
- catch (ScriptRuntimeException ex)
- {
- _logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
- }
- }
-
- protected virtual void OnLuaProfileDrawing(LuaProfileWrapper profileModel, LuaProfileDrawingEventArgs e)
- {
- try
- {
- LuaProfileDrawing?.Invoke(profileModel, e);
- }
- catch (InternalErrorException ex)
- {
- _logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
- }
- catch (SyntaxErrorException ex)
- {
- _logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
- }
- catch (ScriptRuntimeException ex)
- {
- _logger.Error(ex, "[{0}-LUA]: Error: {1}", profileModel.Name, ex.DecoratedMessage);
- }
- }
- }
-
- [MoonSharpUserData]
- public class LuaProfileUpdatingEventArgs : EventArgs
- {
- public LuaProfileUpdatingEventArgs(IDataModel dataModel, bool preview)
- {
- DataModel = dataModel;
- Preview = preview;
- }
-
- public IDataModel DataModel { get; }
- public bool Preview { get; }
- }
-
- [MoonSharpUserData]
- public class LuaProfileDrawingEventArgs : EventArgs
- {
- public LuaProfileDrawingEventArgs(IDataModel dataModel, bool preview, LuaDrawWrapper luaDrawWrapper)
- {
- DataModel = dataModel;
- Preview = preview;
- Drawing = luaDrawWrapper;
- }
-
- public IDataModel DataModel { get; }
- public bool Preview { get; }
- public LuaDrawWrapper Drawing { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/LuaKeyboardWrapper.cs b/Artemis/Artemis/Profiles/Lua/LuaKeyboardWrapper.cs
new file mode 100644
index 000000000..ec5fcdf92
--- /dev/null
+++ b/Artemis/Artemis/Profiles/Lua/LuaKeyboardWrapper.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Windows.Forms;
+using Artemis.DeviceProviders;
+using Artemis.Utilities.Keyboard;
+using MoonSharp.Interpreter;
+using MoonSharp.Interpreter.Interop;
+
+namespace Artemis.Profiles.Lua
+{
+ [MoonSharpUserData]
+ public class LuaKeyboardWrapper : IDisposable
+ {
+ private readonly KeyboardProvider _keyboardProvider;
+ private readonly LuaWrapper _luaWrapper;
+
+ public LuaKeyboardWrapper(LuaWrapper luaWrapper, KeyboardProvider keyboardProvider)
+ {
+ _luaWrapper = luaWrapper;
+ _keyboardProvider = keyboardProvider;
+
+ KeyboardHook.KeyDownCallback += KeyboardHookOnKeyDownCallback;
+ }
+
+ public string Name => _keyboardProvider.Name;
+ public string Slug => _keyboardProvider.Slug;
+ public int Width => _keyboardProvider.Width;
+ public int Height => _keyboardProvider.Height;
+
+ [MoonSharpVisible(false)]
+ public void Dispose()
+ {
+ KeyboardHook.KeyDownCallback -= KeyboardHookOnKeyDownCallback;
+ }
+
+ private void KeyboardHookOnKeyDownCallback(KeyEventArgs e)
+ {
+ var keyMatch = _keyboardProvider.GetKeyPosition(e.KeyCode);
+ if (keyMatch != null)
+ _luaWrapper.LuaEventsWrapper.InvokeKeyPressed(_luaWrapper.ProfileModel, this,
+ keyMatch.Value.KeyCode, keyMatch.Value.X, keyMatch.Value.Y);
+ }
+
+ public void SendKeys(string keys)
+ {
+ System.Windows.Forms.SendKeys.SendWait(keys);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/Lua/LuaWrapper.cs b/Artemis/Artemis/Profiles/Lua/LuaWrapper.cs
index 54a894599..ce0fda411 100644
--- a/Artemis/Artemis/Profiles/Lua/LuaWrapper.cs
+++ b/Artemis/Artemis/Profiles/Lua/LuaWrapper.cs
@@ -2,6 +2,9 @@
using System.IO;
using System.Text;
using Artemis.DAL;
+using Artemis.DeviceProviders;
+using Artemis.Profiles.Lua.Brushes;
+using Artemis.Profiles.Lua.Events;
using Artemis.Properties;
using Castle.Core.Internal;
using MoonSharp.Interpreter;
@@ -9,22 +12,24 @@ using NLog;
namespace Artemis.Profiles.Lua
{
- public class LuaWrapper
+ public class LuaWrapper : IDisposable
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
- public LuaWrapper(ProfileModel profileModel)
+ public LuaWrapper(ProfileModel profileModel, KeyboardProvider keyboardProvider)
{
ProfileModel = profileModel;
LuaProfileWrapper = new LuaProfileWrapper(ProfileModel);
- LuaBrushWrapper = new LuaBrushWrapper(LuaScript);
+ LuaBrushWrapper = new LuaBrushWrapper();
+ LuaKeyboardWrapper = new LuaKeyboardWrapper(this, keyboardProvider);
SetupLuaScript();
}
-
+
public ProfileModel ProfileModel { get; set; }
- public LuaEventsWrapper LuaEventsWrapper { get; set; }
- public LuaBrushWrapper LuaBrushWrapper { get; set; }
public LuaProfileWrapper LuaProfileWrapper { get; set; }
+ public LuaBrushWrapper LuaBrushWrapper { get; set; }
+ public LuaKeyboardWrapper LuaKeyboardWrapper { get; set; }
+ public LuaEventsWrapper LuaEventsWrapper { get; set; }
public Script LuaScript { get; set; }
private void SetupLuaScript()
@@ -36,6 +41,7 @@ namespace Artemis.Profiles.Lua
LuaScript.Globals["Profile"] = LuaProfileWrapper;
LuaScript.Globals["Events"] = LuaEventsWrapper;
LuaScript.Globals["Brushes"] = LuaBrushWrapper;
+ LuaScript.Globals["Keyboard"] = LuaKeyboardWrapper;
if (ProfileModel.LuaScript.IsNullOrEmpty())
return;
@@ -121,5 +127,13 @@ namespace Artemis.Profiles.Lua
}
#endregion
+
+ public void Dispose()
+ {
+ LuaKeyboardWrapper.Dispose();
+ LuaScript.Globals.Clear();
+ LuaScript.Registry.Clear();
+ LuaScript = null;
+ }
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Profiles/ProfileModel.cs b/Artemis/Artemis/Profiles/ProfileModel.cs
index 7d41b6f94..d6d5173ee 100644
--- a/Artemis/Artemis/Profiles/ProfileModel.cs
+++ b/Artemis/Artemis/Profiles/ProfileModel.cs
@@ -11,7 +11,6 @@ using Artemis.Profiles.Layers.Models;
using Artemis.Profiles.Lua;
using Artemis.Utilities;
using Artemis.Utilities.ParentChild;
-using Castle.Core.Internal;
using Newtonsoft.Json;
using Color = System.Windows.Media.Color;
using Point = System.Windows.Point;
@@ -104,11 +103,8 @@ namespace Artemis.Profiles
/// Indicates wheter the layer is drawn as a preview, ignoring dynamic properties
/// Wheter or not to update the layer's animations
internal void DrawLayers(Graphics g, IEnumerable renderLayers, IDataModel dataModel, Rect rect,
- bool preview, bool updateAnimations)
+ bool preview, bool updateAnimations, bool triggerLua = false)
{
- if (LuaWrapper == null && !LuaScript.IsNullOrEmpty())
- LuaWrapper = new LuaWrapper(this);
-
var visual = new DrawingVisual();
var layerModels = renderLayers.ToList();
using (var c = visual.RenderOpen())
@@ -120,12 +116,16 @@ namespace Artemis.Profiles
// Update the layers
foreach (var layerModel in layerModels)
layerModel.Update(dataModel, preview, updateAnimations);
- LuaWrapper?.LuaEventsWrapper?.InvokeProfileUpdate(this, dataModel, preview);
+
+ if (triggerLua)
+ LuaWrapper?.LuaEventsWrapper?.InvokeProfileUpdate(this, dataModel, preview);
// Draw the layers
foreach (var layerModel in layerModels)
layerModel.Draw(dataModel, c, preview, updateAnimations);
- LuaWrapper?.LuaEventsWrapper?.InvokeProfileDraw(this, dataModel, preview, c);
+
+ if (triggerLua)
+ LuaWrapper?.LuaEventsWrapper?.InvokeProfileDraw(this, dataModel, preview, c);
// Remove the clip
c.Pop();
diff --git a/Artemis/Artemis/Resources/lua-placeholder.lua b/Artemis/Artemis/Resources/lua-placeholder.lua
index 15bbabfa5..81a00a149 100644
--- a/Artemis/Artemis/Resources/lua-placeholder.lua
+++ b/Artemis/Artemis/Resources/lua-placeholder.lua
@@ -11,7 +11,7 @@
-- For docs and examples, see wiki: https://github.com/SpoinkyNL/Artemis/wiki/LUA
-- Note: You are editing a temporary file. Whenever you save this file the
--- changes are applied to the profile and the script restarted.
+-- changes are applied to the profile and the script is restarted.
-- This event is raised after every profile update, before drawing.
function updateHandler(profile, eventArgs)
@@ -36,5 +36,5 @@ end
-- Register the default events, you can rename/remove these if you so desire.
-- These events are raised every 40 ms (25 times a second).
-Events.LuaProfileUpdating.add(updateHandler);
-Events.LuaProfileDrawing.add(drawHandler);
\ No newline at end of file
+Events.ProfileUpdating.add(updateHandler);
+Events.ProfileDrawing.add(drawHandler);
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Abstract/GameViewModel.cs b/Artemis/Artemis/ViewModels/Abstract/GameViewModel.cs
index 33b737cb5..d8c60c06f 100644
--- a/Artemis/Artemis/ViewModels/Abstract/GameViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Abstract/GameViewModel.cs
@@ -91,6 +91,7 @@ namespace Artemis.ViewModels.Abstract
{
if (e.PropertyName != "SelectedProfile" && IsActive)
return;
+
GameModel.Profile = ProfileEditor.SelectedProfile;
ProfilePreviewModel.Profile = ProfileEditor.SelectedProfile;
diff --git a/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs
index eb7643546..0d973218f 100644
--- a/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs
@@ -111,8 +111,8 @@ namespace Artemis.ViewModels.Profiles
return;
SelectedProfile = ProfileProvider.GetProfile(
- _mainManager.DeviceManager.ActiveKeyboard,
- _gameModel,
+ _mainManager.DeviceManager.ActiveKeyboard,
+ _gameModel,
value);
NotifyOfPropertyChange(() => SelectedProfileName);
@@ -125,6 +125,11 @@ namespace Artemis.ViewModels.Profiles
set
{
if (Equals(value, _selectedProfile)) return;
+ if (_selectedProfile?.LuaWrapper != null)
+ {
+ _selectedProfile.LuaWrapper.Dispose();
+ _selectedProfile.LuaWrapper = null;
+ }
_selectedProfile = value;
NotifyOfPropertyChange(() => SelectedProfile);
}
@@ -232,8 +237,11 @@ namespace Artemis.ViewModels.Profiles
public void Deactivate()
{
ProfileViewModel.Deactivate();
- if (SelectedProfile != null)
+ if (SelectedProfile?.LuaWrapper != null)
+ {
+ SelectedProfile.LuaWrapper.Dispose();
SelectedProfile.LuaWrapper = null;
+ }
_saveTimer.Stop();
}
@@ -537,8 +545,8 @@ namespace Artemis.ViewModels.Profiles
ProfileProvider.AddOrUpdate(profile);
+ LastProfile = profile.Name;
LoadProfiles();
- SelectedProfile = profile;
}
public async void RenameProfile()
@@ -564,9 +572,9 @@ namespace Artemis.ViewModels.Profiles
}
var profile = SelectedProfile;
- SelectedProfile = null;
ProfileProvider.RenameProfile(profile, name);
+ SelectedProfile = null;
LastProfile = name;
LoadProfiles();
}
@@ -597,8 +605,8 @@ namespace Artemis.ViewModels.Profiles
newProfile.IsDefault = false;
ProfileProvider.AddOrUpdate(newProfile);
+ LastProfile = newProfile.Name;
LoadProfiles();
- SelectedProfile = newProfile;
}
public async void DeleteProfile()
@@ -682,9 +690,8 @@ namespace Artemis.ViewModels.Profiles
}
ProfileProvider.AddOrUpdate(profile);
+ LastProfile = profile.Name;
LoadProfiles();
-
- SelectedProfile = profile;
}
public void ExportProfile()
@@ -707,7 +714,8 @@ namespace Artemis.ViewModels.Profiles
try
{
if (SelectedProfile.LuaWrapper == null)
- SelectedProfile.LuaWrapper = new LuaWrapper(SelectedProfile);
+ SelectedProfile.LuaWrapper = new LuaWrapper(SelectedProfile,
+ _mainManager.DeviceManager.ActiveKeyboard);
SelectedProfile.LuaWrapper.OpenEditor();
}
diff --git a/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs b/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs
index 368ccaf46..9847678e7 100644
--- a/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs
+++ b/Artemis/Artemis/ViewModels/SystemTrayViewModel.cs
@@ -179,6 +179,9 @@ namespace Artemis.ViewModels
NotifyOfPropertyChange(() => CanShowWindow);
NotifyOfPropertyChange(() => CanHideWindow);
+
+ // Force a GC since the UI releases a lot of resources
+ GC.Collect();
}
public void ExitApplication()