1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Basic LUA implementation

This commit is contained in:
SpoinkyNL 2016-10-25 23:08:57 +02:00
parent fb558a1057
commit 7a0d0543cc
12 changed files with 351 additions and 5 deletions

View File

@ -414,6 +414,10 @@
</Compile>
<Compile Include="Profiles\Layers\Types\Mousemat\MousematPropertiesViewModel.cs" />
<Compile Include="Profiles\Layers\Types\Mousemat\MousematType.cs" />
<Compile Include="Profiles\Lua\LuaEventsWrapper.cs" />
<Compile Include="Profiles\Lua\LuaLayerWrapper.cs" />
<Compile Include="Profiles\Lua\LuaProfileWrapper.cs" />
<Compile Include="Profiles\Lua\LuaWrapper.cs" />
<Compile Include="Profiles\ProfileModel.cs" />
<Compile Include="Profiles\Layers\Models\SimplePropertiesModel.cs" />
<Compile Include="Profiles\Layers\Types\Keyboard\KeyboardPropertiesModel.cs" />
@ -637,6 +641,7 @@
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<None Include="Resources\lua-placeholder.txt" />
<None Include="NLog.xsd">
<SubType>Designer</SubType>
</None>
@ -890,7 +895,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Profiles\Lua\" />
<Folder Include="Resources\Lua\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\CUE.NET.1.1.0.2\build\net45\CUE.NET.targets" Condition="Exists('..\packages\CUE.NET.1.1.0.2\build\net45\CUE.NET.targets')" />

View File

@ -10,6 +10,7 @@ using Artemis.Utilities;
using Artemis.Utilities.Converters;
using Artemis.ViewModels;
using Caliburn.Micro;
using MoonSharp.Interpreter;
using Newtonsoft.Json;
using Ninject;
@ -80,12 +81,15 @@ namespace Artemis
_kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
_kernel.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope();
// Configure JSON.NET
var settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
ContractResolver = _kernel.Get<NinjectContractResolver>()
};
JsonConvert.DefaultSettings = () => settings;
// Configure MoonSharp
UserData.RegisterAssembly();
}
protected override void OnExit(object sender, EventArgs e)

View File

@ -0,0 +1,9 @@
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua
{
[MoonSharpUserData]
public class LuaEventsWrapper
{
}
}

View File

@ -0,0 +1,112 @@
using System.Collections.Generic;
using System.Linq;
using Artemis.Profiles.Layers.Models;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua
{
/// <summary>
/// Serves as a sandboxed wrapper around the LayerModel
/// </summary>
[MoonSharpUserData]
public class LuaLayerWrapper
{
private readonly LayerModel _layerModel;
public LuaLayerWrapper(LayerModel layerModel)
{
_layerModel = layerModel;
}
#region Child methods
public List<LuaLayerWrapper> GetChildren()
{
return _layerModel.Children.Select(l => new LuaLayerWrapper(l)).ToList();
}
public LuaLayerWrapper GetChildByName(string name)
{
var layer = _layerModel.Children.FirstOrDefault(l => l.Name == name);
return layer == null ? null : new LuaLayerWrapper(layer);
}
#endregion
#region General layer properties
public string Name
{
get { return _layerModel.Name; }
set { _layerModel.Name = value; }
}
public bool Enabled
{
get { return _layerModel.Enabled; }
set { _layerModel.Enabled = value; }
}
public bool IsEvent
{
get { return _layerModel.IsEvent; }
set { _layerModel.IsEvent = value; }
}
public LuaLayerWrapper Parent => new LuaLayerWrapper(_layerModel.Parent);
#endregion
#region Advanced layer properties
public double X
{
get { return _layerModel.Properties.X; }
set { _layerModel.Properties.X = value; }
}
public double Y
{
get { return _layerModel.Properties.Y; }
set { _layerModel.Properties.Y = value; }
}
public double Width
{
get { return _layerModel.Properties.Width; }
set { _layerModel.Properties.Width = value; }
}
public double Height
{
get { return _layerModel.Properties.Height; }
set { _layerModel.Properties.Height = value; }
}
public bool Contain
{
get { return _layerModel.Properties.Contain; }
set { _layerModel.Properties.Contain = value; }
}
public double Opacity
{
get { return _layerModel.Properties.Opacity; }
set { _layerModel.Properties.Opacity = value; }
}
public double AnimationSpeed
{
get { return _layerModel.Properties.AnimationSpeed; }
set { _layerModel.Properties.AnimationSpeed = value; }
}
public double AnimationProgress
{
get { return _layerModel.Properties.AnimationProgress; }
set { _layerModel.Properties.AnimationProgress = value; }
}
#endregion
}
}

