Skip to content

Commit

Permalink
🎨 Clean up BehaviourManifest data structures and API
Browse files Browse the repository at this point in the history
  • Loading branch information
Fydar committed Mar 8, 2020
1 parent 848dd3c commit a3c57eb
Show file tree
Hide file tree
Showing 32 changed files with 163 additions and 328 deletions.
22 changes: 3 additions & 19 deletions src/RPGCore.Behaviour.UnitTests/Editor/EditorSessionShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace RPGCore.Behaviour.Editor.UnitTests
[TestFixture(TestOf = typeof(EditorSession))]
public class EditorSessionShould
{
[EditorType]
public class RootModel
{
public string FirstValue;
Expand All @@ -18,6 +19,7 @@ public class RootModel
public Dictionary<string, ChildModel> MoreChildren;
}

[EditorType]
public class ChildModel
{
public int ChildFirstValue;
Expand All @@ -27,25 +29,7 @@ public class ChildModel
[Test, Parallelizable]
public void Work()
{
var types = TypeManifest.Construct(
new Type[]
{
typeof(int),
typeof(bool),
typeof(string),
},
new Type[]
{
typeof(RootModel),
typeof(ChildModel)
}
);

var manifest = new BehaviourManifest()
{
Nodes = null,
Types = types
};
var manifest = BehaviourManifest.CreateFromAppDomain(AppDomain.CurrentDomain);

var sourceObject = new RootModel()
{
Expand Down
4 changes: 3 additions & 1 deletion src/RPGCore.Behaviour/Core/Connections/InputSocket.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System.Diagnostics;
using RPGCore.Behaviour.Manifest;
using System.Diagnostics;

namespace RPGCore.Behaviour
{
[EditorType]
public readonly struct InputSocket
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
Expand Down
2 changes: 2 additions & 0 deletions src/RPGCore.Behaviour/Core/LocalId.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using Newtonsoft.Json;
using RPGCore.Behaviour.Manifest;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;

namespace RPGCore.Behaviour
{
[EditorType]
[TypeConverter(typeof(LocalIdConverter))]
[DebuggerDisplay("{ToString(),nq}")]
public readonly struct LocalId : IEquatable<LocalId>
Expand Down
2 changes: 2 additions & 0 deletions src/RPGCore.Behaviour/Core/SerializedGraph.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using RPGCore.Behaviour.Manifest;
using System;
using System.Collections.Generic;
using System.Reflection;

namespace RPGCore.Behaviour
{
[EditorType]
public class SerializedGraph
{
public Dictionary<LocalId, SerializedNode> Nodes;
Expand Down
2 changes: 2 additions & 0 deletions src/RPGCore.Behaviour/Core/SerializedNode.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RPGCore.Behaviour.Manifest;
using System;
using System.Collections.Generic;
using System.Reflection;

namespace RPGCore.Behaviour
{
[EditorType]
public sealed class SerializedNode
{
public string Type;
Expand Down
124 changes: 105 additions & 19 deletions src/RPGCore.Behaviour/Manifest/BehaviourManifest.cs
Original file line number Diff line number Diff line change
@@ -1,52 +1,138 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace RPGCore.Behaviour.Manifest
{
public sealed class BehaviourManifest
{
static readonly Type[] frameworkTypes = new[]
{
typeof(bool),
typeof(string),
typeof(int),
typeof(byte),
typeof(long),
typeof(short),
typeof(uint),
typeof(ulong),
typeof(ushort),
typeof(sbyte),
typeof(char),
typeof(float),
typeof(double),
typeof(decimal),
};

public TypeManifest Types;
public NodeManifest Nodes;

public override string ToString()
private static IEnumerable<Assembly> GetDependentAssemblies(AppDomain appDomain, Assembly analyzedAssembly)
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
return appDomain.GetAssemblies()
.Where(assembly => GetNamesOfAssembliesReferencedBy(assembly)
.Contains(analyzedAssembly.FullName));
}

public TypeInformation GetTypeInformation(string type)
public static IEnumerable<string> GetNamesOfAssembliesReferencedBy(Assembly assembly)
{
if (string.IsNullOrEmpty(type))
return assembly.GetReferencedAssemblies()
.Select(assemblyName => assemblyName.FullName);
}

public static BehaviourManifest CreateFromAppDomain(AppDomain appDomain)
{
var manifest = new BehaviourManifest();

var objectTypes = new Dictionary<string, TypeInformation>();
foreach (var type in frameworkTypes)
{
return null;
objectTypes.Add(type.Name, TypeInformation.Construct(type));
}

string lookupType;
int arrayIndex = type.LastIndexOf('[');
if (arrayIndex == -1)
var nodeTypes = new Dictionary<string, NodeInformation>();
foreach (var assembly in GetDependentAssemblies(appDomain, typeof(NodeTemplate).Assembly))
{
lookupType = type;
Type[] types;
try
{
types = assembly.GetTypes();
}
catch
{
continue;
}

foreach (var type in types)
{
ConstructType(type, objectTypes);

if (type.IsAbstract)
{
continue;
}

if (typeof(NodeTemplate).IsAssignableFrom(type))
{
nodeTypes.Add(type.Name, NodeInformation.Construct(type));
}
}
}
else

manifest.Types = new TypeManifest()
{
lookupType = type.Substring(0, arrayIndex);
}
ObjectTypes = objectTypes,
NodeTypes = nodeTypes,
};

if (Types.JsonTypes != null)
return manifest;
}

static void ConstructType(Type type, Dictionary<string, TypeInformation> objectTypes)
{
if (!type.IsAbstract)
{
if (Types.JsonTypes.TryGetValue(lookupType, out var jsonType))
var typeAttributes = type.GetCustomAttribute(typeof(EditorTypeAttribute));
if (typeAttributes != null)
{
return jsonType;
objectTypes.Add(type.Name, TypeInformation.Construct(type));
}
}
if (Types?.ObjectTypes != null)
}

private BehaviourManifest()
{
}

public override string ToString()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}

public TypeInformation GetTypeInformation(string type)
{
if (Types == null
|| string.IsNullOrEmpty(type))
{
return null;
}

int arrayIndex = type.LastIndexOf('[');
string lookupType = arrayIndex == -1
? type
: type.Substring(0, arrayIndex);

if (Types.ObjectTypes != null)
{
if (Types.ObjectTypes.TryGetValue(lookupType, out var objectType))
{
return objectType;
}
}
if (Nodes?.Nodes != null)
if (Types.NodeTypes != null)
{
if (Nodes.Nodes.TryGetValue(lookupType, out var nodeType))
if (Types.NodeTypes.TryGetValue(lookupType, out var nodeType))
{
return nodeType;
}
Expand Down
13 changes: 13 additions & 0 deletions src/RPGCore.Behaviour/Manifest/EditorTypeAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;

namespace RPGCore.Behaviour.Manifest
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false)]
public class EditorTypeAttribute : Attribute
{
public EditorTypeAttribute()
{

}
}
}
2 changes: 1 addition & 1 deletion src/RPGCore.Behaviour/Manifest/NodeInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public sealed class NodeInformation : TypeInformation
public Dictionary<string, SocketInformation> Inputs;
public Dictionary<string, SocketInformation> Outputs;

public static NodeInformation ConstructNodeInformation(Type nodeType)
public static NodeInformation Construct(Type nodeType)
{
var nodeInformation = new NodeInformation();

Expand Down
4 changes: 2 additions & 2 deletions src/RPGCore.Behaviour/Manifest/NodeManifest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static NodeManifest Construct()

if (typeof(NodeTemplate).IsAssignableFrom(type))
{
information.Add(type.FullName, NodeInformation.ConstructNodeInformation(type));
information.Add(type.FullName, NodeInformation.Construct(type));
}
}
}
Expand All @@ -41,7 +41,7 @@ public static NodeManifest Construct(Type[] types)
var information = new Dictionary<string, NodeInformation>();
foreach (var type in types)
{
information.Add(type.FullName, NodeInformation.ConstructNodeInformation(type));
information.Add(type.FullName, NodeInformation.Construct(type));
}
manifest.Nodes = information;
return manifest;
Expand Down
6 changes: 3 additions & 3 deletions src/RPGCore.Behaviour/Manifest/TypeInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ public class TypeInformation
public Dictionary<string, FieldInformation> Fields;
public JToken DefaultValue;

public static TypeInformation Construct(Type type)
internal static TypeInformation Construct(Type type)
{
var information = new TypeInformation();
ConstructTypeInformation(type, information);
PopulateTypeInformation(type, information);
return information;
}

protected static void ConstructTypeInformation(Type type, TypeInformation typeInformation)
protected static void PopulateTypeInformation(Type type, TypeInformation typeInformation)
{
// Implicit Conversions
var conversions = new Dictionary<string, TypeConversion>();
Expand Down
55 changes: 2 additions & 53 deletions src/RPGCore.Behaviour/Manifest/TypeManifest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,62 +6,11 @@ namespace RPGCore.Behaviour.Manifest
{
public sealed class TypeManifest
{
public string Name;
public string Version;
public Dictionary<string, TypeInformation> JsonTypes;
public Dictionary<string, TypeInformation> ObjectTypes;
public Dictionary<string, NodeInformation> NodeTypes;

public static TypeManifest Construct(Type[] valueTypes, Type[] objectTypes)
internal TypeManifest()
{
var manifest = new TypeManifest();

var valueTypeInformation = new Dictionary<string, TypeInformation>();
foreach (var type in valueTypes)
{
valueTypeInformation.Add(type.Name, TypeInformation.Construct(type));
}
manifest.JsonTypes = valueTypeInformation;

var objectTypeInformation = new Dictionary<string, TypeInformation>();
foreach (var type in objectTypes)
{
objectTypeInformation.Add(type.Name, TypeInformation.Construct(type));
}
manifest.ObjectTypes = objectTypeInformation;

return manifest;
}

public static TypeManifest ConstructBaseTypes()
{
return Construct(
new Type[]
{
typeof(bool),
typeof(string),
typeof(int),
typeof(byte),
typeof(long),
typeof(short),
typeof(uint),
typeof(ulong),
typeof(ushort),
typeof(sbyte),
typeof(char),
typeof(float),
typeof(double),
typeof(decimal),
typeof(InputSocket),
typeof(LocalId),
},
new Type[]
{
typeof(SerializedGraph),
typeof(SerializedNode),
typeof(PackageNodeEditor),
typeof(PackageNodePosition),
}
);
}

public override string ToString()
Expand Down
3 changes: 3 additions & 0 deletions src/RPGCore.Behaviour/PackageNodeEditor.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using RPGCore.Behaviour.Manifest;

namespace RPGCore.Behaviour
{
[EditorType]
public struct PackageNodeEditor
{
public PackageNodePosition Position;
Expand Down
3 changes: 3 additions & 0 deletions src/RPGCore.Behaviour/PackageNodePosition.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using RPGCore.Behaviour.Manifest;

namespace RPGCore.Behaviour
{
[EditorType]
public struct PackageNodePosition
{
public int x;
Expand Down
Loading

0 comments on commit a3c57eb

Please sign in to comment.