Skip to content

Instantly share code, notes, and snippets.

@Chaosed0
Created September 8, 2020 19:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Chaosed0/9f0a811d37456bb740e7751e02f63526 to your computer and use it in GitHub Desktop.
Save Chaosed0/9f0a811d37456bb740e7751e02f63526 to your computer and use it in GitHub Desktop.
Bolt unit for running a flow when a delegate is called. Only supports no-argument delegates.
using UnityEngine;
using System.Collections.Generic;
using Bolt;
using Ludiq;
[UnitTitle("Delegate Event")]
[SpecialUnit]
public class DelegateEventUnit : Unit, IEventUnit, IGraphEventListener, IGraphElementWithData
{
public class Data : IGraphElementData
{
public System.Action handler = null;
public bool isListening;
}
public virtual IGraphElementData CreateData()
{
return new Data();
}
bool IEventUnit.coroutine => false;
// <summary>
// The flag which to look for.
// </summary>
[DoNotSerialize]
[PortLabelHidden]
public ValueOutput action { get; private set; }
[DoNotSerialize]
[PortLabelHidden]
public ControlOutput trigger { get; private set; }
public override bool isControlRoot => true;
protected override void Definition()
{
var output = ValueOutput<System.Action>(nameof(action), GetAction);
this.action = output;
this.trigger = ControlOutput(nameof(trigger));
}
void IGraphEventListener.StartListening(GraphStack stack)
{
var data = stack.GetElementData<Data>(this);
if (data.isListening)
{
return;
}
var reference = stack.ToReference();
data.handler = () => DoAction(reference);
data.isListening = true;
}
void IGraphEventListener.StopListening(GraphStack stack)
{
var data = stack.GetElementData<Data>(this);
if (!data.isListening)
{
return;
}
data.handler = null;
data.isListening = false;
}
bool IGraphEventListener.IsListening(GraphPointer pointer)
{
if (!pointer.hasData)
{
return false;
}
return pointer.GetElementData<Data>(this).isListening;
}
private System.Action GetAction(Flow flow)
{
var data = flow.stack.GetElementData<Data>(this);
if (!data.isListening)
{
return null;
}
else
{
return data.handler;
}
}
private void DoAction(GraphReference graphReference)
{
if (graphReference == null || !graphReference.isValid)
{
Debug.LogWarning("Action executed after graph reference is disposed");
return;
}
var flow = Flow.New(graphReference);
Run(flow);
}
private void Run(Flow flow)
{
if (flow.enableDebug)
{
var editorData = flow.stack.GetElementDebugData<IUnitDebugData>(this);
editorData.lastInvokeFrame = EditorTimeBinding.frame;
editorData.lastInvokeTime = EditorTimeBinding.time;
}
flow.Run(trigger);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment