mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-10-31 15:35:21 +01:00 
			
		
		
		
	Async environment for mods to do concurrent tasks (#11131)
This commit is contained in:
		
							
								
								
									
										46
									
								
								builtin/async/game.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								builtin/async/game.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| core.log("info", "Initializing asynchronous environment (game)") | ||||
|  | ||||
| local function pack2(...) | ||||
| 	return {n=select('#', ...), ...} | ||||
| end | ||||
|  | ||||
| -- Entrypoint to run async jobs, called by C++ | ||||
| function core.job_processor(func, params) | ||||
| 	local retval = pack2(func(unpack(params, 1, params.n))) | ||||
|  | ||||
| 	return retval | ||||
| end | ||||
|  | ||||
| -- Import a bunch of individual files from builtin/game/ | ||||
| local gamepath = core.get_builtin_path() .. "game" .. DIR_DELIM | ||||
|  | ||||
| dofile(gamepath .. "constants.lua") | ||||
| dofile(gamepath .. "item_s.lua") | ||||
| dofile(gamepath .. "misc_s.lua") | ||||
| dofile(gamepath .. "features.lua") | ||||
| dofile(gamepath .. "voxelarea.lua") | ||||
|  | ||||
| -- Transfer of globals | ||||
| do | ||||
| 	assert(core.transferred_globals) | ||||
| 	local all = core.deserialize(core.transferred_globals, true) | ||||
| 	core.transferred_globals = nil | ||||
|  | ||||
| 	-- reassemble other tables | ||||
| 	all.registered_nodes = {} | ||||
| 	all.registered_craftitems = {} | ||||
| 	all.registered_tools = {} | ||||
| 	for k, v in pairs(all.registered_items) do | ||||
| 		if v.type == "node" then | ||||
| 			all.registered_nodes[k] = v | ||||
| 		elseif v.type == "craftitem" then | ||||
| 			all.registered_craftitems[k] = v | ||||
| 		elseif v.type == "tool" then | ||||
| 			all.registered_tools[k] = v | ||||
| 		end | ||||
| 	end | ||||
|  | ||||
| 	for k, v in pairs(all) do | ||||
| 		core[k] = v | ||||
| 	end | ||||
| end | ||||
| @@ -1,5 +1,4 @@ | ||||
| 
 | ||||
| core.log("info", "Initializing Asynchronous environment") | ||||
| core.log("info", "Initializing asynchronous environment") | ||||
| 
 | ||||
| function core.job_processor(func, serialized_param) | ||||
| 	local param = core.deserialize(serialized_param) | ||||
| @@ -8,4 +7,3 @@ function core.job_processor(func, serialized_param) | ||||
| 
 | ||||
| 	return retval or core.serialize(nil) | ||||
| end | ||||
| 
 | ||||
							
								
								
									
										22
									
								
								builtin/game/async.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								builtin/game/async.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
|  | ||||
| core.async_jobs = {} | ||||
|  | ||||
| function core.async_event_handler(jobid, retval) | ||||
| 	local callback = core.async_jobs[jobid] | ||||
| 	assert(type(callback) == "function") | ||||
| 	callback(unpack(retval, 1, retval.n)) | ||||
| 	core.async_jobs[jobid] = nil | ||||
| end | ||||
|  | ||||
| function core.handle_async(func, callback, ...) | ||||
| 	assert(type(func) == "function" and type(callback) == "function", | ||||
| 		"Invalid minetest.handle_async invocation") | ||||
| 	local args = {n = select("#", ...), ...} | ||||
| 	local mod_origin = core.get_last_run_mod() | ||||
|  | ||||
| 	local jobid = core.do_async_callback(func, args, mod_origin) | ||||
| 	core.async_jobs[jobid] = callback | ||||
|  | ||||
| 	return true | ||||
| end | ||||
|  | ||||
| @@ -34,5 +34,6 @@ dofile(gamepath .. "voxelarea.lua") | ||||
| dofile(gamepath .. "forceloading.lua") | ||||
| dofile(gamepath .. "statbars.lua") | ||||
| dofile(gamepath .. "knockback.lua") | ||||
| dofile(gamepath .. "async.lua") | ||||
|  | ||||
| profiler = nil | ||||
|   | ||||
| @@ -235,3 +235,32 @@ end | ||||
|  | ||||
| -- Used for callback handling with dynamic_add_media | ||||
| core.dynamic_media_callbacks = {} | ||||
|  | ||||
|  | ||||
| -- Transfer of certain globals into async environment | ||||
| -- see builtin/async/game.lua for the other side | ||||
|  | ||||
| local function copy_filtering(t, seen) | ||||
| 	if type(t) == "userdata" or type(t) == "function" then | ||||
| 		return true -- don't use nil so presence can still be detected | ||||
| 	elseif type(t) ~= "table" then | ||||
| 		return t | ||||
| 	end | ||||
| 	local n = {} | ||||
| 	seen = seen or {} | ||||
| 	seen[t] = n | ||||
| 	for k, v in pairs(t) do | ||||
| 		local k_ = seen[k] or copy_filtering(k, seen) | ||||
| 		local v_ = seen[v] or copy_filtering(v, seen) | ||||
| 		n[k_] = v_ | ||||
| 	end | ||||
| 	return n | ||||
| end | ||||
|  | ||||
| function core.get_globals_to_transfer() | ||||
| 	local all = { | ||||
| 		registered_items = copy_filtering(core.registered_items), | ||||
| 		registered_aliases = core.registered_aliases, | ||||
| 	} | ||||
| 	return core.serialize(all) | ||||
| end | ||||
|   | ||||
| @@ -56,8 +56,10 @@ elseif INIT == "mainmenu" then | ||||
| 	if not custom_loaded then | ||||
| 		dofile(core.get_mainmenu_path() .. DIR_DELIM .. "init.lua") | ||||
| 	end | ||||
| elseif INIT == "async" then | ||||
| 	dofile(asyncpath .. "init.lua") | ||||
| elseif INIT == "async"  then | ||||
| 	dofile(asyncpath .. "mainmenu.lua") | ||||
| elseif INIT == "async_game" then | ||||
| 	dofile(asyncpath .. "game.lua") | ||||
| elseif INIT == "client" then | ||||
| 	dofile(clientpath .. "init.lua") | ||||
| else | ||||
|   | ||||
		Reference in New Issue
	
	Block a user