Skip to content

Commit

Permalink
Include topi.dll directly and remove Topiary.CSharp project
Browse files Browse the repository at this point in the history
  • Loading branch information
bgk- committed Jul 10, 2024
1 parent 9c6d4d1 commit cf53b32
Show file tree
Hide file tree
Showing 40 changed files with 1,361 additions and 325 deletions.
3 changes: 2 additions & 1 deletion Editor/AddressablesSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ namespace PeartreeGames.Topiary.Unity.Editor
{
public static class AddressablesSetup
{
[MenuItem("Assets/Setup Addressables for EvtTopiVariables")]
[MenuItem("Tools/Evt/Setup Addressables for EvtTopiVariables")]
public static void SetupEvtTopiValuesInAddressables()
{
SetupEvtTopiVariable<EvtTopiBool, bool>();
SetupEvtTopiVariable<EvtTopiInt, int>();
SetupEvtTopiVariable<EvtTopiFloat, float>();
SetupEvtTopiVariable<EvtTopiString, string>();
SetupEvtTopiVariable<EvtTopiEnum, string>();
}

private static void SetupEvtTopiVariable<T, TU>() where T : EvtTopiVariable<TU>
Expand Down
31 changes: 17 additions & 14 deletions Editor/ByteDataEditor.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;

namespace PeartreeGames.Topiary.Unity.Editor
Expand All @@ -11,31 +11,34 @@ public class ByteDataEditor : UnityEditor.Editor
{
private ByteData _byteData;
private SerializedProperty _externsProperty;
private string text;

private void OnEnable()
{
_byteData = (ByteData) target;
_externsProperty = serializedObject.FindProperty("externs");
using var streamReader = new StreamReader(AssetDatabase.GetAssetPath(target), Encoding.UTF8);
text = streamReader.ReadToEnd();
}

public override VisualElement CreateInspectorGUI()
{
var elem = new VisualElement();

var d = _byteData.bytes;
elem.Add(new Label($"Compiled: {d.Length:N0} bytes\n"));

var externsField = new PropertyField(_externsProperty);
externsField.SetEnabled(false);
elem.Add(externsField);
var d = _byteData.bytes;
elem.Add(new Label($"Compiled {d.Length}\n"));
var text = BitConverter.ToString(d)[..Mathf.Min(d.Length + 1, 4001)];
if (d.Length > 4001) text += "...";
var dataLabel = new Label(text)
{
style =
{
whiteSpace = WhiteSpace.Normal
}
};
elem.Add(dataLabel);

var textField = new TextField
{
isReadOnly = true,
value = text
};
elem.Add(textField);

return elem;
}
}
Expand Down
8 changes: 8 additions & 0 deletions Editor/EvtTopiVariableEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ public override VisualElement CreateInspectorGUI()
addEntry?.SetAddress(newName);
});
elem.Add(field);
if (target is EvtTopiEnum)
{
var enumProp = serializedObject.FindProperty("topiEnum");
var enumField = new PropertyField(enumProp);
elem.Add(enumField);
elem.Remove(elem.Q<PropertyField>("value"));
}
elem.Insert(0, new Button(AddressablesSetup.SetupEvtTopiValuesInAddressables){ text = "Set Addressables" });
return elem;
}
}
Expand Down
48 changes: 48 additions & 0 deletions Editor/TopiEnumReferenceDrawer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;

namespace PeartreeGames.Topiary.Unity.Editor
{
[CustomPropertyDrawer(typeof(TopiEnumReference))]
public class TopiEnumReferenceDrawer : PropertyDrawer
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var enumObjectProperty = property.FindPropertyRelative("enumObject");
var enumValueProperty = property.FindPropertyRelative("enumValue");

var enumObjField = new PropertyField(enumObjectProperty);
var dropdownField = new PopupField<string>("Value", new List<string>(), 0);

enumObjField.RegisterCallback<ChangeEvent<Object>>(evt =>
{
var enumObject = enumObjectProperty.objectReferenceValue as TopiEnumObject;
if (enumObject == null) return;

dropdownField.choices.Clear();
dropdownField.choices.AddRange(enumObject.Values);
dropdownField.value = enumValueProperty.stringValue;
});

dropdownField.RegisterCallback<ChangeEvent<string>>(evt =>
{
enumValueProperty.stringValue = evt.newValue;
property.serializedObject.ApplyModifiedProperties();

if (enumValueProperty.serializedObject.targetObject is { } targetObject)
{
EditorUtility.SetDirty(targetObject);
}
});

var elem = new VisualElement();
elem.Add(enumObjField);
elem.Add(dropdownField);

return elem;
}
}
}
3 changes: 3 additions & 0 deletions Editor/TopiEnumReferenceDrawer.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 32 additions & 22 deletions Editor/TopiScriptedImporter.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AssetImporters;
using UnityEngine;
using Object = UnityEngine.Object;

