Helper/Utility Function Collection

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
Lap
Party member
Posts: 256
Joined: Fri Apr 30, 2010 3:46 pm

Helper/Utility Function Collection

Post by Lap »

Since Robin mentioned one of the functions I used I figured I might as well post all the helper functions I currently use. Most of which are from GMOD. If you have any universally useful utility functions throw them here.

Code: Select all

function PrintTable ( t, indent, done )

	done = done or {}
	indent = indent or 0

	for key, value in pairs (t) do
		print( string.rep ("\t", indent) )
		if type (value) == "table" and not done [value] then

	      	done [value] = true
	      	print(tostring (key) .. ":");
	     	PrintTable (value, indent + 2, done)

	    else
	      	print(tostring (key) .. "\t=\t" .. tostring(value))

	    end

	end
	
end


function PrintTableSimple ( t, indent, done )

	done = done or {}
	indent = indent or 0

	for key, value in pairs (t) do
		print( string.rep ("\t", indent) )
	      	print(tostring (key) .. "\t=\t" .. tostring(value))

	end
	
end

function Distance(x1,y1,x2,y2)


return math.sqrt((x2 - x1)^2+(y2 - y1)^2)

end

function math.Clamp( _in, low, high )
	if (_in < low ) then return low end
	if (_in > high ) then return high end
	return _in
end

function AngleBetweenPoints(x1,y1,x2,y2)
--local angle = math.atan2(y1-y2,x1-x2)
local angle = math.atan2(y2-y1,x2-x1)
return angle
end

function math.Deg2Rad( deg )
	return deg * ( math.pi / 180 )
end

function table.Count(tbl)
	if tbl ~= nil then
	
	local num = 0
		for k,v in pairs(tbl) do
		num = num + 1
		end
	return num
	end
end


--Desc: Taken straight from http://lua-users.org/wiki/PitLibTablestuff

function table.Merge(dest, source)

	for k,v in pairs(source) do
	
		if ( type(v) == 'table' and type(dest[k]) == 'table' ) then
			-- don't overwrite one table with another;
			-- instead merge them recurisvely
			table.Merge(dest[k], v)
		else
			dest[k] = v
		end
	end
	
	return dest
	
end
function table.Copy(t, lookup_table)
	if (t == nil) then return nil end
	
	local copy = {}
	setmetatable(copy, getmetatable(t))
	for i,v in pairs(t) do
		if type(v) ~= "table" then
			copy[i] = v
		else
			lookup_table = lookup_table or {}
			lookup_table[t] = copy
			if lookup_table[v] then
				copy[i] = lookup_table[v] -- we already copied this table. reuse the copy.
			else
				copy[i] = table.Copy(v,lookup_table) -- not yet copied. copy it.
			end
		end
	end
	return copy
end

function table.HasValue(tbl, value)

	for k,v in pairs(tbl) do
		if v == value then
		return true
		end
	end
return false
end


function table.HasKey(tbl, key)

	for k,v in pairs(tbl) do
		if k == key then
		return true
		end
	end
return false
end

function string.ToTable ( str )

	local tab = {}
	
	for i=1, string.len( str ) do
		table.insert( tab, string.sub( str, i, i ) )
	end
	
	return tab

end


function string.Explode ( seperator, str )

	if ( seperator == "" ) then
		return string.ToTable( str )
	end

	local tble={}	
	local ll=0
	
	while (true) do
	
		l = string.find( str, seperator, ll, true )
		
		if (l ~= nil) then
			table.insert(tble, string.sub(str,ll,l-1)) 
			ll=l+1
		else
			table.insert(tble, string.sub(str,ll))
			break
		end
		
	end
	
	return tble
	
end


function string.Implode(seperator,Table) return 
	table.concat(Table,seperator) 
end


function string.GetExtensionFromFilename(path)
	local ExplTable = string.ToTable( path )
	for i = table.getn(ExplTable), 1, -1 do
		if ExplTable[i] == "." then return string.sub(path, i+1)end
		if ExplTable[i] == "/" or ExplTable[i] == "\\" then return "" end
	end
	return ""
end

function string.GetPathFromFilename(path)
	local ExplTable = string.ToTable( path )
	for i = table.getn(ExplTable), 1, -1 do
		if ExplTable[i] == "/" or ExplTable[i] == "\\" then return string.sub(path, 1, i) end
	end
	return ""
end

function string.GetFileFromFilename(path)
	local ExplTable = string.ToTable( path )
	for i = table.getn(ExplTable), 1, -1 do
		if ExplTable[i] == "/" or ExplTable[i] == "\\" then return string.sub(path, i) end
	end
	return ""
end



function string.FormattedTime( TimeInSeconds, Format )
	if not TimeInSeconds then TimeInSeconds = 0 end

	local i = math.floor( TimeInSeconds )
	local h,m,s,ms	=	( i/3600 ),
				( i/60 )-( math.floor( i/3600 )*3600 ),
				TimeInSeconds-( math.floor( i/60 )*60 ),
				( TimeInSeconds-i )*100

	if Format then
		return string.format( Format, m, s, ms )
	else
		return { h=h, m=m, s=s, ms=ms }
	end
