Skip to content

Commit

Permalink
Merge pull request #45 from Xlinka/frozenreflex
Browse files Browse the repository at this point in the history
Refactor Json Nodes
  • Loading branch information
Xlinka authored Jul 14, 2024
2 parents 54fc756 + c3d7cc3 commit 5e16be2
Show file tree
Hide file tree
Showing 34 changed files with 790 additions and 451 deletions.
19 changes: 17 additions & 2 deletions ProjectObsidian.SourceGenerators/BindingGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,12 @@ public string Result
namespace {BindingPrefix}{_currentNameSpace};
[Category(new string[] {{""ProtoFlux/Runtimes/Execution/Nodes/{_category}""}})]
public partial class {_fullName} : global::FrooxEngine.ProtoFlux.Runtimes.Execution.{_baseType}
public partial class {_fullName} : global::FrooxEngine.ProtoFlux.Runtimes.Execution.{_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 override INode NodeInstance => (INode)this.TypedNodeInstance;
Expand Down Expand Up @@ -181,6 +183,9 @@ public override N Instantiate<N>()
private string _match;
private string _category;
private string _nodeNameOverride = "";
private string _debug = "";
private bool _isValidGenericTypeMethod;
private string _constraints = "";

private bool TypedFieldDetection(string type, string name, string targetTypeName, string declarationFormat, OrderedCount counter)
{
Expand Down Expand Up @@ -237,7 +242,12 @@ public override void VisitFieldDeclaration(FieldDeclarationSyntax node)

base.VisitFieldDeclaration(node);
}

public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node)
{
if (node.Identifier.ValueText.Contains("IsValidGenericType")) _isValidGenericTypeMethod = true;
base.VisitPropertyDeclaration(node);

}
public override void VisitNamespaceDeclaration(NamespaceDeclarationSyntax node)
{
_currentNameSpace = node.Name.ToString();
Expand Down Expand Up @@ -279,6 +289,11 @@ public override void VisitClassDeclaration(ClassDeclarationSyntax node)

BaseName = baseName;
_fullName = fullName;

if (node.ConstraintClauses.Any())
{
_constraints = node.ConstraintClauses.ToString();
}

var firstBaseType = node.BaseList.Types.First();
var baseTypeName = firstBaseType.Type.ToString();
Expand Down
259 changes: 259 additions & 0 deletions ProjectObsidian/Elements/JsonTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
using System;
using System.Linq;
using Elements.Core;
using Newtonsoft.Json.Linq;

namespace Obsidian.Elements;

public static class JsonTypeHelper
{
public static readonly Type[] JsonTokens =
{
typeof(IJsonToken), typeof(JsonObject), typeof(JsonArray),
};
public static readonly Type[] AllValidTypes =
{
typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint),
typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(string), typeof(Uri),
typeof(IJsonToken), typeof(JsonObject), typeof(JsonArray),
};
public static readonly Type[] AllValidGetTypes =
{
typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint),
typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(string), typeof(Uri),
typeof(JsonObject), typeof(JsonArray),
};
public static readonly Type[] ValidValueTypes =
{
typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint),
typeof(long), typeof(ulong), typeof(float), typeof(double)
};
public static readonly Type[] ValidObjectGetTypes =
{
typeof(string), typeof(Uri), typeof(JsonObject), typeof(JsonArray),
};
public static readonly Type[] ValidObjectSetTypes =
{
typeof(string), typeof(Uri), typeof(IJsonToken), typeof(JsonObject), typeof(JsonArray),
};
}

[DataModelType]
public interface IJsonToken
{
public JToken Wrapped { get; }
}
[DataModelType]
public class JsonObject : IJsonToken
{
public JObject WrappedObject { get; private set; }
public JToken Wrapped => WrappedObject;
public JsonObject(JObject wrap) => WrappedObject = wrap;
public int Count => WrappedObject.Count;
public override string ToString() => WrappedObject.ToString();
public static JsonObject FromString(string str)
{
try
{
return new JsonObject(JObject.Parse(str));
}
catch
{
return null;
}
}
public T Get<T>(string tag)
{
try
{
//TODO: theres probably a better way to do this than boxing the value
if (typeof(T) == typeof(JsonObject)) return (T)(object)new JsonObject(WrappedObject[tag].Value<JObject>());
if (typeof(T) == typeof(JsonArray)) return (T)(object)new JsonArray(WrappedObject[tag].Value<JArray>());
return WrappedObject[tag].Value<T>() ?? default;
}
catch
{
return default;
}
}
public T GetValue<T>(string tag) where T : unmanaged
{
try
{
return WrappedObject[tag]?.Value<T>() ?? default;
}
catch
{
return default;
}
}
public T GetObject<T>(string tag) where T : class
{
try
{
if (typeof(T) == typeof(JsonObject))
{
var value = WrappedObject[tag]?.Value<JObject>();
if (value is null) return null;
return new JsonObject(value) as T;
}
if (typeof(T) == typeof(JsonArray))
{
var value = WrappedObject[tag]?.Value<JArray>();
if (value is null) return null;
return new JsonArray(value) as T;
}
return WrappedObject[tag]?.Value<T>();
}
catch
{
return null;
}
}
public JsonObject Add<T>(string tag, T value)
{
var cloned = (JObject)WrappedObject.DeepClone();
var token = value is IJsonToken jToken ? jToken.Wrapped.DeepClone() : new JValue(value);
cloned.Add(tag, token);
var output = new JsonObject(cloned);
return output;
}
public JsonObject Remove(string tag)
{
try
{
if (!WrappedObject.ContainsKey(tag)) return this;
var output = (JObject)WrappedObject.DeepClone();
output.Remove(tag);
return new JsonObject(output);
}
catch
{
return null;
}
}
}

