mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-13 12:14:16 +01:00
feat: add WIP scratchpad
This commit is contained in:
parent
3ecbadfde8
commit
9c35be2916
8 changed files with 557 additions and 1 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup Label="Target">
|
<PropertyGroup Label="Target">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
<TargetFramework>net472</TargetFramework>
|
<TargetFramework>net472</TargetFramework>
|
||||||
|
|
@ -46,6 +46,7 @@
|
||||||
<PackageReference Include="JetBrains.Annotations" Version="2020.3.0" />
|
<PackageReference Include="JetBrains.Annotations" Version="2020.3.0" />
|
||||||
<PackageReference Include="Lumina" Version="3.1.0" />
|
<PackageReference Include="Lumina" Version="3.1.0" />
|
||||||
<PackageReference Include="Lumina.Excel" Version="5.50.0" />
|
<PackageReference Include="Lumina.Excel" Version="5.50.0" />
|
||||||
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="3.0.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
||||||
<PackageReference Include="PropertyChanged.Fody" Version="2.6.1" />
|
<PackageReference Include="PropertyChanged.Fody" Version="2.6.1" />
|
||||||
<PackageReference Include="Serilog" Version="2.6.0" />
|
<PackageReference Include="Serilog" Version="2.6.0" />
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using System.Runtime.InteropServices;
|
||||||
using CheapLoc;
|
using CheapLoc;
|
||||||
using Dalamud.Interface.Colors;
|
using Dalamud.Interface.Colors;
|
||||||
using Dalamud.Interface.Components;
|
using Dalamud.Interface.Components;
|
||||||
|
using Dalamud.Interface.Scratchpad;
|
||||||
using Dalamud.Interface.Windowing;
|
using Dalamud.Interface.Windowing;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
@ -33,6 +34,7 @@ namespace Dalamud.Interface
|
||||||
private readonly DalamudChangelogWindow changelogWindow;
|
private readonly DalamudChangelogWindow changelogWindow;
|
||||||
private readonly ComponentDemoWindow componentDemoWindow;
|
private readonly ComponentDemoWindow componentDemoWindow;
|
||||||
private readonly ColorDemoWindow colorDemoWindow;
|
private readonly ColorDemoWindow colorDemoWindow;
|
||||||
|
private readonly ScratchpadWindow scratchpadWindow;
|
||||||
|
|
||||||
private readonly WindowSystem windowSystem = new WindowSystem("DalamudCore");
|
private readonly WindowSystem windowSystem = new WindowSystem("DalamudCore");
|
||||||
|
|
||||||
|
|
@ -108,6 +110,12 @@ namespace Dalamud.Interface
|
||||||
};
|
};
|
||||||
this.windowSystem.AddWindow(this.colorDemoWindow);
|
this.windowSystem.AddWindow(this.colorDemoWindow);
|
||||||
|
|
||||||
|
this.scratchpadWindow = new ScratchpadWindow(this.dalamud)
|
||||||
|
{
|
||||||
|
IsOpen = false,
|
||||||
|
};
|
||||||
|
this.windowSystem.AddWindow(this.scratchpadWindow);
|
||||||
|
|
||||||
Log.Information("[DUI] Windows added");
|
Log.Information("[DUI] Windows added");
|
||||||
|
|
||||||
if (dalamud.Configuration.LogOpenAtStartup)
|
if (dalamud.Configuration.LogOpenAtStartup)
|
||||||
|
|
@ -305,6 +313,21 @@ namespace Dalamud.Interface
|
||||||
ImGui.EndMenu();
|
ImGui.EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui.BeginMenu("Scratchpad"))
|
||||||
|
{
|
||||||
|
if (ImGui.MenuItem("Open Scratchpad"))
|
||||||
|
{
|
||||||
|
this.OpenScratchpadWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.MenuItem("Dispose all scratches"))
|
||||||
|
{
|
||||||
|
this.scratchpadWindow.Execution.DisposeAllScratches();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
if (ImGui.BeginMenu("Localization"))
|
if (ImGui.BeginMenu("Localization"))
|
||||||
{
|
{
|
||||||
if (ImGui.MenuItem("Export localizable"))
|
if (ImGui.MenuItem("Export localizable"))
|
||||||
|
|
@ -441,6 +464,14 @@ namespace Dalamud.Interface
|
||||||
this.colorDemoWindow.IsOpen = true;
|
this.colorDemoWindow.IsOpen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Open the colors test window.
|
||||||
|
/// </summary>
|
||||||
|
internal void OpenScratchpadWindow()
|
||||||
|
{
|
||||||
|
this.scratchpadWindow.IsOpen = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Toggle the Plugin Installer window.
|
/// Toggle the Plugin Installer window.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -514,5 +545,13 @@ namespace Dalamud.Interface
|
||||||
{
|
{
|
||||||
this.componentDemoWindow.IsOpen ^= true;
|
this.componentDemoWindow.IsOpen ^= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggle the scratchpad window.
|
||||||
|
/// </summary>
|
||||||
|
internal void ToggleScratchpadWindow()
|
||||||
|
{
|
||||||
|
this.scratchpadWindow.IsOpen ^= true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
95
Dalamud/Interface/Scratchpad/ScratchExecutionManager.cs
Normal file
95
Dalamud/Interface/Scratchpad/ScratchExecutionManager.cs
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Dalamud.Configuration;
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
using ImGuiNET;
|
||||||
|
using Lumina.Excel.GeneratedSheets;
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Scripting;
|
||||||
|
using Microsoft.CodeAnalysis.Scripting;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
|
namespace Dalamud.Interface.Scratchpad
|
||||||
|
{
|
||||||
|
class ScratchExecutionManager
|
||||||
|
{
|
||||||
|
private readonly Dalamud dalamud;
|
||||||
|
private Dictionary<Guid, IDalamudPlugin> loadedScratches = new Dictionary<Guid, IDalamudPlugin>();
|
||||||
|
|
||||||
|
public ScratchMacroProcessor MacroProcessor { get; private set; } = new ScratchMacroProcessor();
|
||||||
|
|
||||||
|
public ScratchExecutionManager(Dalamud dalamud)
|
||||||
|
{
|
||||||
|
this.dalamud = dalamud;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DisposeAllScratches()
|
||||||
|
{
|
||||||
|
foreach (var dalamudPlugin in this.loadedScratches)
|
||||||
|
{
|
||||||
|
dalamudPlugin.Value.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loadedScratches.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScratchLoadStatus RenewScratch(ScratchpadDocument doc)
|
||||||
|
{
|
||||||
|
var existingScratch = this.loadedScratches.FirstOrDefault(x => x.Key == doc.Id);
|
||||||
|
if (existingScratch.Value != null)
|
||||||
|
{
|
||||||
|
existingScratch.Value.Dispose();
|
||||||
|
this.loadedScratches.Remove(existingScratch.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
var code = doc.IsMacro ? this.MacroProcessor.Process(doc.Content) : doc.Content;
|
||||||
|
|
||||||
|
var options = ScriptOptions.Default
|
||||||
|
.AddReferences(typeof(ImGui).Assembly)
|
||||||
|
.AddReferences(typeof(Dalamud).Assembly)
|
||||||
|
.AddReferences(typeof(FFXIVClientStructs.Attributes.Addon)
|
||||||
|
.Assembly) // FFXIVClientStructs
|
||||||
|
.AddReferences(typeof(Lumina.GameData).Assembly) // Lumina
|
||||||
|
.AddReferences(typeof(TerritoryType).Assembly) // Lumina.Excel
|
||||||
|
//.WithReferences(MetadataReference.CreateFromFile(typeof(ScratchExecutionManager).Assembly.Location))
|
||||||
|
.AddImports("System")
|
||||||
|
.AddImports("System.IO")
|
||||||
|
.AddImports("System.Reflection")
|
||||||
|
.AddImports("System.Runtime.InteropServices")
|
||||||
|
.AddImports("Dalamud")
|
||||||
|
.AddImports("Dalamud.Plugin")
|
||||||
|
.AddImports("Dalamud.Game.Command")
|
||||||
|
.AddImports("Dalamud.Hooking")
|
||||||
|
.AddImports("ImGuiNET");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var script = CSharpScript.Create(code, options);
|
||||||
|
|
||||||
|
var pi = new DalamudPluginInterface(this.dalamud, "Scratch-" + doc.Id, null, PluginLoadReason.Installer);
|
||||||
|
var plugin = script.ContinueWith<IDalamudPlugin>("return new ScratchPlugin() as IDalamudPlugin;").RunAsync().GetAwaiter().GetResult()
|
||||||
|
.ReturnValue;
|
||||||
|
|
||||||
|
plugin.Initialize(pi);
|
||||||
|
|
||||||
|
this.loadedScratches.Add(doc.Id, plugin);
|
||||||
|
return ScratchLoadStatus.Success;
|
||||||
|
}
|
||||||
|
catch (CompilationErrorException ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Compilation error occurred!\n" + string.Join(Environment.NewLine, ex.Diagnostics));
|
||||||
|
return ScratchLoadStatus.FailureCompile;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Initialization error occured!\n");
|
||||||
|
|
||||||
|
return ScratchLoadStatus.FailureInit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Dalamud/Interface/Scratchpad/ScratchFileWatcher.cs
Normal file
12
Dalamud/Interface/Scratchpad/ScratchFileWatcher.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Dalamud.Interface.Scratchpad
|
||||||
|
{
|
||||||
|
class ScratchFileWatcher
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
16
Dalamud/Interface/Scratchpad/ScratchLoadStatus.cs
Normal file
16
Dalamud/Interface/Scratchpad/ScratchLoadStatus.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Dalamud.Interface.Scratchpad
|
||||||
|
{
|
||||||
|
enum ScratchLoadStatus
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
FailureCompile,
|
||||||
|
FailureInit,
|
||||||
|
Success,
|
||||||
|
}
|
||||||
|
}
|
||||||
227
Dalamud/Interface/Scratchpad/ScratchMacroProcessor.cs
Normal file
227
Dalamud/Interface/Scratchpad/ScratchMacroProcessor.cs
Normal file
|
|
@ -0,0 +1,227 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
|
||||||
|
namespace Dalamud.Interface.Scratchpad
|
||||||
|
{
|
||||||
|
class ScratchMacroProcessor
|
||||||
|
{
|
||||||
|
private const string template = @"
|
||||||
|
|
||||||
|
public class ScratchPlugin : IDalamudPlugin {
|
||||||
|
|
||||||
|
public string Name => ""ScratchPlugin"";
|
||||||
|
private DalamudPluginInterface pi;
|
||||||
|
|
||||||
|
{SETUPBODY}
|
||||||
|
|
||||||
|
public void Initialize(DalamudPluginInterface pluginInterface)
|
||||||
|
{
|
||||||
|
this.pi = pluginInterface;
|
||||||
|
|
||||||
|
this.pi.UiBuilder.OnBuildUi += DrawUI;
|
||||||
|
|
||||||
|
{INITBODY}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawUI()
|
||||||
|
{
|
||||||
|
{DRAWBODY}
|
||||||
|
}
|
||||||
|
|
||||||
|
{NONEBODY}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
this.pi.UiBuilder.OnBuildUi -= DrawUI;
|
||||||
|
{DISPOSEBODY}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
";
|
||||||
|
|
||||||
|
private enum ParseContext
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Init,
|
||||||
|
Draw,
|
||||||
|
Hook,
|
||||||
|
Dispose,
|
||||||
|
}
|
||||||
|
|
||||||
|
private class HookInfo
|
||||||
|
{
|
||||||
|
public string Body { get; set; }
|
||||||
|
|
||||||
|
public string Arguments { get; set; }
|
||||||
|
|
||||||
|
public string Invocation { get; set; }
|
||||||
|
|
||||||
|
public string RetType { get; set; }
|
||||||
|
|
||||||
|
public string Sig { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Process(string input)
|
||||||
|
{
|
||||||
|
var lines = input.Split(new[] {'\r', '\n'});
|
||||||
|
|
||||||
|
var ctx = ParseContext.None;
|
||||||
|
|
||||||
|
var setupBody = string.Empty;
|
||||||
|
var noneBody = string.Empty;
|
||||||
|
var initBody = string.Empty;
|
||||||
|
var disposeBody = string.Empty;
|
||||||
|
var drawBody = string.Empty;
|
||||||
|
var tHook = new HookInfo();
|
||||||
|
|
||||||
|
var hooks = new List<HookInfo>();
|
||||||
|
|
||||||
|
for (var i = 0; i < lines.Length; i++)
|
||||||
|
{
|
||||||
|
var line = lines[i];
|
||||||
|
|
||||||
|
if (line.StartsWith("INITIALIZE:"))
|
||||||
|
{
|
||||||
|
ctx = ParseContext.Init;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.StartsWith("DRAW:"))
|
||||||
|
{
|
||||||
|
ctx = ParseContext.Draw;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.StartsWith("DISPOSE:"))
|
||||||
|
{
|
||||||
|
ctx = ParseContext.Dispose;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.StartsWith("HOOK("))
|
||||||
|
{
|
||||||
|
ctx = ParseContext.Hook;
|
||||||
|
|
||||||
|
var args = Regex.Match(line, "HOOK\\((.+)+\\):").Groups[0].Captures[0].Value
|
||||||
|
.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(x => x[0] == ' ' ? x[1..] : x).ToArray();
|
||||||
|
|
||||||
|
tHook.Sig = args[0].Replace("\"", string.Empty); // Split quotation marks if any
|
||||||
|
tHook.Sig = tHook.Sig.Replace("HOOK(", string.Empty);
|
||||||
|
tHook.RetType = args[1];
|
||||||
|
tHook.Arguments = string.Join(", ", args.Skip(2).ToArray()).Replace("):", string.Empty);
|
||||||
|
|
||||||
|
var invocationGroups = Regex.Matches(tHook.Arguments, "\\S+ ([a-zA-Z0-9]+),*").Cast<Match>()
|
||||||
|
.Select(x => x.Groups[1].Value);
|
||||||
|
tHook.Invocation = string.Join(", ", invocationGroups);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.StartsWith("END;"))
|
||||||
|
{
|
||||||
|
switch (ctx)
|
||||||
|
{
|
||||||
|
case ParseContext.None:
|
||||||
|
throw new Exception("Not in a macro!!!");
|
||||||
|
case ParseContext.Init:
|
||||||
|
break;
|
||||||
|
case ParseContext.Draw:
|
||||||
|
break;
|
||||||
|
case ParseContext.Hook:
|
||||||
|
hooks.Add(tHook);
|
||||||
|
tHook = new HookInfo();
|
||||||
|
break;
|
||||||
|
case ParseContext.Dispose:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = ParseContext.None;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ctx)
|
||||||
|
{
|
||||||
|
case ParseContext.None:
|
||||||
|
noneBody += line + "\n";
|
||||||
|
break;
|
||||||
|
case ParseContext.Init:
|
||||||
|
initBody += line + "\n";
|
||||||
|
break;
|
||||||
|
case ParseContext.Draw:
|
||||||
|
drawBody += line + "\n";
|
||||||
|
break;
|
||||||
|
case ParseContext.Hook:
|
||||||
|
tHook.Body += line + "\n";
|
||||||
|
break;
|
||||||
|
case ParseContext.Dispose:
|
||||||
|
disposeBody += line + "\n";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var hookSetup = string.Empty;
|
||||||
|
var hookInit = string.Empty;
|
||||||
|
var hookDetour = string.Empty;
|
||||||
|
var hookDispose = string.Empty;
|
||||||
|
for (var i = 0; i < hooks.Count; i++)
|
||||||
|
{
|
||||||
|
var hook = hooks[i];
|
||||||
|
|
||||||
|
hookSetup +=
|
||||||
|
$"private delegate {hook.RetType} Hook{i}Delegate({hook.Arguments});\n";
|
||||||
|
hookSetup +=
|
||||||
|
$"private Hook<Hook{i}Delegate> hook{i}Inst;\n";
|
||||||
|
|
||||||
|
hookInit += $"var addrH{i} = pi.TargetModuleScanner.ScanText(\"{hook.Sig}\");\n";
|
||||||
|
hookInit +=
|
||||||
|
$"this.hook{i}Inst = new Hook<Hook{i}Delegate>(addrH{i}, new Hook{i}Delegate(Hook{i}Detour), this);\n";
|
||||||
|
hookInit +=
|
||||||
|
$"this.hook{i}Inst.Enable();\n";
|
||||||
|
|
||||||
|
var originalCall = $"this.hook{i}Inst.Original({hook.Invocation});\n";
|
||||||
|
if (hook.RetType != "void")
|
||||||
|
originalCall = "return " + originalCall;
|
||||||
|
|
||||||
|
if (hook.Body.Contains("hook{i}Inst.Original"))
|
||||||
|
{
|
||||||
|
PluginLog.Warning($"Attention! A manual call to Original() in Hook #{i} was detected. Original calls will not be managed for you.");
|
||||||
|
originalCall = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
hookDetour +=
|
||||||
|
$"private {hook.RetType} Hook{i}Detour({hook.Arguments}) {{\n" +
|
||||||
|
$"try {{\n" +
|
||||||
|
$" {hook.Body}\n" +
|
||||||
|
$"}} catch(Exception ex) {{\n" +
|
||||||
|
$" PluginLog.Error(ex, \"Exception in Hook{i}Detour!!\");\n" +
|
||||||
|
$"}}\n" +
|
||||||
|
$"{originalCall}" +
|
||||||
|
$"\n}}\n";
|
||||||
|
|
||||||
|
hookDispose += $"this.hook{i}Inst.Dispose();\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
setupBody += "\n" + hookSetup;
|
||||||
|
initBody = hookInit + "\n" + initBody;
|
||||||
|
noneBody += "\n" + hookDetour;
|
||||||
|
disposeBody += "\n" + hookDispose;
|
||||||
|
|
||||||
|
var output = template;
|
||||||
|
output = output.Replace("{SETUPBODY}", setupBody);
|
||||||
|
output = output.Replace("{INITBODY}", initBody);
|
||||||
|
output = output.Replace("{DRAWBODY}", drawBody);
|
||||||
|
output = output.Replace("{NONEBODY}", noneBody);
|
||||||
|
output = output.Replace("{DISPOSEBODY}", disposeBody);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
Dalamud/Interface/Scratchpad/ScratchpadDocument.cs
Normal file
25
Dalamud/Interface/Scratchpad/ScratchpadDocument.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Dalamud.Interface.Scratchpad
|
||||||
|
{
|
||||||
|
class ScratchpadDocument
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; } = Guid.NewGuid();
|
||||||
|
|
||||||
|
public string Content = "INITIALIZE:\n\tPluginLog.Information(\"Loaded!\");\nEND;\n\nDISPOSE:\n\tPluginLog.Information(\"Disposed!\");\nEND;\n";
|
||||||
|
|
||||||
|
public string Title { get; set; } = "New Document";
|
||||||
|
|
||||||
|
public bool HasUnsaved { get; set; }
|
||||||
|
|
||||||
|
public bool IsOpen { get; set; }
|
||||||
|
|
||||||
|
public ScratchLoadStatus Status { get; set; }
|
||||||
|
|
||||||
|
public bool IsMacro = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
141
Dalamud/Interface/Scratchpad/ScratchpadWindow.cs
Normal file
141
Dalamud/Interface/Scratchpad/ScratchpadWindow.cs
Normal file
|
|
@ -0,0 +1,141 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Dalamud.Interface.Colors;
|
||||||
|
using Dalamud.Interface.Windowing;
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
using ImGuiNET;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
|
namespace Dalamud.Interface.Scratchpad
|
||||||
|
{
|
||||||
|
class ScratchpadWindow : Window
|
||||||
|
{
|
||||||
|
private readonly Dalamud dalamud;
|
||||||
|
|
||||||
|
public ScratchExecutionManager Execution { get; private set; }
|
||||||
|
|
||||||
|
private List<ScratchpadDocument> documents = new List<ScratchpadDocument>();
|
||||||
|
|
||||||
|
public ScratchpadWindow(Dalamud dalamud) :
|
||||||
|
base("Plugin Scratchpad")
|
||||||
|
{
|
||||||
|
this.dalamud = dalamud;
|
||||||
|
this.documents.Add(new ScratchpadDocument());
|
||||||
|
|
||||||
|
this.SizeConstraintsMin = new Vector2(400, 400);
|
||||||
|
|
||||||
|
this.Execution = new ScratchExecutionManager(dalamud);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw()
|
||||||
|
{
|
||||||
|
if (ImGui.BeginMenuBar())
|
||||||
|
{
|
||||||
|
if (ImGui.BeginMenu("File"))
|
||||||
|
{
|
||||||
|
if (ImGui.MenuItem("Load & Watch"))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var flags = ImGuiTabBarFlags.Reorderable | ImGuiTabBarFlags.TabListPopupButton |
|
||||||
|
ImGuiTabBarFlags.FittingPolicyScroll;
|
||||||
|
|
||||||
|
if (ImGui.BeginTabBar("ScratchDocTabBar", flags))
|
||||||
|
{
|
||||||
|
if (ImGui.TabItemButton("+", ImGuiTabItemFlags.Trailing | ImGuiTabItemFlags.NoTooltip))
|
||||||
|
this.documents.Add(new ScratchpadDocument());
|
||||||
|
|
||||||
|
for (var i = 0; i < this.documents.Count; i++)
|
||||||
|
{
|
||||||
|
var isOpen = true;
|
||||||
|
|
||||||
|
if (ImGui.BeginTabItem(this.documents[i].Title + (this.documents[i].HasUnsaved ? "*" : string.Empty) + "###ScratchItem" + i, ref isOpen))
|
||||||
|
{
|
||||||
|
if (ImGui.InputTextMultiline("###ScratchInput" + i, ref this.documents[i].Content, 20000,
|
||||||
|
new Vector2(-1, -34), ImGuiInputTextFlags.AllowTabInput))
|
||||||
|
{
|
||||||
|
this.documents[i].HasUnsaved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiHelpers.ScaledDummy(3);
|
||||||
|
|
||||||
|
if (ImGui.Button("Compile & Reload"))
|
||||||
|
{
|
||||||
|
this.documents[i].Status = this.Execution.RenewScratch(this.documents[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
if (ImGui.Button("Dispose all"))
|
||||||
|
{
|
||||||
|
this.Execution.DisposeAllScratches();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
if (ImGui.Button("Dump processed code"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var code = this.Execution.MacroProcessor.Process(this.documents[i].Content);
|
||||||
|
Log.Information(code);
|
||||||
|
ImGui.SetClipboardText(code);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Could not process macros");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
if (ImGui.Button("Toggle Log"))
|
||||||
|
{
|
||||||
|
this.dalamud.DalamudUi.ToggleLog();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
ImGui.Checkbox("Use Macros", ref this.documents[i].IsMacro);
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
switch (this.documents[i].Status)
|
||||||
|
{
|
||||||
|
case ScratchLoadStatus.Unknown:
|
||||||
|
ImGui.TextColored(ImGuiColors.DalamudGrey, "Compile scratch to see status");
|
||||||
|
break;
|
||||||
|
case ScratchLoadStatus.FailureCompile:
|
||||||
|
ImGui.TextColored(ImGuiColors.DalamudRed, "Error during compilation");
|
||||||
|
break;
|
||||||
|
case ScratchLoadStatus.FailureInit:
|
||||||
|
ImGui.TextColored(ImGuiColors.DalamudRed, "Error during init");
|
||||||
|
break;
|
||||||
|
case ScratchLoadStatus.Success:
|
||||||
|
ImGui.TextColored(ImGuiColors.HealerGreen, "OK!");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
ImGui.TextColored(ImGuiColors.DalamudGrey, this.documents[i].Id.ToString());
|
||||||
|
|
||||||
|
ImGui.EndTabItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndTabBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue