1 #define SOL_ALL_SAFETIES_ON 1
2 #include <sol/sol.hpp>
3 
4 #include <string>
5 #include <iostream>
6 
main()7 int main() {
8 	std::cout << "=== coroutine ===" << std::endl;
9 
10 	sol::state lua;
11 	std::vector<sol::coroutine> tasks;
12 
13 	lua.open_libraries(sol::lib::base, sol::lib::coroutine);
14 
15 	sol::thread runner_thread = sol::thread::create(lua);
16 
17 	lua.set_function("start_task", [&runner_thread, &tasks](sol::function f, sol::variadic_args va) {
18 		// You must ALWAYS get the current state
19 		sol::state_view runner_thread_state = runner_thread.state();
20 		// Put the task in our task list to keep it alive and track it
21 		std::size_t task_index = tasks.size();
22 		tasks.emplace_back(runner_thread_state, f);
23 		sol::coroutine& f_on_runner_thread = tasks[task_index];
24 		// call coroutine with arguments that came
25 		// from main thread / other thread
26 		// pusher for `variadic_args` and other sol types will transfer the
27 		// arguments from the calling thread to
28 		// the runner thread automatically for you
29 		// using `lua_xmove` internally
30 		int wait = f_on_runner_thread(va);
31 		std::cout << "First return: " << wait << std::endl;
32 		// When you call it again, you don't need new arguments
33 		// (they remain the same from the first call)
34 		f_on_runner_thread();
35 		std::cout << "Second run complete: " << wait << std::endl;
36 	});
37 
38 	lua.script(
39 	     R"(
40 function main(x, y, z)
41 	-- do something
42 	coroutine.yield(20)
43 	-- do something else
44 	-- do ...
45 	print(x, y, z)
46 end
47 
48 function main2(x, y)
49 	coroutine.yield(10)
50 	print(x, y)
51 end
52 
53 	start_task(main, 10, 12, 8)
54 	start_task(main2, 1, 2)
55 )");
56 
57 	std::cout << std::endl;
58 
59 	return 0;
60 }
61