Difference between revisions of "Ftf libs"

From GiderosMobile
 
(2 intermediate revisions by the same user not shown)
Line 66: Line 66:
  
 
== GFX ==
 
== GFX ==
=== GTween '''Grant Skinner''' ===
 
'''[[Media:gtween.lua|Gtween.lua]]''' '''tip: right click and "Save Link As"'''
 
 
 
=== Hex to Number / Number to Hex '''@hanzhao''' ===
 
=== Hex to Number / Number to Hex '''@hanzhao''' ===
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
Line 230: Line 227:
 
end)
 
end)
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
=== Xml Parser '''@Alexander Makeev''' ===
 +
<syntaxhighlight lang="lua">
 +
-----------------------------------------------------------------------------------------
 +
-- LUA only XmlParser from Alexander Makeev
 +
-----------------------------------------------------------------------------------------
 +
XmlParser = {}
 +
 +
function XmlParser:ToXmlString(value)
 +
value = string.gsub(value, "&", "&amp;") -- '&' -> "&amp;"
 +
value = string.gsub(value, "<", "&lt;") -- '<' -> "&lt;"
 +
value = string.gsub(value, ">", "&gt;") -- '>' -> "&gt;"
 +
--value = string.gsub(value, "'", "&apos;") -- '\'' -> "&apos;"
 +
value = string.gsub(value, "\"", "&quot;") -- '"' -> "&quot;"
 +
-- replace non printable char -> "&#xD;"
 +
value = string.gsub(value, "([^%w%&%;%p%\t% ])", function(c)
 +
return string.format("&#x%X;", string.byte(c))
 +
--return string.format("&#x%02X;", string.byte(c))
 +
--return string.format("&#%02d;", string.byte(c))
 +
end)
 +
return value
 +
end
 +
 +
function XmlParser:FromXmlString(value)
 +
value = string.gsub(value, "&#x([%x]+)%;", function(h)
 +
return string.char(tonumber(h,16))
 +
end)
 +
value = string.gsub(value, "&#([0-9]+)%;", function(h)
 +
return string.char(tonumber(h,10))
 +
end)
 +
value = string.gsub(value, "&quot;", "\"")
 +
value = string.gsub(value, "&apos;", "'")
 +
value = string.gsub(value, "&gt;", ">")
 +
value = string.gsub(value, "&lt;", "<")
 +
value = string.gsub(value, "&amp;", "&")
 +
return value
 +
end
 +
 
 +
function XmlParser:ParseArgs(s)
 +
local arg = {}
 +
string.gsub(s, "(%w+)=([\"'])(.-)%2", function(w, _, a)
 +
arg[w] = self:FromXmlString(a)
 +
end)
 +
return arg
 +
end
 +
 +
function XmlParser:ParseXmlText(xmlText)
 +
local stack = {}
 +
local top = { Name=nil, Value=nil, Attributes={}, ChildNodes={} }
 +
table.insert(stack, top)
 +
local ni, c, label, xarg, empty
 +
local i, j = 1, 1
 +
while true do
 +
ni, j, c, label, xarg, empty = string.find(xmlText, "<(%/?)([%w:]+)(.-)(%/?)>", i)
 +
if not ni then break end
 +
local text = string.sub(xmlText, i, ni-1)
 +
if not string.find(text, "^%s*$") then
 +
top.Value=(top.Value or "")..self:FromXmlString(text)
 +
end
 +
if empty == "/" then -- empty element tag
 +
table.insert(top.ChildNodes,
 +
{
 +
Name=label, Value=nil, Attributes=self:ParseArgs(xarg), ChildNodes={}
 +
}
 +
)
 +
elseif c == "" then -- start tag
 +
top = { Name=label, Value=nil, Attributes=self:ParseArgs(xarg), ChildNodes={} }
 +
table.insert(stack, top) -- new level
 +
--log("openTag ="..top.Name)
 +