end


function string.ToMinutesSecondsMilliseconds( TimeInSeconds )	return string.FormattedTime( TimeInSeconds, "%02i:%02i:%02i")	end
function string.ToMinutesSeconds( TimeInSeconds )		return string.FormattedTime( TimeInSeconds, "%02i:%02i")	end



function string.Left(str, num)
	return string.sub(str, 1, num)
end

function string.Right(str, num)
	return string.sub(str, -num)
end



function string.Replace(str, tofind, toreplace)
	local start = 1
	while (true) do
		local pos = string.find(str, tofind, start, true)
	
		if (pos == nil) then
			break
		end
		
		local left = string.sub(str, 1, pos-1)
		local right = string.sub(str, pos + #tofind)
		
		str = left .. toreplace .. right
		start = pos + #toreplace
	end
	return str
end


function string.Trim( s, char )
	if (char==nil) then char = "%s" end
	return string.gsub(s, "^".. char.."*(.-)"..char.."*$", "%1")
end


function string.TrimRight( s, char )
	
	if (char==nil) then char = " " end	
	
	if ( string.sub( s, -1 ) == char ) then
		s = string.sub( s, 0, -2 )
		s = string.TrimRight( s, char )
	end
	
	return s
	
end

function string.TrimLeft( s, char )

	if (char==nil) then char = " " end	
	
	if ( string.sub( s, 1 ) == char ) then
		s = string.sub( s, 1 )
		s = string.TrimLeft( s, char )
	end
	
	return s

end

function table.ForceInsert( t, v )

	if  t == nil then
	t = {}
	end
	
	table.insert( t, v )
	
end

function string.wrap(str, limit, indent, indent1)
  indent = indent or ""
  indent1 = indent1 or indent
  limit = limit or 72
  local here = 1-#indent1
  return indent1..str:gsub("(%s+)()(%S+)()",
                          function(sp, st, word, fi)
                            if fi-here > limit then
                              here = st - #indent
                              return "\n"..indent..word
                            end
                          end)
end

function string.reflow(str, limit, indent, indent1)
  return (str:gsub("%s*\n%s+", "\n")
             :gsub("%s%s+", " ")
             :gsub("[^\n]+",
                   function(line)
                     return string.wrap(line, limit, indent, indent1)
                   end))
end

function math.Round( i )
	i = i or 0
	return math.floor( i + 0.5 )
end

--like ipairs but will do nonwhole number keys [notfinished]
function nonintpairs (tbl)
local least = math.huge
local numdone = 0
local done = {}
	while numdone < table.Count(tbl) do
		for k,v in pairs(nonintpairs) do
			if k < least and not table.HasValue(done, k) then
			least = k
			end
		end
	end
end

function pairsByKeys (t, f)
      local a = {}
      for n in pairs(t) do table.insert(a, n) end
      table.sort(a, f)
      local i = 0      -- iterator variable
      local iter = function ()   -- iterator function
        i = i + 1
        if a[i] == nil then return nil
        else return a[i], t[a[i]]
        end
      end
      return iter
end


---------------------------------------------------------
   --Name: table.SortByKey( table )
   --Desc: Returns a table sorted numerically by Key value
---------------------------------------------------------*/

function table.SortByKey( Table, Desc )

	local temp = {}

	for key, _ in pairs(Table) do table.insert(temp, key) end
	if ( Desc ) then
		table.sort(temp, function(a, b) return Table[a] < Table[b] end)
	else
		table.sort(temp, function(a, b) return Table[a] > Table[b] end)
	end

	return temp
end

---------------------------------------------------------
--   Name: table.SortByMember( table )
--   Desc: Sorts table by named member
---------------------------------------------------------*/
function table.SortByMember( Table, MemberName, bAsc )

	local TableMemberSort = function( a, b, MemberName, bReverse ) 
	
		if ( type(a) ~= "table" ) then return bReverse end
		if ( type(b) ~= "table" ) then return bReverse end
		if not ( a[MemberName] ) then return bReverse end
		if not ( b[MemberName] ) then return bReverse end
	
		if ( bReverse ) then
			return a[MemberName] < b[MemberName]
		else
			return a[MemberName] > b[MemberName]
		end
		
	end

	table.sort( Table, function(a, b) return TableMemberSort( a, b, MemberName, bAsc or false ) end )
	
end
User avatar
Elvashi
Prole
Posts: 45
Joined: Sat Jul 04, 2009 9:17 am
Location: Australia

Re: Helper/Utility Function Collection

Post by Elvashi »

This reminds me, didn't there used to be a snippets archive or something? we should probably revive that. maybe even package a "helpful.love" :)
"We could make a program for doing this for you, but that is for the LÖVE IDE, planned to be released in March 2142." ~mike
Networking with UDP uLove Proposal CCG: Gangrene
User avatar
Chucknorrisaurrus
Prole
Posts: 23
Joined: Mon Jun 07, 2010 1:00 am

Re: Helper/Utility Function Collection

Post by Chucknorrisaurrus »

There is an examples.love for the basics of LOVE, but it would be nice to have a collection of helpful tutorials or something of that nature.
User avatar
Elvashi
Prole
Posts: 45
Joined: Sat Jul 04, 2009 9:17 am
Location: Australia

Re: Helper/Utility Function Collection

Post by Elvashi »

Chucknorrisaurrus wrote:(...) but it would be nice to have a collection of helpful tutorials or something of that nature.
You mean like these?
"We could make a program for doing this for you, but that is for the LÖVE IDE, planned to be released in March 2142." ~mike
Networking with UDP uLove Proposal CCG: Gangrene
User avatar
Luiji
Party member
Posts: 396
Joined: Mon May 17, 2010 6:59 pm

Re: Helper/Utility Function Collection

Post by Luiji »

Yeah, we really just need more tutorials.
Good bye.
User avatar
Chucknorrisaurrus
Prole
Posts: 23
Joined: Mon Jun 07, 2010 1:00 am

Re: Helper/Utility Function Collection

Post by Chucknorrisaurrus »

Yeah, tuts for more advanced subjects.
User avatar
Luiji
Party member
Posts: 396
Joined: Mon May 17, 2010 6:59 pm

Re: Helper/Utility Function Collection

Post by Luiji »

Isometric rendering would be interesting.
Good bye.
User avatar
Taehl
Dreaming in associative arrays
Posts: 1025
Joined: Mon Jan 11, 2010 5:07 am
Location: CA, USA
Contact:

Re: Helper/Utility Function Collection

Post by Taehl »

Here's a couple handy functions I've written. Most of them are pretty highly optimized.

Code: Select all

----------------------------- Math -----------------------------

-- Returns the distance between two points
function math.dist(x1, y1, x2, y2) return ((x2-x1)^2+(y2-y1)^2)^0.5 end

-- Returns the closest multiple of 'size' (defaulting to 10)
function math.multiple(n, size) size = size or 10 return math.round(n/size)*size end

-- Clamps a number to within a certain range, with optional rounding
function math.clamp(low, n, high) return math.min(math.max(n, low), high) end

-- Returns 'n' rounded to the nearest 'deci'th
function math.round(n, deci) deci = 10^(deci or 0) return math.floor(n*deci+.5)/deci end

-- Randomly returns either -1 or 1
function math.rsign() return math.random(0,1)*2-1 end


--------------------------- Strings ----------------------------

-- Correct the print function to wrap text correctly to a console window.
oldprint = print
function print(s)
	repeat
		-- Get one console-width of the string
		line = string.sub(s, 1, 79)
		local ended = false
		if string.find(line, " ") and string.len(line) >= 79 then
			-- Find the last " " in it
			while not ended do
				local length = string.len(line)
				if string.sub(line, length, length) ~= " " then
					line = string.sub(line, 1, length-1)
				else
					ended = true
				end
			end
		end
		-- Remove the single line from the string
		s = string.sub(s, string.len(line)+1, string.len(s))
		local length = string.len(line)
		if string.sub(line, length, length) == " " then line = string.sub(line, 1, length-1) end
		oldprint(" "..line)
	until string.len(s) < 1
end

-- Turns a table into an English-correct comma-delimited list string.
function ListTable(t, combiner, keys)
	local l, e, current, last, combiner = "", "", 0, table.count(t), combiner or "and"
	if combiner ~= "" then combiner = combiner.." " end
	if last == 0 then return "nothing" end
	for k, v in pairs(t) do
		current = current + 1
		if keys then e = k else e = v  end
		if last == 1 then l = e
		elseif current == last then l = l..combiner..e
		elseif last < 3 and combiner ~= "" then l = e.." "
		else l = l..e..", "
		end
	end
	return l
end

-- Capitalize the input.
function string.capitalize(s)
	if string.len(s) < 2 then return string.upper(s) end
	return string.upper(string.sub(s, 1, 1))..string.sub(s,1-string.len(s))
end


---------------------------- Tables ----------------------------

-- Combines an arbitrary number of tables. Tables are not cross-contaminated in this process.
function table.combine(replace, ...)
	local nt = {}
	for i=1, select('#', ...) do
		local t= select(i, ...)
		for k, v in pairs(t) do
			if replace then nt[k] = v
			else table.insert(nt, v) end
		end
	end
	return nt
end

-- Find the key for a given value in a table
function table.getkey(t, value) for k, v in pairs(t) do if v == value then return k end end end
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Helper/Utility Function Collection

Post by kikito »

I really think this should be moved to a wiki page.
When I write def I mean function.
User avatar
thelinx
The Strongest
Posts: 857
Joined: Fri Sep 26, 2008 3:56 pm
Location: Sweden

Re: Helper/Utility Function Collection

Post by thelinx »

Stop polluting the global namespace with your utility functions :cry:
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot], Semrush [Bot] and 63 guests