View File

@ -0,0 +1,41 @@
using System.Collections.Generic;
using System.Linq;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua
{
/// <summary>
/// Serves as a sandboxed wrapper around the ProfileModel
/// </summary>
[MoonSharpUserData]
public class LuaProfileWrapper
{
private readonly ProfileModel _profileModel;
public LuaProfileWrapper(ProfileModel profileModel)
{
_profileModel = profileModel;
}
#region General profile properties
public string Name => _profileModel.Name;
#endregion
#region Layer methods
public List<LuaLayerWrapper> GetLayers()
{
return _profileModel.Layers.Select(l => new LuaLayerWrapper(l)).ToList();
}
public LuaLayerWrapper GetLayerByName(string name)
{
var layer = _profileModel.Layers.FirstOrDefault(l => l.Name == name);
return layer == null ? null : new LuaLayerWrapper(layer);
}
#endregion
}
}

View File

@ -0,0 +1,116 @@
using System;
using System.IO;
using Artemis.Properties;
using Castle.Core.Internal;
using MoonSharp.Interpreter;
using NLog;
using NuGet;
namespace Artemis.Profiles.Lua
{
public class LuaWrapper
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public LuaWrapper(ProfileModel profileModel)
{
ProfileModel = profileModel;
LuaProfileWrapper = new LuaProfileWrapper(ProfileModel);
LuaEventsWrapper = new LuaEventsWrapper();
SetupLuaScript();
}
public ProfileModel ProfileModel { get; set; }
public LuaEventsWrapper LuaEventsWrapper { get; set; }
public LuaProfileWrapper LuaProfileWrapper { get; set; }
public Script LuaScript { get; set; }
private void SetupLuaScript()
{
LuaScript = new Script(CoreModules.Preset_SoftSandbox);
LuaScript.Options.DebugPrint = LuaPrint;
LuaScript.Globals["Profile"] = LuaProfileWrapper;
LuaScript.Globals["Events"] = LuaEventsWrapper;
if (ProfileModel.LuaScript.IsNullOrEmpty())
return;
try
{
LuaScript.DoString(ProfileModel.LuaScript);
}
catch (ScriptRuntimeException e)
{
Logger.Error(e, "[{0}-LUA]: Error: {1}", ProfileModel.Name, e.DecoratedMessage);
}
}
#region Private lua functions
private void LuaPrint(string s)
{
Logger.Debug("[{0}-LUA]: {1}", ProfileModel.Name, s);
}
#endregion
#region Editor
public void OpenEditor()
{
// Create a temp file
var fileName = Guid.NewGuid() + ".lua";
var file = File.Create(Path.GetTempPath() + fileName);
file.Dispose();
// Add instructions to LUA script if it's a new file
if (ProfileModel.LuaScript.IsNullOrEmpty())
ProfileModel.LuaScript = Resources.lua_placeholder;
File.WriteAllText(Path.GetTempPath() + fileName, ProfileModel.LuaScript);
// Watch the file for changes
var watcher = new FileSystemWatcher(Path.GetTempPath(), fileName);
watcher.Changed += LuaFileChanged;
watcher.EnableRaisingEvents = true;
// Open the temp file with the default editor
System.Diagnostics.Process.Start(Path.GetTempPath() + fileName);
}
private void LuaFileChanged(object sender, FileSystemEventArgs fileSystemEventArgs)
{
if (fileSystemEventArgs.ChangeType != WatcherChangeTypes.Changed)
return;
using (var fs = new FileStream(fileSystemEventArgs.FullPath,
FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var sr = new StreamReader(fs))
{
ProfileModel.LuaScript = sr.ReadToEnd();
}
}
DAL.ProfileProvider.AddOrUpdate(ProfileModel);
SetupLuaScript();
}
#endregion
#region Event triggers
public void TriggerUpdate()
{
}
public void TriggerDraw()
{
}
#endregion
}
}

