@ -8,115 +8,65 @@ author expwnent
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				This  module  is  intended  to  help  facilitate  persistent  table  lookups . 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				It  is  a  wrapper  over  dfhack.persistent  calls . 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				It  supports  tables  of  arbitrary  dimension  and  shape . 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				Argument  names  should  not  include  any  of  the  following  symbols :  _ \ /& 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				It  stores  information  about  each  table  and  subtable ' s size and children. 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				For  convenience ,  all  stored  information  is  itself  persistent . 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				It  would  be  more  efficient  to  cache  stored  information  in  global  variables  and  update  it  on  save / load  but  this  is  not  yet  implemented . 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				Ask  expwnent  to  try  this  if  performance  is  bad . 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				--]] 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				--[[ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				function  accessTable ( ... ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  args  =  { ... } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  name  =  ' mastertable ' 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  previousName  =  nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  child 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 for  n , arg  in  ipairs ( args )  do 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  child  =  ensure ( prefix  ..  name  ..  ' $$ '  ..  arg ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  local  old  =  child.value 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  if  old  ==  ' '  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   child.value  =  gensym ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   child.ints [ 1 ]  =  0 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   local  size  =  ensure ( prefix  ..  name  ..  ' $size ' ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   size.value  =  tostring ( 1 + ( tonumber ( size.value )  or  0 ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   size : save ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   if  previousName  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    --local size = ensure(previousName .. '$size') 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    --size.value = tostring(1+(tonumber(size.value) or 0)) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    --size:save() 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    local  prev  =  ensure ( prefix  ..  name  ..  ' $previous ' ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    prev.value  =  previousName 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    prev : save ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   child : save ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   --new child 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   dfhack.persistent . save ( { key = prefix  ..  name ,  value = arg } ,  true ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  --print(n,arg,previousName,child.key,child.value) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  previousName  =  name 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  name  =  child.value 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 return  child 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				Usage : 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				local  persistTable  =  require  ' persist-table ' 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				persistTable.GlobalTable . doomitude  =  ' doom! '  -- will be stored persistently 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				print ( persistTable.GlobalTable . doomitude )  --doom! 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				persistTable.GlobalTable . doomitude  =  nil  --delete the persistent record 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				print ( persistTable.GlobalTable . doomitude )  --nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				persistTable.GlobalTable . mana  =  { }  --allocate a subtable for mana 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				local  mana  =  persistTable.GlobalTable . mana  --setting elements in this table will be persistent too 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				mana [ ' 1 ' ]  =  ' 3 '  --slightly faster than persistTable.GlobalTable.mana['1'] = '3' 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				--be aware that if you don't change the local variable mana when the game exits and reloads a different save you will run into mysterious problems so don't do that 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				mana [ ' 2 ' ]  =  ' 100 ' 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				mana.maximum  =  ' 1000 '  --tables can be any arbitrary shape 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				local  globalTable  =  persistTable.GlobalTable  --this is safe too 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				globalTable.mana  =  nil  --this is safe: it will deallocate all subtables cleanly 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				globalTable.revengeDesire  =  { } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				--globalTable.revengeDseire.foo = {} -- error: tables must be allocated first with parentTable.subtableName = {} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				--you can check if it exists with globalTable.tableName != nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				local  revengeTable  =  globalTable.revengeDesire 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				revengeTable [ ' 2 ' ]  =  revengeTable [ ' 2 ' ]  or  { }  --this is fine too 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				revengeTable [ ' 2 ' ] [ ' 3 ' ]  =  ' totally a lot, man ' 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				revengeTable [ ' 3 ' ]  =  { } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				revengeTable [ ' 3 ' ] [ ' 2 ' ]  =  ' maybe a little bit ' 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				revengeTable [ ' 2 ' ]  =  nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				------------- 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				And  so  on . 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				Be  careful  not  to  name  your  tables  in  a  way  that  will  conflict  with  other  scripts !  The  easiest  way  is  to  just  put  all  your  tables  in  one  giant  table  named  based  on  your  script . 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				All  stored  values  MUST  be  strings .  Numbers  can  be  supported  later  but  are  not  yet  supported .  Keep  in  mind  there  is  a  significant  overhead  for  each  table  element  so  don ' t go totally crazy storing massive amounts of information or the game will run out of RAM. 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				--table._children returns a list of child keys 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				for  _ , childKey  in  ipairs ( table._children )  do 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  child  =  table [ childKey ] 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 --blah 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				function  deleteTable ( name ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 if  not  name  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  do  return  end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  previous  =  ensure ( prefix  ..  name  ..  ' $previous ' ) . value 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  children  =  dfhack.persistent . get_all ( prefix  ..  name )  or  { } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 for  _ , child  in  ipairs ( children )  do 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  --print('delete: ', name, previous, child) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  local  ptr  =  ensure ( prefix  ..  name  ..  ' $$ '  ..  child.value ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  if  (  ptr.ints [ 1 ]  ==  0  )  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   --releasesym(ptr.value) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   deleteTable ( ptr.value ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  ptr : delete ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  child : delete ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 ensure ( prefix  ..  name  ..  ' $previous ' ) : delete ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 ensure ( prefix  ..  name  ..  ' $size ' ) : delete ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 if  previous  ~=  ' '  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  local  size  =  ensure ( prefix  ..  previous  ..  ' $size ' ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  size.value  =  tostring ( - 1  +  tonumber ( size.value ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  size : save ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  local  children  =  dfhack.persistent . get_all ( prefix  ..  previous )  or  { } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  for  _ , sibling  in  ipairs ( children )  do 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   --print(sibling.value, name, previous .. '$$' .. sibling.value) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   local  ptr  =  ensure ( prefix  ..  previous  ..  ' $$ '  ..  sibling.value ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   if  ptr.value  ==  name  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    ptr : delete ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    sibling : delete ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 releasesym ( name ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				function  setTable ( ... ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  args  =  { ... } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  last  =  args [ # args ] 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 table.remove ( args , # args ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 --table.setn(args, #args-1) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  entry  =  accessTable ( table.unpack ( args ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  old  =  entry.value 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 if  entry.ints [ 1 ]  ==  0  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  deleteTable ( old ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 entry.ints [ 1 ]  =  - 1 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 entry.value  =  last 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 entry : save ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 return  old 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				--]] 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				local  prefix  =  ' persist-table ' 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				prefix  =  ' persist-table ' 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				function  ensure ( name ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				local  function  ensure ( name ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 return  dfhack.persistent . save ( { key = name } ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				function  gensym ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				local  function  gensym ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  availables  =  dfhack.persistent . get_all ( prefix  ..  ' $available ' )  or  { } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  available  =  nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  smallest  =  nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 for  _ , candidate  in  pairs ( availables )  do 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  --TODO: it would be great if we could iterate over these in order but we can't 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  local  score  =  tonumber ( candidate.value ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  print ( ' gensym ' ,  candidate ,  score ,  available ,  smallest  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  --print('gensym', candidate, score, available, smallest) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  if  ( score  and  ( not  available  or  score  <  smallest ) )  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   smallest  =  score 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   available  =  candidate 
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -125,7 +75,7 @@ function gensym()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 if  available  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  local  value  =  available.value 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  available : delete ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  print ( ' gensym: allocate  '  ..  value  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  --print('gensym: allocate ' .. value  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  return  value 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 --none explicitly available, so smallest unused is the next available number 
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -136,21 +86,21 @@ function gensym()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  result  =  smallestUnused.value 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 smallestUnused.value  =  tostring ( 1 + tonumber ( result ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 smallestUnused : save ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  print ( ' gensym: allocate  '  ..  result  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  --print('gensym: allocate ' .. result  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 return  result 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				function  releasesym ( symb ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				local  function  releasesym ( symb ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  availables  =  dfhack.persistent . get_all ( prefix  ..  ' $available ' )  or  { } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 for  _ , available  in  pairs ( availables )  do 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  print ( ' releasesym:  ' ,  symb ,  available.value ,  available  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  --print('releasesym: ', symb, available.value, available  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  if  available.value  ==  symb  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   print ( ' error: persist-table.releasesym( '  ..  symb  ..  ' ): available.value =  '  ..  available.value ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   return 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 dfhack.persistent . save ( { key = prefix  ..  ' $available ' ,  value = symb } ,  true ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 print ( ' releasesym: unallocate  '  ..  symb  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 --print('releasesym: unallocate ' .. symb  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				local  intCount  =  7 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				local  existIndex  =  intCount - 0 
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -179,30 +129,39 @@ local function deletePersistent(name)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  releasesym ( name ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				GlobalTable  =  { key  =  ' mastertable ' } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				GlobalTable.mt  =  { } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				GlobalTable.mt . __index  =  function ( table ,  key ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 print ( rawget ( table , ' key ' )  ..  ' [ '  ..  key  ..  ' ] ' ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  entry  =  ensure ( prefix  ..  rawget ( table , ' key ' )  ..  ' $$ '  ..  key ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				GlobalTable  =  GlobalTable  or  { key  =  ' mastertable ' } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				GlobalTable.mt  =  GlobalTable.mt  or  { } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				GlobalTable.mt . __index  =  GlobalTable.mt . __index  or  function ( theTable ,  key ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 if  key  ==  ' _children '  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  return  rawget ( theTable , key ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 --print(rawget(theTable,'key') .. '[' .. key .. ']') 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  entry  =  ensure ( prefix  ..  rawget ( theTable , ' key ' )  ..  ' $$ '  ..  key ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 if  entry.ints [ existIndex ]  ==  existValue  and  entry.ints [ pointerIndex ]  ==  defaultValue  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  print ( ' string:  '  ..  entry.value ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  --print('string: ' .. entry.value  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  return  entry.value 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 if  entry.ints [ pointerIndex ]  ==  pointerValue  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  --pre-existing pointer 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  local  result  =  { key  =  entry.value } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  result.mt  =  rawget ( GlobalTable , ' mt ' ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  local  childArgs  =  dfhack.persistent . get_all ( prefix  ..  entry.value ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  result._children  =  { } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  for  _ , childArg  in  ipairs ( childArgs  or  { } )  do 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   --print(result._children, childArg.value) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   table.insert ( result._children ,  childArg.value ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  setmetatable ( result , rawget ( GlobalTable , ' mt ' ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  print ( ' table:  '  ..  entry.value ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  --print('theTable: ' .. entry.value  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  return  result 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 entry : delete ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 print  ' table[key] does not exist. ' 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 --print 'theTable[key] does not exist.  '
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 return  nil 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				GlobalTable.mt . __newindex  =  function ( t able,  key ,  value ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 print ( rawget ( table , ' key ' )  ..  ' [ '  ..  key  ..  ' ] =  '  ..  tostring ( value )  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  entry  =  ensure ( prefix  ..  rawget ( t able, ' key ' )  ..  ' $$ '  ..  key ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				GlobalTable.mt . __newindex  =  GlobalTable.mt . __newindex  or  function ( t heT able,  key ,  value ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 --print(rawget(theTable,'key') .. '[' .. key .. '] = ' .. tostring(value)  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  entry  =  ensure ( prefix  ..  rawget ( t heT able, ' key ' )  ..  ' $$ '  ..  key ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  old  =  entry.value 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 local  isNew  =  entry.ints [ existIndex ]  ==  defaultValue 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 if  entry.ints [ existIndex ]  ==  existValue  and  entry.ints [ pointerIndex ]  ==  pointerValue  then 
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -213,9 +172,9 @@ GlobalTable.mt.__newindex = function(table, key, value)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  deletePersistent ( entry.value ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 if  not  value  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  print ( ' __newindesx: delete '  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  --print('__newindesx: delete'  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  --delete 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  for  i , child  in  ipairs ( dfhack.persistent . get_all ( prefix  ..  rawget ( t able, ' key ' ) )  or  { } )  do 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  for  i , child  in  ipairs ( dfhack.persistent . get_all ( prefix  ..  rawget ( t heT able, ' key ' ) )  or  { } )  do 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   if  child.value  ==  key  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    child : delete ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   end 
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -223,23 +182,23 @@ GlobalTable.mt.__newindex = function(table, key, value)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  entry : delete ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  return 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 elseif  type ( value )  ==  ' string '  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  print ( ' __newindesx: string '  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  --print('__newindesx: string'  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  entry.value  =  value 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  entry.ints [ pointerIndex ]  =  defaultValue 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  entry.ints [ existIndex ]  =  existValue 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  entry : save ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  if  isNew  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   print ( ' new child! '  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   dfhack.persistent . save ( { key = prefix  ..  rawget ( t able, ' key ' ) ,  value = key } ,  true ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   --print('new child!'  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   dfhack.persistent . save ( { key = prefix  ..  rawget ( t heT able, ' key ' ) ,  value = key } ,  true ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  return 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 elseif  type ( value )  ==  ' table '  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  print ( ' __newindesx: table '  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  --print('__newindesx: table'  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  if  rawget ( value , ' mt ' )  ~=  rawget ( GlobalTable , ' mt ' )  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   if  not  isEmpty ( value )  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    error ( ' setting value to an invalid table ' ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   print ( ' __newindesx: empty table '  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   --print('__newindesx: empty table'  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   --empty table: allocate a thing 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   entry.ints [ pointerIndex ]  =  pointerValue 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   entry.ints [ existIndex ]  =  existValue 
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -247,19 +206,19 @@ GlobalTable.mt.__newindex = function(table, key, value)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   entry : save ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   if  isNew  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    print ( ' new child! '  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    dfhack.persistent . save ( { key = prefix  ..  rawget ( t able, ' key ' ) ,  value = key } ,  true ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    --print('new child!'  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    dfhack.persistent . save ( { key = prefix  ..  rawget ( t heT able, ' key ' ) ,  value = key } ,  true ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   return 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  print ( ' __newindesx: table assignment '  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  --print('__newindesx: table assignment'  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  entry.value  =  rawget ( value , ' key ' ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  entry.ints [ pointerIndex ]  =  pointerValue 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  entry.ints [ existIndex ]  =  existValue 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  entry : save ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  if  isNew  then 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   print ( ' new child! '  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   dfhack.persistent . save ( { key = prefix  ..  rawget ( t able, ' key ' ) ,  value = key } ,  true ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   --print('new child!'  )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				   dfhack.persistent . save ( { key = prefix  ..  rawget ( t heT able, ' key ' ) ,  value = key } ,  true ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  end 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  return 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 else