namespace PeartreeGames.Topiary.Unity.Editor
{
Expand All @@ -15,38 +17,48 @@ public override void OnImportAsset(AssetImportContext ctx)
{
using var streamReader = new StreamReader(ctx.assetPath, Encoding.UTF8);
var text = streamReader.ReadToEnd();
var asset = new TextAsset(text);
var fileName = Path.GetFileName(ctx.assetPath);
var icon = Resources.Load<Texture2D>("topi");
var byteIcon = Resources.Load<Texture2D>("byte");
if (string.IsNullOrEmpty(text))
{
ctx.AddObjectToAsset("main", asset, icon);
ctx.SetMainObject(asset);
var empty = new TextAsset(text);
ctx.AddObjectToAsset("main", empty, icon);
ctx.SetMainObject(empty);
return;
}

var log = Logger(ctx);
Object asset;
try
{
Library.setDebugLog(Marshal.GetFunctionPointerForDelegate(log));
var absPath = Application.dataPath + ctx.assetPath[6..];
var compiled = Dialogue.Compile(absPath, log);
var size = Library.calculateCompileSize(absPath, absPath.Length);
var output = new byte[size];
_ = Library.compile(absPath, absPath.Length, output, size);

using var memStream = new MemoryStream(compiled);
using var memStream = new MemoryStream(output);
using var reader = new BinaryReader(memStream);
var boughs = ByteCode.GetBoughs(reader);
if (boughs.Length == 0) return;

var boughs = ByteData.GetBoughs(reader);
if (boughs.Length == 0)
{
var empty = new TextAsset(text);
ctx.AddObjectToAsset("main", empty, icon);
ctx.SetMainObject(empty);
return;
}

// var boughs = ByteCode
var identifier = $"{fileName}.byte";
var compiledAsset = ScriptableObject.CreateInstance<ByteData>();
compiledAsset.name = identifier;
compiledAsset.bytes = compiled;
asset = ScriptableObject.CreateInstance<ByteData>();
asset.name = identifier;
((ByteData)asset).bytes = output;

reader.BaseStream.Position = 0;
compiledAsset.ExternsSet = ByteCode.GetExterns(reader);
ctx.AddObjectToAsset(identifier, compiledAsset, byteIcon);

((ByteData)asset).ExternsSet = ByteData.GetExterns(reader);
ctx.AddObjectToAsset("main", asset, byteIcon);
ctx.SetMainObject(asset);

var guid = AssetDatabase.GUIDFromAssetPath(ctx.assetPath);
var settings = AddressableAssetSettingsDefaultObject.Settings;
settings.AddLabel("Topiary");
Expand All @@ -56,6 +68,7 @@ public override void OnImportAsset(AssetImportContext ctx)
false, settings.DefaultGroup.Schemas);
var entry = settings.FindAssetEntry(guid.ToString());
if (entry != null && entry.parentGroup == group) return;

var addressable = settings.CreateOrMoveEntry(guid.ToString(), group);
addressable.address = fileName;
addressable.SetLabel("Topiary", true);
Expand All @@ -64,21 +77,18 @@ public override void OnImportAsset(AssetImportContext ctx)
}
catch (EndOfStreamException)
{
asset = new TextAsset(text);
icon = Resources.Load<Texture2D>("error");
ctx.AddObjectToAsset("main", asset, icon);
ctx.SetMainObject(asset);
}
catch (Exception e)
{
Debug.LogError(e);
}
finally
{
ctx.AddObjectToAsset("main", asset, icon);
ctx.SetMainObject(asset);
}

}

private static Delegates.OutputLogDelegate Logger(AssetImportContext ctx) =>
private static Library.OutputLogDelegate Logger(AssetImportContext ctx) =>
(intPtr, severity) =>
{
var msg = Library.PtrToUtf8String(intPtr);
Expand Down
8 changes: 8 additions & 0 deletions Plugins.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added Plugins/libtopi.dylib
Binary file not shown.
2 changes: 2 additions & 0 deletions Plugins/libtopi.dylib.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added Plugins/topi.lib
Binary file not shown.
2 changes: 2 additions & 0 deletions Plugins/topi.lib.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added Plugins/topi.pdb
Binary file not shown.
2 changes: 1 addition & 1 deletion Topiary.CSharp.pdb.meta → Plugins/topi.pdb.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Plugins/x86_64.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added Plugins/x86_64/topi.dll
Binary file not shown.
2 changes: 2 additions & 0 deletions Plugins/x86_64/topi.dll.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 53 additions & 0 deletions Runtime/ByteData.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using UnityEngine;

namespace PeartreeGames.Topiary.Unity
Expand All @@ -25,5 +28,55 @@ public class ByteData : ScriptableObject, ISerializationCallbackReceiver
public void OnBeforeSerialize() => externs = ExternsSet?.ToArray();

public void OnAfterDeserialize() => ExternsSet = new SortedSet<string>(externs);

/// <summary>
/// Retrieves a sorted set of external names from the given binary reader.
/// </summary>
/// <param name="reader">The binary reader from which to read the external names.</param>
/// <returns>A sorted set of external names.</returns>
public static SortedSet<string> GetExterns(BinaryReader reader)
{
var globalSymbolsCount = reader.ReadUInt64();
var result = new SortedSet<string>();
var indexSize = Marshal.SizeOf<uint>();
for (ulong i = 0; i < globalSymbolsCount; i++)
{
var nameLength = reader.ReadByte();
var name = Encoding.UTF8.GetString(reader.ReadBytes(nameLength));
reader.ReadBytes(indexSize); // skip globals index
var isExtern = reader.ReadByte() == 1;
_ = reader.ReadByte() == 1; // mutable
if (isExtern) result.Add(name);
}

return result;
}

public static string[] GetBoughs(BinaryReader reader)
{
var globalSymbolsCount = reader.ReadUInt64();
var indexSize = Marshal.SizeOf<uint>();

for (ulong i = 0; i < globalSymbolsCount; i++)
{
var nameLength = reader.ReadByte();
reader.ReadBytes(nameLength); // skip name
reader.ReadBytes(indexSize); // skip globals index
reader.ReadByte();
reader.ReadByte(); // mutable
}

var boughCount = reader.ReadUInt64();
var result = new string[boughCount];
for (ulong i = 0; i < boughCount; i++)
{
var nameLength = reader.ReadByte();
var name = Encoding.UTF8.GetString(reader.ReadBytes(nameLength));
reader.ReadBytes(indexSize); // skip index
result[i] = name;
}

return result;
}
}
}
Loading

0 comments on commit cf53b32

Please sign in to comment.