Skip to content

Commit

Permalink
Merge pull request #232 from vchelaru/227-documentation-for-using-fil…
Browse files Browse the repository at this point in the history
…es-generated-by-code-gen

227 documentation for using files generated by code gen
  • Loading branch information
vchelaru authored Oct 30, 2024
2 parents 60d8d94 + 7eb0ad0 commit 5bcf011
Show file tree
Hide file tree
Showing 56 changed files with 4,836 additions and 76 deletions.
2 changes: 1 addition & 1 deletion CodeOutputPlugin/MainPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ private void HandleRefreshAndExport()

var elementSettings = control.CodeOutputElementSettings;

if (elementSettings.AutoGenerateOnChange)
if (elementSettings.AutoGenerateOnChange && control.CodeOutputProjectSettings.IsCodeGenPluginEnabled)
{
GenerateCodeForSelectedElement(showPopups: false);
}
Expand Down
46 changes: 39 additions & 7 deletions CodeOutputPlugin/Manager/CodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ private static void GenerateInitializeInstancesMethod(CodeGenerationContext cont
else
{
context.StringBuilder.AppendLine(context.Tabs + "base.AfterFullCreation();");

}
}

Expand All @@ -372,6 +373,11 @@ private static void GenerateInitializeInstancesMethod(CodeGenerationContext cont
context.Instance = null;
}

if(!isFullyInstantiatingInCode)
{
context.StringBuilder.AppendLine(context.Tabs + "CustomInitialize();");
}

context.TabCount--;
context.StringBuilder.AppendLine(context.Tabs + "}");
}
Expand Down Expand Up @@ -1993,7 +1999,15 @@ private static void GenerateConstructor(CodeGenerationContext context)
{
#region Constructor Header

stringBuilder.AppendLine(context.Tabs + $"public {elementName}(bool fullInstantiation = true)");
if(context.CodeOutputProjectSettings.OutputLibrary == OutputLibrary.MonoGame)
{
// MonoGame expects 0 or 2-arg constructors. We'll start with 0 for now, and eventually go to 2 if we need Forms support
stringBuilder.AppendLine(context.Tabs + $"public {elementName}()");
}
else
{
stringBuilder.AppendLine(context.Tabs + $"public {elementName}(bool fullInstantiation = true)");
}

stringBuilder.AppendLine(context.Tabs + "{");
context.TabCount++;
Expand Down Expand Up @@ -2074,7 +2088,10 @@ private static void GenerateConstructor(CodeGenerationContext context)

if (!DoesElementInheritFromCodeGeneratedElement(element, projectSettings))
{
stringBuilder.AppendLine(context.Tabs + "InitializeInstances();");
if(context.CodeOutputProjectSettings.ObjectInstantiationType == ObjectInstantiationType.FullyInCode)
{
stringBuilder.AppendLine(context.Tabs + "InitializeInstances();");
}

if (context.CodeOutputProjectSettings.GenerateGumDataTypes)
{
Expand Down Expand Up @@ -2108,9 +2125,10 @@ private static void GenerateConstructor(CodeGenerationContext context)
// call it here, I don't think...
stringBuilder.AppendLine(context.Tabs + "AssignParents();");
}
}

stringBuilder.AppendLine(context.Tabs + "CustomInitialize();");
// If not fully in code, we do this in AfterFullCreation
stringBuilder.AppendLine(context.Tabs + "CustomInitialize();");
}