View File

@ -8,6 +8,7 @@ using Artemis.DeviceProviders;
using Artemis.Models.Interfaces;
using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models;
using Artemis.Profiles.Lua;
using Artemis.Utilities;
using Artemis.Utilities.ParentChild;
using Newtonsoft.Json;
@ -22,9 +23,10 @@ namespace Artemis.Profiles
public ProfileModel()
{
Layers = new ChildItemCollection<ProfileModel, LayerModel>(this);
LuaWrapper = new LuaWrapper(this);
DrawingVisual = new DrawingVisual();
}
/// <summary>
/// Indicates whether the profile is actively being rendered
/// </summary>
@ -38,10 +40,14 @@ namespace Artemis.Profiles
public string GameName { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public string LuaScript { get; set; }
[JsonIgnore]
public DrawingVisual DrawingVisual { get; set; }
[JsonIgnore]
public LuaWrapper LuaWrapper { get; set; }
public void FixOrder()
{
Layers.Sort(l => l.Order);

View File

@ -308,6 +308,15 @@ namespace Artemis.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to .
/// </summary>
internal static string lua_placeholder {
get {
return ResourceManager.GetString("lua-placeholder", resourceCulture);
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>

View File

@ -208,4 +208,7 @@
<data name="audio" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\audio.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="lua-placeholder" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\lua-placeholder.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
</root>

View File

@ -0,0 +1,12 @@
--------------------------------------------------------------------------------
------------------------------- Artemis LUA file -------------------------------
--------------------------------------------------------------------------------
-- This is a default script to be executed by Artemis.
-- You do not need to use this if you don't want to script. The default profiles
-- should provide you with a lot of functionality out of the box.
-- However, if you wan't to change the way profiles work, this is the ideal way
-- go about it.
-- Note: You are editing a temporary file. Whenever you save this file the
-- changes are applied to the profile and the script restarted.

View File

@ -76,8 +76,8 @@ namespace Artemis.ViewModels.Profiles
public bool EditorEnabled
=>
SelectedProfile != null && !SelectedProfile.IsDefault &&
_mainManager.DeviceManager.ActiveKeyboard != null;
SelectedProfile != null && !SelectedProfile.IsDefault &&
_mainManager.DeviceManager.ActiveKeyboard != null;
public BindableCollection<ProfileModel> Profiles
{
@ -669,6 +669,20 @@ namespace Artemis.ViewModels.Profiles
ProfileProvider.ExportProfile(SelectedProfile, dialog.FileName);
}
public void EditLua()
{
try
{
SelectedProfile?.LuaWrapper.OpenEditor();
}
catch (Exception e)
{
DialogService.ShowMessageBox("Couldn't open LUA file",
"Please make sure you have a program such as Notepad associated with the .lua extension.\n\n" +
"Windows error message: \n" + e.Message);
}
}
private void EditorStateHandler(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != "SelectedProfile")

View File

@ -115,7 +115,7 @@
Margin="5,5,0,0" Text="Note: To edit a default profile, duplicate it first." FontWeight="Bold" />
</StackPanel>
<StackPanel Grid.Column="0" Grid.Row="2" Orientation="Horizontal" Margin="0,6,0,0" HorizontalAlignment="Right">
<StackPanel Grid.Column="0" Grid.Row="2" Orientation="Horizontal" Margin="0,5,0,0" HorizontalAlignment="Right">
<Button x:Name="ImportProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
Height="26" HorizontalAlignment="Right" ToolTip="Import profile">
<Button.Content>
@ -146,6 +146,21 @@
</StackPanel>
</Button.Content>
</Button>
<Button x:Name="EditLua" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Import profile">
<Button.Content>
<StackPanel Orientation="Horizontal">
<Rectangle
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
Width="12" Height="12" Margin="3,0">
<Rectangle.OpacityMask>
<VisualBrush Visual="{StaticResource appbar_code_xml}" Stretch="Fill" />
</Rectangle.OpacityMask>
</Rectangle>
<TextBlock Margin="2,0,2,0">edit lua</TextBlock>
</StackPanel>
</Button.Content>
</Button>
</StackPanel>
<!-- Layer list -->