Main Menu

UFF - poor man's XML

Started by thaaks, May 14, 2006, 04:30:32 PM

Previous topic - Next topic

thaaks

Okay, I had a little look at the UFF stuff.
It's pretty easy to understand once you get the idea behind it.

I wrote a little test program that dumps an array of types to a UFF file and reads everything back in. You can edit the generated file "TEST.UFF" with a text editor - it looks similar to XML.

Here is the sample code:

; PROJECT : UFFTester
; AUTHOR  : Tommy Haaks
; CREATED : 14.05.2006
; EDITED  : 14.05.2006
; ---------------------------------------------------------------------

Explicit True

#Include "PlayUFF"

Type TNode
name$
x
y
value#
slot(10)
active
EndType

Dim Nodes(15) As TNode
Dim ReadNodes(15) As TNode


; let's fill some data
Local x, y, i, file$, node$, name$, slotnode$, slotline$

For i = 1 To 15
Nodes(i).name$ = "Node_" + Str$(i)
Nodes(i).x = i
Nodes(i).y = 2 * i
Nodes(i).value# = i * 2.5
If Mod(i, 2) = 0
 Nodes(i).active = True
Else
 Nodes(i).active = False
EndIf
For x = 1 To 10
 Nodes(i).slot(x) = i * 100 + x
Next x
Next i

; now let's create and fill the UFF file and data structures
file$ = "TEST.UFF"
; write all nodes into the "class" Nodes, each node has it's name as class name
UFF_addClass("Nodes")
For i = 1 To 15
; make all nodes "subclasses" of class "Nodes"
UFF_addClass("Nodes," + Nodes(i).name$)
; dump the node data
UFF_setInt("Nodes," + Nodes(i).name$, "x", Nodes(i).x)
UFF_setInt("Nodes," + Nodes(i).name$, "y", Nodes(i).y)
UFF_setFloat("Nodes," + Nodes(i).name$, "value", Nodes(i).value#)
UFF_setInt("Nodes," + Nodes(i).name$, "active", Nodes(i).active)
; dump the slots in their own class
UFF_addClass("Nodes," + Nodes(i).name$ + ",Slots")
For x = 1 To 10
 UFF_setInt("Nodes," + Nodes(i).name$ + ",Slots", Str$(x), Nodes(i).slot(x))
Next
Next
;UFF_output()
UFF_saveDB(file$)
Print "UFF file written to '" + file$ + "'!"
Print ""
Print "Press a key to read the file again."
Sync
WaitKey

; and now we retrieve it again
UFF_loadDB(file$)
If UFF_getClassExist("Nodes")
; load them all in
; assume we don't know how many are in, we just know their name
i = 1
node$ = "Node_" + Str$(i)
While UFF_getClassExist("Nodes," + node$)
 ReadNodes(i).name$ = node$
; fill the type by requesting each variable
 If UFF_getVariableExist(node$, "x")
  ReadNodes(i).x = UFF_getInt(node$, "x")
 EndIf
 If UFF_getVariableExist(node$, "y")
  ReadNodes(i).y = UFF_getInt(node$, "y")
 EndIf
 If UFF_getVariableExist(node$, "value")
  ReadNodes(i).value# = UFF_getFloat(node$, "value")
 EndIf
 If UFF_getVariableExist(node$, "active")
  ReadNodes(i).active = UFF_getInt(node$, "active")
 EndIf
; read the slots
 slotnode$ = "Nodes," + Node$ + ",Slots"
 If UFF_getClassExist(slotnode$)
  x = 1
  While UFF_getVariableExist(slotnode$, Str$(x))
   ReadNodes(i).slot(x) = UFF_getInt(slotnode$, Str$(x))
   Inc x
  EndWhile
 EndIf  
; next node
 Inc i
 node$ = "Node_" + Str$(i)
EndWhile
Print "Read " + Str$(i-1) + " nodes from file '" + file$ + "'."
EndIf
; done - now dump it
For i = 1 To 15
Print ReadNodes(i).name$ + ": x = " + Str$(ReadNodes(i).x) + ", y = " + Str$(ReadNodes(i).y) + _
  ", value# = " + Str$(ReadNodes(i).value#) + ", active = " + Str$(ReadNodes(i).active)
slotline$ = ""
For x = 1 To 10
 slotline$ = slotline$ + Str$(ReadNodes(i).slot(x))
 If (x < 10)
  slotline$ = slotline$ + ", "
 EndIf
Next
Print "slot() = " + slotline$
; verify if written nodes are identical to read nodes
If Nodes(i).name$ <> ReadNodes(i).name$
 Print "The names of element " + Str$(i) + " differ!"
EndIf
If Nodes(i).x <> ReadNodes(i).x
 Print "The x values of element " + Str$(i) + " differ!"
EndIf
If Nodes(i).y <> ReadNodes(i).y
 Print "The y values of element " + Str$(i) + " differ!"
EndIf
If Nodes(i).value# <> ReadNodes(i).value#
 Print "The values of element " + Str$(i) + " differ!"
EndIf
If Nodes(i).active <> ReadNodes(i).active
 Print "The names of element " + Str$(i) + " differ!"
EndIf
For x = 1 To 10
 If Nodes(i).slot(x) <> ReadNodes(i).slot(x)
  Print "The slot entries of element " + Str$(i) + " differ at position " + Str$(x) + "!"
 EndIf
Next
Next i
Print ""
Print "Done."
FlushKeys
Sync
WaitKey


You might have to remove the first line (Explicit true) to get the code to work without changes in the PlayUFF.pba.

To Kevin: I modified PlayUFF.pba to make it "Explicit conform".
I attached it to this post.
This will be an issue for all Slib files...

To all: feel free to ask if you have questions regarding the sample code but it's pretty self explaining  :D

So if you need complex ini files or level or character definition files the UFF file stuff is a good option!

Cheers,
Tommy