if (visualApi == VisualApi.Gum)
{
Expand Down Expand Up @@ -2897,10 +2915,24 @@ private static int FillWithStatePropertiesForCategory(ElementSave element, Strin
stringBuilder.AppendLine(ToTabs(tabCount) + "{");
tabCount++;

stringBuilder.AppendLine(ToTabs(tabCount) + $"var category = ((Gum.DataTypes.ElementSave)this.Tag).Categories.FirstOrDefault(item => item.Name == \"{category}\");");
stringBuilder.AppendLine(ToTabs(tabCount) + $"var state = category.States.Find(item => item.Name == \"value.ToString()\");");
stringBuilder.AppendLine(ToTabs(tabCount) + $"this.ApplyState(state);");
stringBuilder.AppendLine(ToTabs(tabCount) + $"if(Categories.ContainsKey(\"{category}\"))");
stringBuilder.AppendLine(ToTabs(tabCount) + "{");
tabCount++;
stringBuilder.AppendLine(ToTabs(tabCount) + $"var category = Categories[\"{category}\"];");
stringBuilder.AppendLine(ToTabs(tabCount) + $"var state = category.States.Find(item => item.Name == value.ToString());");
stringBuilder.AppendLine(ToTabs(tabCount) + $"this.ApplyState(state);");
tabCount--;
stringBuilder.AppendLine(ToTabs(tabCount) + "}");
stringBuilder.AppendLine(ToTabs(tabCount) + $"else");
stringBuilder.AppendLine(ToTabs(tabCount) + "{");
tabCount++;


stringBuilder.AppendLine(ToTabs(tabCount) + $"var category = ((Gum.DataTypes.ElementSave)this.Tag).Categories.FirstOrDefault(item => item.Name == \"{category}\");");
stringBuilder.AppendLine(ToTabs(tabCount) + $"var state = category.States.Find(item => item.Name == value.ToString());");
stringBuilder.AppendLine(ToTabs(tabCount) + $"this.ApplyState(state);");
tabCount--;
stringBuilder.AppendLine(ToTabs(tabCount) + "}");
tabCount--;
stringBuilder.AppendLine(ToTabs(tabCount) + "}");
tabCount--;
Expand Down
2 changes: 2 additions & 0 deletions CodeOutputPlugin/Models/CodeOutputProjectSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public class CodeOutputProjectSettings
using Gum.Wireframe;
using RenderingLibrary.Graphics;
using System.Linq;
";

/// <summary>
Expand Down
7 changes: 6 additions & 1 deletion GumRuntime/ElementSaveExtensions.GumRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -512,13 +512,18 @@ public static void SetGraphicalUiElement(this ElementSave elementSave, Graphical
// We need to set categories and states first since those are used below;
toReturn.SetStatesAndCategoriesRecursively(elementSave);

toReturn.CreateGraphicalComponent(elementSave, systemManagers);
if(toReturn.RenderableComponent == null)
{
// This could have already been created by the type that is instantiated, so don't do this to double-create
toReturn.CreateGraphicalComponent(elementSave, systemManagers);
}

toReturn.AddExposedVariablesRecursively(elementSave);

toReturn.CreateChildrenRecursively(elementSave, systemManagers);

toReturn.Tag = elementSave;
toReturn.ElementSave = elementSave;

toReturn.SetInitialState();

Expand Down
57 changes: 36 additions & 21 deletions GumRuntime/InstanceSaveExtensionMethods.GumRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,32 +30,47 @@ public static GraphicalUiElement ToGraphicalUiElement(this InstanceSave instance
genericType = instanceSave.ParentContainer.DefaultState.GetValueOrDefault<string>(instanceSave.Name + "." + "Contained Type");
}

toReturn = ElementSaveExtensions.CreateGueForElement(instanceElement, true, genericType);
bool byElement = true;
if(byElement)
{

// Feb 7, 2024 - why not set the Name first before calling SetGraphicalUiElement? This would
// help debugging...
toReturn.Name = instanceSave.Name;
toReturn = ElementSaveExtensions.ToGraphicalUiElement(instanceElement, systemManagers,
// don't add to managers, this is going to be added to the owner
addToManagers: false);
toReturn.Name = instanceSave.Name;

// If we get here but there's no contained graphical object then that means we don't
// have a strongly-typed system. Therefore, we'll
// just fall back to the regular creation of graphical objects, like is done in the Gum tool:
if(toReturn.RenderableComponent == null)
{
instanceElement.SetGraphicalUiElement(toReturn, systemManagers);
}
else
{
// Do most of the things that would happen in the SetGraphicalUiElement, but don't actually
// call SetGraphicalUiElement because that would potentially re-create children
toReturn.SetStatesAndCategoriesRecursively(instanceElement);

toReturn.AddExposedVariablesRecursively(instanceElement);

toReturn.Tag = instanceElement;

toReturn.SetInitialState();

toReturn.AfterFullCreation();
// 10/29/2024 - we now do by-element above to unify the code, but keeping this here justin case
// old code, not sure if we need this:
//toReturn = ElementSaveExtensions.CreateGueForElement(instanceElement, true, genericType);

//// Feb 7, 2024 - why not set the Name first before calling SetGraphicalUiElement? This would
//// help debugging...
//toReturn.Name = instanceSave.Name;

//// If we get here but there's no contained graphical object then that means we don't
//// have a strongly-typed system. Therefore, we'll
//// just fall back to the regular creation of graphical objects, like is done in the Gum tool:
//if (toReturn.RenderableComponent == null)
//{
// instanceElement.SetGraphicalUiElement(toReturn, systemManagers);
//}
//else
//{
// // Do most of the things that would happen in the SetGraphicalUiElement, but don't actually
// // call SetGraphicalUiElement because that would potentially re-create children
// toReturn.SetStatesAndCategoriesRecursively(instanceElement);

// toReturn.AddExposedVariablesRecursively(instanceElement);

// toReturn.Tag = instanceElement;

// toReturn.SetInitialState();

// toReturn.AfterFullCreation();
//}
}

toReturn.Tag = instanceSave;
Expand Down
12 changes: 12 additions & 0 deletions Samples/GumFormsSample/GumFormsSampleCommon/GumFormsSampleGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,15 @@ protected override void Initialize()
case 2:
InitializeFormsCustomizationScreen();
break;
case 3:
InitializeComplexListBoxItemScreen();
break;
}

base.Initialize();
}


private void InitializeFromFileDemoScreen()
{
var screen = new FromFileDemoScreen();
Expand All @@ -78,6 +82,14 @@ private void InitializeFrameworkElementExampleScreen()
screen.Initialize(Root);
}


private void InitializeComplexListBoxItemScreen()
{
CreateRoot();
var screen = new ComplexListBoxItemScreen();
screen.Initialize(Root);
}

private void CreateRoot()
{
Root = new ContainerRuntime();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

<ItemGroup>
<Compile Include="CustomRuntimes\CustomListBoxItemRuntime.cs" />
<Compile Include="Screens\ComplexListBoxItemScreen.cs" />
<Compile Include="Screens\FormsCustomizationScreen.cs" />
<Compile Include="Screens\FrameworkElementExampleScreen.cs" />
<Compile Include="FullyCustomizedButton.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
using Gum.DataTypes;
using Gum.Managers;
using Gum.Wireframe;
using GumFormsSample.CustomRuntimes;
using GumRuntime;
using MonoGameGum.Forms;
using MonoGameGum.Forms.Controls;
using MonoGameGum.GueDeriving;
using RenderingLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ToolsUtilities;

namespace GumFormsSample.Screens;

internal class ComplexListBoxItemScreen
{
GraphicalUiElement _root;

public void Initialize(GraphicalUiElement root)
{

root.WidthUnits = Gum.DataTypes.DimensionUnitType.RelativeToContainer;
root.HeightUnits = Gum.DataTypes.DimensionUnitType.RelativeToContainer;
root.Width = 0;
root.Height = 0;

// Load the Gum project to get the ListBoxItem

var gumProject = GumProjectSave.Load("FormsGumProject/GumProject.gumx");
ObjectFinder.Self.GumProjectSave = gumProject;
gumProject.Initialize();
FormsUtilities.RegisterFromFileFormRuntimeDefaults();

FileManager.RelativeDirectory = "Content/FormsGumProject/";

_root = root;

var listBox = new ListBox();
root.Children.Add(listBox.Visual);
listBox.X = 30;
listBox.Y = 30;
listBox.Width = 400;
listBox.Height = 400;

// assign the template before adding new list items
listBox.VisualTemplate =
new MonoGameGum.Forms.VisualTemplate(() =>
// do not create a forms object because this template will be
// automatically added to a ListBoxItem by the ListBox:
new WeaponListBoxItemRuntime(fullInstantiation:true, tryCreateFormsObject: false));

listBox.ListBoxItemFormsType = typeof(WeaponListBoxItem);

for (int i = 0; i < 20; i++)
{
var weaponViewModel = new WeaponViewModel
{
Name = $"Weapon {i}",
Damage = 10 + i,
RemainingDurability = 100 - i,
MaxDurability = 100,
Level = i
};
listBox.Items.Add(weaponViewModel);
}
}
}

class WeaponViewModel
{
public string Name { get; set; }
public int Damage { get; set; }
public int RemainingDurability { get; set; }
public int MaxDurability { get; set; }
public int Level { get; set; }
}


class WeaponListBoxItem : ListBoxItem
{
public WeaponListBoxItem(InteractiveGue gue) : base(gue) { }
public override void UpdateToObject(object o)
{
var weaponViewModel = (WeaponViewModel)o;

var view = this.Visual as WeaponListBoxItemRuntime;

view.NameTextInstance.Text = weaponViewModel.Name;
view.DamageTextInstance.Text = $"Damage: {weaponViewModel.Damage}";
view.DurabilityTextInstance.Text = $"Durability: {weaponViewModel.RemainingDurability}/{weaponViewModel.MaxDurability}";
view.LevelTextInstance.Text = $"Level: {weaponViewModel.Level}";
}
}

public partial class WeaponListBoxItemRuntime : InteractiveGue
{
public NineSliceRuntime Background { get; protected set; }
public TextRuntime NameTextInstance { get; protected set; }
public TextRuntime DamageTextInstance { get; protected set; }
public TextRuntime DurabilityTextInstance { get; protected set; }
public TextRuntime LevelTextInstance { get; protected set; }
public NineSliceRuntime FocusedIndicator { get; protected set; }

public WeaponListBoxItemRuntime(bool fullInstantiation = true, bool tryCreateFormsObject = true)
{
if(fullInstantiation)
{
var element = ObjectFinder.Self.GetComponent("Controls/WeaponListBoxItem");

element.SetGraphicalUiElement(this, SystemManagers.Default);
}

}
public override void AfterFullCreation()
{
Background = this.GetGraphicalUiElementByName("Background") as NineSliceRuntime;
NameTextInstance = this.GetGraphicalUiElementByName("NameTextInstance") as TextRuntime;
DamageTextInstance = this.GetGraphicalUiElementByName("DamageTextInstance") as TextRuntime;
DurabilityTextInstance = this.GetGraphicalUiElementByName("DurabilityTextInstance") as TextRuntime;
LevelTextInstance = this.GetGraphicalUiElementByName("LevelTextInstance") as TextRuntime;
FocusedIndicator = this.GetGraphicalUiElementByName("FocusedIndicator") as NineSliceRuntime;

if(FormsControlAsObject == null)
{
FormsControlAsObject = new WeaponListBoxItem(this);
}
}


}
Loading

0 comments on commit 5bcf011

Please sign in to comment.