Skip to content

Commit

Permalink
Implemented Set Local Variable block
Browse files Browse the repository at this point in the history
  • Loading branch information
joaofarias committed Mar 11, 2023
1 parent fc9678b commit d8763a2
Show file tree
Hide file tree
Showing 11 changed files with 208 additions and 1 deletion.
12 changes: 12 additions & 0 deletions Assets/Content/XML UI/Blocks.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<XmlLayout>
<Styles>
<Style id="set-local-variable" color="Instruction" format="set local variable |var| to (0)" tooltip="Creates a local variable with the given value." />
</Styles>
<Categories>
<Category name="Variables">
<SetLocalVariable style="set-local-variable">
<Constant number="0" />
</SetLocalVariable>
</Category>
</Categories>
</XmlLayout>
7 changes: 7 additions & 0 deletions Assets/Content/XML UI/Blocks.xml.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Assets/Content/XML UI/UIResourceDatabase.asset
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ MonoBehaviour:
- Content/XML UI
AutomaticallyRemoveEntries: 1
entries:
- path: Vizzy Studio/Blocks
resource: {fileID: 4900000, guid: 9f14c504674ecc9459d72bd76a860351, type: 3}
- path: Vizzy Studio/UIResourceDatabase
resource: {fileID: 11400000}
- path: Vizzy Studio/VizzyFileExplorer
Expand Down
8 changes: 8 additions & 0 deletions Assets/Scripts/Blocks.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions Assets/Scripts/Blocks/SetLocalVariableInstruction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using HarmonyLib;
using ModApi.Craft.Program;
using ModApi.Craft.Program.Instructions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Assets.Scripts.Blocks
{
[Serializable]
public class SetLocalVariableInstruction : ProgramInstruction
{
[ProgramNodeProperty]
private string _variable = "var";

public string VariableName
{
get => _variable;
set => _variable = value;
}

public override ProgramInstruction Execute(IThreadContext context)
{
ExpressionResult variableValue = GetExpression(0).Evaluate(context);
context.CreateLocalVariable(VariableName).Value.Set(variableValue);

return base.Execute(context);
}
}
}
11 changes: 11 additions & 0 deletions Assets/Scripts/Blocks/SetLocalVariableInstruction.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 29 additions & 1 deletion Assets/Scripts/Patches/ProgramSerializerPatches.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using HarmonyLib;
using Assets.Scripts.Blocks;
using HarmonyLib;
using ModApi.Craft.Program;
using ModApi.Craft.Program.Instructions;
using System;
using System.Reflection;
using System.Xml.Linq;
using UnityEngine;

Expand Down Expand Up @@ -92,5 +95,30 @@ private static void OnSerializedFlightProgram(ProgramNode node, XElement parentE
__result.SetAttributeValue("module", module.Name);
}
}

private static bool _initializedBlocks = false;
[HarmonyPrefix]
[HarmonyPatch(nameof(ProgramSerializer.CreateProgramNode))]
private static void OnCreateProgramNode()
{
if (_initializedBlocks)
return;

_initializedBlocks = true;

ConstructorInfo programNodeCreatorConstructor = AccessTools.FirstConstructor(AccessTools.TypeByName("ProgramSerializer.ProgramNodeCreator"), c => true);
ConstructorInfo programNodeCreatorConstructor2 = AccessTools.FirstConstructor(AccessTools.TypeByName("ProgramNodeCreator"), c => true);

object typeNameLookup = AccessTools.Field(typeof(ProgramSerializer), "_typeNameLookup").GetValue(null);
object xmlNameLookup = AccessTools.Field(typeof(ProgramSerializer), "_xmlNameLookup").GetValue(null);

MethodInfo typeNameLookupAddMethod = AccessTools.Method(typeNameLookup.GetType(), "Add");
MethodInfo xmlNameLookupAddMethod = AccessTools.Method(xmlNameLookup.GetType(), "Add");

object setLocalVariableCreator = programNodeCreatorConstructor2.Invoke(new object[] { "SetLocalVariable", typeof(SetLocalVariableInstruction), (Func<ProgramNode>)(() => new SetLocalVariableInstruction()) });

typeNameLookupAddMethod.Invoke(typeNameLookup, new object[] { typeof(SetLocalVariableInstruction).Name, setLocalVariableCreator });
xmlNameLookupAddMethod.Invoke(xmlNameLookup, new object[] { "SetLocalVariable", setLocalVariableCreator });
}
}
}
44 changes: 44 additions & 0 deletions Assets/Scripts/Patches/VariableElementScriptPatches.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Assets.Scripts.Blocks;
using Assets.Scripts.Vizzy.UI;
using Assets.Scripts.Vizzy.UI.Elements;
using HarmonyLib;
using ModApi.Craft.Program;
using ModApi.Ui;
using UnityEngine;