else -- end tag
 +
local toclose = table.remove(stack) -- remove top
 +
--log("closeTag="..toclose.Name)
 +
top = stack[#stack]
 +
if #stack < 1 then
 +
error("XmlParser: nothing to close with "..label)
 +
end
 +
if toclose.Name ~= label then
 +
error("XmlParser: trying to close "..toclose.Name.." with "..label)
 +
end
 +
table.insert(top.ChildNodes, toclose)
 +
end
 +
i = j + 1
 +
end
 +
local text = string.sub(xmlText, i)
 +
if not string.find(text, "^%s*$") then
 +
stack[#stack].Value=(stack[#stack].Value or "")..self:FromXmlString(text)
 +
end
 +
if #stack > 1 then
 +
error("XmlParser: unclosed "..stack[stack.n].Name)
 +
end
 +
return stack[1].ChildNodes[1]
 +
end
 +
 +
function XmlParser:ParseXmlFile(xmlFileName)
 +
local hFile, err = io.open(xmlFileName,"r")
 +
if (not err) then
 +
local xmlText=hFile:read("*a") -- read file content
 +
io.close(hFile)
 +
return self:ParseXmlText(xmlText),nil
 +
else
 +
return nil, err
 +
end
 +
end
 +
 +
--[[
 +
-- Usage:
 +
-- parse xml
 +
local xml = XmlParser:ParseXmlText(myxmlfile)
 +
]]
 +
</syntaxhighlight>
 +
 +
== TABLE ==
 +
=== Var Dump '''@xxx''' ===
 +
<syntaxhighlight lang="lua">
 +
function vardump(value, depth, key)
 +
local linePrefix = ""
 +
local spaces = ""
 +
 +
if key ~= nil then
 +
linePrefix = "["..key.."] = "
 +
end
 +
 +
if depth == nil then
 +
depth = 0
 +
else
 +
depth = depth + 1
 +
for i = 1, depth do
 +
spaces = spaces .. "  "
 +
end
 +
end
 +
 +
if type(value) == 'table' then
 +
local mTable = getmetatable(value)
 +
if mTable == nil then
 +
print(spaces ..linePrefix.."(table) ")
 +
else
 +
print(spaces .."(metatable) ")
 +
value = mTable
 +
end
 +
for tableKey, tableValue in pairs(value) do
 +
vardump(tableValue, depth, tableKey)
 +
end
 +
elseif type(value) == 'function' or
 +
type(value) == 'thread' or
 +
type(value) == 'userdata' or
 +
value == nil
 +
then
 +
print(spaces..tostring(value))
 +
else
 +
print(spaces..linePrefix.."("..type(value)..") "..tostring(value))
 +
end
 +
end
 +
 +
--[[
 +
Usage:
 +
foo="Hello world"
 +
vardump(foo)
 +
vardump( { print, 12, nil, io.stdin, math } )
 +
 +
foo = {
 +
"zero",1,2,3,{1,{1,2,3,4,{1,2,{1,"cool",2},4},6},3,vardump,5,6},          5,{Mary=10, Paul="10"},"last value"
 +
}
 +
vardump(foo)
 +
--]]
 +
</syntaxhighlight>
 +
 +
  
  

Latest revision as of 20:54, 17 May 2025

Here are some longer code (classes) from the Gideros forum and some other places :-)

All samples are ready to use. Enjoy!

STRING

Score Counting TextField @errorpi

--[[
	Score Counting TextField
	by: @errorpi
]]

Score = Core.class(Sprite)
 
function Score:init(xscore, xincrease)
	self.score = xscore or 0
	self.countTime = (xincrease or 5) * 100
	-- a textfield
	self.scoreText = TextField.new(nil, tostring(self.score))
	self.scoreText:setLayout({wid = 80, hei = 40, flags=FontBase.TLF_CENTER})
	self.scoreText:setTextColor(math.random(0xffffff))
	self.scoreText:setScale(5)
	self.scoreText:setPosition(64, 64)
	self:addChild(self.scoreText)
	-- a timer
	self.t = Timer.new(1) -- timer init
	self.t:addEventListener(Event.TIMER, self.updateText, self)
end
 
function Score:updateText()
	local displayScore = tonumber(self.scoreText:getText())
	if displayScore < self.score then
		self.scoreText:setText(tostring( displayScore + 1) )
	end
end

function Score:addScore(add)
	self.score += add
	local displayScore = tonumber(self.scoreText:getText())
	-- set timer properties (bigger add score means faster steps)
	local tRepeat = self.score - displayScore
	local tDelay =  self.countTime / tRepeat
	self.t:stop()
	self.t:reset()
	self.t:setDelay(tDelay)
	self.t:setRepeatCount(tRepeat)
	self.t:start()

	return self.score
end

--------------------
application:setBackgroundColor(0x4d4d4d)
-- demo
local initialscore = 500
local score = Score.new(initialscore, 6) -- initial score value, increase speed
stage:addChild(score)
local earnedpoints = 300

Timer.delayedCall(3000, function()
	score:addScore(earnedpoints) -- target score value
end)

GFX

Hex to Number / Number to Hex @hanzhao

--[[
Lua Hex v0.4
-------------------
Hex conversion lib for Lua.

How to use:
 lhex.to_hex(n) -- convert a number to a hex string
 lhex.to_dec(hex) -- convert a hex "string" (prefix with "0x..." or "0X...") to number

Part of LuaBit(http://luaforge.net/projects/bit/).

Under the MIT license.

copyright(c) 2006~2007 hanzhao (abrash_han@hotmail.com)
--]]

local function to_bits(n)
	-- checking not float
	if(n - (n//1) > 0) then error("trying to apply bitwise operation on non-integer!") end
	if(n < 0) then return to_bits(~(n//1) + 1) end -- negative
	-- to bits table
	local tbl = {}
	local cnt = 1
	while (n > 0) do
		local last = n%2
		if(last == 1) then tbl[cnt] = 1
		else tbl[cnt] = 0
		end
		n = (n-last)/2
		cnt += 1
	end
	return tbl
end

local function tbl_to_number(tbl)
	local n = #tbl
	local rslt = 0
	local power = 1
	for i = 1, n do
		rslt += tbl[i]*power
		power *= 2
	end
	return rslt
end

local function to_hex(n)
	if(type(n) ~= "number") then error("non-number type passed in.") end
	-- checking not float
	if(n - (n//1) > 0) then error("trying to apply bitwise operation on non-integer!") end
	if(n < 0) then -- negative
		n = to_bits(~(-n<>n) + 1)
		n = tbl_to_number(n)
	end
	local hex_tbl = { "A", "B", "C", "D", "E", "F" }
	local hex_str = ""
	while(n ~= 0) do
		local last = n%16
		if(last < 10) then hex_str = tostring(last) .. hex_str
		else hex_str = hex_tbl[last-10+1] .. hex_str
		end
		n = (n/16)//1 -- floor
	end
	if(hex_str == "") then hex_str = "0" end
	return "0x"..hex_str
end

local function to_dec(hexstring)
	if(type(hexstring) ~= "string") then error("non-string type passed in.") end
	local head = string.sub(hexstring, 1, 2)
	if(head ~= "0x" and head ~= "0X") then error("wrong hex format, should lead by 0x or 0X.") end
	return tonumber(hexstring:sub(3), 16) -- base 16
end

--------------------
-- lua hex lib interface
lhex = {
	to_hex=to_hex,
	to_dec=to_dec,
}

--------------------
-- examples
local dec = 4341688
local hex = lhex.to_hex(dec) -- number to hex
print(hex) -- 0x423FB8
local revdec = lhex.to_dec(hex) -- hex string (prefix with "0x" or "0X") to number
print(revdec) -- 4341688

print(lhex.to_dec("0x0")) -- 0, hex string (prefix with "0x" or "0X") to number
print(lhex.to_dec("0x00ff00")) -- 65280, hex string (prefix with "0x" or "0X") to number
print(lhex.to_hex(16777215)) -- 0xFFFFFF, number to hex

local pix = Pixel.new(lhex.to_hex(56816), 1, 32, 32)
stage:addChild(pix)

print("hex is", hex)

FILES

Get Files in Folder @xxx

note: requires the Lfs plugin

Gets all the files in a folder matching a file extension and store them in a list.

local myos = application:getDeviceInfo()
local iswin32 = if myos == "win32" then true else false
--print(iswin32)

function getFilesInFolder(xpath, xlist)
	local lfs = require "lfs"
	for file in lfs.dir(xpath) do
		if file ~= "." and file ~= ".." then
			if file:match(".png$") then -- choose your file extension here
				if iswin32 then
					local f = xpath.."\\"..file
--					print(f)
					xlist[#xlist + 1] = f:gsub("/", "\\")
				else
					local f = xpath.."/"..file
--					print(f)
					xlist[#xlist + 1] = f:gsub("\\", "/")
				end
			end
		end
	end
	lfs = nil
end

Demo code using ButtonMonster

local myos = application:getDeviceInfo()
local iswin32 = if myos == "win32" then true else false
--print(iswin32)

local folderimages = {} -- list all images in user selected folder
local images = {} -- list all images with valid extension
local btnimagefolder = ButtonMonster.new({
	pixelcolorup=0xffaa00, text="import images", textcolorup=0xaa0000, textscalex=3,
	isautoscale=true,
})
btnimagefolder:setPosition(16, 16)
stage:addChild(btnimagefolder)
btnimagefolder:addEventListener("clicked", function()
	local path
	if iswin32 then path = application:get("openDirectoryDialog", "Select Folder", "C:\\tmp\\")
	else path = application:get("openDirectoryDialog", "Select Folder", "C:/tmp/")
	end -- print(path)
	if path then getFilesInFolder(path, folderimages) end
	if folderimages and #folderimages > 0 then
		for i = 1, #folderimages do
			images[i] = Bitmap.new(Texture.new(folderimages[i]), true)
			images[i]:setAnchorPoint(0.5, 1)
			images[i]:setPosition(8, 8)
			-- ...
		end
	end
end)

Xml Parser @Alexander Makeev

-----------------------------------------------------------------------------------------
-- LUA only XmlParser from Alexander Makeev
-----------------------------------------------------------------------------------------
XmlParser = {}

function XmlParser:ToXmlString(value)
	value = string.gsub(value, "&", "&amp;")		-- '&' -> "&amp;"
	value = string.gsub(value, "<", "&lt;")		-- '<' -> "&lt;"
	value = string.gsub(value, ">", "&gt;")		-- '>' -> "&gt;"
	--value = string.gsub(value, "'", "&apos;")	-- '\'' -> "&apos;"
	value = string.gsub(value, "\"", "&quot;")	-- '"' -> "&quot;"
	-- replace non printable char -> "&#xD;"
	value = string.gsub(value, "([^%w%&%;%p%\t% ])", function(c)
		return string.format("&#x%X;", string.byte(c))
		--return string.format("&#x%02X;", string.byte(c))
		--return string.format("&#%02d;", string.byte(c))
	end)
	return value
end

function XmlParser:FromXmlString(value)
	value = string.gsub(value, "&#x([%x]+)%;", function(h)
		return string.char(tonumber(h,16))
	end)
	value = string.gsub(value, "&#([0-9]+)%;", function(h)
		return string.char(tonumber(h,10))
	end)
	value = string.gsub(value, "&quot;", "\"")
	value = string.gsub(value, "&apos;", "'")
	value = string.gsub(value, "&gt;", ">")
	value = string.gsub(value, "&lt;", "<")
	value = string.gsub(value, "&amp;", "&")
	return value
end
   
function XmlParser:ParseArgs(s)
	local arg = {}
	string.gsub(s, "(%w+)=([\"'])(.-)%2", function(w, _, a)
		arg[w] = self:FromXmlString(a)
	end)
	return arg
end

function XmlParser:ParseXmlText(xmlText)
	local stack = {}
	local top = { Name=nil, Value=nil, Attributes={}, ChildNodes={} }
	table.insert(stack, top)
	local ni, c, label, xarg, empty
	local i, j = 1, 1
	while true do
		ni, j, c, label, xarg, empty = string.find(xmlText, "<(%/?)([%w:]+)(.-)(%/?)>", i)
		if not ni then break end
		local text = string.sub(xmlText, i, ni-1)
		if not string.find(text, "^%s*$") then
			top.Value=(top.Value or "")..self:FromXmlString(text)
		end
		if empty == "/" then -- empty element tag
			table.insert(top.ChildNodes,
				{
					Name=label, Value=nil, Attributes=self:ParseArgs(xarg), ChildNodes={}
				}
			)
		elseif c == "" then -- start tag
			top = { Name=label, Value=nil, Attributes=self:ParseArgs(xarg), ChildNodes={} }
			table.insert(stack, top) -- new level
			--log("openTag ="..top.Name)
		else -- end tag
			local toclose = table.remove(stack) -- remove top
			--log("closeTag="..toclose.Name)
			top = stack[#stack]
			if #stack < 1 then
				error("XmlParser: nothing to close with "..label)
			end
			if toclose.Name ~= label then
				error("XmlParser: trying to close "..toclose.Name.." with "..label)
			end
			table.insert(top.ChildNodes, toclose)
		end
		i = j + 1
	end
	local text = string.sub(xmlText, i)
	if not string.find(text, "^%s*$") then
		stack[#stack].Value=(stack[#stack].Value or "")..self:FromXmlString(text)
	end
	if #stack > 1 then
		error("XmlParser: unclosed "..stack[stack.n].Name)
	end
	return stack[1].ChildNodes[1]
end

function XmlParser:ParseXmlFile(xmlFileName)
	local hFile, err = io.open(xmlFileName,"r")
	if (not err) then
		local xmlText=hFile:read("*a") -- read file content
		io.close(hFile)
		return self:ParseXmlText(xmlText),nil
	else
		return nil, err
	end
end

--[[
-- Usage:
-- parse xml
local xml = XmlParser:ParseXmlText(myxmlfile)
]]

TABLE

Var Dump @xxx

function vardump(value, depth, key)
	local linePrefix = ""
	local spaces = ""

	if key ~= nil then
		linePrefix = "["..key.."] = "
	end

	if depth == nil then
		depth = 0
	else
		depth = depth + 1
		for i = 1, depth do
			spaces = spaces .. "  "
		end
	end

	if type(value) == 'table' then
		local mTable = getmetatable(value)
		if mTable == nil then
			print(spaces ..linePrefix.."(table) ")
		else
			print(spaces .."(metatable) ")
			value = mTable
		end		
		for tableKey, tableValue in pairs(value) do
			vardump(tableValue, depth, tableKey)
		end
	elseif type(value) == 'function' or
		type(value)	== 'thread' or
		type(value)	== 'userdata' or
		value == nil
		then
		print(spaces..tostring(value))
	else
		print(spaces..linePrefix.."("..type(value)..") "..tostring(value))
	end
end

--[[
Usage:
foo="Hello world"
vardump(foo)
vardump( { print, 12, nil, io.stdin, math } )

foo = {
	"zero",1,2,3,{1,{1,2,3,4,{1,2,{1,"cool",2},4},6},3,vardump,5,6},          5,{Mary=10, Paul="10"},"last value"
}
vardump(foo)
--]]




More to come God's willing...