.. _ex_manual_st:

tmc::ex_manual_st
-----------------------------------------------------------------------------------
An executor that does not own any threads. Work can be posted to this
executor at any time, but it will only be executed when you call one of
the ``run_*()`` functions. The caller of ``run_*()`` will execute work inline on
the current thread.

It is safe to post work from any number of threads concurrently, but
``run_*()`` must only be called from 1 thread at a time.

This allows you to poll for continuations at a specific time, such as
in the main loop of a game engine.

Usage Example
-----------------------------------------------------------------------------------

This example uses ``ex_manual_st`` to poll for completions of both background work
(which may complete at any time) and specific work which must be completed before we can proceed.

.. code-block:: cpp

  tmc::ex_manual_st mainLoopExecutor;

  tmc::task<void> loadEntity(Entity& entity) {
    co_await readFile(...);
    parseFile(...); // CPU-bound work to be done on the multi-threaded ex_cpu
    co_await tmc::resume_on(mainLoopExecutor);
    spawnEntity(...); // must be done on main thread for sync reasons
  }

  int main() {
    tmc::cpu_executor().init();
    mainLoopExecutor.init();
    while (true) {
      // Distant entities can be loaded at any time. We don't need to wait for
      // them to finish.
      std::vector<Entity> distant = get_new_distant_entities();
      for (auto& e : distant) {
        tmc::post(tmc::cpu_executor(), loadEntity(e));
      }

      // Nearby entities must be loaded this frame.
      std::vector<Entity> nearby = get_new_nearby_entities();
      std::future<void> nearbyReady = tmc::post_bulk_waitable(
        tmc::cpu_executor(),
        nearby | std::ranges::views::transform(loadEntity)
      );

      // Continue polling until all nearby entities are loaded.
      // If any distant entities are ready, they will be processed too.
      while (nearbyReady.wait_for(std::chrono::seconds(0)) !=
            std::future_status::ready) {
        mainLoopExecutor.run_all();
      }

      render();
    }
  }

API Reference
-----------------------------------------------------------------------------------
.. doxygenclass:: tmc::ex_manual_st
   :members:
