Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local component = require("component");
- local vdevice_lib = {};
- vdevice_lib.VOnly = 2; --только виртуальные компоненты
- vdevice_lib.ROnly = 1; --только реальные компоненты
- local VDEVICE = {};
- local TYPES = {};
- local MAX = 1;
- local function _IF(f,a,b)
- if f then return a; end; return b;
- end;
- --переопределение метода list, параметр av определяет фильтр
- --виртуальные|не виртуальные|оба типа(если значение не равно не одной из констант)
- local _list = component.list;
- component.list = function(ttype,f,av)
- local inc = _list(ttype,f);
- local i = 0;
- return function()
- local adrs,name = nil,nil;
- if i == 0 and av ~= 2 then
- adrs,name = inc();
- if not(adrs) or not(name) then i = 1; end;
- end;
- if i > 0 and i <= MAX and av ~= 1 then
- while true do
- if VDEVICE[i] and (type(ttype) ~= "string" or VDEVICE[i].type:sub(1,ttype:len()) == ttype) then
- adrs = '#'..i; name = VDEVICE[i].type; i = i + 1; break;
- end;
- i = i + 1;
- if i > MAX then i = -1; break; end;
- end;
- end;
- return adrs,name;
- end;
- end;
- --переопределеие метода invoke
- local _invoke = component.invoke;
- component.invoke = function(adrs,op,...)
- checkArg(1,adrs,"string");
- checkArg(2,op ,"string");
- if adrs:sub(1,1) == '#' then
- local vd = VDEVICE[tonumber(adrs:sub(2,adrs:len()))];
- if vd == nil then error("no such virtual component"); end;
- if type(vd.methods[op]) ~= "function" then error("no such virtual method"); end;
- return vd.methods[op](...);
- end;
- return _invoke(adrs,op,...);
- end;
- --переопределение метода proxy
- local _proxy = component.proxy;
- component.proxy = function(adrs)
- checkArg(1,adrs,"string");
- if adrs:sub(1,1) == '#' then
- local vd = VDEVICE[tonumber(adrs:sub(2,adrs:len()))];
- return setmetatable({},{__index = vd.methods});
- end;
- return _proxy(adrs);
- end;
- --переопределение метода type
- local _type = component.type;
- component.type = function(adrs)
- checkArg(1,adrs,"string");
- if adrs:sub(1,1) == '#' then
- local vd = VDEVICE[tonumber(adrs:sub(2,adrs:len()))];
- return vd.type;
- end;
- return _type(adrs);
- end;
- --метод для добавление нового виртуального устройства,
- --в качестве параметров требудет тип и теблицу с методами
- --табица должна содержать поля в виде function с ключами string
- --в случаи удачного добавления возвращает адресс устройства
- --в случаи неудачи - nil и причину
- function vdevice_lib.addVDevice(ttype,tmethods)
- checkArg(1,ttype ,"string");
- checkArg(2,tmethods, "table");
- for k,d in pairs(tmethods) do
- if type(k) ~= "string" or type(d) ~= "function" then return nil,"invalid methods"; end;
- os.sleep(0.005);
- end;
- local i = 0;
- while true do
- os.sleep(0.005);
- i = i + 1;
- if VDEVICE[i] == nil then break; end;
- end;
- VDEVICE[i] = {
- methods = tmethods,
- type = ttype;
- };
- if TYPES[ttype] == nil then TYPES[ttype] = {}; end;
- table.insert(TYPES[ttype],i);
- if i > MAX then MAX = i; end;
- return '#'..i;
- end;
- --метод для удаления виртуального устройства,
- --в качестве параметра требуется адресс устройства
- --в случаи удачного удаления вернет true
- --в случаи неудачи вернет nil
- function vdevice_lib.delVDevice(adrs)
- checkArg(1,adrs,"string");
- if adrs:sub(1,1) ~= '#' then return nil,"invalid address"; end;
- local ind = tonumber(adrs:sub(2,adrs:len()));
- local vd = VDEVICE[ind];
- if vd == nil then return nil,"no such virtual component"; end;
- --в данном цикле нет прерывания ОС, так-как это может негативно сказатся на результате операции
- for i = 1, #(TYPES[vd.type]) do
- if TYPES[vd.type][i] == ind then table.remove(TYPES[vd.type],i); break; end;
- end;
- VDEVICE[ind] = nil;
- local i = MAX;
- while true do
- if VDEVICE[i] or i == 1 then break; end;
- i = i + 1;
- end;
- MAX = i;
- return true;
- end;
- return vdevice_lib;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement