initStdCoroutines method

void initStdCoroutines({
  1. required CoroutineCallbacks impl,
})

Implementation

void initStdCoroutines({required CoroutineCallbacks impl}) {
  coroutineImpls = impl;
  final defCoroutine = LuaObject.tableFrom('coroutine', [
    LuaFuncBuilder.create('create')
        .arg('fn')
        .exec(
          call: () {
            final fn = findVar('fn');
            if (fn is LuaObject && fn.isFunc) {
              final int addr = impl.onCoroutineCreate.call(fn);
              return LuaThread(addr).toLua('co');
            }

            final t = switch (fn) {
              null => 'nil',
              final LuaObject o => o.luaTypeInfo,
            };

            throw 'Expected function for coroutine. Found $t.';
          },
        )
      ..doc = LuaDoc(
        html: '''
        Creates a new coroutine with a function <code>fn</code> and returns an object
        of type <code>thread</code>.
        ''',
      ),
    LuaFuncBuilder.create('resume')
        .arg('co')
        .varargs()
        .exec(
          call: () {
            final co = findVar('co');
            final vs = findVarArgs();
            if (co?.isThread ?? false) {
              final thread = co!.value as LuaThread;
              return impl.onCoroutineResume
                  .call(thread.addr, vs ?? [])
                  .toLuaRet();
            }

            throw 'Expected coroutine for "resume".';
          },
        )
      ..doc = LuaDoc(
        html: '''
        Resumes the coroutine <code>co</code> and passes the parameters if any.
        It returns the status of operation and optional other return values.
        ''',
      ),
    LuaFuncBuilder.create('yield').varargs().exec(
        call: () {
          final vs = findVarArgs();
          impl.onCoroutineYield.call(vs ?? []);
        },
      )
      ..doc = LuaDoc(
        html: '''
        Suspends the running coroutine. The optional parameters passed to this
        method acts as additional return values to the resume function.
        ''',
      ),
    LuaFuncBuilder.create('status')
        .arg('co')
        .exec(
          call: () {
            final co = findVar('co');
            if (co?.isThread ?? false) {
              final thread = co!.value as LuaThread;
              return impl.onCoroutineStatus.call(thread.addr).toLuaRet();
            }

            throw 'Expected coroutine for "status".';
          },
        )
      ..doc = LuaDoc(
        html: '''
        Returns one of the values: <code>running</code>, <code>normal</code>,
        <code>suspended</code>, or <code>dead</code> based on the state of the coroutine.
        ''',
      ),
  ]);

  defGlobal(defCoroutine).doc = LuaDoc(
    category: catRuntime,
    html: '''
    Lua offsers asymmetric coroutines as a way to reason about statefulness without
    resorting to bloated abstractions to keep track of state and execution.
    ''',
  );
}