Save arrays between sessions

Posted by Fletchling on Mon 07 Aug 2006 01:00 PM — 4 posts, 22,245 views.

Australia #0
I have a few arrays I'd like to save between the infrequent session close/open events. If it was a table I'd be happy with the convert and save/load via a string. Do arrays work the same?

I've created the variable with the following;

<aliases>
<alias
match="savespells"
enabled="y"
send_to="12"
sequence="100"
>
<send>SetVariable ("spellssu5", ArrayExport ("su4", "|"))</send>
</alias>
</aliases>

where;
spellssu5 is the target variable
su4 is the array being exported

Help appreciated with re-creating the array on loading, thanks
USA #1
Here are a serialization and unserialization function I created for my own use. It will store a variable as basic XML.

Examples of use (Lua):

this_is_an_array = {}

world.SetVariable('VarName',serialize(this_is_an_array))
this_is_an_array = unserialize(world.GetVariable()) or {}


--SERIALIZATION FUNCTIONS

function serialize(var,compression)
	if(type(var) == 'table') then
		local output = ''
		for index,value in pairs(var) do
			if(not (value == var)) then
				output = output .. '<i i="' .. index .. '">' .. serialize(value) .. '</i>'
			end
		end
		
		if(compression) then
			return '<ct>' .. utils.base64encode(utils.compress(output,9)) .. '</ct>'
		else
			return '<t>' .. output .. '</t>'
		end
	elseif(type(var) == 'number') then
		return '<n>' .. var .. '</n>'
	elseif(type(var) == 'string') then
		return '<s>' .. var .. '</s>'
	elseif(type(var) == 'boolean') then
		return '<b>' .. (var and 't' or 'f') .. '</b>'
	end
	
	return ''
end
function unserialize(var)
	if(var == nil) then
		return nil
	end
	
	local root = utils.xmlread(var)	
	
	if(root) then
		return unserialize_xml(root.nodes[1])
	else
		return nil
	end
end
function unserialize_xml(node)
	if(node.name == 'n') then return tonumber(node.content) end
	if(node.name == 's') then return tostring(node.content) end
	if(node.name == 'b') then return (tostring(node.content) == 't') end
	
	if(node.name == 'ct') then
		node.name = 't'
		local root = utils.xmlread(utils.decompress(utils.base64decode(node.content)))
		
		if(root) then
			node.nodes = root.nodes
		else
			return {}
		end
	end
	
	if(node.name == 't') then
		local t = {}
	
		if(node.nodes) then
			for _,child in ipairs(node.nodes) do
				if(child.name == 'i') then
					t[child.attributes['i']] = unserialize_xml(child.nodes[1])
				end
			end
		end
		
		return t
	end
	
	return nil
end


I would recommend putting the functions in a seperate script file which you can include through the world scripting interface. Then your triggers can call these functions as they execute their own code. Hope that helps. -Tsunami
Australia Forum Administrator #2
Well, ArrayImport effectively turns a string into an array, provided you create the empty array in advance.

http://www.gammon.com.au/scripts/doc.php?function=ArrayImport
Australia #3
Ilove this mush community.

I tried this and it seems to work nicely;

<aliases>
<alias
match="loadspells"
enabled="y"
expand_variables="y"
send_to="12"
sequence="100"
>
<send>ArrayDelete "su5"
ArrayCreate "su5"
ArrayImport ("su5", "@spellssu5", "|")</send>
</alias>
</aliases>

I've tried to keep all my mush stuff simple so the captive crash test dummy can understand it. Thanks for the help guys.

Mr N Gammon for Aussie of the Year, and thanks Tsunami heaps.