Experimental event delegates (#1)

This commit is contained in:
Alessandro Proto 2023-01-10 23:29:22 +01:00 committed by GitHub
commit 4a99756c24
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 76 additions and 13 deletions

View file

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Capy64.LuaRuntime;
public interface ILuaEvent
{
public string Name { get; set; }
public bool BypassFilter { get; set; }
}

View file

@ -0,0 +1,15 @@
using KeraLua;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Capy64.LuaRuntime;
public class LuaDelegateEvent : ILuaEvent
{
public string Name { get; set; }
public Func<Lua, int> Handler { get; set; }
public bool BypassFilter { get; set; } = false;
}

View file

@ -1,8 +1,8 @@
namespace Capy64.LuaRuntime; namespace Capy64.LuaRuntime;
public struct LuaEvent public class LuaEvent : ILuaEvent
{ {
public string Name { get; set; } public string Name { get; set; }
public object[] Parameters { get; set; } public object[] Parameters { get; set; }
public bool BypassFilter { get; set; } public bool BypassFilter { get; set; } = false;
} }

View file

@ -13,7 +13,7 @@ namespace Capy64.LuaRuntime;
public class Runtime public class Runtime
{ {
private readonly ConcurrentQueue<LuaEvent> eventQueue = new(new LuaEvent[] private readonly ConcurrentQueue<ILuaEvent> eventQueue = new(new LuaEvent[]
{ {
new() new()
{ {
@ -62,7 +62,27 @@ public class Runtime
public void PushEvent(string name, params object[] pars) public void PushEvent(string name, params object[] pars)
{ {
eventQueue.Enqueue(new() { Name = name, Parameters = pars }); eventQueue.Enqueue(new LuaEvent() { Name = name, Parameters = pars });
}
public void PushEvent(LuaDelegateEvent ev)
{
eventQueue.Enqueue(ev);
}
/// <summary>
/// Push a new event to the event queue.
/// </summary>
/// <param name="name">Event name</param>
/// <param name="handler">Event handler. Push any needed parameter from here. Return n as amount of parameters pushed, minus event name.
/// For example: I push an event with 3 parameters, then I return 3.
/// </param>
public void PushEvent(string name, Func<Lua, int> handler)
{
eventQueue.Enqueue(new LuaDelegateEvent {
Name = name,
Handler = handler
});
} }
/// <summary> /// <summary>
@ -71,7 +91,7 @@ public class Runtime
/// <returns>Whether it yielded</returns> /// <returns>Whether it yielded</returns>
public bool Resume() public bool Resume()
{ {
while (eventQueue.TryDequeue(out LuaEvent ev)) while (eventQueue.TryDequeue(out ILuaEvent ev))
{ {
if (!ResumeThread(ev)) if (!ResumeThread(ev))
return false; return false;
@ -80,7 +100,7 @@ public class Runtime
return true; return true;
} }
private bool ResumeThread(LuaEvent ev) private bool ResumeThread(ILuaEvent ev)
{ {
@ -117,17 +137,32 @@ public class Runtime
throw new LuaException($"Top thread exception:\n{error}\n{stacktrace}"); throw new LuaException($"Top thread exception:\n{error}\n{stacktrace}");
} }
private int PushEventToStack(LuaEvent ev) private int PushEventToStack(ILuaEvent ev)
{ {
Thread.PushString(ev.Name); Thread.PushString(ev.Name);
if (ev.Parameters != null)
switch(ev)
{ {
foreach (var par in ev.Parameters) case LuaEvent e:
{
Thread.PushValue(par); if (e.Parameters != null)
} {
foreach (var par in e.Parameters)
{
Thread.PushValue(par);
}
}
return (e.Parameters?.Length ?? 0) + 1;
case LuaDelegateEvent e:
int n = e.Handler(Thread);
return n + 1;
default:
throw new NotImplementedException();
} }
return (ev.Parameters?.Length ?? 0) + 1;
} }
public void Close() public void Close()