mirror of
https://github.com/Ale32bit/Capy64.git
synced 2025-01-18 02:26:44 +00:00
Add support for user tasks, deprecate native task:await()
This commit is contained in:
parent
b2e7969793
commit
a84aedbe38
2 changed files with 112 additions and 3 deletions
|
@ -14,6 +14,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
using Capy64.API;
|
||||
using Capy64.Runtime.Objects;
|
||||
using KeraLua;
|
||||
using System;
|
||||
|
||||
|
@ -26,6 +27,8 @@ public class Event : IComponent
|
|||
|
||||
private static Lua UserQueue;
|
||||
|
||||
private static bool FrozenTaskAwaiter = false;
|
||||
|
||||
private static IGame _game;
|
||||
public Event(IGame game)
|
||||
{
|
||||
|
@ -49,15 +52,36 @@ public class Event : IComponent
|
|||
name = "push",
|
||||
function = L_Push,
|
||||
},
|
||||
new()
|
||||
{
|
||||
name = "setAwaiter",
|
||||
function = L_SetTaskAwaiter,
|
||||
},
|
||||
new()
|
||||
{
|
||||
name = "fulfill",
|
||||
function = L_Fulfill,
|
||||
},
|
||||
new()
|
||||
{
|
||||
name = "reject",
|
||||
function = L_Reject,
|
||||
},
|
||||
new()
|
||||
{
|
||||
name = "newTask",
|
||||
function = L_NewTask,
|
||||
},
|
||||
new(),
|
||||
};
|
||||
|
||||
public void LuaInit(Lua L)
|
||||
{
|
||||
PushQueue = 0;
|
||||
|
||||
UserQueue = _game.LuaRuntime.Parent.NewThread();
|
||||
|
||||
FrozenTaskAwaiter = false;
|
||||
|
||||
L.RequireF("event", OpenLib, false);
|
||||
}
|
||||
|
||||
|
@ -140,4 +164,86 @@ public class Event : IComponent
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int L_SetTaskAwaiter(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
L.CheckType(1, LuaType.Function);
|
||||
|
||||
if (FrozenTaskAwaiter)
|
||||
{
|
||||
L.Error("awaiter is frozen");
|
||||
}
|
||||
|
||||
FrozenTaskAwaiter = L.ToBoolean(2);
|
||||
|
||||
L.GetMetaTable(TaskMeta.ObjectType);
|
||||
L.GetField(-1, "__index");
|
||||
|
||||
L.Rotate(1, -1);
|
||||
L.SetField(-2, "await");
|
||||
L.Pop(2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int L_Fulfill(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
var task = TaskMeta.CheckTask(L, false);
|
||||
L.CheckAny(2);
|
||||
|
||||
if(!task.UserTask)
|
||||
{
|
||||
L.Error("attempt to fulfill machine task");
|
||||
}
|
||||
|
||||
if (task.Status != TaskMeta.TaskStatus.Running)
|
||||
{
|
||||
L.Error("attempt to fulfill a finished task");
|
||||
}
|
||||
|
||||
task.Fulfill(lk =>
|
||||
{
|
||||
L.XMove(lk, 1);
|
||||
});
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int L_Reject(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
var task = TaskMeta.CheckTask(L, false);
|
||||
var error = L.CheckString(2);
|
||||
|
||||
if (!task.UserTask)
|
||||
{
|
||||
L.Error("attempt to reject machine task");
|
||||
}
|
||||
|
||||
if(task.Status != TaskMeta.TaskStatus.Running)
|
||||
{
|
||||
L.Error("attempt to reject a finished task");
|
||||
}
|
||||
|
||||
task.Reject(error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int L_NewTask(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
var name = L.OptString(1, "object");
|
||||
|
||||
var task = TaskMeta.Push(L, name);
|
||||
task.UserTask = true;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ public class TaskMeta : IComponent
|
|||
public TaskStatus Status { get; set; } = TaskStatus.Running;
|
||||
public string Error { get; private set; }
|
||||
public int DataIndex { get; private set; } = 0;
|
||||
public bool UserTask { get; set; } = false;
|
||||
|
||||
public void Fulfill(Action<Lua> lk)
|
||||
{
|
||||
|
@ -191,12 +192,12 @@ public class TaskMeta : IComponent
|
|||
return task;
|
||||
}
|
||||
|
||||
private static RuntimeTask ToTask(Lua L, bool gc = false)
|
||||
public static RuntimeTask ToTask(Lua L, bool gc = false)
|
||||
{
|
||||
return ObjectManager.ToObject<RuntimeTask>(L, 1, gc);
|
||||
}
|
||||
|
||||
private static RuntimeTask CheckTask(Lua L, bool gc = false)
|
||||
public static RuntimeTask CheckTask(Lua L, bool gc = false)
|
||||
{
|
||||
var obj = ObjectManager.CheckObject<RuntimeTask>(L, 1, ObjectType, gc);
|
||||
if (obj is null)
|
||||
|
@ -218,6 +219,8 @@ public class TaskMeta : IComponent
|
|||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
L.Warning("Native task awaiter should be avoided", false);
|
||||
|
||||
var task = CheckTask(L, false);
|
||||
|
||||
if (task.Status == TaskStatus.Succeeded)
|
||||
|
|
Loading…
Reference in a new issue