Skip to content
Merged
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
5240888
try fix abstract class
Nytra Oct 3, 2025
fb5d280
Don't instantiate abstract
Nytra Oct 3, 2025
9ecb1f5
test this
Nytra Oct 3, 2025
8ae06d0
write files debug
Nytra Oct 3, 2025
2aadf0f
fix
Nytra Oct 3, 2025
0849ad9
fix more
Nytra Oct 3, 2025
aae7613
fix class thing
Nytra Oct 3, 2025
1ba72fb
fix partial
Nytra Oct 3, 2025
6a9ec43
try something else
Nytra Oct 3, 2025
35a35d6
try something else again
Nytra Oct 3, 2025
52f72c6
fix it
Nytra Oct 3, 2025
d9fca70
try
Nytra Oct 3, 2025
0311ea4
try this
Nytra Oct 3, 2025
7e35a58
try
Nytra Oct 3, 2025
0bae167
try
Nytra Oct 3, 2025
745a40d
try
Nytra Oct 3, 2025
6e89d98
try
Nytra Oct 3, 2025
30b8c2d
try
Nytra Oct 3, 2025
968d0f2
try
Nytra Oct 3, 2025
f27b0e1
try
Nytra Oct 3, 2025
7fd26ed
try
Nytra Oct 3, 2025
4a29a5b
try
Nytra Oct 3, 2025
cc8fd0b
try
Nytra Oct 3, 2025
8ba4185
try
Nytra Oct 3, 2025
36a9e46
try
Nytra Oct 3, 2025
2a134bb
try
Nytra Oct 3, 2025
65b1af5
try
Nytra Oct 3, 2025
55d4bf8
cleanup
Nytra Oct 3, 2025
a181977
try
Nytra Oct 4, 2025
4d1c3a8
try
Nytra Oct 4, 2025
cbe5b28
try
Nytra Oct 4, 2025
7c4982f
try
Nytra Oct 4, 2025
e6e8108
try
Nytra Oct 4, 2025
298f18c
try
Nytra Oct 4, 2025
c2498ef
try
Nytra Oct 4, 2025
df8a67f
try
Nytra Oct 4, 2025
d3d3782
try
Nytra Oct 4, 2025
3d6c8d0
try
Nytra Oct 4, 2025
ec872af
try
Nytra Oct 4, 2025
0bb5581
try
Nytra Oct 4, 2025
683b538
try
Nytra Oct 4, 2025
3213371
try
Nytra Oct 4, 2025
e33ac7d
try
Nytra Oct 4, 2025
5143d6c
try
Nytra Oct 4, 2025
9b5cce9
try
Nytra Oct 4, 2025
21f5930
try
Nytra Oct 4, 2025
ddb635e
try
Nytra Oct 4, 2025
8195c00
try
Nytra Oct 4, 2025
07c67fc
try
Nytra Oct 4, 2025
c1db486
try
Nytra Oct 4, 2025
8b21e4e
try
Nytra Oct 4, 2025
9436578
cleanup
Nytra Oct 4, 2025
12dbfdb
cleanup more\
Nytra Oct 4, 2025
97a6c11
fix back compat
Nytra Oct 4, 2025
eb58e81
fix back compat 2
Nytra Oct 4, 2025
bf9841d
abstract classes don't need back compat
Nytra Oct 4, 2025
112eb18
back compat always applies
Nytra Oct 4, 2025
caa0f93
cleanup
Nytra Oct 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 53 additions & 60 deletions ProjectObsidian.SourceGenerators/BindingGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
Expand All @@ -15,6 +16,7 @@ public static string TrimEnds(this string str, int fromStart, int fromEnd) =>
[Generator]
public class BindingGenerator : ISourceGenerator
{
private const bool DEBUG = false;
public void Initialize(GeneratorInitializationContext context)
{
}
Expand All @@ -32,7 +34,11 @@ public void Execute(GeneratorExecutionContext context)
var res = result.ToString();

if (!string.IsNullOrWhiteSpace(res))
{
context.AddSource($"{walker.BaseName}Bindings.g.cs", result.ToString());
if (DEBUG)
File.WriteAllText($"C:\\ObsidianBindingsDebug\\{walker.BaseName}Bindings.g.cs", res);
}
}
}
}
Expand All @@ -54,7 +60,6 @@ public string GetOverride
{
get
{
if (VariableNames.Count == 0) return "";
var str = $@"
protected override {MethodReturnType} {MethodName}(ref int index)
{{
Expand Down Expand Up @@ -88,28 +93,8 @@ public OrderedCount(string countVariableName, string methodName, string methodRe
}
}

public const string BindingPrefix = "FrooxEngine.";
public const string FluxPrefix = "ProtoFlux.Runtimes.Execution.";

//TODO: add more, this is not all of the valid node types
public static readonly string[] ValidNodeTypes =
{
"NestedNode",
"VoidNode",

"ObjectFunctionNode",
"ValueFunctionNode",

"ActionNode",
"ActionFlowNode",
"ActionBreakableFlowNode",

"AsyncActionNode",
"AsyncActionFlowNode",
"AsyncActionBreakableFlowNode",

"ProxyVoidNode"
};
public const string BindingPrefix = "Bindings.";
public const string LegacyBindingPrefix = "FrooxEngine.";

private string UsingEnumerate =>
_usingDeclarations
Expand Down Expand Up @@ -152,42 +137,50 @@ namespace {BindingPrefix}{_currentNameSpace};
{_nodeOverloadAttribute}
{_genericTypesAttribute}
{_oldTypeNameAttribute}
{(!_isAbstract ? $"[OldTypeName(\"{LegacyBindingPrefix + _currentNameSpace + "." + BaseName}\")]" : "")}
[Category(new string[] {{""ProtoFlux/Runtimes/Execution/Nodes/{_category}""}})]
public partial class {_fullName} : global::{_baseTypeNamespace}{_baseType} {_constraints}
public {(_isAbstract ? "abstract" : "")} class {_fullName} : {_baseType} {_constraints}
{{
{(string.IsNullOrEmpty(_debug) ? "" : "//")}{_debug}
{Declarations}
{_nodeNameOverride}
{(_isValidGenericTypeMethod ? $" public static bool IsValidGenericType => global::{_currentNameSpace}.{_fullName}.IsValidGenericType;" : "")}
public override System.Type NodeType => typeof (global::{_currentNameSpace}.{_fullName});
public global::{_currentNameSpace}.{_fullName} TypedNodeInstance {{ get; private set; }}
{($" public global::{_currentNameSpace}.{_fullName}" + " TypedNodeInstance { get; private set; }")}
public override INode NodeInstance => (INode)this.TypedNodeInstance;
public override void ClearInstance() => this.TypedNodeInstance = null;
{CountOverride}
{(!_isAbstract ? """
public override N Instantiate<N>()
{{
if (this.TypedNodeInstance != null) throw new System.InvalidOperationException(""Node has already been instantiated"");
{
if (this.TypedNodeInstance != null) throw new System.InvalidOperationException("Node has already been instantiated");
""" + $"""
var localVar = new global::{_currentNameSpace}.{_fullName}();
this.TypedNodeInstance = localVar;
return localVar as N;
}}
protected override void AssociateInstanceInternal(INode node) => this.TypedNodeInstance = node is global::{_currentNameSpace}.{_fullName} localVar ? localVar : throw new System.ArgumentException(""Node instance is not of type "" + typeof (global::{_currentNameSpace}.{_fullName})?.ToString());
""" + """
}
""" : "")}
{($"""
protected override void AssociateInstanceInternal(INode node) => this.TypedNodeInstance = node is global::{_currentNameSpace}.{_fullName} localVar ? localVar : throw new System.ArgumentException("Node instance is not of type " + typeof (global::{_currentNameSpace}.{_fullName})?.ToString());
""")}
{GetOverride}
}}";
return str;
}
}

private readonly List<string> _usingDeclarations = [""];
private readonly List<string> _usingDeclarations = ["FrooxEngineContext = FrooxEngine.ProtoFlux.FrooxEngineContext",
"INodeOutput = FrooxEngine.ProtoFlux.INodeOutput",
"INodeOperation = FrooxEngine.ProtoFlux.INodeOperation",
"ExecutionContext = ProtoFlux.Runtimes.Execution.ExecutionContext",
"FrooxEngine",
"Elements.Data"];
private bool _valid;
private string _currentNameSpace;
private string _fullName;
private string _additionalName = "";
public string BaseName;
private string _baseType;
private string _baseTypeNamespace = "FrooxEngine.ProtoFlux.Runtimes.Execution.";
private string _fullBaseType;
private string _match;
private string _category;
private string _nodeNameOverride = "";
private string _debug = "";
Expand All @@ -196,6 +189,7 @@ public override N Instantiate<N>()
private string _genericTypesAttribute;
private string _oldTypeNameAttribute;
private string _nodeOverloadAttribute;
private bool _isAbstract;

private bool TypedFieldDetection(string type, string name, string targetTypeName, string declarationFormat, OrderedCount counter)
{
Expand Down Expand Up @@ -275,7 +269,16 @@ public override void VisitFileScopedNamespaceDeclaration(FileScopedNamespaceDecl

public override void VisitUsingDirective(UsingDirectiveSyntax node)
{
if (node.Name is not null) _usingDeclarations.Add(node.Name.ToString());
if (node.Name is not null)
{
var usingName = node.Name.ToString();
if (usingName == "FrooxEngine.ProtoFlux")
usingName = "FrooxEngine.FrooxEngine.ProtoFlux";
if (usingName == "ProtoFlux.Runtimes.Execution")
usingName = "FrooxEngine." + usingName;

_usingDeclarations.Add(usingName);
}
base.VisitUsingDirective(node);
}
public override void VisitClassDeclaration(ClassDeclarationSyntax node)
Expand All @@ -286,8 +289,13 @@ public override void VisitClassDeclaration(ClassDeclarationSyntax node)
return;
}

var baseName = node.Identifier.Text;
var fullName = baseName;
if (node.Modifiers.Any(m => m.ToString() == "abstract"))
{
_isAbstract = true;
}

BaseName = node.Identifier.Text;
var fullName = BaseName;

if (node.TypeParameterList is not null)
{
Expand All @@ -300,7 +308,6 @@ public override void VisitClassDeclaration(ClassDeclarationSyntax node)
fullName += _additionalName;
}

BaseName = baseName;
_fullName = fullName;

if (node.ConstraintClauses.Any())
Expand All @@ -312,10 +319,6 @@ public override void VisitClassDeclaration(ClassDeclarationSyntax node)
var baseTypeName = firstBaseType.Type.ToString();

_baseType = baseTypeName;
if (baseTypeName.Contains("ProxyVoidNode"))
{
_baseTypeNamespace = "FrooxEngine.FrooxEngine.ProtoFlux.";
}

if (node.AttributeLists.Any()) // if has any attributes
{
Expand All @@ -326,6 +329,7 @@ public override void VisitClassDeclaration(ClassDeclarationSyntax node)
if (nodeCategoryAttr?.ArgumentList is not null)
{
_category = nodeCategoryAttr.ArgumentList.Arguments.First().ToString().TrimEnds(1, 1);
_valid = true; // If it has the NodeCategory attribute it MUST be a node
}

// generic types
Expand All @@ -339,33 +343,22 @@ public override void VisitClassDeclaration(ClassDeclarationSyntax node)
.FirstOrDefault(i => i.Name.ToString() == "NodeName");

if (findName?.ArgumentList != null)
{
_nodeNameOverride =
$" public override string NodeName => {findName.ArgumentList.Arguments.First().ToString()};";
_valid = true;
}


// overload
var findOverload = node.AttributeLists.SelectMany(i => i.Attributes)
.FirstOrDefault(i => i.Name.ToString() == "NodeOverload");

if (findOverload?.ArgumentList != null)
{
_nodeOverloadAttribute = $"[Grouping({findOverload.ArgumentList.Arguments.First().ToString()})]";
}

foreach (var u in _usingDeclarations)
{
var fullNameSpace = "";
if (string.IsNullOrEmpty(u))
fullNameSpace = baseTypeName;
else
fullNameSpace = u + "." + baseTypeName;

var match = ValidNodeTypes.FirstOrDefault(i => fullNameSpace.StartsWith(FluxPrefix + i));

if (match is null) continue;

_match = match;
_fullBaseType = fullNameSpace;
_valid = true;
break;
_valid = true;
}
}

base.VisitClassDeclaration(node);
Expand Down