Skip to content

Commit

Permalink
Refactor subscribers
Browse files Browse the repository at this point in the history
  • Loading branch information
bgk- committed May 28, 2024
2 parents 176f5ad + ca1c78f commit 2f75b18
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 171 deletions.
32 changes: 12 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Topiary.Unity

Unity Integration for the narrative scripting tool [topiary](https://github.com/peartreegames/topiary) with the [C# bindings](https://github.com/peartreegames/topiary-csharp).
Unity Integration for the dialogue scripting tool [topiary](https://github.com/peartreegames/topiary) with the [C# bindings](https://github.com/peartreegames/topiary-csharp).

Checkout the [syntax](https://github.com/peartreegames/topiary/blob/main/docs/syntax.md) file if you're new to writing with Topi.
Checkout the [syntax](https://peartree.games/topiary/docs/syntax) file if you're new to writing with Topi.

## Installation

Expand Down Expand Up @@ -93,25 +93,17 @@ public static class DialogueFunctions
// ex .topi file:
// extern const playAnim = |name, clip| {}
// playAnim("Player", "Laugh")
[Topi("playAnim"), Preserve]
public static void PlayAnim(TopiValue speakerName, TopiValue animClip)
[Topi("playAnim", 2)]
[MonoPInvokeCallback(typeof(Delegates.ExternFunctionDelegate))]
public static TopiValue PlayAnim(IntPtr argsPtr, byte count)
{
if (!Conversation.Speakers.TryGetValue(speakerName.String, out var speaker)) return;
speaker.GetComponent<Speaker>().PlayAnim(animClip.String);
}

[Topi("triggerAnim"), Preserve]
public static void TriggerAnim(TopiValue speakerName, TopiValue animClip)
{
if (!Conversation.Speakers.TryGetValue(speakerName.String, out var speaker)) return;
speaker.GetComponent<Speaker>().TriggerAnim(animClip.String);
}

[Topi("stopAnim"), Preserve]
public static void StopAnim(TopiValue speakerName, TopiValue animClip)
{
if (!Conversation.Speakers.TryGetValue(speakerName.String, out var speaker)) return;
speaker.GetComponent<Speaker>().StopAnim(animClip.String);
var args = TopiValue.CreateArgs(argsPtr, count);
var speakerName = args[0];
var animClip = args[1];
if (!Conversation.Speakers.TryGetValue(speakerName.String, out var topi) ||
!topi.TryGetComponent(out Speaker speaker)) return default;
speaker.PlayAnim(animClip.String);
return default;
}
}
```
Expand Down
61 changes: 46 additions & 15 deletions Runtime/Conversation.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using AOT;
using PeartreeGames.Evt.Variables;
using UnityEngine;
Expand All @@ -22,14 +23,15 @@ public class Conversation : MonoBehaviour
public string[] Tags => tags;

private TopiSpeaker _previousSpeaker;
private List<EvtTopiReference> _evtReferences;
public static event Action<Dialogue, Conversation> OnCreated;
public static event Action<Dialogue, Conversation> OnStart;
public static event Action<Dialogue, Conversation> OnEnd;
public static event Action<Dialogue, Line, TopiSpeaker> OnLine;
public static event Action<Dialogue, Choice[]> OnChoices;
public static readonly Dictionary<string, TopiSpeaker> Speakers = new();
public static readonly Dictionary<IntPtr, Conversation> Conversations = new();
private static readonly Dictionary<string, EvtVariable> Variables = new();
private static Delegates.Subscriber _subscriber;
public static void AddSpeaker(TopiSpeaker speaker) => Speakers[speaker.name] = speaker;
public static void RemoveSpeaker(TopiSpeaker speaker) => Speakers.Remove(speaker.name);

Expand Down Expand Up @@ -123,6 +125,9 @@ public IEnumerator Play()
Log("[Topiary.Unity] Invalid Dialogue", Library.Severity.Warn);
yield break;
}

_subscriber = ValueChanged;
Dialogue.Library.SetSubscriberCallback(Dialogue.VmPtr, Marshal.GetFunctionPointerForDelegate(_subscriber));
Dialogue.Library.SetDebugSeverity(logs);
yield return StartCoroutine(LoadAddressableTopiValues());
State.Inject(Dialogue);
Expand All @@ -134,7 +139,7 @@ public IEnumerator Play()
{
Dialogue?.Run();
}
catch (System.Runtime.InteropServices.SEHException ex)
catch (SEHException ex)
{
Log($"Caught an SEHException: {ex}", Library.Severity.Error);
break;
Expand All @@ -155,39 +160,65 @@ public IEnumerator Play()
UnloadAddressableTopiValues();
}


[MonoPInvokeCallback(typeof(Delegates.Subscriber))]
public static void ValueChanged(string name, ref TopiValue value)
{
if (Variables.TryGetValue(name, out var variable))
{
switch (value.tag)
{
case TopiValue.Tag.Bool when variable is EvtTopiBool b:
b.Value = value.Bool;
break;
case TopiValue.Tag.Number when variable is EvtTopiInt i:
i.Value = value.Int;
break;
case TopiValue.Tag.Number when variable is EvtTopiFloat f:
f.Value = value.Float;
break;
case TopiValue.Tag.String when variable is EvtTopiString s:
s.Value = value.String;
break;
}
}
}

private IEnumerator LoadAddressableTopiValues()
{
var ao = Addressables.LoadResourceLocationsAsync(new List<string> {"Topiary", "Evt"},
Addressables.MergeMode.Intersection);
yield return ao;
var list = ao.Result;
_evtReferences = new List<EvtTopiReference>();
foreach (var item in list)
{
var key = item.PrimaryKey;
if (!_data.ExternsSet.Contains(key)) continue;
var aoEvt = Addressables.LoadAssetAsync<EvtVariable>(key);
yield return aoEvt;

EvtTopiReference evtRef = aoEvt.Result switch
var topiName = aoEvt.Result switch
{
EvtTopiBool b => new EvtBoolReference(this, b),
EvtTopiFloat f => new EvtFloatReference(this, f),
EvtTopiInt i => new EvtIntReference(this, i),
EvtTopiString s => new EvtStringReference(this, s),
EvtTopiBool b => b.Name,
EvtTopiFloat f => f.Name,
EvtTopiInt i => i.Name,
EvtTopiString s => s.Name,
_ => null
};
if (evtRef == null) continue;
_evtReferences.Add(evtRef);
if (topiName == null)
{
Addressables.Release(aoEvt);
continue;
}
Variables[topiName] = aoEvt.Result;
}
}

private void UnloadAddressableTopiValues()
{
if (_evtReferences == null) return;
foreach (var reference in _evtReferences) reference?.Dispose();
_evtReferences.Clear();
foreach (var kvp in Variables)
{
Addressables.Release(kvp.Value);
}
}
}
}
133 changes: 0 additions & 133 deletions Runtime/Evt/EvtTopiReference.cs

This file was deleted.

3 changes: 0 additions & 3 deletions Runtime/Evt/EvtTopiReference.cs.meta

This file was deleted.

0 comments on commit 2f75b18

Please sign in to comment.