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
1 parent 37f3b53 commit ca1c78f
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 174 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
70 changes: 52 additions & 18 deletions Runtime/Conversation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ public class Conversation : MonoBehaviour
public string[] Tags => tags;

private TopiSpeaker _previousSpeaker;
private List<EvtTopiReference> _evtReferences;
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;
private static Dictionary<string, EvtVariable> Variables = new();
public static Dictionary<string, TopiSpeaker> Speakers { get; } = new();
public static void AddSpeaker(TopiSpeaker speaker) => Speakers[speaker.name] = speaker;
public static void RemoveSpeaker(TopiSpeaker speaker) => Speakers.Remove(speaker.name);
Expand All @@ -51,10 +51,16 @@ private IEnumerator Start()
yield return ao;
_data = ao.Result;
Library.OnDebugLogMessage += Log;
Dialogue = new Dialogue(_data.bytes, OnLineCallback, OnChoicesCallback, logs);
if (!Dialogue.IsValid) Log("[Topiary.Unity] Could not create Dialogue ", Library.Severity.Error);
else Dialogue.BindFunctions(AppDomain.CurrentDomain.GetAssemblies());
Library.OnDebugLogMessage -= Log;
try
{
Dialogue = new Dialogue(_data.bytes, OnLineCallback, OnChoicesCallback, logs);
if (!Dialogue.IsValid) Log("[Topiary.Unity] Could not create Dialogue ", Library.Severity.Error);
else Dialogue.BindFunctions(AppDomain.CurrentDomain.GetAssemblies());
}
finally
{
Library.OnDebugLogMessage -= Log;
}
}

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

Dialogue.Library.SetSubscribeCallback(ValueChanged);
Dialogue.Library.SetDebugSeverity(logs);
Library.OnDebugLogMessage += Log;
yield return StartCoroutine(LoadAddressableTopiValues());
Expand Down Expand Up @@ -147,39 +155,65 @@ public IEnumerator Play()
Library.OnDebugLogMessage -= Log;
}


[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.Int when variable is EvtTopiInt i:
i.Value = value.Int;
break;
case TopiValue.tag.Float 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
string name = 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 (evtRef == null)
{
Addressables.ReleaseAsset(aoEvt);
continue;
}
Variables[name] = aoEvt.Result;
}
}

private void UnloadAddressableTopiValues()
{
if (_evtReferences == null) return;
foreach (var reference in _evtReferences) reference?.Dispose();
_evtReferences.Clear();
foreach (var kvp in Variables)
{
Addressables.ReleaseAsset(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.

Binary file modified Topiary.CSharp.dll
Binary file not shown.
Binary file modified Topiary.CSharp.pdb
Binary file not shown.

0 comments on commit ca1c78f

Please sign in to comment.