Skip to main content
The Coroutine class represents a Lua coroutine, which allows cooperative multitasking by suspending and resuming execution.

Properties

Type
CoroutineType
Gets the type of coroutine: Coroutine (Lua coroutine), ClrCallback (C# callback), ClrCallbackDead (executed C# callback), or Recycled.
if (co.Type == Coroutine.CoroutineType.Coroutine) {
    // It's a Lua coroutine
}
State
CoroutineState
Gets the coroutine state: NotStarted, Suspended, Running, or Dead.
if (co.State == CoroutineState.Suspended) {
    co.Resume();
}
OwnerScript
Script
Gets the script owning this coroutine.

Resume Methods

Resume()
method
Resumes the coroutine with no arguments. Only works for non-CLR coroutines.
returns
LuaValue
The value(s) yielded or returned by the coroutine
var script = new Script();
var func = script.LoadString("return coroutine.yield(42)");
var co = script.CreateCoroutine(func);

LuaValue result = co.Resume(); // Returns 42
Resume(params LuaValue[])
method
Resumes the coroutine with Lua arguments.
returns
LuaValue
The value(s) yielded or returned by the coroutine
LuaValue result = co.Resume(
    LuaValue.NewNumber(10),
    LuaValue.NewString("hello")
);
Resume(params object[])
method
Resumes the coroutine with CLR arguments.
returns
LuaValue
The value(s) yielded or returned by the coroutine
LuaValue result = co.Resume(10, "hello", true);
Resume(ScriptExecutionContext)
method
Resumes the coroutine with an execution context. Works for all coroutine types.
returns
LuaValue
The value(s) yielded or returned by the coroutine
// Use inside a C# callback
LuaValue.NewCallback((ctx, args) => {
    var co = args[0].Coroutine;
    return co.Resume(ctx);
});
Resume(ScriptExecutionContext, params LuaValue[])
method
Resumes the coroutine with an execution context and arguments.
returns
LuaValue
The value(s) yielded or returned by the coroutine

Enumeration Methods

AsTypedEnumerable
method
Gets this coroutine as a typed enumerable which can be looped over for resuming. Returns results as LuaValue(s).
returns
IEnumerable<LuaValue>
An enumerable that resumes the coroutine on each iteration
foreach (var value in co.AsTypedEnumerable()) {
    Console.WriteLine($"Yielded: {value}");
}
AsEnumerable
method
Gets this coroutine as an enumerable. Returns results as System.Object (only first element of tuples).
returns
IEnumerable<object>
An enumerable that resumes the coroutine on each iteration
foreach (object value in co.AsEnumerable()) {
    Console.WriteLine($"Yielded: {value}");
}
AsEnumerable<T>
method
Gets this coroutine as a typed enumerable with automatic type conversion.
returns
IEnumerable<T>
An enumerable returning values of the specified type
foreach (int value in co.AsEnumerable<int>()) {
    Console.WriteLine($"Yielded number: {value}");
}
AsUnityCoroutine
method
Converts this coroutine to a Unity3D coroutine. Resumes each frame, discarding returned values.
returns
IEnumerator
An IEnumerator compatible with Unity’s StartCoroutine
// In Unity
StartCoroutine(luaCoroutine.AsUnityCoroutine());

Debugging Methods

GetStackTrace
method
Gets the coroutine stack trace for debugging purposes.
returns
StackFrame[]
Array of stack frames
var frames = co.GetStackTrace(0);
foreach (var frame in frames) {
    Console.WriteLine(frame.ToString());
}

CoroutineType Enum

Coroutine
enum
A valid Lua coroutine.
ClrCallback
enum
A CLR callback assigned to a coroutine.
ClrCallbackDead
enum
A CLR callback that has already been executed.
Recycled
enum
A recycled coroutine (for performance optimization).

Example Usage

using SolarSharp.Interpreter;
using SolarSharp.Interpreter.DataTypes;

var script = new Script();

// Create a coroutine that yields values
script.DoString(@"
    function counter(max)
        for i = 1, max do
            coroutine.yield(i)
        end
        return 'done'
    end
");

var func = script.Globals.Get("counter");
var co = script.CreateCoroutine(func);

// Resume the coroutine manually
Console.WriteLine(co.State); // NotStarted
var result1 = co.Resume(5);
Console.WriteLine($"Yielded: {result1.Number}"); // 1
Console.WriteLine(co.State); // Suspended

var result2 = co.Resume();
Console.WriteLine($"Yielded: {result2.Number}"); // 2

// Use as enumerable
foreach (var value in co.AsTypedEnumerable()) {
    Console.WriteLine($"Yielded: {value}");
}
// Output: 3, 4, 5, "done"

// Create a new coroutine with foreach
var co2 = script.CreateCoroutine(func);
foreach (int num in co2.AsEnumerable<int>()) {
    Console.WriteLine($"Number: {num}");
    if (num >= 3) break; // Stop early
}

// Passing arguments to resume
script.DoString(@"
    function processor()
        local value = coroutine.yield('ready')
        coroutine.yield('received: ' .. value)
        return 'finished'
    end
");

var co3 = script.CreateCoroutine(script.Globals.Get("processor"));
Console.WriteLine(co3.Resume().String); // "ready"
Console.WriteLine(co3.Resume("hello").String); // "received: hello"
Console.WriteLine(co3.Resume().String); // "finished"

// Check coroutine state
if (co3.State == CoroutineState.Dead) {
    Console.WriteLine("Coroutine has finished");
}

Build docs developers (and LLMs) love