+ Reply to Thread
Page 1 of 2 12 LastLast
Results 1 to 10 of 15

Thread: [E2] Multi-dimentional tables

  1. #1
    No u Divran's Avatar
    Join Date
    Jul 2008
    Location
    Sweden
    Posts
    4,582

    Wink [E2] Multi-dimentional tables

    I made a small extension for E2 which allows you to create infinitely deep tables (like Lua). This will probably not be in the official SVN, though.

    You're of course welcome to use it as a custom extension on your server. And report any bugs here. Thanks.

    Code:
    local table_IsEmpty = table.IsEmpty
    local table_Count = table.Count
    local Right = string.Right
    local type = type
    
    ------------------------------------------------------------------------------------------------
    -- Multi Dimentional Tables
    ------------------------------------------------------------------------------------------------
    ------------------------------------------------
    -- Helper functions
    ------------------------------------------------
    
    local function checkZero( zero, value, id )
    	if (type(zero) == "table" and type(value) == "table") then
    		if (#zero == 0) then return true end
    		for k,v in pairs( zero ) do
    			if (value[id .. k] != v) then
    				return true
    			end
    		end
    	elseif (type(zero) == type(value)) then
    		return (value != zero)
    	end
    	return false
    end
    
    local function upperfirst( word )
    	return word:Left(1):upper() .. word:Right(-2):lower()
    end
    
    local function findVar( tbl, index )
    	for k,v in pairs( wire_expression_types ) do
    		local id = v[1]
    		if (tbl[id..index]) then return true, id..index
    		end
    	end
    	return false
    end
    
    ------------------------------------------------
    -- Type
    ------------------------------------------------
    
    registerType("mtable", "xmt", {},
    	function(self, input)
    		local ret = {}
    		local c = 0
    		for k,v in pairs(input) do c = c + 1 ret[k] = v end
    		self.prf = self.prf + c / 3
    		return ret
    	end,
    	nil,
    	function(retval)
    		if type(retval) ~= "table" then error("Return value is not a table, but a "..type(retval).."!",0) end
    	end,
    	function(v)
    		return type(v) ~= "table"
    	end
    )
    
    ------------------------------------------------
    -- General functions
    ------------------------------------------------
    
    __e2setcost(1)
    
    e2function mtable mtable( ... )
    	local tbl = {...}
    	if (#tbl == 0) then return {} end
    	local ret = {}
    	for k,v in ipairs( tbl ) do
    		self.prf = self.prf + 5
    		ret[typeids[k]..tostring(k)] = v
    	end
    	return ret
    end
    
    e2function mtable operator=(mtable lhs, mtable rhs)
    	--return rhs
    	local lookup = self.data.lookup
    	
    	-- remove old lookup entry
    	if lookup[rhs] then lookup[rhs][lhs] = nil end
    	
    	-- add new lookup entry
    	local lookup_entry = lookup[rhs]
    	if not lookup_entry then
    		lookup_entry = {}
    		lookup[rhs] = lookup_entry
    	end
    	lookup_entry[lhs] = true
    
    	self.vars[lhs] = rhs
    	self.vclk[lhs] = true
    	return rhs
    end
    
    e2function number operator_is( mtable op )
    	return table_IsEmpty( op ) and 1 or 0
    end
    
    ------------------------------------------------
    -- Remove
    ------------------------------------------------
    
    __e2setcost(20)
    
    e2function void mtable:remove( string index )
    	local bool, index = findVar( this, index )
    	if (bool) then
    		this[index] = nil
    	end
    end
    
    ------------------------------------------------
    -- Getters, setters and remove
    ------------------------------------------------
    
    __e2setcost(5)
    
    registerCallback( "postinit", function()
    	local getf, setf
    	for k,v in pairs( wire_expression_types ) do
    		local name = k
    		local id = v[1]
    		local def = v[2]
    		function getf(self, args)
    			local op1, op2 = args[2], args[3]
    			local rv1, rv2, rv3 = op1[1](self, op1), op2[1](self, op2)
    			if (!rv1) then return def end
    			if (!rv2) then return def end
    			if (type(rv2) == "number") then rv2 = tostring(rv2) end
    			if (!rv1[id..rv2]) then return def end
    			return rv1[id..rv2]
    		end
    			
    		function setf(self, args)
    			local op1, op2, op3 = args[2], args[3], args[4]
    			local rv1, rv2, rv3 = op1[1](self, op1), op2[1](self, op2), op3[1](self, op3)
    			if (!rv1) then return def end
    			if (!rv2) then return def end
    			if (type(rv2) == "number") then rv2 = tostring(rv2) end
    			if (!rv3) then return def end
    			if (!checkZero( def, rv3, id )) then return end
    			rv1[id..rv2] = rv3
    			self.vclk[rv1] = true
    		end
    		
    		registerOperator("idx", id.."=xmts", id, getf)
    		registerOperator("idx", id.."=xmts"..id, id, setf)
    		
    		registerOperator("idx", id.."=xmtn", id, getf)
    		registerOperator("idx", id.."=xmtn"..id, id, setf)
    		
    		name = upperfirst( name )
    		if (name == "Normal") then name = "Number" end
    		registerFunction("remove"..name,"xmt:s",id,function(self,args)
    			local op1, op2 = args[2], args[3]
    			local rv1, rv2 = op1[1](self, op1), op2[1](self, op2)
    			local bool, index = findVar( rv1, rv2 )
    			if (bool) then
    				local temp = rv1[index]
    				rv1[index] = nil
    				self.vclk[rv1] = true
    				return temp
    			end
    		end)
    	end
    end)
    
    ------------------------------------------------
    -- Debug
    ------------------------------------------------
    
    __e2setcost(1)
    
    e2function void printTable( mtable tbl )
    	if (!tbl) then return end
    	self.prf = self.prf + table_Count(tbl) / 2
    	for k,v in pairs( tbl ) do
    		self.player:ChatPrint( k .. " = " .. tostring(v) )
    	end
    end
    
    __e2setcost(nil)
    Example usage:
    Code:
    T = mtable( 1,2,3, "hello", vec(5,6,7), mtable("blargh","rofl",1231) )
    print("6,3:",T[6,mtable][3,number])
    printTable(T)
    prints:
    6,3: 1231
    xmt6 = table: 36413650
    n1 = 1
    n2 = 2
    n3 = 3
    v5 = table: 36411490
    s4 = hello
    And

    Code:
    T = mtable()
    T[1,string] = "hello"
    T["abc",string] = "world"
    T["deeper",mtable] = mtable(1,2,3,4)
    printTable(T)
    printTable(T["deeper",mtable])
    s1 = hello
    sabc = world
    xmtdeeper = table: 2EC7DBF8
    n4 = 4
    n1 = 1
    n2 = 2
    n3 = 3
    Enjoy!
    Last edited by Divran; 07-04-2010 at 09:20 AM.
    SVN Tutorial
    My SVN:
    Code:
    http://divranspack.googlecode.com/svn/trunk/%20divranspack/
    Get dropbox and get 250 MB extra space: Dropbox

  2. #2
    Wiremod Helper Donkie's Avatar
    Join Date
    May 2008
    Location
    Sweden
    Posts
    1,661

    Default Re: [E2] Multi-dimentional tables

    ooooo
    Get out. Seriously, do it.

  3. #3
    Lifetime Supporter Nikita's Avatar
    Join Date
    May 2009
    Posts
    769

    Default Re: [E2] Multi-dimentional tables

    Donkie change your signature it's too addicting ><

    Ontopic: yay!

  4. #4
    Wire Sofaking jacoby6000's Avatar
    Join Date
    Feb 2008
    Location
    behind you when you aren't looking
    Posts
    792

    Default Re: [E2] Multi-dimentional tables

    To clarify: They're just tables that you can put inside tables that you can put inside tables that you can put inside............................................ .................................................. .................................................. ......... tables that you can put inside tables?
    Quote Originally Posted by Garrysmod View Post
    Warning: You're trying to render in the wrong place. This doesn't play nice with multi-core rendering, so we're not going to let you draw here.
    I'm not stupid!
    In [his] experience that was a sentence never to be uttered except to prove its own inaccuracy
    --Orson Scott Card

  5. #5
    No u Divran's Avatar
    Join Date
    Jul 2008
    Location
    Sweden
    Posts
    4,582

    Default Re: [E2] Multi-dimentional tables

    Quote Originally Posted by jacoby6000 View Post
    To clarify: They're just tables that you can put inside tables that you can put inside tables that you can put inside............................................ .................................................. .................................................. ......... tables that you can put inside tables?
    Yes
    SVN Tutorial
    My SVN:
    Code:
    http://divranspack.googlecode.com/svn/trunk/%20divranspack/
    Get dropbox and get 250 MB extra space: Dropbox

  6. #6
    Wirererer ben1066's Avatar
    Join Date
    Aug 2009
    Posts
    151

    Default Re: [E2] Multi-dimentional tables

    Yay, Divran, slowly your creaping to my favourite coder

  7. #7
    Wiremod Helper Donkie's Avatar
    Join Date
    May 2008
    Location
    Sweden
    Posts
    1,661

    Default Re: [E2] Multi-dimentional tables

    Slowly?
    I would say rather fast.
    Get out. Seriously, do it.

  8. #8
    Ursus maritimus Drunkie's Avatar
    Join Date
    Feb 2009
    Location
    Canada
    Posts
    5,662
    Blog Entries
    1

    Default Re: [E2] Multi-dimentional tables

    I prefer the old tables:



  9. #9
    Wire Sofaking Ehmmett's Avatar
    Join Date
    Sep 2009
    Posts
    595

    Default Re: [E2] Multi-dimentional tables

    Quote Originally Posted by Drunkie View Post
    I prefer the old tables:


    I prefer more modern tables.

  10. #10
    Wirererer TGifallen's Avatar
    Join Date
    Feb 2010
    Posts
    141

    Default Re: [E2] Multi-dimentional tables

    good idea, filepaths away!
    Slso you spelled Dimensional wrong.

+ Reply to Thread
Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
proceed-collector
proceed-collector
proceed-collector
proceed-collector
linguistic-parrots
linguistic-parrots
linguistic-parrots
linguistic-parrots