Перейти к содержимому
  • 0
Quant

Эмуляция компонентов

Вопрос

Приветствую,программисты!

Когда-то давно в openNet была такая фича : эмулированная интернет карта.

Мне захотелось сделать что-то в этом роде,но для gpu.

Так что прошу помощи от тех,кто знает.

Пазязя.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Рекомендуемые сообщения

Никакого прелоада не нужно


Это vcomponent

 

local component = require("component")
local computer = require("computer")

local proxylist = {}
local proxyobjs = {}
local typelist = {}
local doclist = {}

local oproxy = component.proxy
function component.proxy(address)
	checkArg(1,address,"string")
	if proxyobjs[address] ~= nil then
		return proxyobjs[address]
	end
	return oproxy(address)
end

local olist = component.list
function component.list(filter, exact)
	checkArg(1,filter,"string","nil")
	local data = {}
	for k,v in olist(filter, exact) do
		data[#data + 1] = k
		data[#data + 1] = v
	end
	for k,v in pairs(typelist) do
		if filter == nil or (exact and v == filter) or (not exact and v:find(filter, nil, true)) then
			data[#data + 1] = k
			data[#data + 1] = v
		end
	end
	local place = 1
	return function()
		local addr,type = data[place], data[place + 1]
		place = place + 2
		return addr,type
	end
end

local otype = component.type
function component.type(address)
	checkArg(1,address,"string")
	if typelist[address] ~= nil then
		return typelist[address]
	end
	return otype(address)
end

local odoc = component.doc
function component.doc(address, method)
	checkArg(1,address,"string")
	checkArg(2,method,"string")
	if proxylist[address] ~= nil then
		if proxylist[address][method] == nil then
			error("no such method",2)
		end
		if doclist[address] ~= nil then
			return doclist[address][method]
		end
		return nil
	end
	return odoc(address, method)
end

local oslot = component.slot
function component.slot(address)
	checkArg(1,address,"string")
	if proxylist[address] ~= nil then
		return -1 -- vcomponents do not exist in a slot
	end
	return oslot(address)
end

local omethods = component.methods
function component.methods(address)
	checkArg(1,address,"string")
	if proxylist[address] ~= nil then
		local methods = {}
		for k,v in pairs(proxylist[address]) do
			if type(v) == "function" then
				methods[k] = true -- All vcomponent methods are direct
			end
		end
		return methods
	end
	return omethods(address)
end

local oinvoke = component.invoke
function component.invoke(address, method, ...)
	checkArg(1,address,"string")
	checkArg(2,method,"string")
	if proxylist[address] ~= nil then
		if proxylist[address][method] == nil then
			error("no such method",2)
		end
		return proxylist[address][method](...)
	end
	return oinvoke(address, method, ...)
end

local ofields = component.fields
function component.fields(address)
	checkArg(1,address,"string")
	if proxylist[address] ~= nil then
		return {} -- What even is this?
	end
	return ofields(address)
end

local componentCallback =
{
	__call = function(self, ...) return proxylist[self.address][self.name](...) end,
	__tostring = function(self) return (doclist[self.address] ~= nil and doclist[self.address][self.name] ~= nil) and doclist[self.address][self.name] or "function" end
}

local vcomponent = {}

function vcomponent.register(address, ctype, proxy, doc)
	checkArg(1,address,"string")
	checkArg(2,ctype,"string")
	checkArg(3,proxy,"table")
	if proxylist[address] ~= nil then
		return nil, "component already at address"
	elseif component.type(address) ~= nil then
		return nil, "cannot register over real component"
	end
	proxy.address = address
	proxy.type = ctype
	local proxyobj = {}
	for k,v in pairs(proxy) do
		if type(v) == "function" then
			proxyobj[k] = setmetatable({name=k,address=address},componentCallback)
		else
			proxyobj[k] = v
		end
	end
	proxylist[address] = proxy
	proxyobjs[address] = proxyobj
	typelist[address] = ctype
	doclist[address] = doc
	computer.pushSignal("component_added",address,ctype)
	return true
end

function vcomponent.unregister(address)
	checkArg(1,address,"string")
	if proxylist[address] == nil then
		if component.type(address) ~= nil then
			return nil, "cannot unregister real component"
		else
			return nil, "no component at address"
		end
	end
	local thetype = typelist[address]
	proxylist[address] = nil
	proxyobjs[address] = nil
	typelist[address] = nil
	doclist[address] = nil
	computer.pushSignal("component_removed",address,thetype)
	return true
end

function vcomponent.list()
	local list = {}
	for k,v in pairs(proxylist) do
		list[#list + 1] = {k,typelist[k],v}
	end
	return list
end

function vcomponent.resolve(address, componentType)
	checkArg(1, address, "string")
	checkArg(2, componentType, "string", "nil")
	for k,v in pairs(typelist) do
		if componentType == nil or v == componentType then
			if k:sub(1, #address) == address then
				return k
			end
		end
	end
	return nil, "no such component"
end

local r = math.random
function vcomponent.uuid()
	return string.format("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
	r(0,255),r(0,255),r(0,255),r(0,255),
	r(0,255),r(0,255),
	r(64,79),r(0,255),
	r(128,191),r(0,255),
	r(0,255),r(0,255),r(0,255),r(0,255),r(0,255),r(0,255))
end

return vcomponent

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Этим занимался Крутой. Думаю он через require получал таблицу component и добавлял в нее поле с именем нового компонента и нужными функциями. Где-то в облаке есть исходники.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Кажется,дошло.Вызвать компонент и подкорректировать package.preload(ну или куда там либы буферизуются).

Изменено пользователем Quant

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Зачем preload? require("component") уже возвращает нужную таблицу из preload

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Зачем preload? require("component") уже возвращает нужную таблицу из preload

В прелоад либа хранится в виде функции,и через require не поменяешь компонент для всех,а только для себя.

Мои успехи

oHrla.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...