[DataModelType]
public class JsonArray : IJsonToken
{
public JArray WrappedObject { get; private set; }
public JToken Wrapped => WrappedObject;

public JsonArray(JArray wrap) => WrappedObject = wrap;

public int Count => WrappedObject.Count;
public override string ToString() => WrappedObject.ToString();
public static JsonArray FromString(string str)
{
try
{
return new JsonArray(JArray.Parse(str));
}
catch
{
return null;
}
}
public T Get<T>(int index)
{
try
{
if (typeof(T) == typeof(JsonObject)) return (T)(object)new JsonObject(WrappedObject[index].Value<JObject>());
if (typeof(T) == typeof(JsonArray)) return (T)(object)new JsonArray(WrappedObject[index].Value<JArray>());
return WrappedObject[index].Value<T>() ?? default;
}
catch
{
return default;
}
}
public T GetValue<T>(int index) where T : unmanaged
{
try
{
return WrappedObject[index].Value<T>();
}
catch
{
return default;
}
}
public T GetObject<T>(int index) where T : class
{
try
{
if (typeof(T) == typeof(JsonObject))
{
var value = WrappedObject[index].Value<JObject>();
if (value is null) return null;
return new JsonObject(value) as T;
}
if (typeof(T) == typeof(JsonArray))
{
var value = WrappedObject[index].Value<JArray>();
if (value is null) return null;
return new JsonArray(value) as T;
}
return WrappedObject[index].Value<T>();
}
catch
{
return null;
}
}
public JsonArray Insert<T>(int index, T value)
{
try
{
var cloned = (JArray)WrappedObject.DeepClone();
var token = value switch
{
null => JValue.CreateNull(),
IJsonToken jToken => jToken.Wrapped.DeepClone(),
_ => new JValue(value),
};
cloned.Insert(index, token);
var output = new JsonArray(cloned);
return output;
}
catch
{
return null;
}
}
public JsonArray Append<T>(T value)
{
try
{
var cloned = (JArray)WrappedObject.DeepClone();
var token = value switch
{
null => JValue.CreateNull(),
IJsonToken jToken => jToken.Wrapped.DeepClone(),
_ => new JValue(value),
};
cloned.Add(token);
var output = new JsonArray(cloned);
return output;
}
catch
{
return null;
}
}
public JsonArray Remove(int index)
{
try
{
if (index < 0 || index >= Count) return this;
var output = (JArray)WrappedObject.DeepClone();
output.RemoveAt(index);
return new JsonArray(output);
}
catch
{
return null;
}
}
}
34 changes: 34 additions & 0 deletions ProjectObsidian/ProtoFlux/JSON/JsonAddObjectToObjectNode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Linq;
using Newtonsoft.Json.Linq;
using ProtoFlux.Core;
using ProtoFlux.Runtimes.Execution;
using Elements.Core;
using FrooxEngine;
using FrooxEngine.ProtoFlux;
using Obsidian.Elements;

namespace ProtoFlux.Runtimes.Execution.Nodes.Obsidian.Json;

[NodeName("Add To Object")]
[NodeCategory("Obsidian/Json")]
[GenericTypes(typeof(string), typeof(Uri), typeof(IJsonToken), typeof(JsonObject), typeof(JsonArray))]
public class JsonAddObjectToObjectNode<T> : ObjectFunctionNode<FrooxEngineContext, JsonObject> where T : class
{
public readonly ObjectInput<JsonObject> Input;
public readonly ObjectInput<string> Tag;
public readonly ObjectInput<T> Object;

public static bool IsValidGenericType => JsonTypeHelper.ValidObjectSetTypes.Contains(typeof(T));

protected override JsonObject Compute(FrooxEngineContext context)
{
var input = Input.Evaluate(context);
if (input == null) return null;

var tag = Tag.Evaluate(context);
var obj = Object.Evaluate(context);

return string.IsNullOrEmpty(tag) ? input : input.Add(tag, obj);
}
}
42 changes: 0 additions & 42 deletions ProjectObsidian/ProtoFlux/JSON/JsonAddToObject.cs

This file was deleted.

Loading

0 comments on commit 5e16be2

Please sign in to comment.