djpeters original code (with some notes and minimal modifications by me:)
Code: Select all
'' Custom UDT Properties by djpeters (2006)
'' Modified by mrToad (2024)
'' Changes: adjusting from base-0 to base-1 for user interaction. the UDT itself must use Reallocate (base-0).
type PROPERTY_T
declare constructor(desc as string, v as string)
as string Description
as string tValue ' text
as integer iValue ' int
as single fValue ' float
end type
type PPROPERTY_T as PROPERTY_T ptr
constructor PROPERTY_T(desc as string, value as string)
Description=desc
select case lcase(left(desc,1))
case "i":iValue=val(value)
case "f":fValue=val(value)
case "t":tValue=value
end select
end constructor
type UDT
declare function Count() as integer
declare sub Add(desc as string, v as string)
declare sub Show(byval n as integer)
declare sub Edit(byval n as Integer, byval ival As Integer)
Declare Sub Del(byval n As Integer)
private:
as integer nProperties
as PPROPERTY_T ptr Properties
end type
function UDT.Count() as integer
return nProperties
end function
sub UDT.Add(desc as string, v as string)
Properties = reallocate(Properties, _
(nProperties+1) _
* sizeof(PPROPERTY_T))
Properties[nProperties]=new PROPERTY_T(desc,v)
nProperties+=1
end sub
sub UDT.Show(byval n as integer)
n -= 1 '' Reduce n by 1 to align with base-0 array
print right( properties[n]->Description, _
len(properties[n]->Description)-1) & ": ";
select case lcase(left(properties[n]->Description,1))
case "i" :print str(Properties[n]->iValue)
case "f" :print str(Properties[n]->fValue)
case else:print Properties[n]->tValue
end select
end sub
sub UDT.Edit(byval n as Integer, byval ival As Integer)
properties[n-1]->iValue = ival
end Sub
Sub UDT.Del(byval n As Integer)
DeAllocate properties[n-1]
nProperties-=1
End Sub
on error goto err_
dim as UDT GameUdt
' add properties to your UDT
' you can do it via code
' or load it from file
' the first letter of the description
' are the type and will not shown
print str(GameUdt.Count()); " properties"
GameUdt.Add("tName" ,"Jon")
GameUdt.Add("iAge" ,"14")
GameUdt.Add("fWeight","55.8")
print
print "added " & GameUdt.Count() & " properties:"
for i as integer=1 to GameUdt.Count
GameUdt.Show(i)
next
'' You cannot adjust the datatype of a property (from string to integer, from integer to float, for example.) -mrToad
'' does not work:
'GameUdt.Edit(3,18)
'GameUdt.Edit(1,"Johnny")
GameUdt.Edit(2,12)
GameUdt.Edit(3,39.4)
print
print "edited properties":
for i as integer = 1 to GameUdt.Count
GameUdt.Show(i)
GameUdt.del(i)
Next
print
print "deleted properties. bye bye!"
Sleep
end
err_:
'' Doesn't work for manual memory handling problems. -mrToad
print "Runtime Error:" & err
sleep
Lengthy ChatGPT-4o rewrite that doesn't work (with minimal changes by me):
Code: Select all
'' Problematic rewrite of "djpeters custom udt properties.bas" using chatGPT-4o.
'' Contains good ideas but might have been a waste of time since the goal was to
'' use dynamic arrays in a nested UDT which it claims this will work, but there
'' are 8 errors to start with and look similar to the array issue I had before.
'' Some of the errors are due to illegal member access (error 202) but the error
'' 9 and 54 are related to the core problem.
'' Besides that it is a lot more code to replace my current method (with a set
'' max amount of attributes.)
'' Also I still planned on revising it to edit attributes by name and not just index.
'' mrToad, Dec 7 2024
Type Property_T
Declare Constructor(desc As String, v As String)
Declare Sub SetValue(v As String)
Declare Sub Show()
As String Description
As String tValue ' Text
As Integer iValue ' Integer
As Single fValue ' Float
End Type
Constructor Property_T(desc As String, v As String)
Description = desc
SetValue(v)
End Constructor
Sub Property_T.SetValue(v As String)
Select Case LCase(Left(Description, 1))
Case "i": iValue = Val(v)
Case "f": fValue = Val(v)
Case Else: tValue = v
End Select
End Sub
Sub Property_T.Show()
Print Right(Description, Len(Description) - 1) & ": ";
Select Case LCase(Left(Description, 1))
Case "i": Print iValue
Case "f": Print fValue
Case Else: Print tValue
End Select
End Sub
Type UDT
Declare Constructor() ' Initialize array
Declare Function Count() As Integer
Declare Sub Add(desc As String, v As String)
Declare Sub Edit(index As Integer, v As String)
Declare Sub Show(index As Integer)
Declare Sub ClearAll()
Private:
As Integer nProperties
As Property_T Ptr Properties() ' Dynamic array of pointers
End Type
error
Constructor UDT()
nProperties = 0
ReDim Properties(0 To -1) As Property_T Ptr ' Initialize as empty array
End Constructor
Function UDT.Count() As Integer
Return nProperties
End Function
Sub UDT.Add(desc As String, v As String)
ReDim Preserve Properties(0 To nProperties) As Property_T Ptr
Properties(nProperties) = New Property_T(desc, v)
nProperties += 1
End Sub
Sub UDT.Edit(index As Integer, v As String)
If index < 1 Or index > nProperties Then
Print "Invalid property index!"
Exit Sub
End If
Properties(index - 1)->SetValue(v)
End Sub
Sub UDT.Show(index As Integer)
If index < 1 Or index > nProperties Then
Print "Invalid property index!"
Exit Sub
End If
Properties(index - 1)->Show()
End Sub
Sub UDT.ClearAll()
For i As Integer = 0 To nProperties - 1
Delete Properties(i)
Next
nProperties = 0
ReDim Properties(0)
End Sub
Type attr
Declare Sub add(desc As String, v As String)
Declare Sub showAll()
Declare Sub edit(index As Integer, v As String)
Declare Sub clearAll()
Declare Sub remove(index As Integer)
Private:
As String Name
As UDT InnerUDT ' Nested UDT
End Type
Sub attr.add(desc As String, v As String)
InnerUDT.Add(desc, v)
End Sub
Sub attr.showAll()
Print "Properties for attr - Name: "; Name
For i As Integer = 1 To InnerUDT.Count()
InnerUDT.Show(i)
Next
End Sub
Sub attr.edit(index As Integer, v As String)
InnerUDT.Edit(index, v)
End Sub
Sub attr.clearAll()
InnerUDT.ClearAll()
End Sub
Sub attr.remove(index As Integer)
If index < 1 Or index > InnerUDT.Count() Then
Print "Invalid property index!"
Exit Sub
End If
' Remove the property at the specified index
For i As Integer = index To InnerUDT.Count() - 1
InnerUDT.Properties(i - 1) = InnerUDT.Properties(i)
Next
' Deallocate the last property and resize the array
InnerUDT.Properties(InnerUDT.Count() - 1)->~Property_T() ' Call destructor
InnerUDT.nProperties -= 1
ReDim Preserve InnerUDT.Properties(0 To InnerUDT.Count() - 1)
End Sub
Dim obj(1 To 3) As attr ' Renamed from Game
' Add properties to each attr
obj(1).add("tName", "Hero")
obj(1).add("iLevel", "5")
obj(1).add("fHealth", "95.6")
obj(2).add("tName", "Mage")
obj(2).add("iLevel", "7")
obj(2).add("fHealth", "80.4")
obj(3).add("tName", "Archer")
obj(3).add("iLevel", "6")
obj(3).add("fHealth", "70.2")
' Show properties for all attr instances
For i As Integer = 1 To 3
Print "obj(" & i & ") State:"
obj(i).showAll()
Print
Next
' Edit properties in specific attr instances
obj(1).edit(1, "Champion")
obj(2).edit(2, "10")
obj(3).edit(3, "120.4")
' Show updated properties
Print "After Editing:"
For i As Integer = 1 To 3
Print "obj(" & i & ") State:"
obj(i).showAll()
Print
Next
' Remove the second property (iLevel)
obj(2).remove(2)
' Show properties after removing
Print "After Removing:"
obj.showAll()
' Clear all properties
For i As Integer = 1 To 3
obj(i).clearAll()
Next
Print "All properties cleared!"
Just a portion of the lengthy "convo" between me and the ChatGPT:
>i get error 9 for "As Property_T Ptr Properties()" during compilation. the error is "Expected expression"
ChatGPT said:
The error "Expected expression" at As Property_T Ptr Properties() occurs because FreeBASIC requires dynamic arrays to be declared in a different manner, and we cannot use the (). Specifically, (), when used after a pointer type, is reserved for array notation, but here we want to declare a pointer to the array, not an array itself.
Solution: Properly Declare the Pointer Array
Instead of declaring the Properties as As Property_T Ptr Properties(), we need to declare it as a dynamic array of pointers using As Property_T Ptr and initialize it later.
Here's how you can fix it:
Change the Declaration of Properties to be a dynamic array of pointers.
Initialize the Array correctly when creating a new instance of the UDT or attr.
Corrected CodeExplanation of FixesCode: Select all
Type Property_T As String Description As String tValue ' text As Integer iValue ' int As Single fValue ' float Declare Constructor(desc As String, v As String) End Type ' Constructor for Property_T Constructor Property_T(desc As String, v As String) Description = desc Select Case LCase(Left(desc, 1)) Case "i": iValue = Val(v) Case "f": fValue = Val(v) Case "t": tValue = v End Select End Constructor Type UDT Declare Constructor() Declare Function Count() As Integer Declare Sub Add(desc As String, v As String) Declare Sub Show(index As Integer) Declare Sub Edit(index As Integer, v As String) Declare Sub ClearAll() Private: As Integer nProperties As Property_T Ptr Properties() ' Dynamic array of pointers End Type ' Constructor for UDT Constructor UDT() nProperties = 0 ReDim Properties(0 To -1) As Property_T Ptr ' Initialize the array as empty End Constructor Function UDT.Count() As Integer Return nProperties End Function Sub UDT.Add(desc As String, v As String) ReDim Preserve Properties(0 To nProperties) As Property_T Ptr Properties(nProperties) = New Property_T(desc, v) nProperties += 1 End Sub Sub UDT.Show(index As Integer) If index < 1 Or index > nProperties Then Print "Invalid property index!" Exit Sub End If Print Properties(index - 1)->Description & ": " & Properties(index - 1)->tValue End Sub Sub UDT.Edit(index As Integer, v As String) If index < 1 Or index > nProperties Then Print "Invalid property index!" Exit Sub End If Properties(index - 1)->tValue = v End Sub Sub UDT.ClearAll() For i As Integer = 0 To nProperties - 1 Delete Properties(i) Next nProperties = 0 ReDim Properties(0 To -1) ' Reset to empty array End Sub ' Example of Usage Dim obj As UDT obj.Add("tName", "Hero") obj.Add("iLevel", "5") obj.Add("fHealth", "95.6") Print "Properties added:" For i As Integer = 1 To obj.Count() obj.Show(i) Next ' Edit a property obj.Edit(2, "10") Print "Properties after edit:" For i As Integer = 1 To obj.Count() obj.Show(i) Next ' Clear all properties obj.ClearAll() Print "All properties cleared!"
Dynamic Array of Pointers:
We declare As Property_T Ptr Properties() as a dynamic array of pointers to Property_T objects, allowing us to manage memory dynamically.
Array Initialization:
In the constructor of UDT, we initialize Properties with ReDim Properties(0 To -1), which creates an empty array.
Adding Properties:
The Add method resizes the Properties array and creates new Property_T objects, placing them in the array.
Memory Cleanup:
In the ClearAll method, we deallocate each property using Delete, ensuring proper memory management.
Expected Output
If you run the example code, the output should be:
NotesCode: Select all
Properties added: Name: Hero Level: 5 Health: 95.6 Properties after edit: Name: Hero Level: 10 Health: 95.6 All properties cleared!
The "Expected expression" error should now be resolved because the array is properly initialized as a dynamic array of pointers.
The example correctly adds, shows, edits, and clears properties using the nested UDT structure.
The code in the above convo is the same as in the quoted code above it, but I shared it just to show the thing doesn't know what it's talking about. It did an okay job besides that it doesn't work after several tries. I understand dynamic arrays and strings can't be within nested UDT arrays, but not sure why ChatGPT can't provide a proper revision.