namespace Assets.Scripts.Patches
{
[HarmonyPatch(typeof(VariableElementScript))]
internal static class VariableElementScriptPatches
{
[HarmonyPostfix]
[HarmonyPatch("OnPointerClick")]
private static void OnPointerClick(VariableElementScript __instance)
{
if (__instance.Parent?.Node is SetLocalVariableInstruction setLocalVarInstruction)
{
VariableExpression variableExpression = AccessTools.Field(typeof(VariableElementScript), "_expression").GetValue(__instance) as VariableExpression;
InputDialogScript variableNameInputDialog = VizzyUIController.CreateVariableNameInputDialog(variableExpression.VariableName);
variableNameInputDialog.MessageText = "RENAME LOCAL VARIABLE";
variableNameInputDialog.OkayClicked += dialog =>
{
if (string.IsNullOrWhiteSpace(dialog.InputText))
return;

string oldName = variableExpression.VariableName;
variableExpression.VariableName = dialog.InputText;
setLocalVarInstruction.VariableName = dialog.InputText;

AccessTools.Method(typeof(VariableElementScript), "RenameLocalVariableInScope").Invoke(__instance, new object[] { setLocalVarInstruction, oldName, setLocalVarInstruction.VariableName });

foreach (VariableElementScript varScript in __instance.VizzyUI.ProgramTransform.GetComponentsInChildren<VariableElementScript>())
{
varScript.Parent?.LayoutElement();
}

dialog.Close();
};
}
}
}
}
11 changes: 11 additions & 0 deletions Assets/Scripts/Patches/VariableElementScriptPatches.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions Assets/Scripts/Patches/VizzyToolboxPatches.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using Assets.Scripts.Vizzy.UI;
using HarmonyLib;
using ModApi.Common.Extensions;
using System;
using System.Linq;
using System.Xml.Linq;
using UnityEngine;

namespace Assets.Scripts.Patches
{
[HarmonyPatch(typeof(VizzyToolbox))]
internal static class VizzyToolboxPatches
{
[HarmonyPrefix]
[HarmonyPatch(MethodType.Constructor)]
[HarmonyPatch(new Type[] { typeof(XElement), typeof(bool) })]
private static void OnConstructor(XElement xml)
{
XElement blocksXml = XElement.Parse(Game.Instance.UserInterface.ResourceDatabase.GetResource<TextAsset>("Vizzy Studio/Blocks").text);
XElement toolboxStyles = xml.Element("Styles");
foreach (XElement style in blocksXml.Element("Styles").Elements())
{
toolboxStyles.Add(style);
}

XElement toolboxCategories = xml.Element("Categories");
foreach (XElement category in blocksXml.Element("Categories").Elements())
{
XElement toolboxCategory = toolboxCategories.Elements().FirstOrDefault(e => e.GetStringAttribute("name") == category.GetStringAttribute("name"));
if (toolboxCategory != null)
{
foreach (XElement block in category.Elements())
{
//#TODO: Setting as first is specific to "SetLocalVariable". Add an attribute to specify position
toolboxCategory.AddFirst(block);
}
}
}
}
}
}
11 changes: 11 additions & 0 deletions Assets/Scripts/Patches/VizzyToolboxPatches.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit d8763a2

Please sign in to comment.