Skip to content

Commit

Permalink
Add use local variables for fallthrough arguments
Browse files Browse the repository at this point in the history
- Add component node names to render method names
  • Loading branch information
araszka committed Feb 3, 2024
1 parent ba16b71 commit c0a0a91
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 49 deletions.
2 changes: 1 addition & 1 deletion src/ManiaTemplates/Components/MtComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,6 @@ private static HashSet<string> GetSlotNamesInTemplate(XmlNode node)

public string Id()
{
return "MtContext" + GetHashCode().ToString().Replace("-", "N");
return GetHashCode().ToString().Replace("-", "N");
}
}
63 changes: 37 additions & 26 deletions src/ManiaTemplates/Lib/MtTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,11 @@ private string CreateRenderMethodsBlock()
/// <summary>
/// Creates the slot-render method for a given data context.
/// </summary>
private string CreateSlotRenderMethod(MtComponent component, int scope, MtDataContext context, string slotName,
private string CreateSlotRenderMethod(string nodeName, MtComponent component, int scope, MtDataContext context, string slotName,
string? slotContent = null, MtComponent? parentComponent = null)
{
var variablesInherited = new List<string>();
var methodName = GetSlotRenderMethodName(scope, slotName);
var methodName = GetSlotRenderMethodName(nodeName, scope, slotName, context);

var methodArguments = new List<string>
{
Expand Down Expand Up @@ -299,6 +299,7 @@ private string ProcessNode(XmlNode node, MtComponentMap availableMtComponents, M
var component = _engine.GetComponent(availableMtComponents[tag].TemplateKey);
var slotContents = GetSlotContentsBySlotName(childNode, component, availableMtComponents, currentContext);
var componentRenderMethodCall = ProcessComponentNode(
childNode.Name,
context != currentContext,
childNode.GetHashCode(),
component,
Expand Down Expand Up @@ -340,9 +341,12 @@ private string ProcessNode(XmlNode node, MtComponentMap availableMtComponents, M
default:
{
var hasChildren = childNode.HasChildNodes;
if (node.ChildNodes.Count == 1 && parentAttributes != null)
if (node.ChildNodes.Count == 1 && parentAttributes != null && parentComponent != null)
{
foreach (var attribute in parentAttributes)
var attributesThatArentProperties = parentAttributes.Where(attribute =>
!parentComponent.Properties.ContainsKey(attribute.Key));

foreach (var attribute in attributesThatArentProperties)
{
attributeList.TryAdd(attribute.Key, attribute.Value);
}
Expand Down Expand Up @@ -427,6 +431,7 @@ private Dictionary<string, string> GetSlotContentsBySlotName(XmlNode componentNo
/// Process a node that has been identified as an component.
/// </summary>
private string ProcessComponentNode(
string nodeName,
bool newScopeCreated,
int scope,
MtComponent component,
Expand All @@ -451,6 +456,7 @@ private string ProcessComponentNode(
Context = currentContext,
Name = slotName,
RenderMethodT4 = CreateSlotRenderMethod(
nodeName,
component,
scope,
currentContext,
Expand All @@ -461,12 +467,12 @@ private string ProcessComponentNode(
});
}

var renderMethodName = GetComponentRenderMethodName(component);
var renderMethodName = GetComponentRenderMethodName(nodeName, component, currentContext);
if (!_renderMethods.ContainsKey(renderMethodName))
{
_renderMethods.Add(
renderMethodName,
CreateComponentRenderMethod(component, renderMethodName, componentBody)
CreateComponentRenderMethod(component, renderMethodName, componentBody, currentContext)
);
}

Expand All @@ -475,23 +481,19 @@ private string ProcessComponentNode(

//Create available arguments
var renderArguments = new List<string> { "" };

//Attach variables from current context, that are not mapped to properties of component
renderArguments.AddRange(from variableName in currentContext.Keys where !attributeList.ContainsKey(variableName) select $"{variableName}: {variableName}");

//Attach attributes to render method call
foreach (var (attributeName, attributeValue) in attributeList)
{
if (component.Properties.TryGetValue(attributeName, out var value))
{
if (IsStringType(value))
{
renderArguments.Add(
$"{attributeName}: {WrapIfString(value, ReplaceCurlyBraces(attributeValue, s => $@"{{({s})}}"))}");
}
else
{
renderArguments.Add(
$"{attributeName}: {ReplaceCurlyBraces(attributeValue, s => $"({s})")}");
}
}
if (!component.Properties.TryGetValue(attributeName, out var value)) continue;

renderArguments.Add(
IsStringType(value)
? $"{attributeName}: {WrapStringInQuotes(ReplaceCurlyBraces(attributeValue, s => $"{{({s})}}"))}"
: $"{attributeName}: {ReplaceCurlyBraces(attributeValue, s => $"({s})")}");
}

renderComponentCall.Append(string.Join(", ", renderArguments));
Expand All @@ -509,7 +511,7 @@ private string ProcessComponentNode(

renderComponentCall.Append($"__slotRenderer_{slotName}: ")
.Append("() => ")
.Append(GetSlotRenderMethodName(scope, slotName));
.Append(GetSlotRenderMethodName(nodeName, scope, slotName, currentContext));

if (newScopeCreated)
{
Expand Down Expand Up @@ -572,7 +574,7 @@ private string ProcessComponentNode(
/// <summary>
/// Creates the method which renders the contents of a component.
/// </summary>
private string CreateComponentRenderMethod(MtComponent component, string renderMethodName, string componentBody)
private string CreateComponentRenderMethod(MtComponent component, string renderMethodName, string componentBody, MtDataContext currentContext)
{
var renderMethod = new StringBuilder(_maniaTemplateLanguage.FeatureBlockStart())
.Append("void ")
Expand All @@ -587,6 +589,15 @@ private string CreateComponentRenderMethod(MtComponent component, string renderM

//add slot render methods
AppendSlotRenderArgumentsToList(arguments, component);

//Add fallthrough properties
foreach (var (variableName, variableType) in currentContext)
{
if (!component.Properties.ContainsKey(variableName))
{
arguments.Add($"{variableType} {variableName}");
}
}

//add component properties as arguments with defaults
AppendComponentPropertiesToMethodArgumentsList(component, arguments);
Expand Down Expand Up @@ -1045,25 +1056,25 @@ private static string CreateMethodCall(string methodName, string methodArguments
/// <summary>
/// Returns the method name that renders the given component.
/// </summary>
private string GetComponentRenderMethodName(MtComponent component)
private string GetComponentRenderMethodName(string nodeName, MtComponent component, MtDataContext dataContext)
{
return $"Render_Component_{component.Id()}";
return $"Component_{nodeName}_{dataContext}_{component.Id()}";
}

/// <summary>
/// Returns the method name that renders the scripts of a given component.
/// </summary>
private string GetComponentScriptsRenderMethodName(MtComponent component)
{
return $"Render_ComponentScript_{component.Id()}";
return $"ComponentScript_{component.Id()}";
}

/// <summary>
/// Returns the name of the method that renders the slot contents.
/// </summary>
private static string GetSlotRenderMethodName(int scope, string name)
private static string GetSlotRenderMethodName(string nodeName, int scope, string name, MtDataContext context)
{
return $"Render_Slot_{scope.GetHashCode()}_{name}";
return $"Slot_{name}_of_{nodeName}_in_{context}_{scope.GetHashCode()}";
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,11 @@ public async void Should_Append_Parent_Attributes_To_Single_Component_Child()
_maniaTemplateEngine.AddTemplateFromString("FallthroughComponent", fallthroughComponent);
_maniaTemplateEngine.AddTemplateFromString("FallthroughWrapper", fallthroughWrapper);

var template = _maniaTemplateEngine.RenderAsync("FallthroughWrapper", new { }, assemblies).Result;
var template = _maniaTemplateEngine.RenderAsync("FallthroughWrapper", new
{
testString = "unit",
index = -1
}, assemblies).Result;
Assert.Equal(expected, template, ignoreLineEndingDifferences: true);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
<manialink version="3" id="MtFallthroughWrapper" name="EvoSC#-MtFallthroughWrapper">
<label text="negative" />
<label text="negative" />
<label text="negative" />
<label text="negative" />
<label text="negative" />
<label text="negative" />
</manialink>
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<manialink version="3" id="MtFallthroughWrapper" name="EvoSC#-MtFallthroughWrapper">
<label text="test" data-test="unit" />
<label text="test" i="1" data-index="1" data-test="unit" />
<label text="test" i="2" data-index="2" data-test="unit" />
<label text="test" i="3" data-index="3" data-test="unit" />
</manialink>
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<manialink version="3" id="MtPropertyTest" name="EvoSC#-MtPropertyTest">
<frame size="15 11" width="15">
<frame size="15 11">
<label size="15 3" text="integrationtest" />
</frame>
<frame size="15 11" width="15">
<frame size="15 11">
<label size="15 3" text="integrationintegration" />
</frame>
<frame size="15 11" width="15">
<frame size="15 11">
<label size="15 3" text="test" />
</frame>
<label text="integration" />
<frame size="123 11" width="123">
<frame size="77 11" width="77">
<frame size="123 11">
<frame size="77 11">
<label text="integration" />
</frame>
</frame>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<component>
<property type="int" name="index" default="-2" />
<property type="int" name="i" default="-2" />

<template>
<label text="test" />
<label text="test" i="{{ i }}" />
</template>
</component>
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<component>
<using namespace="System.Linq" />
<import component="FallthroughComponent" as="FallthroughComponent"/>
<property type="string" name="testString" />
<property type="int" name="index" />

<template>
<FallthroughComponent data-test="unit"/>
<FallthroughComponent foreach="int i in Enumerable.Range(1, 3)" data-index="{{ i }}" index="{{ i * 10 }}" data-test="unit"/>
</template>
</component>
35 changes: 22 additions & 13 deletions tests/ManiaTemplates.Tests/Lib/expected.tt
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ var __outerIndex1 = 0;
foreach (int i in numbers) {
var __index = __outerIndex1;
if (enabled) {
Render_Component_MtContext2(__data: __data, x: (20 * __index), __slotRenderer_default: () => Render_Slot_3_default(__data: new CRoot_ForEachLoop1(__data){__index = __index, i = i}, __slotRenderer_default: () => DoNothing()));
Component_Frame_CRoot_ForEachLoop1_2(__data: __data, __index: __index, i: i, x: (20 * __index), __slotRenderer_default: () => Slot_default_of_Frame_in_CRoot_ForEachLoop1_3(__data: new CRoot_ForEachLoop1(__data){__index = __index, i = i}, __slotRenderer_default: () => DoNothing()));
}
__outerIndex1++;
}
Render_Component_MtContext2(__data: __data, __slotRenderer_default: () => Render_Slot_4_default(__data: __data, __slotRenderer_default: () => DoNothing()));
Component_Frame_CRoot_2(__data: __data, numbers: numbers, enabled: enabled, __slotRenderer_default: () => Slot_default_of_Frame_in_CRoot_4(__data: __data, __slotRenderer_default: () => DoNothing()));
foreach(var maniaScriptRenderMethod in __maniaScriptRenderMethods){ maniaScriptRenderMethod(); }
#>
<script>scriptText1
Expand All @@ -59,12 +59,12 @@ scriptText3
</script>
<#+
}
void Render_Component_MtContext5(CRoot __data, double x = 0.0, double y = 0.0, double w = 0.0, double h = 0.0, string halign = $"left", string valign = $"center", double opacity = 1.0, int zIndex = 0, int events = 0, string action = $"", string url = $"", string manialink = $"", string style = $"", string textfont = $"GameFont", double textsize = 1.0, string textcolor = $"", string focusareacolor1 = $"", string focusareacolor2 = $"", string text = $"", string textprefix = $"", int bold = 0, int autonewline = 0, int maxline = 0, int translate = 0, string textid = $"", string id = $"") {
void Component_Label_CRoot_ForEachLoop1_ForEachLoop1_5(CRoot __data, int __index, int j, double x = 0.0, double y = 0.0, double w = 0.0, double h = 0.0, string halign = $"left", string valign = $"center", double opacity = 1.0, int zIndex = 0, int events = 0, string action = $"", string url = $"", string manialink = $"", string style = $"", string textfont = $"GameFont", double textsize = 1.0, string textcolor = $"", string focusareacolor1 = $"", string focusareacolor2 = $"", string text = $"", string textprefix = $"", int bold = 0, int autonewline = 0, int maxline = 0, int translate = 0, string textid = $"", string id = $"") {
#>
<label pos="<#= (x) #> <#= (y) #>" size="<#= (w) #> <#= (h) #>" halign="<#= (halign) #>" valign="<#= (valign) #>" opacity="<#= (opacity) #>" z-index="<#= (zIndex) #>" ScriptEvents="<#= (events) #>" action="<#= (action) #>" url="<#= (url) #>" manialink="<#= (manialink) #>" style="<#= (style) #>" textfont="<#= (textfont) #>" textsize="<#= (textsize) #>" textcolor="<#= (textcolor) #>" focusareacolor1="<#= (focusareacolor1) #>" focusareacolor2="<#= (focusareacolor2) #>" text="<#= (text) #>" textprefix="<#= (textprefix) #>" textemboss="<#= (bold) #>" autonewline="<#= (autonewline) #>" maxline="<#= (maxline) #>" translate="<#= (translate) #>" textid="<#= (textid) #>" id="<#= (id) #>" />
<#+
}
void Render_Component_MtContext2(CRoot __data, Action __slotRenderer_default, int zIndex = 0, double x = 0.0, double y = 0.0, double w = 0.0, double h = 0.0) {
void Component_Frame_CRoot_ForEachLoop1_2(CRoot __data, Action __slotRenderer_default, int __index, int i, int zIndex = 0, double x = 0.0, double y = 0.0, double w = 0.0, double h = 0.0) {
#>
<frame pos="<#= (x) #> <#= (y) #>" size="<#= (w) #> <#= (h) #>" z-index="<#= (zIndex) #>">
<#+
Expand All @@ -73,10 +73,19 @@ __slotRenderer_default();
</frame>
<#+
}
void Render_Component_MtContext6(CRoot __data, test arg3, string arg1 = $"", int arg2 = 0) {
__maniaScriptRenderMethods.Add(() => Render_ComponentScript_MtContext6(arg3,arg1,arg2));
void Component_Graph_CRoot_6(CRoot __data, List<int> numbers, boolean enabled, test arg3, string arg1 = $"", int arg2 = 0) {
__maniaScriptRenderMethods.Add(() => ComponentScript_6(arg3,arg1,arg2));
}
void Render_ComponentScript_MtContext6(test arg3, string arg1 = $"", int arg2 = 0) {
void Component_Frame_CRoot_2(CRoot __data, Action __slotRenderer_default, List<int> numbers, boolean enabled, int zIndex = 0, double x = 0.0, double y = 0.0, double w = 0.0, double h = 0.0) {
#>
<frame pos="<#= (x) #> <#= (y) #>" size="<#= (w) #> <#= (h) #>" z-index="<#= (zIndex) #>">
<#+
__slotRenderer_default();
#>
</frame>
<#+
}
void ComponentScript_6(test arg3, string arg1 = $"", int arg2 = 0) {
#>
<script>GraphScript
<#+
Expand All @@ -90,7 +99,7 @@ __insertedOneTimeManiaScripts.Add("FWKSFxnFcgdsXVn9dn5IW3isD6T8z+2eK6liK8rPSpU="
</script>
<#+
}
void Render_Slot_3_default(CRoot_ForEachLoop1 __data,Action __slotRenderer_default) {
void Slot_default_of_Frame_in_CRoot_ForEachLoop1_3(CRoot_ForEachLoop1 __data,Action __slotRenderer_default) {
var numbers = __data.numbers;
var enabled = __data.enabled;
var __index = __data.__index;
Expand All @@ -99,25 +108,25 @@ var __outerIndex7 = 0;
foreach (int j in numbers.GetRange(0, i)) {
var __index2 = __outerIndex7;
if (i < numbers.Count) {
Render_Component_MtContext5(__data: __data, text: $"{(i)}, {(j)} at index {(__index)}, {(__index2)}");
Component_Label_CRoot_ForEachLoop1_ForEachLoop1_5(__data: __data, __index: __index, j: j, text: $"{(i)}, {(j)} at index {(__index)}, {(__index2)}");
}
__outerIndex7++;
}
}
void Render_Slot_8_default(CRoot __data,Action __slotRenderer_default) {
void Slot_default_of_Frame_in_CRoot_8(CRoot __data,Action __slotRenderer_default) {
var numbers = __data.numbers;
var enabled = __data.enabled;
#>
<test>
<#+
Render_Component_MtContext6(__data: __data, arg3: (new test()));
Component_Graph_CRoot_6(__data: __data, numbers: numbers, enabled: enabled, arg3: (new test()));
#>
</test>
<#+
}
void Render_Slot_4_default(CRoot __data,Action __slotRenderer_default) {
void Slot_default_of_Frame_in_CRoot_4(CRoot __data,Action __slotRenderer_default) {
var numbers = __data.numbers;
var enabled = __data.enabled;
Render_Component_MtContext2(__data: __data, __slotRenderer_default: () => Render_Slot_8_default(__data: __data, __slotRenderer_default: () => DoNothing()));
Component_Frame_CRoot_2(__data: __data, numbers: numbers, enabled: enabled, __slotRenderer_default: () => Slot_default_of_Frame_in_CRoot_8(__data: __data, __slotRenderer_default: () => DoNothing()));
}
#>

0 comments on commit c0a0a91

Please sign in to comment.