mirror of
https://github.com/Ale32bit/Capy64.git
synced 2025-01-18 10:36: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.
|
// limitations under the License.
|
||||||
|
|
||||||
using Capy64.API;
|
using Capy64.API;
|
||||||
|
using Capy64.Runtime.Objects;
|
||||||
using KeraLua;
|
using KeraLua;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
@ -26,6 +27,8 @@ public class Event : IComponent
|
||||||
|
|
||||||
private static Lua UserQueue;
|
private static Lua UserQueue;
|
||||||
|
|
||||||
|
private static bool FrozenTaskAwaiter = false;
|
||||||
|
|
||||||
private static IGame _game;
|
private static IGame _game;
|
||||||
public Event(IGame game)
|
public Event(IGame game)
|
||||||
{
|
{
|
||||||
|
@ -49,15 +52,36 @@ public class Event : IComponent
|
||||||
name = "push",
|
name = "push",
|
||||||
function = L_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(),
|
new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
public void LuaInit(Lua L)
|
public void LuaInit(Lua L)
|
||||||
{
|
{
|
||||||
PushQueue = 0;
|
PushQueue = 0;
|
||||||
|
|
||||||
UserQueue = _game.LuaRuntime.Parent.NewThread();
|
UserQueue = _game.LuaRuntime.Parent.NewThread();
|
||||||
|
|
||||||
|
FrozenTaskAwaiter = false;
|
||||||
|
|
||||||
L.RequireF("event", OpenLib, false);
|
L.RequireF("event", OpenLib, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,4 +164,86 @@ public class Event : IComponent
|
||||||
|
|
||||||
return 0;
|
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 TaskStatus Status { get; set; } = TaskStatus.Running;
|
||||||
public string Error { get; private set; }
|
public string Error { get; private set; }
|
||||||
public int DataIndex { get; private set; } = 0;
|
public int DataIndex { get; private set; } = 0;
|
||||||
|
public bool UserTask { get; set; } = false;
|
||||||
|
|
||||||
public void Fulfill(Action<Lua> lk)
|
public void Fulfill(Action<Lua> lk)
|
||||||
{
|
{
|
||||||
|
@ -191,12 +192,12 @@ public class TaskMeta : IComponent
|
||||||
return task;
|
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);
|
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);
|
var obj = ObjectManager.CheckObject<RuntimeTask>(L, 1, ObjectType, gc);
|
||||||
if (obj is null)
|
if (obj is null)
|
||||||
|
@ -218,6 +219,8 @@ public class TaskMeta : IComponent
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
|
L.Warning("Native task awaiter should be avoided", false);
|
||||||
|
|
||||||
var task = CheckTask(L, false);
|
var task = CheckTask(L, false);
|
||||||
|
|
||||||
if (task.Status == TaskStatus.Succeeded)
|
if (task.Status == TaskStatus.Succeeded)
|
||||||
|
|
Loading…
Reference in a new issue