Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --DOCS FOUND AT http://pastebin.com/ym6aXhG1
- local config=
- {
- imply_self=true; --Remove the need for setting a self value in functions (removes the need for a colon)
- self_name="self"; --What the name is for the self value
- using_userdata=true; --Use userdata to allow __gc and __len metamethods. NOTE - WITHOUT THIS, STRICT ERRORS, PRIVATE, AND READ ONLY VALUES WILL NOT FUNCTION.
- strict_errors=true; --Error if 1) Value inside an object does not exist or 2) Attempt to set a value of an object where the field does not exist
- private_values=true; --Use private values
- private_value_index="__"; --How to start private values
- read_only_values=true; --Use read only values
- read_only_value_index="_"; --How to start read only values
- class_config_location="__settings"; --Where the config is located.
- class_config_setup= --How the config is setup.
- {
- new="new";
- mt="mt";
- };
- }
- local classes={}
- local objects={}
- local function locals(lev)
- local variables = {}
- local names={}
- local idx = 1
- while true do
- local ln, lv = debug.getlocal(lev, idx)
- if ln ~= nil then
- variables[idx] = lv
- names[idx]=ln
- else
- break
- end
- idx = 1 + idx
- end
- return variables,names
- end
- function remove(usd)
- local lev=2
- repeat
- local valid=debug.getinfo(lev)
- if not valid then break end
- local list,names=locals(lev)
- local num=0
- for i,v in pairs(list) do
- if rawequal(v,usd) then
- num=num+1
- debug.setlocal(lev,i,nil)
- end
- end
- lev=lev+1
- until false
- usd=nil
- collectgarbage()
- end
- local function giveTabAProxy(tab,metatable) --Create a userdata representation of a table with a metatable
- local proxy=newproxy(true)
- local mt=getmetatable(proxy)
- mt.__origtab=tab
- mt.__index=
- function(usd,ind)
- if config["private_values"] then
- local start=config["private_value_index"]
- if ind:sub(1,#start)==start then
- error("Attempt to index '"..ind.."' (a private value) of "..tostring(proxy)..", a wOOP object.") --Oops! Can't do that.
- end
- end
- if config["strict_errors"] then
- if not tab[ind]==nil then
- error("Attempt to index '"..ind.."' (a nil value) of "..tostring(proxy)..", a wOOP object.") --Oops! You did something you're not supposed to.
- end
- end
- return tab[ind]
- end
- mt.__newindex=
- function(usd,ind,val)
- if config["read_only_values"] then
- local start=config["read_only_value_index"]
- if ind:sub(1,#start)==start then
- error("Attempt to set '"..ind.."' (a read only value) of "..tostring(proxy)..", a wOOP object.") --Oops! Can't set read onlys (onlies?).
- end
- end
- if config["private_values"] then
- local start=config["private_value_index"]
- if ind:sub(1,#start)==start then
- error("Attempt to set '"..ind.."' (a private value) of "..tostring(proxy)..", a wOOP object.") --Oops! Can't do that.
- end
- end
- if config["strict_errors"] then
- if not tab[ind]==nil then
- error("Attempt to set '"..ind.."' (a nil value) of "..tostring(proxy)..", a wOOP object.") --Oops! You did something you're not supposed to.
- end
- end
- tab[ind]=val
- end
- for method,val in pairs(metatable or {}) do
- if not mt[method] then
- mt[method]=val
- end
- end
- for method,val in pairs({__tostring=function(a) return "wOOP object : "..a.className end,__concat=function(a,b) return tostring(a)..tostring(b) end}) do
- if not mt[method] then
- mt[method]=val
- end
- end
- return proxy
- end
- local function implySelfToFunctions(tab) --Change all functions to tables with __call metamethod set to do a little dance
- for i,v in pairs(tab) do
- if type(v)=="function" then
- local func=v
- local tabWithMt={}
- setmetatable(tabWithMt,
- {
- __call=
- function(_,...)
- if config["imply_self"] then
- _G.self=tab
- local args={func(...)}
- _G.self=nil
- return unpack(args)
- else
- return func(...)
- end
- end
- })
- tab[i]=tabWithMt
- end
- end
- end
- local function newObj(name,...)
- if not classes[name] then error("Class not found : "..name) end
- local userdata=config["using_userdata"]
- local implySelf=config["imply_self"]
- local configLoc=config["class_config_location"]
- local configTab=config["class_config_setup"]
- local settings=classes[name][configLoc]
- local new=settings['new']
- local mt=settings[configTab['mt']]
- mt.__index=classes[name]
- for method,val in pairs({__tostring=function(a) return "wOOP object : "..a.className end,__concat=function(a,b) return tostring(a)..tostring(b) end}) do
- if not mt[method] then
- mt[method]=val
- end
- end
- table.remove(arg,1)
- local tab=new(unpack(arg))
- for i,v in pairs(classes[name]) do
- if not tab[i] then tab[i]=v end
- end
- if implySelf then
- implySelfToFunctions(tab)
- end
- local prox
- if userdata then
- prox=giveTabAProxy(tab,mt)
- else
- prox=setmetatable({},{__index=tab})
- end
- return prox
- end
- local function realClass(tab,name,extends) --Do a short jig to remove the parentheses
- local mt={}
- local index={}
- if extends and classes[extends] then
- index=classes[extends]
- elseif classes.base then
- index=classes.base
- end
- for i,v in pairs(index) do
- if not tab[i] then tab[i]=v end
- end
- local configLoc=config["class_config_location"]
- if not tab[configLoc] then
- tab[configLoc]={}
- end
- setmetatable(tab[configLoc],{__index=index[configLoc] or {}})
- mt.__tostring=function() return "wOOP Class "..name end
- mt.__metatable=false
- mt.__concat=function(a,b) return tostring(a)..tostring(b) end
- mt.__call=function(...) return newObj(name,...) end
- tab.className=name
- tab.extends=extends or "base"
- setmetatable(tab,mt)
- classes[name]=tab
- _G[name]=tab
- end
- local function class3(tab,name)
- return function(arg)
- realClass(arg,name,tab)
- end
- end
- local function class2(name)
- return function(arg)
- if type(arg)=="table" then
- realClass(arg,name)
- else
- return class3(arg,name)
- end
- end
- end
- function class(name)
- return class2(name)
- end
- class "base"
- {
- isA=
- function(name)
- if self.className==name then
- return true
- end
- local var=self.extends
- while var~=name do
- var=classes[var].extends
- if var=="base" or not var then
- return false
- end
- end
- return var
- end,
- __settings=
- {
- new=function(...) return {} end,
- mt={__gc=function(self) print(self.className) end}
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement