mirror of
				https://github.com/kepler155c/opus
				synced 2025-10-31 23:53:01 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			139 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| local Util       = require('opus.util')
 | |
| 
 | |
| local device     = _G.device
 | |
| local kernel     = _G.kernel
 | |
| local os         = _G.os
 | |
| 
 | |
| local containers = {
 | |
| 	manipulator = true,
 | |
| 	neuralInterface = true,
 | |
| }
 | |
| 
 | |
| local cache = { }
 | |
| 
 | |
| -- manipulators will throw an error on listModules
 | |
| -- if the user has logged off
 | |
| local function getModules(dev, side)
 | |
| 	local list = { }
 | |
| 	local s, m = pcall(function()
 | |
| 		if dev and dev.listModules then
 | |
| 			for _, module in pairs(dev.listModules()) do
 | |
| 				list[module] = Util.shallowCopy(dev)
 | |
| 				list[module].name = module
 | |
| 				list[module].type = module
 | |
| 				list[module].side = side
 | |
| 			end
 | |
| 		end
 | |
| 	end)
 | |
| 	if not s and m then
 | |
| 		_G._syslog(m)
 | |
| 	end
 | |
| 	return list
 | |
| end
 | |
| 
 | |
| -- if a device has been reattached, reuse the existing
 | |
| -- table so any references to the table are retained
 | |
| local function addDevice(dev, args, doQueue)
 | |
| 	local name = args.name
 | |
| 
 | |
| 	if not cache[name] then
 | |
| 		cache[name] = { }
 | |
| 	end
 | |
| 	device[name] = cache[name]
 | |
| 	Util.merge(device[name], dev)
 | |
| 	Util.merge(device[name], args)
 | |
| 
 | |
| 	if doQueue then
 | |
| 		os.queueEvent('device_attach', name)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| -- directly access the peripheral as the methods in getInventory, etc.
 | |
| -- can become invalid without any way to tell
 | |
| local function damnManipulator(container, method, args, doQueue)
 | |
| 	local dev = { }
 | |
| 	local methods = {
 | |
| 		'drop', 'getDocs', 'getItem', 'getItemMeta', 'getTransferLocations',
 | |
| 		'list', 'pullItems', 'pushItems', 'size', 'suck',
 | |
| 	}
 | |
| 	-- the user might not be logged in when the compputer is started
 | |
| 	-- and there's no way to know when they have logged in.
 | |
| 	-- these methods will error if the user is not logged in
 | |
| 	if container[method] then
 | |
| 		for _,k in pairs(methods) do
 | |
| 			dev[k] = function(...)
 | |
| 				return device[container.name][method]()[k](...)
 | |
| 			end
 | |
| 		end
 | |
| 
 | |
| 		addDevice(dev, args, doQueue)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| local function addContainer(v, doQueue)
 | |
| 	-- add devices like plethora:scanner
 | |
| 	for name, dev in pairs(getModules(v, v.side)) do
 | |
| 		-- neural and attached modules have precedence over manipulator modules
 | |
| 		if not device[name] or v.type ~= 'manipulator' then
 | |
| 			addDevice(dev, { name = dev.name, type = dev.name, side = dev.side }, doQueue)
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	if v.getName then
 | |
| 		local s, m = pcall(function()
 | |
| 			local name = v.getName()
 | |
| 			if name then
 | |
| 				damnManipulator(v, 'getInventory', {
 | |
| 					name = name .. ':inventory',
 | |
| 					type = 'inventory',
 | |
| 					side = v.side
 | |
| 				}, doQueue)
 | |
| 				damnManipulator(v, 'getEquipment', {
 | |
| 					name = name .. ':equipment',
 | |
| 					type = 'equipment',
 | |
| 					side = v.side
 | |
| 				}, doQueue)
 | |
| 				damnManipulator(v, 'getEnder', {
 | |
| 					name = name .. ':enderChest',
 | |
| 					type = 'enderChest',
 | |
| 					side = v.side
 | |
| 				}, doQueue)
 | |
| 			end
 | |
| 		end)
 | |
| 		if not s and m then
 | |
| 			_G._syslog(m)
 | |
| 		end
 | |
| 	end
 | |
| end
 | |
| 
 | |
| for k,v in pairs(device) do
 | |
| 	if containers[v.type] then
 | |
| 		cache[k] = v
 | |
| 		addContainer(v)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| -- register modules as peripherals
 | |
| kernel.hook('device_attach', function(_, eventData)
 | |
| 	local name = eventData[1]
 | |
| 	local dev = device[name]
 | |
| 
 | |
| 	if dev and containers[dev.type] then
 | |
| 		-- so... basically, if you get a handle to device.neuralInterface
 | |
| 		-- (or manipulator) - that handle will still be valid after
 | |
| 		-- a module is removed
 | |
| 		if cache[name] then
 | |
| 			device[name] = cache[name]
 | |
| 			for k,v in pairs(device[name]) do
 | |
| 				if type(v) == 'function' then
 | |
| 					device[name][k] = nil
 | |
| 				end
 | |
| 			end
 | |
| 			Util.merge(device[name], dev)
 | |
| 		else
 | |
| 			cache[name] = dev
 | |
| 		end
 | |
| 		addContainer(dev, true)
 | |
| 	end
 | |
| end)
 | 
